From 6d918b0621ea7814edac71f9a151d244172c939f Mon Sep 17 00:00:00 2001 From: zhanghaibo Date: Wed, 22 Feb 2023 14:21:59 +0800 Subject: [PATCH 1/3] add elfutils-0.185 Signed-off-by: zhanghaibo --- ABOUT-NLS | 1 + AUTHORS | 4 + CONTRIBUTING | 106 + COPYING | 674 + COPYING-GPLV2 | 339 + COPYING-LGPLV3 | 165 + ChangeLog | 964 ++ GPG-KEY | 114 + INSTALL | 368 + Makefile.am | 103 + Makefile.in | 1013 ++ NEWS | 1736 ++ NOTES | 95 + README | 31 + README.en.md | 36 - README.md | 39 - THANKS | 6 + TODO | 195 + aclocal.m4 | 1535 ++ backends/ChangeLog | 1369 ++ backends/Makefile.am | 110 + backends/Makefile.in | 1206 ++ backends/aarch64_cfi.c | 85 + backends/aarch64_corenote.c | 172 + backends/aarch64_init.c | 66 + backends/aarch64_initreg.c | 92 + backends/aarch64_regs.c | 108 + backends/aarch64_reloc.def | 157 + backends/aarch64_retval.c | 376 + backends/aarch64_symbol.c | 136 + backends/aarch64_unwind.c | 83 + backends/alpha_auxv.c | 49 + backends/alpha_corenote.c | 70 + backends/alpha_init.c | 63 + backends/alpha_regs.c | 164 + backends/alpha_reloc.def | 63 + backends/alpha_retval.c | 150 + backends/alpha_symbol.c | 156 + backends/arm_attrs.c | 241 + backends/arm_auxv.c | 49 + backends/arm_cfi.c | 90 + backends/arm_corenote.c | 94 + backends/arm_init.c | 71 + backends/arm_initreg.c | 94 + backends/arm_regs.c | 120 + backends/arm_reloc.def | 157 + backends/arm_retval.c | 127 + backends/arm_symbol.c | 160 + backends/bpf_init.c | 54 + backends/bpf_regs.c | 60 + backends/bpf_reloc.def | 32 + backends/bpf_symbol.c | 55 + backends/common-reloc.c | 162 + backends/csky_attrs.c | 67 + backends/csky_cfi.c | 60 + backends/csky_corenote.c | 61 + backends/csky_init.c | 60 + backends/csky_initreg.c | 87 + backends/csky_regs.c | 101 + backends/csky_reloc.def | 86 + backends/csky_symbol.c | 77 + backends/i386_auxv.c | 52 + backends/i386_cfi.c | 68 + backends/i386_corenote.c | 138 + backends/i386_init.c | 64 + backends/i386_initreg.c | 79 + backends/i386_regs.c | 153 + backends/i386_reloc.def | 71 + backends/i386_retval.c | 140 + backends/i386_symbol.c | 76 + backends/i386_unwind.c | 84 + backends/ia64_init.c | 60 + backends/ia64_regs.c | 273 + backends/ia64_reloc.def | 113 + backends/ia64_retval.c | 366 + backends/ia64_symbol.c | 158 + backends/libebl_CPU.h | 75 + backends/linux-core-note.c | 315 + backends/m68k_cfi.c | 58 + backends/m68k_corenote.c | 72 + backends/m68k_init.c | 58 + backends/m68k_initreg.c | 82 + backends/m68k_regs.c | 96 + backends/m68k_reloc.def | 70 + backends/m68k_retval.c | 151 + backends/m68k_symbol.c | 71 + backends/ppc64_corenote.c | 2 + backends/ppc64_init.c | 105 + backends/ppc64_reloc.def | 161 + backends/ppc64_resolve_sym.c | 63 + backends/ppc64_retval.c | 195 + backends/ppc64_symbol.c | 134 + backends/ppc64_unwind.c | 76 + backends/ppc_attrs.c | 86 + backends/ppc_auxv.c | 55 + backends/ppc_cfi.c | 77 + backends/ppc_corenote.c | 145 + backends/ppc_init.c | 67 + backends/ppc_initreg.c | 116 + backends/ppc_regs.c | 208 + backends/ppc_reloc.def | 137 + backends/ppc_retval.c | 191 + backends/ppc_symbol.c | 188 + backends/riscv64_corenote.c | 2 + backends/riscv_cfi.c | 75 + backends/riscv_corenote.c | 88 + backends/riscv_init.c | 72 + backends/riscv_initreg.c | 77 + backends/riscv_regs.c | 177 + backends/riscv_reloc.def | 83 + backends/riscv_retval.c | 251 + backends/riscv_symbol.c | 121 + backends/s390_cfi.c | 65 + backends/s390_corenote.c | 189 + backends/s390_init.c | 74 + backends/s390_initreg.c | 95 + backends/s390_regs.c | 146 + backends/s390_reloc.def | 91 + backends/s390_retval.c | 144 + backends/s390_symbol.c | 95 + backends/s390_unwind.c | 139 + backends/s390x_corenote.c | 2 + backends/sh_corenote.c | 88 + backends/sh_init.c | 57 + backends/sh_regs.c | 191 + backends/sh_reloc.def | 67 + backends/sh_retval.c | 131 + backends/sh_symbol.c | 95 + backends/sparc64_corenote.c | 2 + backends/sparc_attrs.c | 105 + backends/sparc_auxv.c | 46 + backends/sparc_cfi.c | 83 + backends/sparc_corenote.c | 120 + backends/sparc_init.c | 78 + backends/sparc_initreg.c | 129 + backends/sparc_regs.c | 111 + backends/sparc_reloc.def | 124 + backends/sparc_retval.c | 159 + backends/sparc_symbol.c | 149 + backends/x32_corenote.c | 2 + backends/x86_64_cfi.c | 63 + backends/x86_64_corenote.c | 139 + backends/x86_64_init.c | 69 + backends/x86_64_initreg.c | 73 + backends/x86_64_regs.c | 186 + backends/x86_64_reloc.def | 65 + backends/x86_64_retval.c | 194 + backends/x86_64_symbol.c | 81 + backends/x86_64_unwind.c | 86 + backends/x86_corenote.c | 51 + config.h.in | 180 + config/10-default-yama-scope.conf | 35 + config/ChangeLog | 564 + config/Makefile.am | 66 + config/Makefile.in | 588 + config/ar-lib | 271 + config/compile | 348 + config/config.guess | 1480 ++ config/config.rpath | 684 + config/config.sub | 1801 ++ config/debuginfod.service | 17 + config/debuginfod.sysconfig | 14 + config/depcomp | 791 + config/elfutils.spec.in | 1209 ++ config/eu.am | 139 + config/install-sh | 541 + config/known-dwarf.awk | 56 + config/libdebuginfod.pc.in | 12 + config/libdw.pc.in | 22 + config/libelf.pc.in | 14 + config/missing | 215 + config/profile.csh.in | 11 + config/profile.sh.in | 4 + config/test-driver | 150 + config/version.h.in | 38 + config/ylwrap | 247 + configure | 14284 ++++++++++++++++ configure.ac | 847 + debuginfod/ChangeLog | 643 + debuginfod/Makefile.am | 146 + debuginfod/Makefile.in | 949 + debuginfod/debuginfod-client.c | 1330 ++ debuginfod/debuginfod-find.c | 239 + debuginfod/debuginfod.cxx | 3615 ++++ debuginfod/debuginfod.h | 104 + debuginfod/debuginfod.h.in | 104 + debuginfod/libdebuginfod.map | 20 + doc/COPYING-GFDL | 455 + doc/ChangeLog | 201 + doc/Makefile.am | 41 + doc/Makefile.in | 697 + doc/README | 20 + doc/debuginfod-find.1 | 160 + doc/debuginfod.8 | 455 + doc/debuginfod_add_http_header.3 | 1 + doc/debuginfod_begin.3 | 1 + doc/debuginfod_end.3 | 1 + doc/debuginfod_find_debuginfo.3 | 349 + doc/debuginfod_find_executable.3 | 1 + doc/debuginfod_find_source.3 | 1 + doc/debuginfod_get_url.3 | 1 + doc/debuginfod_get_user_data.3 | 1 + doc/debuginfod_set_progressfn.3 | 1 + doc/debuginfod_set_user_data.3 | 1 + doc/elf_begin.3 | 37 + doc/elf_clone.3 | 14 + doc/elf_getdata.3 | 28 + doc/elf_update.3 | 14 + doc/elfclassify.1 | 197 + doc/readelf.1 | 511 + elfutils.spec | 1209 ++ lib/ChangeLog | 338 + lib/Makefile.am | 47 + lib/Makefile.in | 726 + lib/atomics.h | 37 + lib/bpf.h | 86 + lib/color.c | 238 + lib/color.h | 65 + lib/crc32.c | 102 + lib/crc32_file.c | 92 + lib/dynamicsizehash.c | 315 + lib/dynamicsizehash.h | 127 + lib/dynamicsizehash_concurrent.c | 482 + lib/dynamicsizehash_concurrent.h | 118 + lib/eu-config.h | 210 + lib/fixedsizehash.h | 272 + lib/libeu.h | 46 + lib/list.h | 100 + lib/next_prime.c | 66 + lib/printversion.c | 45 + lib/printversion.h | 49 + lib/stdatomic-fbsd.h | 442 + lib/system.h | 176 + lib/xmalloc.c | 75 + lib/xstrdup.c | 42 + lib/xstrndup.c | 46 + libasm/ChangeLog | 289 + libasm/Makefile.am | 88 + libasm/Makefile.in | 950 + libasm/asm_abort.c | 60 + libasm/asm_addint16.c | 32 + libasm/asm_addint32.c | 32 + libasm/asm_addint64.c | 32 + libasm/asm_addint8.c | 121 + libasm/asm_addsleb128.c | 97 + libasm/asm_addstrz.c | 125 + libasm/asm_adduint16.c | 32 + libasm/asm_adduint32.c | 32 + libasm/asm_adduint64.c | 32 + libasm/asm_adduint8.c | 54 + libasm/asm_adduleb128.c | 93 + libasm/asm_align.c | 175 + libasm/asm_begin.c | 181 + libasm/asm_end.c | 617 + libasm/asm_error.c | 95 + libasm/asm_fill.c | 74 + libasm/asm_getelf.c | 43 + libasm/asm_newabssym.c | 131 + libasm/asm_newcomsym.c | 114 + libasm/asm_newscn.c | 211 + libasm/asm_newscn_ingrp.c | 77 + libasm/asm_newscngrp.c | 102 + libasm/asm_newsubscn.c | 97 + libasm/asm_newsym.c | 136 + libasm/asm_scngrp_newsignature.c | 46 + libasm/disasm_begin.c | 64 + libasm/disasm_cb.c | 181 + libasm/disasm_end.c | 45 + libasm/disasm_str.c | 72 + libasm/libasm.h | 203 + libasm/libasm.map | 38 + libasm/libasmP.h | 307 + libasm/symbolhash.c | 54 + libasm/symbolhash.h | 40 + libcpu/ChangeLog | 512 + libcpu/Makefile.am | 99 + libcpu/Makefile.in | 811 + libcpu/bpf_disasm.c | 504 + libcpu/defs/i386 | 970 ++ libcpu/i386_data.h | 1418 ++ libcpu/i386_dis.h | 1657 ++ libcpu/i386_disasm.c | 1156 ++ libcpu/i386_gendis.c | 71 + libcpu/i386_lex.c | 2272 +++ libcpu/i386_lex.l | 129 + libcpu/i386_parse.c | 3117 ++++ libcpu/i386_parse.h | 113 + libcpu/i386_parse.y | 1687 ++ libcpu/memory-access.h | 182 + libcpu/riscv_disasm.c | 1501 ++ libcpu/x86_64_dis.h | 1632 ++ libcpu/x86_64_disasm.c | 34 + libdw/ChangeLog | 3732 ++++ libdw/Makefile.am | 154 + libdw/Makefile.in | 1445 ++ libdw/cfi.c | 530 + libdw/cfi.h | 238 + libdw/cie.c | 196 + libdw/dwarf.h | 1029 ++ libdw/dwarf_abbrev_hash.c | 45 + libdw/dwarf_abbrev_hash.h | 38 + libdw/dwarf_abbrevhaschildren.c | 43 + libdw/dwarf_addrdie.c | 51 + libdw/dwarf_aggregate_size.c | 224 + libdw/dwarf_arrayorder.c | 49 + libdw/dwarf_attr.c | 52 + libdw/dwarf_attr_integrate.c | 73 + libdw/dwarf_begin.c | 99 + libdw/dwarf_begin_elf.c | 484 + libdw/dwarf_bitoffset.c | 49 + libdw/dwarf_bitsize.c | 49 + libdw/dwarf_bytesize.c | 49 + libdw/dwarf_cfi_addrframe.c | 54 + libdw/dwarf_cfi_end.c | 48 + libdw/dwarf_child.c | 190 + libdw/dwarf_cu_die.c | 62 + libdw/dwarf_cu_getdwarf.c | 46 + libdw/dwarf_cu_info.c | 103 + libdw/dwarf_cuoffset.c | 44 + libdw/dwarf_decl_column.c | 44 + libdw/dwarf_decl_file.c | 89 + libdw/dwarf_decl_line.c | 70 + libdw/dwarf_default_lower_bound.c | 91 + libdw/dwarf_die_addr_die.c | 70 + libdw/dwarf_diecu.c | 52 + libdw/dwarf_diename.c | 47 + libdw/dwarf_dieoffset.c | 45 + libdw/dwarf_end.c | 157 + libdw/dwarf_entry_breakpoints.c | 163 + libdw/dwarf_entrypc.c | 48 + libdw/dwarf_error.c | 130 + libdw/dwarf_filesrc.c | 51 + libdw/dwarf_formaddr.c | 148 + libdw/dwarf_formblock.c | 103 + libdw/dwarf_formflag.c | 59 + libdw/dwarf_formref.c | 112 + libdw/dwarf_formref_die.c | 137 + libdw/dwarf_formsdata.c | 101 + libdw/dwarf_formstring.c | 180 + libdw/dwarf_formudata.c | 357 + libdw/dwarf_frame_cfa.c | 77 + libdw/dwarf_frame_info.c | 50 + libdw/dwarf_frame_register.c | 119 + libdw/dwarf_func_inline.c | 101 + libdw/dwarf_get_units.c | 131 + libdw/dwarf_getabbrev.c | 186 + libdw/dwarf_getabbrevattr.c | 94 + libdw/dwarf_getabbrevcode.c | 43 + libdw/dwarf_getabbrevtag.c | 43 + libdw/dwarf_getalt.c | 184 + libdw/dwarf_getarange_addr.c | 60 + libdw/dwarf_getarangeinfo.c | 53 + libdw/dwarf_getaranges.c | 277 + libdw/dwarf_getattrcnt.c | 61 + libdw/dwarf_getattrs.c | 132 + libdw/dwarf_getcfi.c | 78 + libdw/dwarf_getcfi_elf.c | 338 + libdw/dwarf_getelf.c | 47 + libdw/dwarf_getfuncs.c | 118 + libdw/dwarf_getlocation.c | 1030 ++ libdw/dwarf_getlocation_attr.c | 162 + libdw/dwarf_getlocation_die.c | 95 + libdw/dwarf_getlocation_implicit_pointer.c | 78 + libdw/dwarf_getmacros.c | 593 + libdw/dwarf_getpubnames.c | 244 + libdw/dwarf_getscopes.c | 203 + libdw/dwarf_getscopes_die.c | 74 + libdw/dwarf_getscopevar.c | 159 + libdw/dwarf_getsrc_die.c | 74 + libdw/dwarf_getsrc_file.c | 178 + libdw/dwarf_getsrcdirs.c | 45 + libdw/dwarf_getsrcfiles.c | 111 + libdw/dwarf_getsrclines.c | 1228 ++ libdw/dwarf_getstring.c | 63 + libdw/dwarf_hasattr.c | 77 + libdw/dwarf_hasattr_integrate.c | 73 + libdw/dwarf_haschildren.c | 51 + libdw/dwarf_hasform.c | 45 + libdw/dwarf_haspc.c | 54 + libdw/dwarf_highpc.c | 70 + libdw/dwarf_line_file.c | 52 + libdw/dwarf_lineaddr.c | 46 + libdw/dwarf_linebeginstatement.c | 46 + libdw/dwarf_lineblock.c | 46 + libdw/dwarf_linecol.c | 46 + libdw/dwarf_linediscriminator.c | 45 + libdw/dwarf_lineendsequence.c | 46 + libdw/dwarf_lineepiloguebegin.c | 46 + libdw/dwarf_lineisa.c | 45 + libdw/dwarf_lineno.c | 46 + libdw/dwarf_lineop_index.c | 45 + libdw/dwarf_lineprologueend.c | 46 + libdw/dwarf_linesrc.c | 56 + libdw/dwarf_lowpc.c | 48 + libdw/dwarf_macro_getparamcnt.c | 43 + libdw/dwarf_macro_getsrcfiles.c | 86 + libdw/dwarf_macro_opcode.c | 46 + libdw/dwarf_macro_param.c | 46 + libdw/dwarf_macro_param1.c | 48 + libdw/dwarf_macro_param2.c | 55 + libdw/dwarf_next_cfi.c | 253 + libdw/dwarf_next_lines.c | 197 + libdw/dwarf_nextcu.c | 309 + libdw/dwarf_offabbrev.c | 51 + libdw/dwarf_offdie.c | 84 + libdw/dwarf_onearange.c | 50 + libdw/dwarf_onesrcline.c | 50 + libdw/dwarf_peel_type.c | 80 + libdw/dwarf_ranges.c | 562 + libdw/dwarf_setalt.c | 49 + libdw/dwarf_siblingof.c | 144 + libdw/dwarf_sig8_hash.c | 41 + libdw/dwarf_sig8_hash.h | 43 + libdw/dwarf_srclang.c | 50 + libdw/dwarf_tag.c | 94 + libdw/dwarf_whatattr.c | 42 + libdw/dwarf_whatform.c | 42 + libdw/encoded-value.h | 232 + libdw/fde.c | 324 + libdw/frame-cache.c | 70 + libdw/known-dwarf.h | 782 + libdw/libdw.h | 1111 ++ libdw/libdw.map | 362 + libdw/libdwP.h | 1389 ++ libdw/libdw_alloc.c | 156 + libdw/libdw_find_split_unit.c | 147 + libdw/libdw_findcu.c | 307 + libdw/libdw_form.c | 144 + libdw/libdw_visit_scopes.c | 192 + libdw/memory-access.h | 407 + libdwelf/ChangeLog | 95 + libdwelf/Makefile.am | 57 + libdwelf/Makefile.in | 794 + libdwelf/dwelf_dwarf_gnu_debugaltlink.c | 62 + libdwelf/dwelf_elf_begin.c | 64 + libdwelf/dwelf_elf_e_machine_string.c | 406 + libdwelf/dwelf_elf_gnu_build_id.c | 158 + libdwelf/dwelf_elf_gnu_debuglink.c | 99 + libdwelf/dwelf_scn_gnu_compressed_size.c | 77 + libdwelf/dwelf_strtab.c | 360 + libdwelf/libdwelf.h | 147 + libdwelf/libdwelfP.h | 42 + libdwfl/ChangeLog | 3310 ++++ libdwfl/Makefile.am | 99 + libdwfl/Makefile.in | 1099 ++ libdwfl/argp-std.c | 381 + libdwfl/bzip2.c | 4 + libdwfl/core-file.c | 641 + libdwfl/cu.c | 317 + libdwfl/debuginfod-client.c | 128 + libdwfl/derelocate.c | 434 + libdwfl/dwfl_addrdie.c | 40 + libdwfl/dwfl_addrdwarf.c | 41 + libdwfl/dwfl_addrmodule.c | 42 + libdwfl/dwfl_begin.c | 55 + libdwfl/dwfl_build_id_find_debuginfo.c | 132 + libdwfl/dwfl_build_id_find_elf.c | 213 + libdwfl/dwfl_cumodule.c | 40 + libdwfl/dwfl_dwarf_line.c | 47 + libdwfl/dwfl_end.c | 70 + libdwfl/dwfl_error.c | 186 + libdwfl/dwfl_frame.c | 458 + libdwfl/dwfl_frame_pc.c | 64 + libdwfl/dwfl_frame_regs.c | 61 + libdwfl/dwfl_getdwarf.c | 63 + libdwfl/dwfl_getmodules.c | 96 + libdwfl/dwfl_getsrc.c | 40 + libdwfl/dwfl_getsrclines.c | 52 + libdwfl/dwfl_line_comp_dir.c | 47 + libdwfl/dwfl_linecu.c | 45 + libdwfl/dwfl_lineinfo.c | 65 + libdwfl/dwfl_linemodule.c | 42 + libdwfl/dwfl_module.c | 243 + libdwfl/dwfl_module_addrdie.c | 49 + libdwfl/dwfl_module_addrname.c | 42 + libdwfl/dwfl_module_addrsym.c | 335 + libdwfl/dwfl_module_build_id.c | 121 + libdwfl/dwfl_module_dwarf_cfi.c | 73 + libdwfl/dwfl_module_eh_cfi.c | 59 + libdwfl/dwfl_module_getdwarf.c | 1507 ++ libdwfl/dwfl_module_getelf.c | 71 + libdwfl/dwfl_module_getsrc.c | 85 + libdwfl/dwfl_module_getsrc_file.c | 178 + libdwfl/dwfl_module_getsym.c | 220 + libdwfl/dwfl_module_info.c | 65 + libdwfl/dwfl_module_nextcu.c | 48 + libdwfl/dwfl_module_register_names.c | 82 + libdwfl/dwfl_module_report_build_id.c | 84 + libdwfl/dwfl_module_return_value_location.c | 66 + libdwfl/dwfl_nextcu.c | 86 + libdwfl/dwfl_onesrcline.c | 60 + libdwfl/dwfl_report_elf.c | 342 + libdwfl/dwfl_segment_report_module.c | 985 ++ libdwfl/dwfl_validate_address.c | 65 + libdwfl/dwfl_version.c | 39 + libdwfl/elf-from-memory.c | 372 + libdwfl/find-debuginfo.c | 430 + libdwfl/frame_unwind.c | 777 + libdwfl/gzip.c | 404 + libdwfl/image-header.c | 105 + libdwfl/libdwfl.h | 802 + libdwfl/libdwflP.h | 798 + libdwfl/libdwfl_crc32.c | 35 + libdwfl/libdwfl_crc32_file.c | 35 + libdwfl/lines.c | 56 + libdwfl/link_map.c | 1057 ++ libdwfl/linux-core-attach.c | 434 + libdwfl/linux-kernel-modules.c | 1040 ++ libdwfl/linux-pid-attach.c | 540 + libdwfl/linux-proc-maps.c | 440 + libdwfl/lzma.c | 4 + libdwfl/offline.c | 318 + libdwfl/open.c | 204 + libdwfl/relocate.c | 824 + libdwfl/segment.c | 330 + libdwfl/zstd.c | 4 + libebl/ChangeLog | 1328 ++ libebl/Makefile.am | 64 + libebl/Makefile.in | 920 + libebl/ebl-hooks.h | 188 + libebl/ebl_check_special_section.c | 41 + libebl/ebl_check_special_symbol.c | 45 + libebl/ebl_data_marker_symbol.c | 44 + libebl/eblabicfi.c | 46 + libebl/eblauxvinfo.c | 100 + libebl/eblbackendname.c | 42 + libebl/eblbsspltp.c | 41 + libebl/eblcheckobjattr.c | 56 + libebl/eblcheckreloctargettype.c | 55 + libebl/eblclosebackend.c | 50 + libebl/eblcopyrelocp.c | 41 + libebl/eblcorenote.c | 79 + libebl/eblcorenotetypename.c | 107 + libebl/ebldebugscnp.c | 42 + libebl/ebldwarftoregno.c | 40 + libebl/ebldynamictagcheck.c | 54 + libebl/ebldynamictagname.c | 111 + libebl/eblelfclass.c | 41 + libebl/eblelfdata.c | 41 + libebl/eblelfmachine.c | 41 + libebl/eblgotpcreloccheck.c | 42 + libebl/eblinitreg.c | 59 + libebl/eblmachineflagcheck.c | 41 + libebl/eblmachineflagname.c | 88 + libebl/eblmachinesectionflagcheck.c | 40 + libebl/eblnonerelocp.c | 41 + libebl/eblnormalizepc.c | 41 + libebl/eblobjnote.c | 658 + libebl/eblobjnotetypename.c | 138 + libebl/eblopenbackend.c | 713 + libebl/eblosabiname.c | 80 + libebl/eblreginfo.c | 44 + libebl/eblrelativerelocp.c | 41 + libebl/eblrelocsimpletype.c | 40 + libebl/eblreloctypecheck.c | 41 + libebl/eblreloctypename.c | 49 + libebl/eblrelocvaliduse.c | 41 + libebl/eblresolvesym.c | 43 + libebl/eblretval.c | 42 + libebl/eblsectionname.c | 90 + libebl/eblsectionstripp.c | 70 + libebl/eblsectiontypename.c | 123 + libebl/eblsegmenttypename.c | 88 + libebl/eblstother.c | 41 + libebl/eblsymbolbindingname.c | 75 + libebl/eblsymboltypename.c | 81 + libebl/eblsysvhashentrysize.c | 41 + libebl/eblunwind.c | 44 + libebl/libebl.h | 403 + libebl/libeblP.h | 94 + libelf/ChangeLog | 1880 ++ libelf/Makefile.am | 137 + libelf/Makefile.in | 1364 ++ libelf/abstract.h | 330 + libelf/chdr_xlate.h | 33 + libelf/common.h | 163 + libelf/dl-hash.h | 75 + libelf/elf-knowledge.h | 101 + libelf/elf.h | 4105 +++++ libelf/elf32_checksum.c | 168 + libelf/elf32_fsize.c | 60 + libelf/elf32_getchdr.c | 83 + libelf/elf32_getehdr.c | 96 + libelf/elf32_getphdr.c | 265 + libelf/elf32_getshdr.c | 299 + libelf/elf32_newehdr.c | 91 + libelf/elf32_newphdr.c | 193 + libelf/elf32_offscn.c | 99 + libelf/elf32_updatefile.c | 855 + libelf/elf32_updatenull.c | 461 + libelf/elf32_xlatetof.c | 109 + libelf/elf32_xlatetom.c | 114 + libelf/elf64_checksum.c | 31 + libelf/elf64_fsize.c | 31 + libelf/elf64_getchdr.c | 30 + libelf/elf64_getehdr.c | 31 + libelf/elf64_getphdr.c | 31 + libelf/elf64_getshdr.c | 31 + libelf/elf64_newehdr.c | 31 + libelf/elf64_newphdr.c | 31 + libelf/elf64_offscn.c | 31 + libelf/elf64_updatefile.c | 30 + libelf/elf64_updatenull.c | 30 + libelf/elf64_xlatetof.c | 31 + libelf/elf64_xlatetom.c | 31 + libelf/elf_begin.c | 1204 ++ libelf/elf_clone.c | 81 + libelf/elf_cntl.c | 81 + libelf/elf_compress.c | 535 + libelf/elf_compress_gnu.c | 212 + libelf/elf_end.c | 239 + libelf/elf_error.c | 355 + libelf/elf_fill.c | 46 + libelf/elf_flagdata.c | 68 + libelf/elf_flagehdr.c | 65 + libelf/elf_flagelf.c | 67 + libelf/elf_flagphdr.c | 65 + libelf/elf_flagscn.c | 65 + libelf/elf_flagshdr.c | 65 + libelf/elf_getarhdr.c | 73 + libelf/elf_getaroff.c | 53 + libelf/elf_getarsym.c | 331 + libelf/elf_getbase.c | 44 + libelf/elf_getdata.c | 573 + libelf/elf_getdata_rawchunk.c | 185 + libelf/elf_getident.c | 61 + libelf/elf_getphdrnum.c | 151 + libelf/elf_getscn.c | 120 + libelf/elf_getshdrnum.c | 87 + libelf/elf_getshdrstrndx.c | 235 + libelf/elf_gnu_hash.c | 46 + libelf/elf_hash.c | 44 + libelf/elf_kind.c | 44 + libelf/elf_memory.c | 50 + libelf/elf_ndxscn.c | 47 + libelf/elf_newdata.c | 136 + libelf/elf_newscn.c | 162 + libelf/elf_next.c | 72 + libelf/elf_nextscn.c | 83 + libelf/elf_rand.c | 63 + libelf/elf_rawdata.c | 76 + libelf/elf_rawfile.c | 67 + libelf/elf_readall.c | 152 + libelf/elf_scnshndx.c | 50 + libelf/elf_strptr.c | 240 + libelf/elf_update.c | 238 + libelf/elf_version.c | 62 + libelf/exttypes.h | 104 + libelf/gelf.h | 342 + libelf/gelf_checksum.c | 48 + libelf/gelf_fsize.c | 103 + libelf/gelf_getauxv.c | 107 + libelf/gelf_getchdr.c | 69 + libelf/gelf_getclass.c | 44 + libelf/gelf_getdyn.c | 108 + libelf/gelf_getehdr.c | 108 + libelf/gelf_getlib.c | 77 + libelf/gelf_getmove.c | 79 + libelf/gelf_getnote.c | 116 + libelf/gelf_getphdr.c | 135 + libelf/gelf_getrel.c | 99 + libelf/gelf_getrela.c | 100 + libelf/gelf_getshdr.c | 103 + libelf/gelf_getsym.c | 114 + libelf/gelf_getsyminfo.c | 77 + libelf/gelf_getsymshndx.c | 136 + libelf/gelf_getverdaux.c | 79 + libelf/gelf_getverdef.c | 78 + libelf/gelf_getvernaux.c | 81 + libelf/gelf_getverneed.c | 81 + libelf/gelf_getversym.c | 86 + libelf/gelf_newehdr.c | 46 + libelf/gelf_newphdr.c | 46 + libelf/gelf_offscn.c | 55 + libelf/gelf_update_auxv.c | 111 + libelf/gelf_update_dyn.c | 107 + libelf/gelf_update_ehdr.c | 118 + libelf/gelf_update_lib.c | 75 + libelf/gelf_update_move.c | 77 + libelf/gelf_update_phdr.c | 143 + libelf/gelf_update_rel.c | 108 + libelf/gelf_update_rela.c | 111 + libelf/gelf_update_shdr.c | 111 + libelf/gelf_update_sym.c | 116 + libelf/gelf_update_syminfo.c | 83 + libelf/gelf_update_symshndx.c | 145 + libelf/gelf_update_verdaux.c | 78 + libelf/gelf_update_verdef.c | 78 + libelf/gelf_update_vernaux.c | 78 + libelf/gelf_update_verneed.c | 78 + libelf/gelf_update_versym.c | 77 + libelf/gelf_xlate.c | 210 + libelf/gelf_xlate.h | 57 + libelf/gelf_xlatetof.c | 50 + libelf/gelf_xlatetom.c | 50 + libelf/gnuhash_xlate.h | 74 + libelf/libelf.h | 522 + libelf/libelf.map | 150 + libelf/libelfP.h | 615 + libelf/libelf_crc32.c | 35 + libelf/libelf_next_prime.c | 33 + libelf/nlist.c | 246 + libelf/nlist.h | 56 + libelf/note_xlate.h | 98 + libelf/version_xlate.h | 230 + m4/ax_cxx_compile_stdcxx.m4 | 556 + m4/biarch.m4 | 47 + m4/gettext.m4 | 386 + m4/host-cpu-c-abi.m4 | 675 + m4/iconv.m4 | 288 + m4/intlmacosx.m4 | 65 + m4/lib-ld.m4 | 168 + m4/lib-link.m4 | 800 + m4/lib-prefix.m4 | 320 + m4/nls.m4 | 32 + m4/po.m4 | 450 + m4/progtest.m4 | 91 + m4/zip.m4 | 20 + po/ChangeLog | 259 + po/LINGUAS | 5 + po/Makefile.in.in | 510 + po/Makevars | 74 + po/POTFILES.in | 54 + po/Rules-quot | 62 + po/boldquot.sed | 10 + po/de.gmo | Bin 0 -> 17890 bytes po/de.po | 7004 ++++++++ po/elfutils.pot | 6781 ++++++++ po/en@boldquot.gmo | Bin 0 -> 156548 bytes po/en@boldquot.header | 25 + po/en@boldquot.po | 7364 ++++++++ po/en@quot.gmo | Bin 0 -> 154720 bytes po/en@quot.header | 22 + po/en@quot.po | 7328 ++++++++ po/es.gmo | Bin 0 -> 107373 bytes po/es.po | 8092 +++++++++ po/insert-header.sin | 28 + po/ja.gmo | Bin 0 -> 57859 bytes po/ja.po | 7726 +++++++++ po/pl.gmo | Bin 0 -> 167391 bytes po/pl.po | 7487 ++++++++ po/quot.sed | 6 + po/remove-potcdate.sin | 25 + po/stamp-po | 1 + po/uk.gmo | Bin 0 -> 195958 bytes po/uk.po | 8101 +++++++++ src/ChangeLog | 5270 ++++++ src/Makefile.am | 115 + src/Makefile.in | 1100 ++ src/addr2line.c | 819 + src/ar.c | 1576 ++ src/arlib-argp.c | 95 + src/arlib.c | 280 + src/arlib.h | 98 + src/arlib2.c | 41 + src/debugpred.h | 45 + src/elfclassify.c | 1045 ++ src/elfcmp.c | 911 + src/elfcompress.c | 1362 ++ src/elflint.c | 4825 ++++++ src/findtextrel.c | 613 + src/make-debug-archive.in | 132 + src/nm.c | 1635 ++ src/objdump.c | 799 + src/ranlib.c | 287 + src/readelf.c | 12885 ++++++++++++++ src/size.c | 667 + src/stack.c | 763 + src/strings.c | 747 + src/strip.c | 2769 +++ src/unstrip.c | 2632 +++ tests/ChangeLog | 4263 +++++ tests/Makefile.am | 703 + tests/Makefile.in | 4642 +++++ tests/addrcfi.c | 233 + tests/addrscopes.c | 196 + tests/addrx_constx-4.dwo.bz2 | Bin 0 -> 809 bytes tests/addrx_constx-5.dwo.bz2 | Bin 0 -> 824 bytes tests/addsections.c | 331 + tests/aggregate_size.c | 83 + tests/all-dwarf-ranges.c | 90 + tests/alldts.c | 271 + tests/allfcts.c | 112 + tests/allregs.c | 204 + tests/arextract.c | 159 + tests/arls.c | 111 + tests/arsymtest.c | 136 + tests/asm-tst1.c | 257 + tests/asm-tst2.c | 279 + tests/asm-tst3.c | 340 + tests/asm-tst4.c | 105 + tests/asm-tst5.c | 117 + tests/asm-tst6.c | 151 + tests/asm-tst7.c | 182 + tests/asm-tst8.c | 190 + tests/asm-tst9.c | 336 + tests/attr-integrate-skel.c | 109 + tests/backtrace-child.c | 248 + tests/backtrace-data.c | 332 + tests/backtrace-dwarf.c | 181 + tests/backtrace-subr.sh | 203 + tests/backtrace.aarch64.core.bz2 | Bin 0 -> 7865 bytes tests/backtrace.aarch64.exec.bz2 | Bin 0 -> 370058 bytes tests/backtrace.aarch64.fp.core.bz2 | Bin 0 -> 8437 bytes tests/backtrace.aarch64.fp.exec.bz2 | Bin 0 -> 394972 bytes tests/backtrace.c | 494 + tests/backtrace.i386.core.bz2 | Bin 0 -> 8777 bytes tests/backtrace.i386.exec.bz2 | Bin 0 -> 383356 bytes tests/backtrace.i386.fp.core.bz2 | Bin 0 -> 8532 bytes tests/backtrace.i386.fp.exec.bz2 | Bin 0 -> 357436 bytes tests/backtrace.ppc.core.bz2 | Bin 0 -> 44482 bytes tests/backtrace.ppc.exec.bz2 | Bin 0 -> 352197 bytes tests/backtrace.ppc64le.fp.core.bz2 | Bin 0 -> 37786 bytes tests/backtrace.ppc64le.fp.exec.bz2 | Bin 0 -> 383808 bytes tests/backtrace.s390.core.bz2 | Bin 0 -> 7375 bytes tests/backtrace.s390.exec.bz2 | Bin 0 -> 352692 bytes tests/backtrace.s390x.core.bz2 | Bin 0 -> 7740 bytes tests/backtrace.s390x.exec.bz2 | Bin 0 -> 347228 bytes tests/backtrace.sparc.core.bz2 | Bin 0 -> 9628 bytes tests/backtrace.sparc.exec.bz2 | Bin 0 -> 348964 bytes tests/backtrace.x32.core.bz2 | Bin 0 -> 9830 bytes tests/backtrace.x32.exec.bz2 | Bin 0 -> 407568 bytes tests/backtrace.x86_64.core.bz2 | Bin 0 -> 11115 bytes tests/backtrace.x86_64.exec.bz2 | Bin 0 -> 401581 bytes tests/backtrace.x86_64.fp.core.bz2 | Bin 0 -> 11072 bytes tests/backtrace.x86_64.fp.exec.bz2 | Bin 0 -> 434645 bytes tests/buildid.c | 81 + tests/cleanup-13.c | 316 + tests/coverage.sh | 40 + tests/debug-ranges-no-lowpc.o.bz2 | Bin 0 -> 376 bytes tests/debugaltlink.c | 83 + .../hithere-dbgsym_1.0-1_amd64.ddeb | Bin 0 -> 3820 bytes .../hithere_1.0-1.debian.tar.xz | Bin 0 -> 764 bytes tests/debuginfod-debs/hithere_1.0-1.dsc | 19 + tests/debuginfod-debs/hithere_1.0-1_amd64.deb | Bin 0 -> 3020 bytes tests/debuginfod-debs/hithere_1.0.orig.tar.gz | Bin 0 -> 617 bytes .../fedora30/hello2-1.0-2.src.rpm | Bin 0 -> 8087 bytes .../fedora30/hello2-1.0-2.x86_64.rpm | Bin 0 -> 10448 bytes .../hello2-debuginfo-1.0-2.x86_64.rpm | Bin 0 -> 11316 bytes .../hello2-debugsource-1.0-2.x86_64.rpm | Bin 0 -> 7308 bytes .../fedora30/hello2-two-1.0-2.x86_64.rpm | Bin 0 -> 10380 bytes .../hello2-two-debuginfo-1.0-2.x86_64.rpm | Bin 0 -> 10888 bytes .../fedora31/hello3-1.0-2.src.rpm | Bin 0 -> 8135 bytes .../fedora31/hello3-1.0-2.x86_64.rpm | Bin 0 -> 10350 bytes .../hello3-debuginfo-1.0-2.x86_64.rpm | Bin 0 -> 11223 bytes .../hello3-debugsource-1.0-2.x86_64.rpm | Bin 0 -> 7268 bytes .../fedora31/hello3-two-1.0-2.x86_64.rpm | Bin 0 -> 10263 bytes .../hello3-two-debuginfo-1.0-2.x86_64.rpm | Bin 0 -> 10806 bytes tests/debuginfod-rpms/hello2.spec. | 57 + .../rhel6/hello2-1.0-2.i686.rpm | Bin 0 -> 4112 bytes .../rhel6/hello2-1.0-2.src.rpm | Bin 0 -> 3816 bytes .../rhel6/hello2-debuginfo-1.0-2.i686.rpm | Bin 0 -> 6060 bytes .../rhel6/hello2-two-1.0-2.i686.rpm | Bin 0 -> 4052 bytes .../rhel7/hello2-1.0-2.src.rpm | Bin 0 -> 3819 bytes .../rhel7/hello2-1.0-2.x86_64.rpm | Bin 0 -> 5156 bytes .../rhel7/hello2-debuginfo-1.0-2.x86_64.rpm | Bin 0 -> 6936 bytes .../rhel7/hello2-two-1.0-2.x86_64.rpm | Bin 0 -> 5092 bytes .../hello-1-1-x86_64.pkg.tar.xz | Bin 0 -> 3572 bytes .../hello-debug-1-1-x86_64.pkg.tar.bz2 | Bin 0 -> 5814 bytes tests/debuginfod-tars/pacman-sources/PKGBUILD | 19 + .../debuginfod-tars/pacman-sources/README.md | 19 + tests/debuginfod-tars/pacman-sources/hello.c | 6 + tests/debuginfod_build_id_find.c | 62 + tests/debuglink.c | 64 + tests/deleted-lib.c | 27 + tests/deleted.c | 57 + tests/dwarf-die-addr-die.c | 186 + tests/dwarf-getmacros.c | 144 + tests/dwarf-getstring.c | 78 + tests/dwarf-ranges.c | 57 + tests/dwarf_default_lower_bound.c | 83 + tests/dwarfcfi.c | 175 + tests/dwelf_elf_e_machine_string.c | 67 + tests/dwelfgnucompressed.c | 106 + tests/dwfl-addr-sect.c | 80 + tests/dwfl-bug-addr-overflow.c | 72 + tests/dwfl-bug-fd-leak.c | 123 + tests/dwfl-bug-getmodules.c | 66 + tests/dwfl-bug-report.c | 48 + tests/dwfl-proc-attach.c | 122 + tests/dwfl-report-elf-align.c | 72 + tests/dwfl-report-segment-contiguous.c | 82 + tests/dwfllines.c | 164 + tests/dwflmodtest.c | 283 + tests/dwflsyms.c | 225 + tests/early-offscn.c | 52 + tests/ecp.c | 99 + tests/elfcopy.c | 369 + tests/elfgetchdr.c | 126 + tests/elfgetzdata.c | 113 + tests/elfputzdata.c | 244 + tests/elfrdwrnop.c | 100 + tests/elfshphehdr.c | 182 + tests/elfstrmerge.c | 684 + tests/elfstrtab.c | 397 + tests/emptyfile.c | 278 + tests/fillfile.c | 449 + tests/find-prologues.c | 108 + tests/funcretval.c | 106 + tests/funcretval_test.c | 828 + tests/funcretval_test_aarch64.bz2 | Bin 0 -> 15644 bytes tests/funcscopes.c | 195 + tests/get-aranges.c | 142 + tests/get-files.c | 107 + tests/get-lines.c | 160 + tests/get-pubnames.c | 98 + tests/get-units-invalid.c | 121 + tests/get-units-split.c | 101 + tests/getphdrnum.c | 48 + tests/getsrc_die.c | 72 + tests/hash.c | 45 + tests/hello_aarch64.ko.bz2 | Bin 0 -> 12768 bytes tests/hello_csky.ko.bz2 | Bin 0 -> 26448 bytes tests/hello_i386.ko.bz2 | Bin 0 -> 47401 bytes tests/hello_m68k.ko.bz2 | Bin 0 -> 26549 bytes tests/hello_ppc64.ko.bz2 | Bin 0 -> 68189 bytes tests/hello_riscv64.ko.bz2 | Bin 0 -> 39548 bytes tests/hello_s390.ko.bz2 | Bin 0 -> 109190 bytes tests/hello_x86_64.ko.bz2 | Bin 0 -> 35106 bytes tests/leb128.c | 173 + tests/lfs-symbols | 73 + tests/libtestfile_multi_shared.so.bz2 | Bin 0 -> 2547 bytes tests/line2addr.c | 148 + tests/linkmap-cut-lib.so.bz2 | Bin 0 -> 2151 bytes tests/linkmap-cut.bz2 | Bin 0 -> 2633 bytes tests/linkmap-cut.core.bz2 | Bin 0 -> 21343 bytes tests/low_high_pc.c | 132 + tests/msg_tst.c | 112 + tests/newdata.c | 404 + tests/newfile.c | 170 + tests/newscn.c | 66 + tests/next-files.c | 93 + tests/next-lines.c | 144 + tests/next_cfi.c | 150 + tests/peel_type.c | 119 + tests/rdwrmmap.c | 49 + tests/read_unaligned.c | 564 + tests/rerequest_tag.c | 47 + tests/run-addr2line-alt-debugpath.sh | 67 + tests/run-addr2line-i-demangle-test.sh | 70 + tests/run-addr2line-i-lex-test.sh | 71 + tests/run-addr2line-i-test.sh | 223 + tests/run-addr2line-test.sh | 116 + tests/run-addrcfi.sh | 3792 ++++ tests/run-addrname-test.sh | 360 + tests/run-addrscopes.sh | 43 + tests/run-aggregate-size.sh | 113 + tests/run-all-dwarf-ranges.sh | 129 + tests/run-alldts.sh | 98 + tests/run-allfcts-multi.sh | 72 + tests/run-allfcts.sh | 173 + tests/run-allregs.sh | 2907 ++++ tests/run-annobingroup.sh | 156 + tests/run-ar.sh | 40 + tests/run-arextract.sh | 40 + tests/run-arsymtest.sh | 47 + tests/run-attr-integrate-skel.sh | 52 + tests/run-backtrace-core-aarch64.sh | 23 + tests/run-backtrace-core-i386.sh | 20 + tests/run-backtrace-core-ppc.sh | 29 + tests/run-backtrace-core-s390.sh | 20 + tests/run-backtrace-core-s390x.sh | 20 + tests/run-backtrace-core-sparc.sh | 20 + tests/run-backtrace-core-x32.sh | 23 + tests/run-backtrace-core-x86_64.sh | 20 + tests/run-backtrace-data.sh | 32 + tests/run-backtrace-demangle.sh | 58 + tests/run-backtrace-dwarf.sh | 30 + tests/run-backtrace-fp-core-aarch64.sh | 28 + tests/run-backtrace-fp-core-i386.sh | 29 + tests/run-backtrace-fp-core-ppc64le.sh | 29 + tests/run-backtrace-fp-core-x86_64.sh | 29 + tests/run-backtrace-native-biarch.sh | 25 + tests/run-backtrace-native-core-biarch.sh | 25 + tests/run-backtrace-native-core.sh | 20 + tests/run-backtrace-native.sh | 20 + tests/run-bug1-test.sh | 34 + tests/run-buildid.sh | 38 + tests/run-compress-test.sh | 102 + tests/run-copyadd-sections.sh | 87 + tests/run-copymany-sections.sh | 99 + tests/run-debugaltlink.sh | 34 + tests/run-debuginfod-find.sh | 677 + tests/run-debuglink.sh | 29 + tests/run-deleted.sh | 52 + tests/run-disasm-bpf.sh | 63 + tests/run-disasm-riscv64.sh | 529 + tests/run-disasm-x86-64.sh | 28 + tests/run-disasm-x86.sh | 28 + tests/run-dwarf-die-addr-die.sh | 52 + tests/run-dwarf-getmacros.sh | 710 + tests/run-dwarf-getstring.sh | 125 + tests/run-dwarf-ranges.sh | 126 + tests/run-dwarfcfi.sh | 133 + tests/run-dwelf_elf_e_machine_string.sh | 31 + tests/run-dwelfgnucompressed.sh | 108 + tests/run-dwfl-addr-sect.sh | 32 + tests/run-dwfl-bug-offline-rel.sh | 28 + tests/run-dwfl-report-elf-align.sh | 44 + tests/run-dwfllines.sh | 88 + tests/run-dwflsyms.sh | 826 + tests/run-early-offscn.sh | 24 + tests/run-ecp-test.sh | 28 + tests/run-ecp-test2.sh | 26 + tests/run-elf_cntl_gelf_getshdr.sh | 30 + tests/run-elfclassify-self.sh | 36 + tests/run-elfclassify.sh | 327 + tests/run-elfgetchdr.sh | 188 + tests/run-elfgetzdata.sh | 214 + tests/run-elflint-self.sh | 22 + tests/run-elflint-test.sh | 60 + tests/run-elfputzdata.sh | 340 + tests/run-elfstrmerge-test.sh | 40 + tests/run-exprlocs-self.sh | 22 + tests/run-exprlocs.sh | 180 + tests/run-find-prologues.sh | 85 + tests/run-funcretval.sh | 153 + tests/run-funcscopes.sh | 29 + tests/run-get-aranges.sh | 68 + tests/run-get-files.sh | 133 + tests/run-get-lines.sh | 91 + tests/run-get-pubnames.sh | 50 + tests/run-get-units-invalid.sh | 44 + tests/run-get-units-split.sh | 66 + tests/run-getphdrnum.sh | 137 + tests/run-getsrc-die.sh | 51 + tests/run-large-elf-file.sh | 114 + tests/run-lfs-symbols.sh | 89 + tests/run-line2addr.sh | 49 + tests/run-linkmap-cut.sh | 32 + tests/run-low_high_pc-dw-form-indirect.sh | 23 + tests/run-low_high_pc.sh | 41 + tests/run-macro-test.sh | 52 + tests/run-native-test.sh | 88 + tests/run-next-cfi-self.sh | 21 + tests/run-next-cfi.sh | 108 + tests/run-next-files.sh | 165 + tests/run-next-lines.sh | 116 + tests/run-nm-self.sh | 36 + tests/run-nm-syms.sh | 166 + tests/run-peel-type.sh | 63 + tests/run-prelink-addr-test.sh | 252 + tests/run-pt_gnu_prop-tests.sh | 135 + tests/run-ranlib-test.sh | 38 + tests/run-ranlib-test2.sh | 37 + tests/run-ranlib-test3.sh | 22 + tests/run-ranlib-test4.sh | 23 + tests/run-readelf-A.sh | 96 + tests/run-readelf-addr.sh | 143 + tests/run-readelf-aranges.sh | 161 + tests/run-readelf-compressed-zstd.sh | 39 + tests/run-readelf-compressed.sh | 39 + tests/run-readelf-const-values.sh | 230 + tests/run-readelf-d.sh | 70 + tests/run-readelf-discr.sh | 337 + tests/run-readelf-dw-form-indirect.sh | 678 + tests/run-readelf-dwz-multi.sh | 332 + tests/run-readelf-frames.sh | 173 + tests/run-readelf-gdb_index.sh | 130 + tests/run-readelf-info-plus.sh | 31 + tests/run-readelf-line.sh | 1149 ++ tests/run-readelf-loc.sh | 1160 ++ tests/run-readelf-macro.sh | 345 + tests/run-readelf-mixed-corenote.sh | 719 + tests/run-readelf-n.sh | 259 + tests/run-readelf-ranges.sh | 236 + tests/run-readelf-s.sh | 392 + tests/run-readelf-self.sh | 21 + tests/run-readelf-str.sh | 211 + tests/run-readelf-test1.sh | 45 + tests/run-readelf-test2.sh | 35 + tests/run-readelf-test3.sh | 31 + tests/run-readelf-test4.sh | 33 + tests/run-readelf-twofiles.sh | 65 + tests/run-readelf-types.sh | 122 + tests/run-readelf-variant.sh | 89 + tests/run-readelf-vmcoreinfo.sh | 114 + tests/run-readelf-z.sh | 202 + tests/run-readelf-zdebug-rel.sh | 255 + tests/run-readelf-zdebug.sh | 548 + tests/run-readelf-zp.sh | 271 + tests/run-readelf-zx.sh | 66 + tests/run-reloc-bpf.sh | 33 + tests/run-rerequest_tag.sh | 25 + tests/run-retain.sh | 44 + tests/run-reverse-sections-self.sh | 45 + tests/run-reverse-sections.sh | 69 + tests/run-show-abbrev.sh | 352 + tests/run-show-die-info.sh | 985 ++ tests/run-stack-d-test.sh | 122 + tests/run-stack-demangled-test.sh | 105 + tests/run-stack-i-test.sh | 81 + tests/run-strings-test.sh | 470 + tests/run-strip-g.sh | 102 + tests/run-strip-groups.sh | 55 + tests/run-strip-nobitsalign.sh | 35 + tests/run-strip-nothing.sh | 62 + tests/run-strip-reloc.sh | 149 + tests/run-strip-remove-keep.sh | 688 + tests/run-strip-strmerge.sh | 79 + tests/run-strip-test-many.sh | 83 + tests/run-strip-test.sh | 71 + tests/run-strip-test10.sh | 22 + tests/run-strip-test11.sh | 4 + tests/run-strip-test12.sh | 4 + tests/run-strip-test2.sh | 22 + tests/run-strip-test3.sh | 22 + tests/run-strip-test4.sh | 5 + tests/run-strip-test5.sh | 5 + tests/run-strip-test6.sh | 5 + tests/run-strip-test7.sh | 5 + tests/run-strip-test8.sh | 5 + tests/run-strip-test9.sh | 21 + tests/run-strip-version.sh | 58 + tests/run-strptr.sh | 98 + tests/run-test-archive64.sh | 55 + tests/run-test-flag-nobits.sh | 22 + tests/run-test-includes.sh | 26 + tests/run-typeiter-many.sh | 31 + tests/run-typeiter.sh | 62 + tests/run-unit-info.sh | 81 + tests/run-unstrip-M.sh | 51 + tests/run-unstrip-n.sh | 76 + tests/run-unstrip-test.sh | 43 + tests/run-unstrip-test2.sh | 5 + tests/run-unstrip-test3.sh | 17 + tests/run-unstrip-test4.sh | 18 + tests/run-varlocs-self.sh | 24 + tests/run-varlocs.sh | 604 + tests/run-xlate-note.sh | 93 + tests/run-zstrptr.sh | 167 + tests/saridx.c | 257 + tests/scnnames.c | 91 + tests/sectiondump.c | 182 + tests/show-abbrev.c | 139 + tests/show-die-info.c | 358 + tests/showptable.c | 139 + tests/splitdwarf4-not-split4.dwo.bz2 | Bin 0 -> 931 bytes tests/strptr.c | 95 + tests/system-elf-libelf-test.c | 35 + tests/test-core-lib.so.bz2 | Bin 0 -> 2028 bytes tests/test-core.core.bz2 | Bin 0 -> 14165 bytes tests/test-core.exec.bz2 | Bin 0 -> 2565 bytes tests/test-elf_cntl_gelf_getshdr.c | 107 + tests/test-flag-nobits.c | 42 + tests/test-nlist.c | 83 + tests/test-offset-loop.alt.bz2 | Bin 0 -> 685 bytes tests/test-offset-loop.bz2 | Bin 0 -> 3062 bytes tests/test-subr.sh | 214 + tests/test-wrapper.sh | 73 + tests/testarchive64.a.bz2 | Bin 0 -> 834 bytes tests/testcore-rtlib-ppc.bz2 | Bin 0 -> 200184 bytes tests/testcore-rtlib.bz2 | Bin 0 -> 25566 bytes tests/testfile-ada-variant.bz2 | Bin 0 -> 1305 bytes tests/testfile-addrx_constx-4.bz2 | Bin 0 -> 2851 bytes tests/testfile-addrx_constx-5.bz2 | Bin 0 -> 2847 bytes tests/testfile-annobingroup-i386.o.bz2 | Bin 0 -> 1387 bytes tests/testfile-annobingroup-x86_64.o.bz2 | Bin 0 -> 1437 bytes tests/testfile-annobingroup.o.bz2 | Bin 0 -> 1266 bytes tests/testfile-backtrace-demangle.bz2 | Bin 0 -> 3016 bytes tests/testfile-backtrace-demangle.cc | 47 + tests/testfile-backtrace-demangle.core.bz2 | Bin 0 -> 39510 bytes tests/testfile-bpf-dis1.expect.bz2 | Bin 0 -> 1516 bytes tests/testfile-bpf-dis1.o.bz2 | Bin 0 -> 737 bytes tests/testfile-bpf-reloc.expect.bz2 | Bin 0 -> 300 bytes tests/testfile-bpf-reloc.o.bz2 | Bin 0 -> 933 bytes tests/testfile-const-values.debug.bz2 | Bin 0 -> 1540 bytes tests/testfile-debug-rel-g.o.bz2 | Bin 0 -> 1238 bytes tests/testfile-debug-rel-ppc64-g.o.bz2 | Bin 0 -> 1400 bytes tests/testfile-debug-rel-ppc64-z.o.bz2 | Bin 0 -> 1420 bytes tests/testfile-debug-rel-ppc64.o.bz2 | Bin 0 -> 1103 bytes tests/testfile-debug-rel-z.o.bz2 | Bin 0 -> 1225 bytes tests/testfile-debug-rel.o.bz2 | Bin 0 -> 1069 bytes tests/testfile-debug-types.bz2 | Bin 0 -> 3024 bytes tests/testfile-debug.bz2 | Bin 0 -> 5441 bytes tests/testfile-dw-form-indirect.bz2 | Bin 0 -> 7007 bytes tests/testfile-dwarf-4.bz2 | Bin 0 -> 4304 bytes tests/testfile-dwarf-45.source | 89 + tests/testfile-dwarf-5.bz2 | Bin 0 -> 4318 bytes ...estfile-dwfl-report-elf-align-shlib.so.bz2 | Bin 0 -> 1546 bytes tests/testfile-dwzstr.bz2 | Bin 0 -> 2768 bytes tests/testfile-dwzstr.multi.bz2 | Bin 0 -> 518 bytes tests/testfile-gnu-property-note-aarch64.bz2 | Bin 0 -> 1952 bytes tests/testfile-gnu-property-note.bz2 | Bin 0 -> 1146 bytes tests/testfile-gnu-property-note.o.bz2 | Bin 0 -> 482 bytes tests/testfile-hello4.dwo.bz2 | Bin 0 -> 1453 bytes tests/testfile-hello5.dwo.bz2 | Bin 0 -> 1520 bytes tests/testfile-info-link.bz2 | Bin 0 -> 2768 bytes tests/testfile-info-link.debuginfo.bz2 | Bin 0 -> 1844 bytes tests/testfile-info-link.stripped.bz2 | Bin 0 -> 2422 bytes tests/testfile-inlines.bz2 | Bin 0 -> 2815 bytes tests/testfile-lex-inlines.bz2 | Bin 0 -> 2599 bytes tests/testfile-lto-gcc10.bz2 | Bin 0 -> 4319 bytes tests/testfile-lto-gcc8.bz2 | Bin 0 -> 3686 bytes tests/testfile-lto-gcc9.bz2 | Bin 0 -> 3809 bytes tests/testfile-m68k-core.bz2 | Bin 0 -> 22041 bytes tests/testfile-m68k-s.bz2 | Bin 0 -> 1590 bytes tests/testfile-m68k.bz2 | Bin 0 -> 3659 bytes tests/testfile-macinfo.bz2 | Bin 0 -> 6689 bytes tests/testfile-macros-0xff.bz2 | Bin 0 -> 2844 bytes tests/testfile-macros.bz2 | Bin 0 -> 7882 bytes tests/testfile-nobitsalign.bz2 | Bin 0 -> 2921 bytes tests/testfile-nobitsalign.strip.bz2 | Bin 0 -> 1723 bytes tests/testfile-nolfs.bz2 | Bin 0 -> 2563 bytes tests/testfile-only-debug-line.bz2 | Bin 0 -> 2514 bytes tests/testfile-phdrs.elf.bz2 | Bin 0 -> 188 bytes tests/testfile-ppc64-min-instr.bz2 | Bin 0 -> 3106 bytes tests/testfile-ranges-hello.dwo.bz2 | Bin 0 -> 948 bytes tests/testfile-ranges-hello5.dwo.bz2 | Bin 0 -> 1256 bytes tests/testfile-ranges-world.dwo.bz2 | Bin 0 -> 1176 bytes tests/testfile-ranges-world5.dwo.bz2 | Bin 0 -> 1514 bytes tests/testfile-retain.o.bz2 | Bin 0 -> 261 bytes tests/testfile-riscv64-core.bz2 | Bin 0 -> 16229 bytes tests/testfile-riscv64-dis1.expect.bz2 | Bin 0 -> 4603 bytes tests/testfile-riscv64-dis1.o.bz2 | Bin 0 -> 1507 bytes tests/testfile-riscv64-s.bz2 | Bin 0 -> 1657 bytes tests/testfile-riscv64.bz2 | Bin 0 -> 6006 bytes tests/testfile-rng.debug.bz2 | Bin 0 -> 1286 bytes tests/testfile-s390x-hash-both.bz2 | Bin 0 -> 2435 bytes tests/testfile-sizes1.o.bz2 | Bin 0 -> 1012 bytes tests/testfile-sizes2.o.bz2 | Bin 0 -> 1283 bytes tests/testfile-sizes3.o.bz2 | Bin 0 -> 1208 bytes tests/testfile-sizes4.o.bz2 | Bin 0 -> 387 bytes tests/testfile-sizes4.s | 77 + tests/testfile-splitdwarf-4.bz2 | Bin 0 -> 3591 bytes tests/testfile-splitdwarf-5.bz2 | Bin 0 -> 3611 bytes .../testfile-splitdwarf4-not-split4.debug.bz2 | Bin 0 -> 2230 bytes tests/testfile-stridex.bz2 | Bin 0 -> 4009 bytes tests/testfile-strtab.bz2 | Bin 0 -> 189062 bytes tests/testfile-strtab.debuginfo.bz2 | Bin 0 -> 176208 bytes tests/testfile-strtab.stripped.bz2 | Bin 0 -> 17108 bytes tests/testfile-urng.debug.bz2 | Bin 0 -> 1178 bytes tests/testfile-version.bz2 | Bin 0 -> 378 bytes tests/testfile-world4.dwo.bz2 | Bin 0 -> 1444 bytes tests/testfile-world5.dwo.bz2 | Bin 0 -> 1498 bytes tests/testfile-x32-core.bz2 | Bin 0 -> 19624 bytes tests/testfile-x32-d.bz2 | Bin 0 -> 1725 bytes tests/testfile-x32-debug.bz2 | Bin 0 -> 2206 bytes tests/testfile-x32-s.bz2 | Bin 0 -> 1687 bytes tests/testfile-x32.bz2 | Bin 0 -> 3059 bytes tests/testfile-zdebug.bz2 | Bin 0 -> 6647 bytes tests/testfile-zgabi32.bz2 | Bin 0 -> 767 bytes tests/testfile-zgabi32be.bz2 | Bin 0 -> 769 bytes tests/testfile-zgabi64.bz2 | Bin 0 -> 795 bytes tests/testfile-zgabi64be.bz2 | Bin 0 -> 780 bytes tests/testfile-zgnu32.bz2 | Bin 0 -> 780 bytes tests/testfile-zgnu32be.bz2 | Bin 0 -> 779 bytes tests/testfile-zgnu64.bz2 | Bin 0 -> 785 bytes tests/testfile-zgnu64be.bz2 | Bin 0 -> 795 bytes tests/testfile.bz2 | Bin 0 -> 8115 bytes tests/testfile10.bz2 | Bin 0 -> 2635 bytes tests/testfile11-debugframe.bz2 | Bin 0 -> 2202 bytes tests/testfile11.bz2 | Bin 0 -> 30561 bytes tests/testfile12-debugframe.bz2 | Bin 0 -> 1385 bytes tests/testfile12.bz2 | Bin 0 -> 9948 bytes tests/testfile13.bz2 | Bin 0 -> 1593 bytes tests/testfile14.bz2 | Bin 0 -> 2903 bytes tests/testfile15.bz2 | Bin 0 -> 3132 bytes tests/testfile15.debug.bz2 | Bin 0 -> 28499 bytes tests/testfile16.bz2 | Bin 0 -> 8413 bytes tests/testfile16.debug.bz2 | Bin 0 -> 24257 bytes tests/testfile17.bz2 | Bin 0 -> 1660 bytes tests/testfile17.debug.bz2 | Bin 0 -> 9134 bytes tests/testfile18.bz2 | Bin 0 -> 1721 bytes tests/testfile19.bz2 | Bin 0 -> 458 bytes tests/testfile19.index.bz2 | Bin 0 -> 501 bytes tests/testfile2.bz2 | Bin 0 -> 6400 bytes tests/testfile20.bz2 | Bin 0 -> 502 bytes tests/testfile20.index.bz2 | Bin 0 -> 523 bytes tests/testfile21.bz2 | Bin 0 -> 127 bytes tests/testfile21.index.bz2 | Bin 0 -> 100 bytes tests/testfile22.bz2 | Bin 0 -> 2555 bytes tests/testfile23.bz2 | Bin 0 -> 956 bytes tests/testfile24.bz2 | Bin 0 -> 2644 bytes tests/testfile25.bz2 | Bin 0 -> 2575 bytes tests/testfile26.bz2 | Bin 0 -> 2331 bytes tests/testfile27.bz2 | Bin 0 -> 2371 bytes tests/testfile28.bz2 | Bin 0 -> 171 bytes tests/testfile28.rdwr.bz2 | Bin 0 -> 172 bytes tests/testfile29.bz2 | Bin 0 -> 164 bytes tests/testfile29.rdwr.bz2 | Bin 0 -> 164 bytes tests/testfile3.bz2 | Bin 0 -> 8051 bytes tests/testfile30.bz2 | Bin 0 -> 753 bytes tests/testfile31.bz2 | Bin 0 -> 769 bytes tests/testfile32.bz2 | Bin 0 -> 5778 bytes tests/testfile33.bz2 | Bin 0 -> 35075 bytes tests/testfile34.bz2 | Bin 0 -> 315 bytes tests/testfile35.bz2 | Bin 0 -> 1643 bytes tests/testfile35.debug.bz2 | Bin 0 -> 9106 bytes tests/testfile36.bz2 | Bin 0 -> 714 bytes tests/testfile36.debug.bz2 | Bin 0 -> 24909 bytes tests/testfile37.bz2 | Bin 0 -> 3140 bytes tests/testfile37.debug.bz2 | Bin 0 -> 28522 bytes tests/testfile38.bz2 | Bin 0 -> 457 bytes tests/testfile39.bz2 | Bin 0 -> 2992 bytes tests/testfile4.bz2 | Bin 0 -> 41405 bytes tests/testfile40.bz2 | Bin 0 -> 2302 bytes tests/testfile40.debug.bz2 | Bin 0 -> 1398 bytes tests/testfile41.bz2 | Bin 0 -> 295 bytes tests/testfile42.bz2 | Bin 0 -> 16201 bytes tests/testfile42_noshdrs.bz2 | Bin 0 -> 6746 bytes tests/testfile43.bz2 | Bin 0 -> 739 bytes tests/testfile44.S.bz2 | Bin 0 -> 18296 bytes tests/testfile44.expect.bz2 | Bin 0 -> 60096 bytes tests/testfile45.S.bz2 | Bin 0 -> 24742 bytes tests/testfile45.expect.bz2 | Bin 0 -> 81706 bytes tests/testfile46.bz2 | Bin 0 -> 322 bytes tests/testfile47.bz2 | Bin 0 -> 793 bytes tests/testfile48.bz2 | Bin 0 -> 408 bytes tests/testfile48.debug.bz2 | Bin 0 -> 758 bytes tests/testfile49.bz2 | Bin 0 -> 337 bytes tests/testfile5.bz2 | Bin 0 -> 5646 bytes tests/testfile50.bz2 | Bin 0 -> 229 bytes tests/testfile51.bz2 | Bin 0 -> 4294 bytes tests/testfile52-32.noshdrs.so.bz2 | Bin 0 -> 944 bytes tests/testfile52-32.prelink.so.bz2 | Bin 0 -> 1839 bytes tests/testfile52-32.so.bz2 | Bin 0 -> 1445 bytes tests/testfile52-32.so.debug.bz2 | Bin 0 -> 1681 bytes tests/testfile52-64.noshdrs.so.bz2 | Bin 0 -> 1044 bytes tests/testfile52-64.prelink.so.bz2 | Bin 0 -> 1978 bytes tests/testfile52-64.so.bz2 | Bin 0 -> 1558 bytes tests/testfile52-64.so.debug.bz2 | Bin 0 -> 1693 bytes tests/testfile53-32.bz2 | Bin 0 -> 1628 bytes tests/testfile53-32.debug.bz2 | Bin 0 -> 1959 bytes tests/testfile53-32.prelink.bz2 | Bin 0 -> 2192 bytes tests/testfile53-64.bz2 | Bin 0 -> 1683 bytes tests/testfile53-64.debug.bz2 | Bin 0 -> 1927 bytes tests/testfile53-64.prelink.bz2 | Bin 0 -> 2180 bytes tests/testfile54-32.noshdrs.so.bz2 | Bin 0 -> 416 bytes tests/testfile54-32.prelink.so.bz2 | Bin 0 -> 1035 bytes tests/testfile54-32.so.bz2 | Bin 0 -> 745 bytes tests/testfile54-32.so.debug.bz2 | Bin 0 -> 1009 bytes tests/testfile54-64.noshdrs.so.bz2 | Bin 0 -> 458 bytes tests/testfile54-64.prelink.so.bz2 | Bin 0 -> 1127 bytes tests/testfile54-64.so.bz2 | Bin 0 -> 799 bytes tests/testfile54-64.so.debug.bz2 | Bin 0 -> 1052 bytes tests/testfile55-32.bz2 | Bin 0 -> 1661 bytes tests/testfile55-32.debug.bz2 | Bin 0 -> 1894 bytes tests/testfile55-32.prelink.bz2 | Bin 0 -> 2163 bytes tests/testfile55-64.bz2 | Bin 0 -> 1725 bytes tests/testfile55-64.debug.bz2 | Bin 0 -> 1869 bytes tests/testfile55-64.prelink.bz2 | Bin 0 -> 2259 bytes tests/testfile56.bz2 | Bin 0 -> 2768 bytes tests/testfile57.bz2 | Bin 0 -> 593 bytes tests/testfile58.bz2 | Bin 0 -> 1680 bytes tests/testfile59.bz2 | Bin 0 -> 3097 bytes tests/testfile6.bz2 | Bin 0 -> 30577 bytes tests/testfile61.bz2 | Bin 0 -> 7906 bytes tests/testfile62.bz2 | Bin 0 -> 3506 bytes tests/testfile63.bz2 | Bin 0 -> 457 bytes tests/testfile64.bz2 | Bin 0 -> 395 bytes tests/testfile65.bz2 | Bin 0 -> 4674 bytes tests/testfile66.bz2 | Bin 0 -> 741 bytes tests/testfile66.core.bz2 | Bin 0 -> 56448 bytes tests/testfile67.bz2 | Bin 0 -> 424 bytes tests/testfile68.bz2 | Bin 0 -> 399 bytes tests/testfile69.core.bz2 | Bin 0 -> 4416 bytes tests/testfile69.so.bz2 | Bin 0 -> 2099 bytes tests/testfile7.bz2 | Bin 0 -> 3107 bytes tests/testfile70.core.bz2 | Bin 0 -> 2739 bytes tests/testfile70.exec.bz2 | Bin 0 -> 2567 bytes tests/testfile71.bz2 | Bin 0 -> 18164 bytes tests/testfile8.bz2 | Bin 0 -> 31982 bytes tests/testfile9.bz2 | Bin 0 -> 8367 bytes tests/testfile_aarch64_core.bz2 | Bin 0 -> 61748 bytes tests/testfile_class_func.bz2 | Bin 0 -> 2962 bytes tests/testfile_const_type.bz2 | Bin 0 -> 3353 bytes tests/testfile_const_type.c | 14 + tests/testfile_entry_value.bz2 | Bin 0 -> 3309 bytes tests/testfile_entry_value.c | 19 + tests/testfile_gnu_props.32be.o.bz2 | Bin 0 -> 225 bytes tests/testfile_gnu_props.32le.o.bz2 | Bin 0 -> 215 bytes tests/testfile_gnu_props.64be.o.bz2 | Bin 0 -> 238 bytes tests/testfile_gnu_props.64le.o.bz2 | Bin 0 -> 233 bytes tests/testfile_i686_core.bz2 | Bin 0 -> 15980 bytes tests/testfile_implicit_pointer.bz2 | Bin 0 -> 2952 bytes tests/testfile_implicit_pointer.c | 12 + tests/testfile_implicit_value.bz2 | Bin 0 -> 2973 bytes tests/testfile_implicit_value.c | 12 + tests/testfile_low_high_pc.bz2 | Bin 0 -> 2812 bytes tests/testfile_multi.dwz.bz2 | Bin 0 -> 512 bytes tests/testfile_multi_main.bz2 | Bin 0 -> 3086 bytes tests/testfile_nested_funcs.bz2 | Bin 0 -> 3045 bytes tests/testfile_parameter_ref.bz2 | Bin 0 -> 3329 bytes tests/testfile_parameter_ref.c | 20 + tests/testfile_pt_gnu_prop.bz2 | Bin 0 -> 1593 bytes tests/testfile_pt_gnu_prop32.bz2 | Bin 0 -> 1777 bytes tests/testfileaarch64-debugframe.bz2 | Bin 0 -> 1820 bytes tests/testfileaarch64.bz2 | Bin 0 -> 3441 bytes tests/testfilearm-debugframe.bz2 | Bin 0 -> 1987 bytes tests/testfilearm.bz2 | Bin 0 -> 3545 bytes tests/testfilebasmin.bz2 | Bin 0 -> 1082 bytes tests/testfilebaxmin.bz2 | Bin 0 -> 2987 bytes tests/testfilebazdbg.bz2 | Bin 0 -> 2185 bytes tests/testfilebazdbg.debug.bz2 | Bin 0 -> 2187 bytes tests/testfilebazdbg_pl.bz2 | Bin 0 -> 2589 bytes tests/testfilebazdbg_plr.bz2 | Bin 0 -> 2241 bytes tests/testfilebazdbgppc64.bz2 | Bin 0 -> 2366 bytes tests/testfilebazdbgppc64.debug.bz2 | Bin 0 -> 2295 bytes tests/testfilebazdbgppc64_pl.bz2 | Bin 0 -> 2775 bytes tests/testfilebazdbgppc64_plr.bz2 | Bin 0 -> 2399 bytes tests/testfilebazdyn.bz2 | Bin 0 -> 2164 bytes tests/testfilebazdynppc64.bz2 | Bin 0 -> 2327 bytes tests/testfilebazmdb.bz2 | Bin 0 -> 3313 bytes tests/testfilebazmdbppc64.bz2 | Bin 0 -> 3528 bytes tests/testfilebazmin.bz2 | Bin 0 -> 3323 bytes tests/testfilebazmin_pl.bz2 | Bin 0 -> 3749 bytes tests/testfilebazmin_plr.bz2 | Bin 0 -> 3337 bytes tests/testfilebazminppc64.bz2 | Bin 0 -> 3464 bytes tests/testfilebazminppc64_pl.bz2 | Bin 0 -> 3900 bytes tests/testfilebazminppc64_plr.bz2 | Bin 0 -> 3535 bytes tests/testfilebaztab.bz2 | Bin 0 -> 3418 bytes tests/testfilebaztabppc64.bz2 | Bin 0 -> 3697 bytes tests/testfilecsky.bz2 | Bin 0 -> 3145 bytes tests/testfiledwarfinlines.bz2 | Bin 0 -> 4225 bytes tests/testfiledwarfinlines.core.bz2 | Bin 0 -> 39713 bytes tests/testfilefoobarbaz.bz2 | Bin 0 -> 3974 bytes tests/testfilegdbindex5.bz2 | Bin 0 -> 3481 bytes tests/testfilegdbindex7.bz2 | Bin 0 -> 3497 bytes tests/testfileloc.bz2 | Bin 0 -> 3148 bytes tests/testfilemacro.bz2 | Bin 0 -> 5601 bytes tests/testfilenolines.bz2 | Bin 0 -> 2855 bytes tests/testfileppc32-debugframe.bz2 | Bin 0 -> 1526 bytes tests/testfileppc32.bz2 | Bin 0 -> 3344 bytes tests/testfileppc32attrs.o.bz2 | Bin 0 -> 228 bytes tests/testfileppc64-debugframe.bz2 | Bin 0 -> 1555 bytes tests/testfileppc64.bz2 | Bin 0 -> 3351 bytes tests/testfileppc64attrs.o.bz2 | Bin 0 -> 222 bytes tests/testfileranges4.debug.bz2 | Bin 0 -> 3038 bytes tests/testfileranges5.debug.bz2 | Bin 0 -> 3009 bytes tests/testfiles390.bz2 | Bin 0 -> 3132 bytes tests/testfiles390x.bz2 | Bin 0 -> 3026 bytes tests/testfilesparc64attrs.o.bz2 | Bin 0 -> 242 bytes tests/testfilesplitranges4.debug.bz2 | Bin 0 -> 2154 bytes tests/testfilesplitranges5.debug.bz2 | Bin 0 -> 2229 bytes tests/testfilesyms32.bz2 | Bin 0 -> 771 bytes tests/testfilesyms64.bz2 | Bin 0 -> 652 bytes tests/testlib_dynseg.so.bz2 | Bin 0 -> 2275 bytes tests/typeiter.c | 90 + tests/typeiter2.c | 91 + tests/unit-info.c | 323 + tests/update1.c | 128 + tests/update2.c | 151 + tests/update3.c | 206 + tests/update4.c | 358 + tests/varlocs.c | 1162 ++ tests/vdsosyms.c | 112 + tests/vendorelf.c | 198 + tests/xlate_notes.c | 157 + tests/zstrptr.c | 125 + version.h | 38 + 1451 files changed, 339994 insertions(+), 75 deletions(-) create mode 100644 ABOUT-NLS create mode 100644 AUTHORS create mode 100644 CONTRIBUTING create mode 100644 COPYING create mode 100644 COPYING-GPLV2 create mode 100644 COPYING-LGPLV3 create mode 100644 ChangeLog create mode 100644 GPG-KEY create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 NOTES create mode 100644 README delete mode 100644 README.en.md delete mode 100644 README.md create mode 100644 THANKS create mode 100644 TODO create mode 100644 aclocal.m4 create mode 100644 backends/ChangeLog create mode 100644 backends/Makefile.am create mode 100644 backends/Makefile.in create mode 100644 backends/aarch64_cfi.c create mode 100644 backends/aarch64_corenote.c create mode 100644 backends/aarch64_init.c create mode 100644 backends/aarch64_initreg.c create mode 100644 backends/aarch64_regs.c create mode 100644 backends/aarch64_reloc.def create mode 100644 backends/aarch64_retval.c create mode 100644 backends/aarch64_symbol.c create mode 100644 backends/aarch64_unwind.c create mode 100644 backends/alpha_auxv.c create mode 100644 backends/alpha_corenote.c create mode 100644 backends/alpha_init.c create mode 100644 backends/alpha_regs.c create mode 100644 backends/alpha_reloc.def create mode 100644 backends/alpha_retval.c create mode 100644 backends/alpha_symbol.c create mode 100644 backends/arm_attrs.c create mode 100644 backends/arm_auxv.c create mode 100644 backends/arm_cfi.c create mode 100644 backends/arm_corenote.c create mode 100644 backends/arm_init.c create mode 100644 backends/arm_initreg.c create mode 100644 backends/arm_regs.c create mode 100644 backends/arm_reloc.def create mode 100644 backends/arm_retval.c create mode 100644 backends/arm_symbol.c create mode 100644 backends/bpf_init.c create mode 100644 backends/bpf_regs.c create mode 100644 backends/bpf_reloc.def create mode 100644 backends/bpf_symbol.c create mode 100644 backends/common-reloc.c create mode 100644 backends/csky_attrs.c create mode 100644 backends/csky_cfi.c create mode 100644 backends/csky_corenote.c create mode 100644 backends/csky_init.c create mode 100644 backends/csky_initreg.c create mode 100644 backends/csky_regs.c create mode 100644 backends/csky_reloc.def create mode 100644 backends/csky_symbol.c create mode 100644 backends/i386_auxv.c create mode 100644 backends/i386_cfi.c create mode 100644 backends/i386_corenote.c create mode 100644 backends/i386_init.c create mode 100644 backends/i386_initreg.c create mode 100644 backends/i386_regs.c create mode 100644 backends/i386_reloc.def create mode 100644 backends/i386_retval.c create mode 100644 backends/i386_symbol.c create mode 100644 backends/i386_unwind.c create mode 100644 backends/ia64_init.c create mode 100644 backends/ia64_regs.c create mode 100644 backends/ia64_reloc.def create mode 100644 backends/ia64_retval.c create mode 100644 backends/ia64_symbol.c create mode 100644 backends/libebl_CPU.h create mode 100644 backends/linux-core-note.c create mode 100644 backends/m68k_cfi.c create mode 100644 backends/m68k_corenote.c create mode 100644 backends/m68k_init.c create mode 100644 backends/m68k_initreg.c create mode 100644 backends/m68k_regs.c create mode 100644 backends/m68k_reloc.def create mode 100644 backends/m68k_retval.c create mode 100644 backends/m68k_symbol.c create mode 100644 backends/ppc64_corenote.c create mode 100644 backends/ppc64_init.c create mode 100644 backends/ppc64_reloc.def create mode 100644 backends/ppc64_resolve_sym.c create mode 100644 backends/ppc64_retval.c create mode 100644 backends/ppc64_symbol.c create mode 100644 backends/ppc64_unwind.c create mode 100644 backends/ppc_attrs.c create mode 100644 backends/ppc_auxv.c create mode 100644 backends/ppc_cfi.c create mode 100644 backends/ppc_corenote.c create mode 100644 backends/ppc_init.c create mode 100644 backends/ppc_initreg.c create mode 100644 backends/ppc_regs.c create mode 100644 backends/ppc_reloc.def create mode 100644 backends/ppc_retval.c create mode 100644 backends/ppc_symbol.c create mode 100644 backends/riscv64_corenote.c create mode 100644 backends/riscv_cfi.c create mode 100644 backends/riscv_corenote.c create mode 100644 backends/riscv_init.c create mode 100644 backends/riscv_initreg.c create mode 100644 backends/riscv_regs.c create mode 100644 backends/riscv_reloc.def create mode 100644 backends/riscv_retval.c create mode 100644 backends/riscv_symbol.c create mode 100644 backends/s390_cfi.c create mode 100644 backends/s390_corenote.c create mode 100644 backends/s390_init.c create mode 100644 backends/s390_initreg.c create mode 100644 backends/s390_regs.c create mode 100644 backends/s390_reloc.def create mode 100644 backends/s390_retval.c create mode 100644 backends/s390_symbol.c create mode 100644 backends/s390_unwind.c create mode 100644 backends/s390x_corenote.c create mode 100644 backends/sh_corenote.c create mode 100644 backends/sh_init.c create mode 100644 backends/sh_regs.c create mode 100644 backends/sh_reloc.def create mode 100644 backends/sh_retval.c create mode 100644 backends/sh_symbol.c create mode 100644 backends/sparc64_corenote.c create mode 100644 backends/sparc_attrs.c create mode 100644 backends/sparc_auxv.c create mode 100644 backends/sparc_cfi.c create mode 100644 backends/sparc_corenote.c create mode 100644 backends/sparc_init.c create mode 100644 backends/sparc_initreg.c create mode 100644 backends/sparc_regs.c create mode 100644 backends/sparc_reloc.def create mode 100644 backends/sparc_retval.c create mode 100644 backends/sparc_symbol.c create mode 100644 backends/x32_corenote.c create mode 100644 backends/x86_64_cfi.c create mode 100644 backends/x86_64_corenote.c create mode 100644 backends/x86_64_init.c create mode 100644 backends/x86_64_initreg.c create mode 100644 backends/x86_64_regs.c create mode 100644 backends/x86_64_reloc.def create mode 100644 backends/x86_64_retval.c create mode 100644 backends/x86_64_symbol.c create mode 100644 backends/x86_64_unwind.c create mode 100644 backends/x86_corenote.c create mode 100644 config.h.in create mode 100644 config/10-default-yama-scope.conf create mode 100644 config/ChangeLog create mode 100644 config/Makefile.am create mode 100644 config/Makefile.in create mode 100755 config/ar-lib create mode 100755 config/compile create mode 100755 config/config.guess create mode 100755 config/config.rpath create mode 100755 config/config.sub create mode 100644 config/debuginfod.service create mode 100644 config/debuginfod.sysconfig create mode 100755 config/depcomp create mode 100644 config/elfutils.spec.in create mode 100644 config/eu.am create mode 100755 config/install-sh create mode 100755 config/known-dwarf.awk create mode 100644 config/libdebuginfod.pc.in create mode 100644 config/libdw.pc.in create mode 100644 config/libelf.pc.in create mode 100755 config/missing create mode 100644 config/profile.csh.in create mode 100644 config/profile.sh.in create mode 100755 config/test-driver create mode 100644 config/version.h.in create mode 100755 config/ylwrap create mode 100755 configure create mode 100644 configure.ac create mode 100644 debuginfod/ChangeLog create mode 100644 debuginfod/Makefile.am create mode 100644 debuginfod/Makefile.in create mode 100644 debuginfod/debuginfod-client.c create mode 100644 debuginfod/debuginfod-find.c create mode 100644 debuginfod/debuginfod.cxx create mode 100644 debuginfod/debuginfod.h create mode 100644 debuginfod/debuginfod.h.in create mode 100644 debuginfod/libdebuginfod.map create mode 100644 doc/COPYING-GFDL create mode 100644 doc/ChangeLog create mode 100644 doc/Makefile.am create mode 100644 doc/Makefile.in create mode 100644 doc/README create mode 100644 doc/debuginfod-find.1 create mode 100644 doc/debuginfod.8 create mode 100644 doc/debuginfod_add_http_header.3 create mode 100644 doc/debuginfod_begin.3 create mode 100644 doc/debuginfod_end.3 create mode 100644 doc/debuginfod_find_debuginfo.3 create mode 100644 doc/debuginfod_find_executable.3 create mode 100644 doc/debuginfod_find_source.3 create mode 100644 doc/debuginfod_get_url.3 create mode 100644 doc/debuginfod_get_user_data.3 create mode 100644 doc/debuginfod_set_progressfn.3 create mode 100644 doc/debuginfod_set_user_data.3 create mode 100644 doc/elf_begin.3 create mode 100644 doc/elf_clone.3 create mode 100644 doc/elf_getdata.3 create mode 100644 doc/elf_update.3 create mode 100644 doc/elfclassify.1 create mode 100644 doc/readelf.1 create mode 100644 elfutils.spec create mode 100644 lib/ChangeLog create mode 100644 lib/Makefile.am create mode 100644 lib/Makefile.in create mode 100644 lib/atomics.h create mode 100644 lib/bpf.h create mode 100644 lib/color.c create mode 100644 lib/color.h create mode 100644 lib/crc32.c create mode 100644 lib/crc32_file.c create mode 100644 lib/dynamicsizehash.c create mode 100644 lib/dynamicsizehash.h create mode 100644 lib/dynamicsizehash_concurrent.c create mode 100644 lib/dynamicsizehash_concurrent.h create mode 100644 lib/eu-config.h create mode 100644 lib/fixedsizehash.h create mode 100644 lib/libeu.h create mode 100644 lib/list.h create mode 100644 lib/next_prime.c create mode 100644 lib/printversion.c create mode 100644 lib/printversion.h create mode 100644 lib/stdatomic-fbsd.h create mode 100644 lib/system.h create mode 100644 lib/xmalloc.c create mode 100644 lib/xstrdup.c create mode 100644 lib/xstrndup.c create mode 100644 libasm/ChangeLog create mode 100644 libasm/Makefile.am create mode 100644 libasm/Makefile.in create mode 100644 libasm/asm_abort.c create mode 100644 libasm/asm_addint16.c create mode 100644 libasm/asm_addint32.c create mode 100644 libasm/asm_addint64.c create mode 100644 libasm/asm_addint8.c create mode 100644 libasm/asm_addsleb128.c create mode 100644 libasm/asm_addstrz.c create mode 100644 libasm/asm_adduint16.c create mode 100644 libasm/asm_adduint32.c create mode 100644 libasm/asm_adduint64.c create mode 100644 libasm/asm_adduint8.c create mode 100644 libasm/asm_adduleb128.c create mode 100644 libasm/asm_align.c create mode 100644 libasm/asm_begin.c create mode 100644 libasm/asm_end.c create mode 100644 libasm/asm_error.c create mode 100644 libasm/asm_fill.c create mode 100644 libasm/asm_getelf.c create mode 100644 libasm/asm_newabssym.c create mode 100644 libasm/asm_newcomsym.c create mode 100644 libasm/asm_newscn.c create mode 100644 libasm/asm_newscn_ingrp.c create mode 100644 libasm/asm_newscngrp.c create mode 100644 libasm/asm_newsubscn.c create mode 100644 libasm/asm_newsym.c create mode 100644 libasm/asm_scngrp_newsignature.c create mode 100644 libasm/disasm_begin.c create mode 100644 libasm/disasm_cb.c create mode 100644 libasm/disasm_end.c create mode 100644 libasm/disasm_str.c create mode 100644 libasm/libasm.h create mode 100644 libasm/libasm.map create mode 100644 libasm/libasmP.h create mode 100644 libasm/symbolhash.c create mode 100644 libasm/symbolhash.h create mode 100644 libcpu/ChangeLog create mode 100644 libcpu/Makefile.am create mode 100644 libcpu/Makefile.in create mode 100644 libcpu/bpf_disasm.c create mode 100644 libcpu/defs/i386 create mode 100644 libcpu/i386_data.h create mode 100644 libcpu/i386_dis.h create mode 100644 libcpu/i386_disasm.c create mode 100644 libcpu/i386_gendis.c create mode 100644 libcpu/i386_lex.c create mode 100644 libcpu/i386_lex.l create mode 100644 libcpu/i386_parse.c create mode 100644 libcpu/i386_parse.h create mode 100644 libcpu/i386_parse.y create mode 100644 libcpu/memory-access.h create mode 100644 libcpu/riscv_disasm.c create mode 100644 libcpu/x86_64_dis.h create mode 100644 libcpu/x86_64_disasm.c create mode 100644 libdw/ChangeLog create mode 100644 libdw/Makefile.am create mode 100644 libdw/Makefile.in create mode 100644 libdw/cfi.c create mode 100644 libdw/cfi.h create mode 100644 libdw/cie.c create mode 100644 libdw/dwarf.h create mode 100644 libdw/dwarf_abbrev_hash.c create mode 100644 libdw/dwarf_abbrev_hash.h create mode 100644 libdw/dwarf_abbrevhaschildren.c create mode 100644 libdw/dwarf_addrdie.c create mode 100644 libdw/dwarf_aggregate_size.c create mode 100644 libdw/dwarf_arrayorder.c create mode 100644 libdw/dwarf_attr.c create mode 100644 libdw/dwarf_attr_integrate.c create mode 100644 libdw/dwarf_begin.c create mode 100644 libdw/dwarf_begin_elf.c create mode 100644 libdw/dwarf_bitoffset.c create mode 100644 libdw/dwarf_bitsize.c create mode 100644 libdw/dwarf_bytesize.c create mode 100644 libdw/dwarf_cfi_addrframe.c create mode 100644 libdw/dwarf_cfi_end.c create mode 100644 libdw/dwarf_child.c create mode 100644 libdw/dwarf_cu_die.c create mode 100644 libdw/dwarf_cu_getdwarf.c create mode 100644 libdw/dwarf_cu_info.c create mode 100644 libdw/dwarf_cuoffset.c create mode 100644 libdw/dwarf_decl_column.c create mode 100644 libdw/dwarf_decl_file.c create mode 100644 libdw/dwarf_decl_line.c create mode 100644 libdw/dwarf_default_lower_bound.c create mode 100644 libdw/dwarf_die_addr_die.c create mode 100644 libdw/dwarf_diecu.c create mode 100644 libdw/dwarf_diename.c create mode 100644 libdw/dwarf_dieoffset.c create mode 100644 libdw/dwarf_end.c create mode 100644 libdw/dwarf_entry_breakpoints.c create mode 100644 libdw/dwarf_entrypc.c create mode 100644 libdw/dwarf_error.c create mode 100644 libdw/dwarf_filesrc.c create mode 100644 libdw/dwarf_formaddr.c create mode 100644 libdw/dwarf_formblock.c create mode 100644 libdw/dwarf_formflag.c create mode 100644 libdw/dwarf_formref.c create mode 100644 libdw/dwarf_formref_die.c create mode 100644 libdw/dwarf_formsdata.c create mode 100644 libdw/dwarf_formstring.c create mode 100644 libdw/dwarf_formudata.c create mode 100644 libdw/dwarf_frame_cfa.c create mode 100644 libdw/dwarf_frame_info.c create mode 100644 libdw/dwarf_frame_register.c create mode 100644 libdw/dwarf_func_inline.c create mode 100644 libdw/dwarf_get_units.c create mode 100644 libdw/dwarf_getabbrev.c create mode 100644 libdw/dwarf_getabbrevattr.c create mode 100644 libdw/dwarf_getabbrevcode.c create mode 100644 libdw/dwarf_getabbrevtag.c create mode 100644 libdw/dwarf_getalt.c create mode 100644 libdw/dwarf_getarange_addr.c create mode 100644 libdw/dwarf_getarangeinfo.c create mode 100644 libdw/dwarf_getaranges.c create mode 100644 libdw/dwarf_getattrcnt.c create mode 100644 libdw/dwarf_getattrs.c create mode 100644 libdw/dwarf_getcfi.c create mode 100644 libdw/dwarf_getcfi_elf.c create mode 100644 libdw/dwarf_getelf.c create mode 100644 libdw/dwarf_getfuncs.c create mode 100644 libdw/dwarf_getlocation.c create mode 100644 libdw/dwarf_getlocation_attr.c create mode 100644 libdw/dwarf_getlocation_die.c create mode 100644 libdw/dwarf_getlocation_implicit_pointer.c create mode 100644 libdw/dwarf_getmacros.c create mode 100644 libdw/dwarf_getpubnames.c create mode 100644 libdw/dwarf_getscopes.c create mode 100644 libdw/dwarf_getscopes_die.c create mode 100644 libdw/dwarf_getscopevar.c create mode 100644 libdw/dwarf_getsrc_die.c create mode 100644 libdw/dwarf_getsrc_file.c create mode 100644 libdw/dwarf_getsrcdirs.c create mode 100644 libdw/dwarf_getsrcfiles.c create mode 100644 libdw/dwarf_getsrclines.c create mode 100644 libdw/dwarf_getstring.c create mode 100644 libdw/dwarf_hasattr.c create mode 100644 libdw/dwarf_hasattr_integrate.c create mode 100644 libdw/dwarf_haschildren.c create mode 100644 libdw/dwarf_hasform.c create mode 100644 libdw/dwarf_haspc.c create mode 100644 libdw/dwarf_highpc.c create mode 100644 libdw/dwarf_line_file.c create mode 100644 libdw/dwarf_lineaddr.c create mode 100644 libdw/dwarf_linebeginstatement.c create mode 100644 libdw/dwarf_lineblock.c create mode 100644 libdw/dwarf_linecol.c create mode 100644 libdw/dwarf_linediscriminator.c create mode 100644 libdw/dwarf_lineendsequence.c create mode 100644 libdw/dwarf_lineepiloguebegin.c create mode 100644 libdw/dwarf_lineisa.c create mode 100644 libdw/dwarf_lineno.c create mode 100644 libdw/dwarf_lineop_index.c create mode 100644 libdw/dwarf_lineprologueend.c create mode 100644 libdw/dwarf_linesrc.c create mode 100644 libdw/dwarf_lowpc.c create mode 100644 libdw/dwarf_macro_getparamcnt.c create mode 100644 libdw/dwarf_macro_getsrcfiles.c create mode 100644 libdw/dwarf_macro_opcode.c create mode 100644 libdw/dwarf_macro_param.c create mode 100644 libdw/dwarf_macro_param1.c create mode 100644 libdw/dwarf_macro_param2.c create mode 100644 libdw/dwarf_next_cfi.c create mode 100644 libdw/dwarf_next_lines.c create mode 100644 libdw/dwarf_nextcu.c create mode 100644 libdw/dwarf_offabbrev.c create mode 100644 libdw/dwarf_offdie.c create mode 100644 libdw/dwarf_onearange.c create mode 100644 libdw/dwarf_onesrcline.c create mode 100644 libdw/dwarf_peel_type.c create mode 100644 libdw/dwarf_ranges.c create mode 100644 libdw/dwarf_setalt.c create mode 100644 libdw/dwarf_siblingof.c create mode 100644 libdw/dwarf_sig8_hash.c create mode 100644 libdw/dwarf_sig8_hash.h create mode 100644 libdw/dwarf_srclang.c create mode 100644 libdw/dwarf_tag.c create mode 100644 libdw/dwarf_whatattr.c create mode 100644 libdw/dwarf_whatform.c create mode 100644 libdw/encoded-value.h create mode 100644 libdw/fde.c create mode 100644 libdw/frame-cache.c create mode 100644 libdw/known-dwarf.h create mode 100644 libdw/libdw.h create mode 100644 libdw/libdw.map create mode 100644 libdw/libdwP.h create mode 100644 libdw/libdw_alloc.c create mode 100644 libdw/libdw_find_split_unit.c create mode 100644 libdw/libdw_findcu.c create mode 100644 libdw/libdw_form.c create mode 100644 libdw/libdw_visit_scopes.c create mode 100644 libdw/memory-access.h create mode 100644 libdwelf/ChangeLog create mode 100644 libdwelf/Makefile.am create mode 100644 libdwelf/Makefile.in create mode 100644 libdwelf/dwelf_dwarf_gnu_debugaltlink.c create mode 100644 libdwelf/dwelf_elf_begin.c create mode 100644 libdwelf/dwelf_elf_e_machine_string.c create mode 100644 libdwelf/dwelf_elf_gnu_build_id.c create mode 100644 libdwelf/dwelf_elf_gnu_debuglink.c create mode 100644 libdwelf/dwelf_scn_gnu_compressed_size.c create mode 100644 libdwelf/dwelf_strtab.c create mode 100644 libdwelf/libdwelf.h create mode 100644 libdwelf/libdwelfP.h create mode 100644 libdwfl/ChangeLog create mode 100644 libdwfl/Makefile.am create mode 100644 libdwfl/Makefile.in create mode 100644 libdwfl/argp-std.c create mode 100644 libdwfl/bzip2.c create mode 100644 libdwfl/core-file.c create mode 100644 libdwfl/cu.c create mode 100644 libdwfl/debuginfod-client.c create mode 100644 libdwfl/derelocate.c create mode 100644 libdwfl/dwfl_addrdie.c create mode 100644 libdwfl/dwfl_addrdwarf.c create mode 100644 libdwfl/dwfl_addrmodule.c create mode 100644 libdwfl/dwfl_begin.c create mode 100644 libdwfl/dwfl_build_id_find_debuginfo.c create mode 100644 libdwfl/dwfl_build_id_find_elf.c create mode 100644 libdwfl/dwfl_cumodule.c create mode 100644 libdwfl/dwfl_dwarf_line.c create mode 100644 libdwfl/dwfl_end.c create mode 100644 libdwfl/dwfl_error.c create mode 100644 libdwfl/dwfl_frame.c create mode 100644 libdwfl/dwfl_frame_pc.c create mode 100644 libdwfl/dwfl_frame_regs.c create mode 100644 libdwfl/dwfl_getdwarf.c create mode 100644 libdwfl/dwfl_getmodules.c create mode 100644 libdwfl/dwfl_getsrc.c create mode 100644 libdwfl/dwfl_getsrclines.c create mode 100644 libdwfl/dwfl_line_comp_dir.c create mode 100644 libdwfl/dwfl_linecu.c create mode 100644 libdwfl/dwfl_lineinfo.c create mode 100644 libdwfl/dwfl_linemodule.c create mode 100644 libdwfl/dwfl_module.c create mode 100644 libdwfl/dwfl_module_addrdie.c create mode 100644 libdwfl/dwfl_module_addrname.c create mode 100644 libdwfl/dwfl_module_addrsym.c create mode 100644 libdwfl/dwfl_module_build_id.c create mode 100644 libdwfl/dwfl_module_dwarf_cfi.c create mode 100644 libdwfl/dwfl_module_eh_cfi.c create mode 100644 libdwfl/dwfl_module_getdwarf.c create mode 100644 libdwfl/dwfl_module_getelf.c create mode 100644 libdwfl/dwfl_module_getsrc.c create mode 100644 libdwfl/dwfl_module_getsrc_file.c create mode 100644 libdwfl/dwfl_module_getsym.c create mode 100644 libdwfl/dwfl_module_info.c create mode 100644 libdwfl/dwfl_module_nextcu.c create mode 100644 libdwfl/dwfl_module_register_names.c create mode 100644 libdwfl/dwfl_module_report_build_id.c create mode 100644 libdwfl/dwfl_module_return_value_location.c create mode 100644 libdwfl/dwfl_nextcu.c create mode 100644 libdwfl/dwfl_onesrcline.c create mode 100644 libdwfl/dwfl_report_elf.c create mode 100644 libdwfl/dwfl_segment_report_module.c create mode 100644 libdwfl/dwfl_validate_address.c create mode 100644 libdwfl/dwfl_version.c create mode 100644 libdwfl/elf-from-memory.c create mode 100644 libdwfl/find-debuginfo.c create mode 100644 libdwfl/frame_unwind.c create mode 100644 libdwfl/gzip.c create mode 100644 libdwfl/image-header.c create mode 100644 libdwfl/libdwfl.h create mode 100644 libdwfl/libdwflP.h create mode 100644 libdwfl/libdwfl_crc32.c create mode 100644 libdwfl/libdwfl_crc32_file.c create mode 100644 libdwfl/lines.c create mode 100644 libdwfl/link_map.c create mode 100644 libdwfl/linux-core-attach.c create mode 100644 libdwfl/linux-kernel-modules.c create mode 100644 libdwfl/linux-pid-attach.c create mode 100644 libdwfl/linux-proc-maps.c create mode 100644 libdwfl/lzma.c create mode 100644 libdwfl/offline.c create mode 100644 libdwfl/open.c create mode 100644 libdwfl/relocate.c create mode 100644 libdwfl/segment.c create mode 100644 libdwfl/zstd.c create mode 100644 libebl/ChangeLog create mode 100644 libebl/Makefile.am create mode 100644 libebl/Makefile.in create mode 100644 libebl/ebl-hooks.h create mode 100644 libebl/ebl_check_special_section.c create mode 100644 libebl/ebl_check_special_symbol.c create mode 100644 libebl/ebl_data_marker_symbol.c create mode 100644 libebl/eblabicfi.c create mode 100644 libebl/eblauxvinfo.c create mode 100644 libebl/eblbackendname.c create mode 100644 libebl/eblbsspltp.c create mode 100644 libebl/eblcheckobjattr.c create mode 100644 libebl/eblcheckreloctargettype.c create mode 100644 libebl/eblclosebackend.c create mode 100644 libebl/eblcopyrelocp.c create mode 100644 libebl/eblcorenote.c create mode 100644 libebl/eblcorenotetypename.c create mode 100644 libebl/ebldebugscnp.c create mode 100644 libebl/ebldwarftoregno.c create mode 100644 libebl/ebldynamictagcheck.c create mode 100644 libebl/ebldynamictagname.c create mode 100644 libebl/eblelfclass.c create mode 100644 libebl/eblelfdata.c create mode 100644 libebl/eblelfmachine.c create mode 100644 libebl/eblgotpcreloccheck.c create mode 100644 libebl/eblinitreg.c create mode 100644 libebl/eblmachineflagcheck.c create mode 100644 libebl/eblmachineflagname.c create mode 100644 libebl/eblmachinesectionflagcheck.c create mode 100644 libebl/eblnonerelocp.c create mode 100644 libebl/eblnormalizepc.c create mode 100644 libebl/eblobjnote.c create mode 100644 libebl/eblobjnotetypename.c create mode 100644 libebl/eblopenbackend.c create mode 100644 libebl/eblosabiname.c create mode 100644 libebl/eblreginfo.c create mode 100644 libebl/eblrelativerelocp.c create mode 100644 libebl/eblrelocsimpletype.c create mode 100644 libebl/eblreloctypecheck.c create mode 100644 libebl/eblreloctypename.c create mode 100644 libebl/eblrelocvaliduse.c create mode 100644 libebl/eblresolvesym.c create mode 100644 libebl/eblretval.c create mode 100644 libebl/eblsectionname.c create mode 100644 libebl/eblsectionstripp.c create mode 100644 libebl/eblsectiontypename.c create mode 100644 libebl/eblsegmenttypename.c create mode 100644 libebl/eblstother.c create mode 100644 libebl/eblsymbolbindingname.c create mode 100644 libebl/eblsymboltypename.c create mode 100644 libebl/eblsysvhashentrysize.c create mode 100644 libebl/eblunwind.c create mode 100644 libebl/libebl.h create mode 100644 libebl/libeblP.h create mode 100644 libelf/ChangeLog create mode 100644 libelf/Makefile.am create mode 100644 libelf/Makefile.in create mode 100644 libelf/abstract.h create mode 100644 libelf/chdr_xlate.h create mode 100644 libelf/common.h create mode 100644 libelf/dl-hash.h create mode 100644 libelf/elf-knowledge.h create mode 100644 libelf/elf.h create mode 100644 libelf/elf32_checksum.c create mode 100644 libelf/elf32_fsize.c create mode 100644 libelf/elf32_getchdr.c create mode 100644 libelf/elf32_getehdr.c create mode 100644 libelf/elf32_getphdr.c create mode 100644 libelf/elf32_getshdr.c create mode 100644 libelf/elf32_newehdr.c create mode 100644 libelf/elf32_newphdr.c create mode 100644 libelf/elf32_offscn.c create mode 100644 libelf/elf32_updatefile.c create mode 100644 libelf/elf32_updatenull.c create mode 100644 libelf/elf32_xlatetof.c create mode 100644 libelf/elf32_xlatetom.c create mode 100644 libelf/elf64_checksum.c create mode 100644 libelf/elf64_fsize.c create mode 100644 libelf/elf64_getchdr.c create mode 100644 libelf/elf64_getehdr.c create mode 100644 libelf/elf64_getphdr.c create mode 100644 libelf/elf64_getshdr.c create mode 100644 libelf/elf64_newehdr.c create mode 100644 libelf/elf64_newphdr.c create mode 100644 libelf/elf64_offscn.c create mode 100644 libelf/elf64_updatefile.c create mode 100644 libelf/elf64_updatenull.c create mode 100644 libelf/elf64_xlatetof.c create mode 100644 libelf/elf64_xlatetom.c create mode 100644 libelf/elf_begin.c create mode 100644 libelf/elf_clone.c create mode 100644 libelf/elf_cntl.c create mode 100644 libelf/elf_compress.c create mode 100644 libelf/elf_compress_gnu.c create mode 100644 libelf/elf_end.c create mode 100644 libelf/elf_error.c create mode 100644 libelf/elf_fill.c create mode 100644 libelf/elf_flagdata.c create mode 100644 libelf/elf_flagehdr.c create mode 100644 libelf/elf_flagelf.c create mode 100644 libelf/elf_flagphdr.c create mode 100644 libelf/elf_flagscn.c create mode 100644 libelf/elf_flagshdr.c create mode 100644 libelf/elf_getarhdr.c create mode 100644 libelf/elf_getaroff.c create mode 100644 libelf/elf_getarsym.c create mode 100644 libelf/elf_getbase.c create mode 100644 libelf/elf_getdata.c create mode 100644 libelf/elf_getdata_rawchunk.c create mode 100644 libelf/elf_getident.c create mode 100644 libelf/elf_getphdrnum.c create mode 100644 libelf/elf_getscn.c create mode 100644 libelf/elf_getshdrnum.c create mode 100644 libelf/elf_getshdrstrndx.c create mode 100644 libelf/elf_gnu_hash.c create mode 100644 libelf/elf_hash.c create mode 100644 libelf/elf_kind.c create mode 100644 libelf/elf_memory.c create mode 100644 libelf/elf_ndxscn.c create mode 100644 libelf/elf_newdata.c create mode 100644 libelf/elf_newscn.c create mode 100644 libelf/elf_next.c create mode 100644 libelf/elf_nextscn.c create mode 100644 libelf/elf_rand.c create mode 100644 libelf/elf_rawdata.c create mode 100644 libelf/elf_rawfile.c create mode 100644 libelf/elf_readall.c create mode 100644 libelf/elf_scnshndx.c create mode 100644 libelf/elf_strptr.c create mode 100644 libelf/elf_update.c create mode 100644 libelf/elf_version.c create mode 100644 libelf/exttypes.h create mode 100644 libelf/gelf.h create mode 100644 libelf/gelf_checksum.c create mode 100644 libelf/gelf_fsize.c create mode 100644 libelf/gelf_getauxv.c create mode 100644 libelf/gelf_getchdr.c create mode 100644 libelf/gelf_getclass.c create mode 100644 libelf/gelf_getdyn.c create mode 100644 libelf/gelf_getehdr.c create mode 100644 libelf/gelf_getlib.c create mode 100644 libelf/gelf_getmove.c create mode 100644 libelf/gelf_getnote.c create mode 100644 libelf/gelf_getphdr.c create mode 100644 libelf/gelf_getrel.c create mode 100644 libelf/gelf_getrela.c create mode 100644 libelf/gelf_getshdr.c create mode 100644 libelf/gelf_getsym.c create mode 100644 libelf/gelf_getsyminfo.c create mode 100644 libelf/gelf_getsymshndx.c create mode 100644 libelf/gelf_getverdaux.c create mode 100644 libelf/gelf_getverdef.c create mode 100644 libelf/gelf_getvernaux.c create mode 100644 libelf/gelf_getverneed.c create mode 100644 libelf/gelf_getversym.c create mode 100644 libelf/gelf_newehdr.c create mode 100644 libelf/gelf_newphdr.c create mode 100644 libelf/gelf_offscn.c create mode 100644 libelf/gelf_update_auxv.c create mode 100644 libelf/gelf_update_dyn.c create mode 100644 libelf/gelf_update_ehdr.c create mode 100644 libelf/gelf_update_lib.c create mode 100644 libelf/gelf_update_move.c create mode 100644 libelf/gelf_update_phdr.c create mode 100644 libelf/gelf_update_rel.c create mode 100644 libelf/gelf_update_rela.c create mode 100644 libelf/gelf_update_shdr.c create mode 100644 libelf/gelf_update_sym.c create mode 100644 libelf/gelf_update_syminfo.c create mode 100644 libelf/gelf_update_symshndx.c create mode 100644 libelf/gelf_update_verdaux.c create mode 100644 libelf/gelf_update_verdef.c create mode 100644 libelf/gelf_update_vernaux.c create mode 100644 libelf/gelf_update_verneed.c create mode 100644 libelf/gelf_update_versym.c create mode 100644 libelf/gelf_xlate.c create mode 100644 libelf/gelf_xlate.h create mode 100644 libelf/gelf_xlatetof.c create mode 100644 libelf/gelf_xlatetom.c create mode 100644 libelf/gnuhash_xlate.h create mode 100644 libelf/libelf.h create mode 100644 libelf/libelf.map create mode 100644 libelf/libelfP.h create mode 100644 libelf/libelf_crc32.c create mode 100644 libelf/libelf_next_prime.c create mode 100644 libelf/nlist.c create mode 100644 libelf/nlist.h create mode 100644 libelf/note_xlate.h create mode 100644 libelf/version_xlate.h create mode 100644 m4/ax_cxx_compile_stdcxx.m4 create mode 100644 m4/biarch.m4 create mode 100644 m4/gettext.m4 create mode 100644 m4/host-cpu-c-abi.m4 create mode 100644 m4/iconv.m4 create mode 100644 m4/intlmacosx.m4 create mode 100644 m4/lib-ld.m4 create mode 100644 m4/lib-link.m4 create mode 100644 m4/lib-prefix.m4 create mode 100644 m4/nls.m4 create mode 100644 m4/po.m4 create mode 100644 m4/progtest.m4 create mode 100644 m4/zip.m4 create mode 100644 po/ChangeLog create mode 100644 po/LINGUAS create mode 100644 po/Makefile.in.in create mode 100644 po/Makevars create mode 100644 po/POTFILES.in create mode 100644 po/Rules-quot create mode 100644 po/boldquot.sed create mode 100644 po/de.gmo create mode 100644 po/de.po create mode 100644 po/elfutils.pot create mode 100644 po/en@boldquot.gmo create mode 100644 po/en@boldquot.header create mode 100644 po/en@boldquot.po create mode 100644 po/en@quot.gmo create mode 100644 po/en@quot.header create mode 100644 po/en@quot.po create mode 100644 po/es.gmo create mode 100644 po/es.po create mode 100644 po/insert-header.sin create mode 100644 po/ja.gmo create mode 100644 po/ja.po create mode 100644 po/pl.gmo create mode 100644 po/pl.po create mode 100644 po/quot.sed create mode 100644 po/remove-potcdate.sin create mode 100644 po/stamp-po create mode 100644 po/uk.gmo create mode 100644 po/uk.po create mode 100644 src/ChangeLog create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/addr2line.c create mode 100644 src/ar.c create mode 100644 src/arlib-argp.c create mode 100644 src/arlib.c create mode 100644 src/arlib.h create mode 100644 src/arlib2.c create mode 100644 src/debugpred.h create mode 100644 src/elfclassify.c create mode 100644 src/elfcmp.c create mode 100644 src/elfcompress.c create mode 100644 src/elflint.c create mode 100644 src/findtextrel.c create mode 100644 src/make-debug-archive.in create mode 100644 src/nm.c create mode 100644 src/objdump.c create mode 100644 src/ranlib.c create mode 100644 src/readelf.c create mode 100644 src/size.c create mode 100644 src/stack.c create mode 100644 src/strings.c create mode 100644 src/strip.c create mode 100644 src/unstrip.c create mode 100644 tests/ChangeLog create mode 100644 tests/Makefile.am create mode 100644 tests/Makefile.in create mode 100644 tests/addrcfi.c create mode 100644 tests/addrscopes.c create mode 100644 tests/addrx_constx-4.dwo.bz2 create mode 100644 tests/addrx_constx-5.dwo.bz2 create mode 100644 tests/addsections.c create mode 100644 tests/aggregate_size.c create mode 100644 tests/all-dwarf-ranges.c create mode 100644 tests/alldts.c create mode 100644 tests/allfcts.c create mode 100644 tests/allregs.c create mode 100644 tests/arextract.c create mode 100644 tests/arls.c create mode 100644 tests/arsymtest.c create mode 100644 tests/asm-tst1.c create mode 100644 tests/asm-tst2.c create mode 100644 tests/asm-tst3.c create mode 100644 tests/asm-tst4.c create mode 100644 tests/asm-tst5.c create mode 100644 tests/asm-tst6.c create mode 100644 tests/asm-tst7.c create mode 100644 tests/asm-tst8.c create mode 100644 tests/asm-tst9.c create mode 100644 tests/attr-integrate-skel.c create mode 100644 tests/backtrace-child.c create mode 100644 tests/backtrace-data.c create mode 100644 tests/backtrace-dwarf.c create mode 100644 tests/backtrace-subr.sh create mode 100644 tests/backtrace.aarch64.core.bz2 create mode 100755 tests/backtrace.aarch64.exec.bz2 create mode 100644 tests/backtrace.aarch64.fp.core.bz2 create mode 100644 tests/backtrace.aarch64.fp.exec.bz2 create mode 100644 tests/backtrace.c create mode 100644 tests/backtrace.i386.core.bz2 create mode 100644 tests/backtrace.i386.exec.bz2 create mode 100644 tests/backtrace.i386.fp.core.bz2 create mode 100755 tests/backtrace.i386.fp.exec.bz2 create mode 100644 tests/backtrace.ppc.core.bz2 create mode 100644 tests/backtrace.ppc.exec.bz2 create mode 100644 tests/backtrace.ppc64le.fp.core.bz2 create mode 100755 tests/backtrace.ppc64le.fp.exec.bz2 create mode 100644 tests/backtrace.s390.core.bz2 create mode 100644 tests/backtrace.s390.exec.bz2 create mode 100644 tests/backtrace.s390x.core.bz2 create mode 100644 tests/backtrace.s390x.exec.bz2 create mode 100644 tests/backtrace.sparc.core.bz2 create mode 100755 tests/backtrace.sparc.exec.bz2 create mode 100644 tests/backtrace.x32.core.bz2 create mode 100644 tests/backtrace.x32.exec.bz2 create mode 100644 tests/backtrace.x86_64.core.bz2 create mode 100644 tests/backtrace.x86_64.exec.bz2 create mode 100644 tests/backtrace.x86_64.fp.core.bz2 create mode 100644 tests/backtrace.x86_64.fp.exec.bz2 create mode 100644 tests/buildid.c create mode 100644 tests/cleanup-13.c create mode 100755 tests/coverage.sh create mode 100644 tests/debug-ranges-no-lowpc.o.bz2 create mode 100644 tests/debugaltlink.c create mode 100644 tests/debuginfod-debs/hithere-dbgsym_1.0-1_amd64.ddeb create mode 100644 tests/debuginfod-debs/hithere_1.0-1.debian.tar.xz create mode 100644 tests/debuginfod-debs/hithere_1.0-1.dsc create mode 100644 tests/debuginfod-debs/hithere_1.0-1_amd64.deb create mode 100644 tests/debuginfod-debs/hithere_1.0.orig.tar.gz create mode 100644 tests/debuginfod-rpms/fedora30/hello2-1.0-2.src.rpm create mode 100644 tests/debuginfod-rpms/fedora30/hello2-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora30/hello2-debuginfo-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora30/hello2-debugsource-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora30/hello2-two-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora30/hello2-two-debuginfo-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora31/hello3-1.0-2.src.rpm create mode 100644 tests/debuginfod-rpms/fedora31/hello3-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora31/hello3-debuginfo-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora31/hello3-debugsource-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora31/hello3-two-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/fedora31/hello3-two-debuginfo-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/hello2.spec. create mode 100644 tests/debuginfod-rpms/rhel6/hello2-1.0-2.i686.rpm create mode 100644 tests/debuginfod-rpms/rhel6/hello2-1.0-2.src.rpm create mode 100644 tests/debuginfod-rpms/rhel6/hello2-debuginfo-1.0-2.i686.rpm create mode 100644 tests/debuginfod-rpms/rhel6/hello2-two-1.0-2.i686.rpm create mode 100644 tests/debuginfod-rpms/rhel7/hello2-1.0-2.src.rpm create mode 100644 tests/debuginfod-rpms/rhel7/hello2-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/rhel7/hello2-debuginfo-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-rpms/rhel7/hello2-two-1.0-2.x86_64.rpm create mode 100644 tests/debuginfod-tars/hello-1-1-x86_64.pkg.tar.xz create mode 100644 tests/debuginfod-tars/hello-debug-1-1-x86_64.pkg.tar.bz2 create mode 100644 tests/debuginfod-tars/pacman-sources/PKGBUILD create mode 100644 tests/debuginfod-tars/pacman-sources/README.md create mode 100644 tests/debuginfod-tars/pacman-sources/hello.c create mode 100644 tests/debuginfod_build_id_find.c create mode 100644 tests/debuglink.c create mode 100644 tests/deleted-lib.c create mode 100644 tests/deleted.c create mode 100644 tests/dwarf-die-addr-die.c create mode 100644 tests/dwarf-getmacros.c create mode 100644 tests/dwarf-getstring.c create mode 100644 tests/dwarf-ranges.c create mode 100644 tests/dwarf_default_lower_bound.c create mode 100644 tests/dwarfcfi.c create mode 100644 tests/dwelf_elf_e_machine_string.c create mode 100644 tests/dwelfgnucompressed.c create mode 100644 tests/dwfl-addr-sect.c create mode 100644 tests/dwfl-bug-addr-overflow.c create mode 100644 tests/dwfl-bug-fd-leak.c create mode 100644 tests/dwfl-bug-getmodules.c create mode 100644 tests/dwfl-bug-report.c create mode 100644 tests/dwfl-proc-attach.c create mode 100644 tests/dwfl-report-elf-align.c create mode 100644 tests/dwfl-report-segment-contiguous.c create mode 100644 tests/dwfllines.c create mode 100644 tests/dwflmodtest.c create mode 100644 tests/dwflsyms.c create mode 100644 tests/early-offscn.c create mode 100644 tests/ecp.c create mode 100644 tests/elfcopy.c create mode 100644 tests/elfgetchdr.c create mode 100644 tests/elfgetzdata.c create mode 100644 tests/elfputzdata.c create mode 100644 tests/elfrdwrnop.c create mode 100644 tests/elfshphehdr.c create mode 100644 tests/elfstrmerge.c create mode 100644 tests/elfstrtab.c create mode 100644 tests/emptyfile.c create mode 100644 tests/fillfile.c create mode 100644 tests/find-prologues.c create mode 100644 tests/funcretval.c create mode 100644 tests/funcretval_test.c create mode 100755 tests/funcretval_test_aarch64.bz2 create mode 100644 tests/funcscopes.c create mode 100644 tests/get-aranges.c create mode 100644 tests/get-files.c create mode 100644 tests/get-lines.c create mode 100644 tests/get-pubnames.c create mode 100644 tests/get-units-invalid.c create mode 100644 tests/get-units-split.c create mode 100644 tests/getphdrnum.c create mode 100644 tests/getsrc_die.c create mode 100644 tests/hash.c create mode 100644 tests/hello_aarch64.ko.bz2 create mode 100644 tests/hello_csky.ko.bz2 create mode 100644 tests/hello_i386.ko.bz2 create mode 100644 tests/hello_m68k.ko.bz2 create mode 100644 tests/hello_ppc64.ko.bz2 create mode 100644 tests/hello_riscv64.ko.bz2 create mode 100644 tests/hello_s390.ko.bz2 create mode 100644 tests/hello_x86_64.ko.bz2 create mode 100644 tests/leb128.c create mode 100644 tests/lfs-symbols create mode 100755 tests/libtestfile_multi_shared.so.bz2 create mode 100644 tests/line2addr.c create mode 100644 tests/linkmap-cut-lib.so.bz2 create mode 100644 tests/linkmap-cut.bz2 create mode 100644 tests/linkmap-cut.core.bz2 create mode 100644 tests/low_high_pc.c create mode 100644 tests/msg_tst.c create mode 100644 tests/newdata.c create mode 100644 tests/newfile.c create mode 100644 tests/newscn.c create mode 100644 tests/next-files.c create mode 100644 tests/next-lines.c create mode 100644 tests/next_cfi.c create mode 100644 tests/peel_type.c create mode 100644 tests/rdwrmmap.c create mode 100644 tests/read_unaligned.c create mode 100644 tests/rerequest_tag.c create mode 100755 tests/run-addr2line-alt-debugpath.sh create mode 100755 tests/run-addr2line-i-demangle-test.sh create mode 100755 tests/run-addr2line-i-lex-test.sh create mode 100755 tests/run-addr2line-i-test.sh create mode 100755 tests/run-addr2line-test.sh create mode 100755 tests/run-addrcfi.sh create mode 100755 tests/run-addrname-test.sh create mode 100755 tests/run-addrscopes.sh create mode 100755 tests/run-aggregate-size.sh create mode 100755 tests/run-all-dwarf-ranges.sh create mode 100755 tests/run-alldts.sh create mode 100755 tests/run-allfcts-multi.sh create mode 100755 tests/run-allfcts.sh create mode 100755 tests/run-allregs.sh create mode 100755 tests/run-annobingroup.sh create mode 100755 tests/run-ar.sh create mode 100755 tests/run-arextract.sh create mode 100755 tests/run-arsymtest.sh create mode 100755 tests/run-attr-integrate-skel.sh create mode 100755 tests/run-backtrace-core-aarch64.sh create mode 100755 tests/run-backtrace-core-i386.sh create mode 100755 tests/run-backtrace-core-ppc.sh create mode 100755 tests/run-backtrace-core-s390.sh create mode 100755 tests/run-backtrace-core-s390x.sh create mode 100755 tests/run-backtrace-core-sparc.sh create mode 100755 tests/run-backtrace-core-x32.sh create mode 100755 tests/run-backtrace-core-x86_64.sh create mode 100755 tests/run-backtrace-data.sh create mode 100755 tests/run-backtrace-demangle.sh create mode 100755 tests/run-backtrace-dwarf.sh create mode 100755 tests/run-backtrace-fp-core-aarch64.sh create mode 100755 tests/run-backtrace-fp-core-i386.sh create mode 100755 tests/run-backtrace-fp-core-ppc64le.sh create mode 100755 tests/run-backtrace-fp-core-x86_64.sh create mode 100755 tests/run-backtrace-native-biarch.sh create mode 100755 tests/run-backtrace-native-core-biarch.sh create mode 100755 tests/run-backtrace-native-core.sh create mode 100755 tests/run-backtrace-native.sh create mode 100755 tests/run-bug1-test.sh create mode 100755 tests/run-buildid.sh create mode 100755 tests/run-compress-test.sh create mode 100755 tests/run-copyadd-sections.sh create mode 100755 tests/run-copymany-sections.sh create mode 100755 tests/run-debugaltlink.sh create mode 100755 tests/run-debuginfod-find.sh create mode 100755 tests/run-debuglink.sh create mode 100755 tests/run-deleted.sh create mode 100755 tests/run-disasm-bpf.sh create mode 100755 tests/run-disasm-riscv64.sh create mode 100755 tests/run-disasm-x86-64.sh create mode 100755 tests/run-disasm-x86.sh create mode 100755 tests/run-dwarf-die-addr-die.sh create mode 100755 tests/run-dwarf-getmacros.sh create mode 100755 tests/run-dwarf-getstring.sh create mode 100755 tests/run-dwarf-ranges.sh create mode 100755 tests/run-dwarfcfi.sh create mode 100755 tests/run-dwelf_elf_e_machine_string.sh create mode 100755 tests/run-dwelfgnucompressed.sh create mode 100755 tests/run-dwfl-addr-sect.sh create mode 100755 tests/run-dwfl-bug-offline-rel.sh create mode 100755 tests/run-dwfl-report-elf-align.sh create mode 100755 tests/run-dwfllines.sh create mode 100755 tests/run-dwflsyms.sh create mode 100755 tests/run-early-offscn.sh create mode 100755 tests/run-ecp-test.sh create mode 100755 tests/run-ecp-test2.sh create mode 100755 tests/run-elf_cntl_gelf_getshdr.sh create mode 100755 tests/run-elfclassify-self.sh create mode 100755 tests/run-elfclassify.sh create mode 100755 tests/run-elfgetchdr.sh create mode 100755 tests/run-elfgetzdata.sh create mode 100755 tests/run-elflint-self.sh create mode 100755 tests/run-elflint-test.sh create mode 100755 tests/run-elfputzdata.sh create mode 100755 tests/run-elfstrmerge-test.sh create mode 100755 tests/run-exprlocs-self.sh create mode 100755 tests/run-exprlocs.sh create mode 100755 tests/run-find-prologues.sh create mode 100755 tests/run-funcretval.sh create mode 100755 tests/run-funcscopes.sh create mode 100755 tests/run-get-aranges.sh create mode 100755 tests/run-get-files.sh create mode 100755 tests/run-get-lines.sh create mode 100755 tests/run-get-pubnames.sh create mode 100755 tests/run-get-units-invalid.sh create mode 100755 tests/run-get-units-split.sh create mode 100755 tests/run-getphdrnum.sh create mode 100755 tests/run-getsrc-die.sh create mode 100755 tests/run-large-elf-file.sh create mode 100755 tests/run-lfs-symbols.sh create mode 100755 tests/run-line2addr.sh create mode 100755 tests/run-linkmap-cut.sh create mode 100755 tests/run-low_high_pc-dw-form-indirect.sh create mode 100755 tests/run-low_high_pc.sh create mode 100755 tests/run-macro-test.sh create mode 100755 tests/run-native-test.sh create mode 100755 tests/run-next-cfi-self.sh create mode 100755 tests/run-next-cfi.sh create mode 100755 tests/run-next-files.sh create mode 100755 tests/run-next-lines.sh create mode 100755 tests/run-nm-self.sh create mode 100755 tests/run-nm-syms.sh create mode 100755 tests/run-peel-type.sh create mode 100755 tests/run-prelink-addr-test.sh create mode 100755 tests/run-pt_gnu_prop-tests.sh create mode 100755 tests/run-ranlib-test.sh create mode 100755 tests/run-ranlib-test2.sh create mode 100755 tests/run-ranlib-test3.sh create mode 100755 tests/run-ranlib-test4.sh create mode 100755 tests/run-readelf-A.sh create mode 100755 tests/run-readelf-addr.sh create mode 100755 tests/run-readelf-aranges.sh create mode 100755 tests/run-readelf-compressed-zstd.sh create mode 100755 tests/run-readelf-compressed.sh create mode 100755 tests/run-readelf-const-values.sh create mode 100755 tests/run-readelf-d.sh create mode 100755 tests/run-readelf-discr.sh create mode 100755 tests/run-readelf-dw-form-indirect.sh create mode 100755 tests/run-readelf-dwz-multi.sh create mode 100755 tests/run-readelf-frames.sh create mode 100755 tests/run-readelf-gdb_index.sh create mode 100755 tests/run-readelf-info-plus.sh create mode 100755 tests/run-readelf-line.sh create mode 100755 tests/run-readelf-loc.sh create mode 100755 tests/run-readelf-macro.sh create mode 100755 tests/run-readelf-mixed-corenote.sh create mode 100755 tests/run-readelf-n.sh create mode 100755 tests/run-readelf-ranges.sh create mode 100755 tests/run-readelf-s.sh create mode 100755 tests/run-readelf-self.sh create mode 100755 tests/run-readelf-str.sh create mode 100755 tests/run-readelf-test1.sh create mode 100755 tests/run-readelf-test2.sh create mode 100755 tests/run-readelf-test3.sh create mode 100755 tests/run-readelf-test4.sh create mode 100755 tests/run-readelf-twofiles.sh create mode 100755 tests/run-readelf-types.sh create mode 100755 tests/run-readelf-variant.sh create mode 100755 tests/run-readelf-vmcoreinfo.sh create mode 100755 tests/run-readelf-z.sh create mode 100755 tests/run-readelf-zdebug-rel.sh create mode 100755 tests/run-readelf-zdebug.sh create mode 100755 tests/run-readelf-zp.sh create mode 100755 tests/run-readelf-zx.sh create mode 100755 tests/run-reloc-bpf.sh create mode 100755 tests/run-rerequest_tag.sh create mode 100755 tests/run-retain.sh create mode 100755 tests/run-reverse-sections-self.sh create mode 100755 tests/run-reverse-sections.sh create mode 100755 tests/run-show-abbrev.sh create mode 100755 tests/run-show-die-info.sh create mode 100755 tests/run-stack-d-test.sh create mode 100755 tests/run-stack-demangled-test.sh create mode 100755 tests/run-stack-i-test.sh create mode 100755 tests/run-strings-test.sh create mode 100755 tests/run-strip-g.sh create mode 100755 tests/run-strip-groups.sh create mode 100755 tests/run-strip-nobitsalign.sh create mode 100755 tests/run-strip-nothing.sh create mode 100755 tests/run-strip-reloc.sh create mode 100755 tests/run-strip-remove-keep.sh create mode 100755 tests/run-strip-strmerge.sh create mode 100755 tests/run-strip-test-many.sh create mode 100755 tests/run-strip-test.sh create mode 100755 tests/run-strip-test10.sh create mode 100755 tests/run-strip-test11.sh create mode 100755 tests/run-strip-test12.sh create mode 100755 tests/run-strip-test2.sh create mode 100755 tests/run-strip-test3.sh create mode 100755 tests/run-strip-test4.sh create mode 100755 tests/run-strip-test5.sh create mode 100755 tests/run-strip-test6.sh create mode 100755 tests/run-strip-test7.sh create mode 100755 tests/run-strip-test8.sh create mode 100755 tests/run-strip-test9.sh create mode 100755 tests/run-strip-version.sh create mode 100755 tests/run-strptr.sh create mode 100755 tests/run-test-archive64.sh create mode 100755 tests/run-test-flag-nobits.sh create mode 100755 tests/run-test-includes.sh create mode 100755 tests/run-typeiter-many.sh create mode 100755 tests/run-typeiter.sh create mode 100755 tests/run-unit-info.sh create mode 100755 tests/run-unstrip-M.sh create mode 100755 tests/run-unstrip-n.sh create mode 100755 tests/run-unstrip-test.sh create mode 100755 tests/run-unstrip-test2.sh create mode 100755 tests/run-unstrip-test3.sh create mode 100755 tests/run-unstrip-test4.sh create mode 100755 tests/run-varlocs-self.sh create mode 100755 tests/run-varlocs.sh create mode 100755 tests/run-xlate-note.sh create mode 100755 tests/run-zstrptr.sh create mode 100644 tests/saridx.c create mode 100644 tests/scnnames.c create mode 100644 tests/sectiondump.c create mode 100644 tests/show-abbrev.c create mode 100644 tests/show-die-info.c create mode 100644 tests/showptable.c create mode 100644 tests/splitdwarf4-not-split4.dwo.bz2 create mode 100644 tests/strptr.c create mode 100644 tests/system-elf-libelf-test.c create mode 100755 tests/test-core-lib.so.bz2 create mode 100644 tests/test-core.core.bz2 create mode 100755 tests/test-core.exec.bz2 create mode 100644 tests/test-elf_cntl_gelf_getshdr.c create mode 100644 tests/test-flag-nobits.c create mode 100644 tests/test-nlist.c create mode 100644 tests/test-offset-loop.alt.bz2 create mode 100755 tests/test-offset-loop.bz2 create mode 100644 tests/test-subr.sh create mode 100755 tests/test-wrapper.sh create mode 100644 tests/testarchive64.a.bz2 create mode 100644 tests/testcore-rtlib-ppc.bz2 create mode 100644 tests/testcore-rtlib.bz2 create mode 100644 tests/testfile-ada-variant.bz2 create mode 100755 tests/testfile-addrx_constx-4.bz2 create mode 100755 tests/testfile-addrx_constx-5.bz2 create mode 100644 tests/testfile-annobingroup-i386.o.bz2 create mode 100644 tests/testfile-annobingroup-x86_64.o.bz2 create mode 100644 tests/testfile-annobingroup.o.bz2 create mode 100755 tests/testfile-backtrace-demangle.bz2 create mode 100644 tests/testfile-backtrace-demangle.cc create mode 100644 tests/testfile-backtrace-demangle.core.bz2 create mode 100644 tests/testfile-bpf-dis1.expect.bz2 create mode 100644 tests/testfile-bpf-dis1.o.bz2 create mode 100644 tests/testfile-bpf-reloc.expect.bz2 create mode 100644 tests/testfile-bpf-reloc.o.bz2 create mode 100755 tests/testfile-const-values.debug.bz2 create mode 100644 tests/testfile-debug-rel-g.o.bz2 create mode 100644 tests/testfile-debug-rel-ppc64-g.o.bz2 create mode 100644 tests/testfile-debug-rel-ppc64-z.o.bz2 create mode 100644 tests/testfile-debug-rel-ppc64.o.bz2 create mode 100644 tests/testfile-debug-rel-z.o.bz2 create mode 100644 tests/testfile-debug-rel.o.bz2 create mode 100755 tests/testfile-debug-types.bz2 create mode 100755 tests/testfile-debug.bz2 create mode 100755 tests/testfile-dw-form-indirect.bz2 create mode 100755 tests/testfile-dwarf-4.bz2 create mode 100644 tests/testfile-dwarf-45.source create mode 100755 tests/testfile-dwarf-5.bz2 create mode 100755 tests/testfile-dwfl-report-elf-align-shlib.so.bz2 create mode 100755 tests/testfile-dwzstr.bz2 create mode 100644 tests/testfile-dwzstr.multi.bz2 create mode 100755 tests/testfile-gnu-property-note-aarch64.bz2 create mode 100755 tests/testfile-gnu-property-note.bz2 create mode 100644 tests/testfile-gnu-property-note.o.bz2 create mode 100644 tests/testfile-hello4.dwo.bz2 create mode 100644 tests/testfile-hello5.dwo.bz2 create mode 100755 tests/testfile-info-link.bz2 create mode 100755 tests/testfile-info-link.debuginfo.bz2 create mode 100755 tests/testfile-info-link.stripped.bz2 create mode 100755 tests/testfile-inlines.bz2 create mode 100755 tests/testfile-lex-inlines.bz2 create mode 100755 tests/testfile-lto-gcc10.bz2 create mode 100755 tests/testfile-lto-gcc8.bz2 create mode 100755 tests/testfile-lto-gcc9.bz2 create mode 100644 tests/testfile-m68k-core.bz2 create mode 100755 tests/testfile-m68k-s.bz2 create mode 100755 tests/testfile-m68k.bz2 create mode 100755 tests/testfile-macinfo.bz2 create mode 100755 tests/testfile-macros-0xff.bz2 create mode 100755 tests/testfile-macros.bz2 create mode 100755 tests/testfile-nobitsalign.bz2 create mode 100755 tests/testfile-nobitsalign.strip.bz2 create mode 100644 tests/testfile-nolfs.bz2 create mode 100644 tests/testfile-only-debug-line.bz2 create mode 100644 tests/testfile-phdrs.elf.bz2 create mode 100755 tests/testfile-ppc64-min-instr.bz2 create mode 100644 tests/testfile-ranges-hello.dwo.bz2 create mode 100644 tests/testfile-ranges-hello5.dwo.bz2 create mode 100644 tests/testfile-ranges-world.dwo.bz2 create mode 100644 tests/testfile-ranges-world5.dwo.bz2 create mode 100644 tests/testfile-retain.o.bz2 create mode 100644 tests/testfile-riscv64-core.bz2 create mode 100644 tests/testfile-riscv64-dis1.expect.bz2 create mode 100644 tests/testfile-riscv64-dis1.o.bz2 create mode 100755 tests/testfile-riscv64-s.bz2 create mode 100755 tests/testfile-riscv64.bz2 create mode 100644 tests/testfile-rng.debug.bz2 create mode 100755 tests/testfile-s390x-hash-both.bz2 create mode 100644 tests/testfile-sizes1.o.bz2 create mode 100644 tests/testfile-sizes2.o.bz2 create mode 100644 tests/testfile-sizes3.o.bz2 create mode 100644 tests/testfile-sizes4.o.bz2 create mode 100644 tests/testfile-sizes4.s create mode 100755 tests/testfile-splitdwarf-4.bz2 create mode 100755 tests/testfile-splitdwarf-5.bz2 create mode 100755 tests/testfile-splitdwarf4-not-split4.debug.bz2 create mode 100755 tests/testfile-stridex.bz2 create mode 100644 tests/testfile-strtab.bz2 create mode 100644 tests/testfile-strtab.debuginfo.bz2 create mode 100644 tests/testfile-strtab.stripped.bz2 create mode 100644 tests/testfile-urng.debug.bz2 create mode 100755 tests/testfile-version.bz2 create mode 100644 tests/testfile-world4.dwo.bz2 create mode 100644 tests/testfile-world5.dwo.bz2 create mode 100644 tests/testfile-x32-core.bz2 create mode 100755 tests/testfile-x32-d.bz2 create mode 100755 tests/testfile-x32-debug.bz2 create mode 100755 tests/testfile-x32-s.bz2 create mode 100755 tests/testfile-x32.bz2 create mode 100755 tests/testfile-zdebug.bz2 create mode 100755 tests/testfile-zgabi32.bz2 create mode 100755 tests/testfile-zgabi32be.bz2 create mode 100755 tests/testfile-zgabi64.bz2 create mode 100755 tests/testfile-zgabi64be.bz2 create mode 100755 tests/testfile-zgnu32.bz2 create mode 100755 tests/testfile-zgnu32be.bz2 create mode 100755 tests/testfile-zgnu64.bz2 create mode 100755 tests/testfile-zgnu64be.bz2 create mode 100644 tests/testfile.bz2 create mode 100644 tests/testfile10.bz2 create mode 100644 tests/testfile11-debugframe.bz2 create mode 100644 tests/testfile11.bz2 create mode 100644 tests/testfile12-debugframe.bz2 create mode 100644 tests/testfile12.bz2 create mode 100644 tests/testfile13.bz2 create mode 100644 tests/testfile14.bz2 create mode 100644 tests/testfile15.bz2 create mode 100644 tests/testfile15.debug.bz2 create mode 100644 tests/testfile16.bz2 create mode 100644 tests/testfile16.debug.bz2 create mode 100644 tests/testfile17.bz2 create mode 100644 tests/testfile17.debug.bz2 create mode 100644 tests/testfile18.bz2 create mode 100644 tests/testfile19.bz2 create mode 100644 tests/testfile19.index.bz2 create mode 100644 tests/testfile2.bz2 create mode 100644 tests/testfile20.bz2 create mode 100644 tests/testfile20.index.bz2 create mode 100644 tests/testfile21.bz2 create mode 100644 tests/testfile21.index.bz2 create mode 100644 tests/testfile22.bz2 create mode 100644 tests/testfile23.bz2 create mode 100644 tests/testfile24.bz2 create mode 100644 tests/testfile25.bz2 create mode 100644 tests/testfile26.bz2 create mode 100644 tests/testfile27.bz2 create mode 100644 tests/testfile28.bz2 create mode 100644 tests/testfile28.rdwr.bz2 create mode 100644 tests/testfile29.bz2 create mode 100644 tests/testfile29.rdwr.bz2 create mode 100644 tests/testfile3.bz2 create mode 100644 tests/testfile30.bz2 create mode 100644 tests/testfile31.bz2 create mode 100644 tests/testfile32.bz2 create mode 100644 tests/testfile33.bz2 create mode 100644 tests/testfile34.bz2 create mode 100644 tests/testfile35.bz2 create mode 100644 tests/testfile35.debug.bz2 create mode 100644 tests/testfile36.bz2 create mode 100644 tests/testfile36.debug.bz2 create mode 100644 tests/testfile37.bz2 create mode 100644 tests/testfile37.debug.bz2 create mode 100644 tests/testfile38.bz2 create mode 100644 tests/testfile39.bz2 create mode 100644 tests/testfile4.bz2 create mode 100644 tests/testfile40.bz2 create mode 100644 tests/testfile40.debug.bz2 create mode 100644 tests/testfile41.bz2 create mode 100644 tests/testfile42.bz2 create mode 100644 tests/testfile42_noshdrs.bz2 create mode 100644 tests/testfile43.bz2 create mode 100644 tests/testfile44.S.bz2 create mode 100644 tests/testfile44.expect.bz2 create mode 100644 tests/testfile45.S.bz2 create mode 100644 tests/testfile45.expect.bz2 create mode 100644 tests/testfile46.bz2 create mode 100644 tests/testfile47.bz2 create mode 100644 tests/testfile48.bz2 create mode 100644 tests/testfile48.debug.bz2 create mode 100644 tests/testfile49.bz2 create mode 100644 tests/testfile5.bz2 create mode 100644 tests/testfile50.bz2 create mode 100755 tests/testfile51.bz2 create mode 100755 tests/testfile52-32.noshdrs.so.bz2 create mode 100755 tests/testfile52-32.prelink.so.bz2 create mode 100755 tests/testfile52-32.so.bz2 create mode 100755 tests/testfile52-32.so.debug.bz2 create mode 100755 tests/testfile52-64.noshdrs.so.bz2 create mode 100755 tests/testfile52-64.prelink.so.bz2 create mode 100755 tests/testfile52-64.so.bz2 create mode 100755 tests/testfile52-64.so.debug.bz2 create mode 100755 tests/testfile53-32.bz2 create mode 100755 tests/testfile53-32.debug.bz2 create mode 100755 tests/testfile53-32.prelink.bz2 create mode 100755 tests/testfile53-64.bz2 create mode 100755 tests/testfile53-64.debug.bz2 create mode 100755 tests/testfile53-64.prelink.bz2 create mode 100755 tests/testfile54-32.noshdrs.so.bz2 create mode 100755 tests/testfile54-32.prelink.so.bz2 create mode 100755 tests/testfile54-32.so.bz2 create mode 100755 tests/testfile54-32.so.debug.bz2 create mode 100755 tests/testfile54-64.noshdrs.so.bz2 create mode 100755 tests/testfile54-64.prelink.so.bz2 create mode 100755 tests/testfile54-64.so.bz2 create mode 100755 tests/testfile54-64.so.debug.bz2 create mode 100755 tests/testfile55-32.bz2 create mode 100755 tests/testfile55-32.debug.bz2 create mode 100755 tests/testfile55-32.prelink.bz2 create mode 100755 tests/testfile55-64.bz2 create mode 100755 tests/testfile55-64.debug.bz2 create mode 100755 tests/testfile55-64.prelink.bz2 create mode 100644 tests/testfile56.bz2 create mode 100644 tests/testfile57.bz2 create mode 100644 tests/testfile58.bz2 create mode 100755 tests/testfile59.bz2 create mode 100644 tests/testfile6.bz2 create mode 100644 tests/testfile61.bz2 create mode 100644 tests/testfile62.bz2 create mode 100644 tests/testfile63.bz2 create mode 100644 tests/testfile64.bz2 create mode 100644 tests/testfile65.bz2 create mode 100755 tests/testfile66.bz2 create mode 100644 tests/testfile66.core.bz2 create mode 100644 tests/testfile67.bz2 create mode 100644 tests/testfile68.bz2 create mode 100644 tests/testfile69.core.bz2 create mode 100755 tests/testfile69.so.bz2 create mode 100644 tests/testfile7.bz2 create mode 100644 tests/testfile70.core.bz2 create mode 100644 tests/testfile70.exec.bz2 create mode 100644 tests/testfile71.bz2 create mode 100644 tests/testfile8.bz2 create mode 100644 tests/testfile9.bz2 create mode 100644 tests/testfile_aarch64_core.bz2 create mode 100755 tests/testfile_class_func.bz2 create mode 100755 tests/testfile_const_type.bz2 create mode 100644 tests/testfile_const_type.c create mode 100755 tests/testfile_entry_value.bz2 create mode 100644 tests/testfile_entry_value.c create mode 100644 tests/testfile_gnu_props.32be.o.bz2 create mode 100644 tests/testfile_gnu_props.32le.o.bz2 create mode 100644 tests/testfile_gnu_props.64be.o.bz2 create mode 100644 tests/testfile_gnu_props.64le.o.bz2 create mode 100644 tests/testfile_i686_core.bz2 create mode 100755 tests/testfile_implicit_pointer.bz2 create mode 100644 tests/testfile_implicit_pointer.c create mode 100755 tests/testfile_implicit_value.bz2 create mode 100644 tests/testfile_implicit_value.c create mode 100755 tests/testfile_low_high_pc.bz2 create mode 100644 tests/testfile_multi.dwz.bz2 create mode 100755 tests/testfile_multi_main.bz2 create mode 100755 tests/testfile_nested_funcs.bz2 create mode 100755 tests/testfile_parameter_ref.bz2 create mode 100644 tests/testfile_parameter_ref.c create mode 100755 tests/testfile_pt_gnu_prop.bz2 create mode 100755 tests/testfile_pt_gnu_prop32.bz2 create mode 100755 tests/testfileaarch64-debugframe.bz2 create mode 100755 tests/testfileaarch64.bz2 create mode 100755 tests/testfilearm-debugframe.bz2 create mode 100755 tests/testfilearm.bz2 create mode 100755 tests/testfilebasmin.bz2 create mode 100755 tests/testfilebaxmin.bz2 create mode 100755 tests/testfilebazdbg.bz2 create mode 100755 tests/testfilebazdbg.debug.bz2 create mode 100755 tests/testfilebazdbg_pl.bz2 create mode 100755 tests/testfilebazdbg_plr.bz2 create mode 100755 tests/testfilebazdbgppc64.bz2 create mode 100755 tests/testfilebazdbgppc64.debug.bz2 create mode 100755 tests/testfilebazdbgppc64_pl.bz2 create mode 100755 tests/testfilebazdbgppc64_plr.bz2 create mode 100755 tests/testfilebazdyn.bz2 create mode 100755 tests/testfilebazdynppc64.bz2 create mode 100755 tests/testfilebazmdb.bz2 create mode 100755 tests/testfilebazmdbppc64.bz2 create mode 100755 tests/testfilebazmin.bz2 create mode 100755 tests/testfilebazmin_pl.bz2 create mode 100755 tests/testfilebazmin_plr.bz2 create mode 100755 tests/testfilebazminppc64.bz2 create mode 100755 tests/testfilebazminppc64_pl.bz2 create mode 100755 tests/testfilebazminppc64_plr.bz2 create mode 100755 tests/testfilebaztab.bz2 create mode 100755 tests/testfilebaztabppc64.bz2 create mode 100644 tests/testfilecsky.bz2 create mode 100755 tests/testfiledwarfinlines.bz2 create mode 100644 tests/testfiledwarfinlines.core.bz2 create mode 100755 tests/testfilefoobarbaz.bz2 create mode 100755 tests/testfilegdbindex5.bz2 create mode 100755 tests/testfilegdbindex7.bz2 create mode 100755 tests/testfileloc.bz2 create mode 100755 tests/testfilemacro.bz2 create mode 100755 tests/testfilenolines.bz2 create mode 100755 tests/testfileppc32-debugframe.bz2 create mode 100755 tests/testfileppc32.bz2 create mode 100644 tests/testfileppc32attrs.o.bz2 create mode 100755 tests/testfileppc64-debugframe.bz2 create mode 100755 tests/testfileppc64.bz2 create mode 100644 tests/testfileppc64attrs.o.bz2 create mode 100755 tests/testfileranges4.debug.bz2 create mode 100755 tests/testfileranges5.debug.bz2 create mode 100755 tests/testfiles390.bz2 create mode 100755 tests/testfiles390x.bz2 create mode 100644 tests/testfilesparc64attrs.o.bz2 create mode 100755 tests/testfilesplitranges4.debug.bz2 create mode 100755 tests/testfilesplitranges5.debug.bz2 create mode 100644 tests/testfilesyms32.bz2 create mode 100644 tests/testfilesyms64.bz2 create mode 100755 tests/testlib_dynseg.so.bz2 create mode 100644 tests/typeiter.c create mode 100644 tests/typeiter2.c create mode 100644 tests/unit-info.c create mode 100644 tests/update1.c create mode 100644 tests/update2.c create mode 100644 tests/update3.c create mode 100644 tests/update4.c create mode 100644 tests/varlocs.c create mode 100644 tests/vdsosyms.c create mode 100644 tests/vendorelf.c create mode 100644 tests/xlate_notes.c create mode 100644 tests/zstrptr.c create mode 100644 version.h diff --git a/ABOUT-NLS b/ABOUT-NLS new file mode 100644 index 00000000..0a9d56d9 --- /dev/null +++ b/ABOUT-NLS @@ -0,0 +1 @@ + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..ef3c5430 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +For Now: +Ulrich Drepper. +Roland McGrath +Petr Machata diff --git a/CONTRIBUTING b/CONTRIBUTING new file mode 100644 index 00000000..bb48975b --- /dev/null +++ b/CONTRIBUTING @@ -0,0 +1,106 @@ +The project home is http://elfutils.org/ + +The current elfutils source code can be checked out with +git clone git://sourceware.org/git/elfutils.git + +The developer mailinglist to send patches to is +elfutils-devel@sourceware.org. +https://sourceware.org/ml/elfutils-devel/ + +To subscribe send an email to elfutils-devel-subscribe@sourceware.org +Or use the form at https://sourceware.org/mailman/listinfo/elfutils-devel + +Please supply patches using git format-patch or using git send-email. + +Sign your work + +To facilitate tracking of who did what, we've adopted a "sign-off" +procedure for patches based on the procedure used by the Linux kernel +project. + +The sign-off is a simple line at the end of the explanation for the +patch, which certifies that you wrote it or otherwise have the right +to pass it on as a patch under an appropriate license. The rules are +pretty simple: if you can certify the below: + + Developer's Certificate of Origin + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me, + and I have the right to submit the contribution under each + license indicated in, or otherwise designated as being + applicable to, the file. + + (b) The contribution was provided directly to me by some other + person who certified (a), and I have not modified it. + + (c) I understand and agree that the project and the + contribution are public and that a record of the + contribution (including all personal information I submit + with it, including my sign-off) is maintained indefinitely + and may be redistributed. + +then you just add a line saying + +Signed-off-by: Random J Developer + +using your real name (sorry, no pseudonyms or anonymous contributions.) + +git commit --signoff will add such a Signed-off-by line at the end of +the commit log message for you. + +The ideal patch contains a ChangeLog entry and a test case for the +bug fixed or feature added. + +The testsuite (make check) is expected to have zero failing tests. +Do not knowingly add tests that FAIL. If there are architectures or +configurations where a tests is not supported make sure they are +skipped instead of failing. Adding "exit 77" in the test shell wrapper +indicates that a test was SKIPPED. + +We do allow binaries in the testsuite for tests that only need to +read ELF or DWARF data and if generating the data in the testcase +itself is difficult or would be architecture specific. +The binaries should be bzip2 compressed. Add a note in the test +wrapper run-.sh script how to regenerate the binary. + +After sending your patch to the mailinglist one of the committers +to the project will review it, give feedback, and if perfect they +will commit it for you. + +You can become a maintainer/committer yourself after you have provided +at least a handful of accepted patches and agree to the guidelines in +this document for creating, reviewing, accepting and committing patches. + +To become a committer you need a sourceware account: +https://sourceware.org/cgi-bin/pdw/ps_form.cgi +Upload a SSH public key and have an existing maintainer sponsor you +for the elfutils group. + +committers can push patches through: +ssh://@sourceware.org/git/elfutils.git + +The current webpages published at https://sourceware.org/elfutils/ +can be checked out with: +git clone ssh://@sourceware.org/git/elfutils-htdocs.git +Patches should also be posted to the mailinglist. + +As a maintainer/committer you should still post patches as described +above. And ideally they are reviewed and approved as above. If no +other committer has reviewed or objected to your patch for a week +you may use your own judgement whether you ping your patch or push +it after "self-review". If you do, you should post a message to the +mailinglist that the patch has been pushed. + +committers may also create git branches starting with /... +patches on these branches are works in progress, so might not be perfect +yet, but should follow the above guidelines as much as possible and should +be aimed at integration into master. For merging a branch into master +the same process as above should be followed by posting the patches +to the list first. + +committers/maintainers who repeatedly ignore the above guidelines, +are hostile or offensive towards other committers or contributors, +and don't correct their behavior after being asked by other committers +will be removed as maintainer/committer. diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/COPYING-GPLV2 b/COPYING-GPLV2 new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING-GPLV2 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/COPYING-LGPLV3 b/COPYING-LGPLV3 new file mode 100644 index 00000000..65c5ca88 --- /dev/null +++ b/COPYING-LGPLV3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..a01f6f9f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,964 @@ +2021-05-22 Mark Wielaard + + * configure.ac (AC_INIT): Set version to 0.185. + * NEWS: Add 0.185 entries. + +2021-05-10 Mark Wielaard + + * configure.ac (AC_INIT): Set version to 0.184. + * NEWS: Add libdw, translation and debuginfod-client entries. + +2021-03-30 Frank Ch. Eigler + + * configure.ac: Look for pthread_setname_np. + +2021-02-17 Timm Bäder + + * configure.ac: Add -Wno-packed-not-aligned check. + +2021-02-17 Timm Bäder + + * configure.ac: Add -Wtrampolines check. + +2021-02-05 Mark Wielaard + + * configure.ac (AC_INIT): Set version to 0.183. + (AC_COPYRIGHT): Update Copyright year. + * NEWS: Add 0.183 section. + +2021-02-01 Érico Nogueira + + * configure.ac: Check for GNU strerror_r. + +2021-01-12 Dmitry V. Levin + + * configure.ac [--enable-gcov]: Check for gcov, lcov, and genhtml. + * Makefile.am [GCOV] (coverage, coverage-clean): New targets. + * .gitignore: Update. + +2020-12-20 Dmitry V. Levin + + * .gitignore: Move subdirectory patterns to separate .gitignore files. + + * .gitignore: Update. + +2020-12-15 Dmitry V. Levin + + * configure.ac (USE_NLS, AM_PO_SUBDIRS): Remove. + (AM_GNU_GETTEXT, AM_GNU_GETTEXT_VERSION, + AM_GNU_GETTEXT_REQUIRE_VERSION): Use these macros to setup the gettext + infrastructure. + * .gitignore: Update. + + * Makefile.am (SUBDIRS): Remove m4. + * configure.ac (AC_CONFIG_FILES): Remove m4/Makefile. + + * configure.ac (AC_CONFIG_MACRO_DIR): Remove. + +2020-12-12 Dmitry V. Levin + + * configure.ac: Fix spelling typos in comments. + * NEWS: Fix spelling typos. + * NOTES: Likewise. + * TODO: Likewise. + +2020-12-11 Dmitry V. Levin + + * configure.ac (AM_CONDITIONAL): Remove HAVE_LIBASM and STANDALONE. + + * configure.ac: Rewrite argp check. + + * configure.ac (AC_MSG_FAILURE): Fix typo. + +2020-11-30 Dmitry V. Levin + + * configure.ac (LIBDEBUGINFOD_SONAME): New AC_SUBST variable. + (AC_CONFIG_FILES): Add debuginfod/debuginfod.h. + +2020-11-01 Érico N. Rolim + + * configure.ac: Check for fts and obstack from outside libc. + +2020-10-28 Mark Wielaard + + * configure.ac: Set version to 0.182. + * NEWS: Add 0.182 section. + +2020-10-28 Tom Tromey + + * .gitignore: Add /tests/leb128. + +2020-10-01 Frank Ch. Eigler + + PR25461 + * configure.ac: Add --enable-debuginfod-urls[=URLS] option. + +2020-09-18 Mark Wielaard + + * configure.ac: Check availability of libzstd and zstd. + +2020-09-08 Mark Wielaard + + * configure.ac: Set version to 0.181. + * NEWS: Add 0.181 section. + +2020-08-20 Dmitry V. Levin + + * configure.ac (--enable-libdebuginfod): AC_DEFINE ENABLE_LIBDEBUGINFOD. + +2020-07-17 Mark Wielaard + + * configure.ac: Set -DBAD_FTS=1 also for CXXFLAGS. + +2020-06-19 Mark Wielaard + + * Makefile.am (SUBDIRS): Always add debuginfod. + * configure.ac (debuginfod): Split off... + (libdebuginfod): ... this. Also add DUMME_DEBUGINFOD. + +2020-06-15 Sergei Trofimovich + + * configure.ac: Use READELF in build-id check. + +2020-06-11 Mark Wielaard + + * configure.ac: Set version to 0.180. + * NEWS: Add 0.180 section. + * .gitignore: Update with new generated file. + +2020-06-10 Mark Wielaard + + * configure.ac (MODVERSION): Remove. + +2020-03-30 Mark Wielaard + + * configure.ac: Set version to 0.179. + * NEWS: Add 0.179 section. + +2020-03-25 Mark Wielaard + + * README: Update mailinglist subscription info. + * CONTRIBUTING: Likewise. + +2020-02-03 Frank Ch. Eigler + + * configure.ac: Tolerate CXX= for debuginfod configuration. + +2019-12-11 Omar Sandoval + + * configure.ac: Apply -Werror after user-defined CFLAGS in + -D_FORTIFY_SOURCE=2 check. + +2019-12-06 Mark Wielaard + + * configure.ac: Add ac_cv_buildid check. + +2019-11-26 Mark Wielaard + + * configure.ac: Set version to 0.178. + NEWS: Add 0.178 section. + +2019-11-26 Mark Wielaard + + * configure.ac: Add CXXFLAGS for gcov. + +2019-10-28 Aaron Merey + + * debuginfod/: New directory for debuginfod code. + * Makefile.am (SUBDIRS): Recurse there. + * configure.ac (--enable-debuginfod): New flag & checks. + +2019-08-25 Jonathon Anderson + + * configure.ac: Add new --enable-valgrind-annotations + * configure.ac: Add new --with-valgrind (headers only) + +2019-07-05 Omar Sandoval + + * configure.ac: Get rid of --enable-libebl-subdir. + * Makefile.am (SUBDIRS): Reorder backends and libcpu before libebl to + satisfy build dependencies. + +2019-08-13 Mark Wielaard + + * configure.ac: Set version to 0.177. + * NEWS: Mention elfclassify, readelf DW_AT_data_member_location + and DW_AT_discr_list attribute changes, dwarf.h DW_AT_GNU additions, + dwelf_elf_e_machine_string function, dwelf_elf_begin change and + C-SKY backend support. + +2019-02-14 Mark Wielaard + + * configure.ac: Set version to 0.176. + * NEWS: Mention riscv backend updates, new --enable-install-elfh + configure flag and fixed CVEs. + * GPG-KEY: Update. + +2019-01-18 Mark Wielaard + + * configure.ac: Add new --enable-install-elfh. + +2018-07-04 Ross Burton + + * configure.ac: Check for gawk. + +2018-06-11 Mark Wielaard + + * configure.ac: Set version to 0.172. + * NEWS: Mention bug fixes. + +2018-06-01 Mark Wielaard + + * configure.ac: Set version to 0.171. + * NEWS: Mention DWARF5, split-dwarf and GNU DebugFission support. + +2018-03-17 Mark Wielaard + + * configure.ac (CHECK_FUNCS): Check for process_vm_readv. + +2018-02-09 Joshua Watt + + * configure.ac (HAVE_FALLTHROUGH): New define. + +2017-10-16 Mark Wielaard + + * .gitignore: Remove tests/md5-sha1-test. + +2017-08-18 Ulf Hermann + + * configure.ac: Check if the compiler supports + __attribute__((gcc_struct)). + +2017-09-19 Mark Wielaard + + * README: Add basic build instructions. + +2017-05-03 Ulf Hermann + + * configure.ac: Test if symbol versioning is supported. + +2017-04-27 Ulf Hermann + + * configure.ac: Check if the compiler supports + __attribute__((visibility(...))). + +2017-04-27 Ulf Hermann + + * configure.ac: Check if -fPIC, -fPIE, -Wl,-z,defs, + and -Wl,-z,relro are supported by the compiler. + +2017-08-02 Mark Wielaard + + * configure.ac: Set version to 0.170. + * NEWS: Mention new libdw dwarf_line_file function. + +2017-07-26 Mark Wielaard + + * NEWS: Mention dwarf_getmacros handling version 5 .debug_macro. + +2017-07-26 Mark Wielaard + + * NEWS: Mention dwarf_peel_type DWARF5 tags improvement. + +2017-07-26 Mark Wielaard + + * NEWS: Mention new DWARF5 calling conventions and defaulted member + function. + +2017-07-26 Mark Wielaard + + * NEWS: Mention new dwarf_default_lower_bound function. + +2017-07-25 Mark Wielaard + + * NEWS: Mention new DWARF5 attributes, tags, character encodings + and language codes in dwarf.h. + +2017-07-18 Mark Wielaard + + * configure.ac: Don't check for linux/bpf.h. + * NEWS: Mention always build bpf backend. + +2017-07-14 Mark Wielaard + + * NEWS: Add 0.170 section and new strip options. + +2017-05-05 Mark Wielaard + + * configure.ac: Set version to 0.169. Update copyright year. + * NEWS: Add 0.169 section. + +2017-04-21 Ulf Hermann + + * .gitignore: Add fillfile and peel_type tests. + +2017-02-15 Ulf Hermann + + * configure.ac: Add check for mempcpy. + +2017-02-09 Mark Wielaard + + * configure.ac: Add check for adding -D_FORTIFY_SOURCE=2 to CFLAGS. + +2017-01-12 Mark Wielaard + + * configure.ac: Define PACKAGE_URL for older autoconf. + +2016-12-27 Mark Wielaard + + * configure.ac: Set version to 0.168. + * NEWS: Add 0.168 updates. + +2016-12-24 Mark Wielaard + + * README: Move design notes to NOTES. Add URLs for home, releases, + bugs, git and mailinglist now on sourceware. + * NOTES: Add notes from README. + * CONTRIBUTING: Change fedorahosted.org references to new + sourceware.org locations. + * configure.ac (AC_INIT): Add package URL http://elfutils.org/ + change bug-report to https://sourceware.org/bugzilla/ + (AC_COPYRIGHT): Set to the elfutils developers. + +2016-11-23 Mark Wielaard + + * configure.ac: Add test for bad fts.h. Add -DBAD_FTS=1 to CFLAGS + if necessary. + +2016-11-02 Mark Wielaard + + * configure.ac: Add check for whether gcc accepts + -Wimplict-fallthrough. + +2016-10-11 Akihiko Odaki + + * configure.ac: Add memrchr, rawmemchr and powerof2 checks. + +2016-08-04 Mark Wielaard + + * configure.ac: Set version to 0.167. + * NEWS: Add 0.167 section. + +2016-07-06 Mark Wielaard + + * .gitignore: Remove src/ld. ldlex.c, ldscript.c and ldscript.h. + * configure.ac (enable generic): Removed. + +2016-06-28 Richard Henderson + + * configure.ac (HAVE_LINUX_BPF_H): New test and conditional. + +2016-06-10 Mark Wielaard + + * CONTRIBUTING: Extend patch, committer and maintainer guidelines. + +2016-05-02 Filipe Brandenburger + + * configure.ac (argp check): Pass pass &argv. + * configure.ac (-W<...> checks): Pass -Werror to the warning checks, + to ensure unsupported warning options are noticed during ./configure + time and not only later during build. + +2016-03-31 Mark Wielaard + + * configure.ac: Set version to 0.166. + +2016-03-02 Mark Wielaard + + * configure.ac: Set program_prefix to eu- by default. + * NEWS (0.166): New sections, document --program-prefix default. + +2016-02-13 Mark Wielaard + + * configure.ac: Add check for whether gcc accepts -Wnull-dereference. + +2016-02-08 Mark Wielaard + + * configure.ac: Add checks for sane -Wlogical-op and whether gcc + accepts -Wduplicated-cond. + +2016-01-08 Mark Wielaard + + * configure.ac: Set version to 0.165. + * NEWS: Add 0.164 section. + +2016-01-04 Mark Wielaard + + * configure.ac: Add BZ2_LIBS and LIBLZMA substitutions. + Add config/libelf.pc and config/libdw.pc config files. + +2015-12-31 Mark Wielaard + + * Makefile.am (AM_MAKEFLAGS): Set --no-print-directory. + +2015-10-16 Mark Wielaard + + * configure.ac: Make zlib mandatory. + +2015-10-15 Mark Wielaard + + * configure.ac: Set version to 0.164. + * NEWS: Add 0.164 additions. + +2015-10-07 Mark Wielaard + + * configure.ac: Add AM_SILENT_RULES([yes]). + +2015-09-24 Jose E. Marchesi + + * configure.ac: Use -fPIC instead of -fpic to avoid relocation + overflows in some platforms. + +2015-07-11 Pino Toscano + + * .gitignore: Add more generated files, and anchor some of the + existing ones. + +2015-06-19 Mark Wielaard + + * configure.ac: Set version to 0.163. + * NEWS: Mention 0.163 is bug fixes only. + +2015-06-10 Mark Wielaard + + * configure.ac: Set version to 0.162. + * NEWS: Add 0.162 additions. + +2015-06-08 Mark Wielaard + + * configure.ac (ADD_STACK_USAGE_WARNING): New conditional based on + gcc -Wstack-usage check. + +2015-05-31 Mark Wielaard + + * configure.ac (MODVERSION): Define using LIBEBL_SUBDIR, eu_version + and ac_cv_build. + +2015-05-31 Mark Wielaard + + * configure.ac (use_undefined): Use AC_LINK_IFELSE. AC_DEFINE + CHECK_UNDEFINED. + +2015-05-30 Mark Wielaard + + * configure.ac: Check for bunzip2. Check flex and bison are + installed in maintainer-mode. Otherwise check libdw/known-dwarf.h + is already generated. + +2015-05-21 Mark Wielaard + + * configure.ac: Add --enable-sanitize-undefined. + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Rename to... + (AM_DISTCHECK_CONFIGURE_FLAGS): this. Add --enable-sanitize-undefined. + +2015-05-04 Anthony G. Basile + + * configure.ac (argp_LDADD): Check if libc has argp and set + argp_LDADD accordingly. + +2015-05-03 Max Filippov + + * configure.ac (DEMANGLE): Fix enable_demangler setting. + +2015-05-01 Mark Wielaard + + * configure.ac (DEMANGLE): Explicitly set enable_demangler. + +2015-05-01 Mark Wielaard + + * configure.ac (debugpred): Use and set use_debugpred_val. + (textrelcheck): Explicitly set enable_textrelcheck to yes or no. + (symbol-versioning): Likewise for enable_symbol_versioning. + AC_MSG_NOTICE overview of enabled/disabled features. + +2015-04-23 Max Filippov + + * configure.ac: Add --disable-symbol-versioning. + +2015-04-14 Mark Wielaard + + * configure.ac (ac_cv_c99): Add explicit checks for all GNU99 + extensions used. + +2015-03-13 Mark Wielaard + + * configure.ac (ac_cv_c99): Add explicit return. + (ac_cv_tls): Add stdlib.h include. + +2014-12-18 Mark Wielaard + + * configure.ac: Set version to 0.161. + * NEWS: Add dwarf.h additions. + +2014-12-15 Josh Stone + + * .gitignore: Add config/compile as installed by automake 1.14. + +2014-11-27 Mark Wielaard + + * configure.ac: Add --disable-textrelcheck. + +2014-10-06 Mark Wielaard + + * NEWS: New section 0.161. Add dwarf_peel_type. + +2014-08-25 Mark Wielaard + + * configure.ac: Set version to 0.160. + * NEWS: Add removal of DW_TAG_mutable_type, LZMA .ko.xz kernel + module support, ARM THUMB functions and ppc64le ELFv2 abi backends. + +2014-08-15 Mark Wielaard + + * NEWS: Add dwarf_cu_die. + +2014-08-15 Mark Wielaard + + * NEWS: Add dwarf_cu_getdwarf. + +2014-07-18 Mark Wielaard + + * configure.ac (AC_CHECK_TYPE): Test for struct user_regs_struct. + +2014-05-26 Mark Wielaard + + * NEWS: New section 0.160. Add unstrip --force. + +2014-05-17 Mark Wielaard + + * configure.ac: Set version to 0.159. + * NEWS: Add entries for version 0.159. + +2014-05-02 Mark Wielaard + + * NEWS: Add note about dwz support no longer being experimental and + new helper functions. + * configure.ac: Remove --enable-dwz. + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Remove --enable-dwz. + +2014-04-11 Mark Wielaard + + * Makefile.am (SUBDIRS): Add libdwelf. + * configure.ac (AC_CONFIG_FILES): Add libdwelf/Makefile. + * NEWS: Add note about libdwelf. + +2014-04-13 Mark Wielaard + + * configure.ac: Remove mudflap enable arg and MUDFLAP conditional. + +2014-01-21 Mark Wielaard + + * NEWS (Version 0.159): Add stack -i. + +2014-01-20 Mark Wielaard + + * NEWS (Version 0.159): New. Add stack -d. + +2014-01-03 Mark Wielaard + + * configure.ac: Set version to 0.158. + * NEWS: Add entries for version 0.158. + +2013-12-20 Mark Wielaard + + * NEWS (libdwfl): Add dwfl_getthread_frames. + (stack): New entry. + +2013-12-18 Mark Wielaard + + * NEWS (libdwfl): Add dwfl_module_getsym_info and + dwfl_module_addrinfo. + (addr2line): Add -x option. + +2013-12-17 Jan Kratochvil + + * NEWS (Version 0.158) (libdwfl): Added Dwfl_Thread_Callbacks, + Dwfl_Thread, Dwfl_Frame, dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl, + dwfl_thread_tid, dwfl_frame_thread, dwfl_thread_state_registers, + dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes + and dwfl_frame_pc. + +2013-12-16 Mark Wielaard + + * NEWS (libdwfl): Add dwfl_module_getsymtab_first_global. + +2013-12-09 Josh Stone + + * .gitignore: Add config/ar-lib, installed due to AM_PROG_AR. + +2013-12-02 Jan Kratochvil + + * configure.ac (CC_BIARCH): Remove AS_IF for it. + +2013-11-07 Jan Kratochvil + + * configure.ac: New AC_CHECK_SIZEOF for long. Call utrace_BIARCH, new + AC_SUBST for CC_BIARCH. + +2013-11-06 Mark Wielaard + + * configure.ac (--enable-dwz): Add AC_MSG_WARN when disabled but + local system does have /usr/lib/debug/.dwz. + +2013-11-06 Mark Wielaard + + * configure.ac (--enable-thread-safety): Add AC_MSG_WARN experimental + option. + +2013-11-01 Michael Forney + + * configure.ac: Call AM_PROG_AR and AC_CHECK_TOOL for readelf and nm. + +2013-10-30 Jan Kratochvil + + * NEWS (Version 0.158): New. + +2013-09-30 Mark Wielaard + + * NEWS: Update for readelf NT_SIGINFO and NT_FILE core notes. + +2013-09-27 Mark Wielaard + + * configure.ac: Set version to 0.157. + * NEWS: Add entries for version 0.157. + +2013-09-20 Mark Wielaard + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-dwz. + +2013-07-25 Jan Kratochvil + + * configure.ac: Set version to 0.156. + +2013-07-19 Jan Kratochvil + + * NEWS: Remove bugfix only entries from Version 0.156. + +2013-07-18 Jan Kratochvil + + * NEWS: Add entries for Version 0.156. + +2013-04-28 Jan Kratochvil + + * NEWS (Version 0.156): New. + +2013-04-26 Mark Wielaard + + * configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests. + +2013-04-25 Mark Wielaard + + * .gitignore: Add config/test-driver as installed by automake 1.13. + * configure.ac (AM_INIT_AUTOMAKE): Require at least automake 1.11. + +2012-10-01 Mark Wielaard + + * configure.ac: Add --enable-valgrind check. + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-valgrind. + +2012-08-27 Mark Wielaard + + * configure.ac: Set version to 0.155. + +2012-08-24 Mark Wielaard + + * configure.ac: Add --enable-dwz check, defaults to no. + +2012-07-24 Mark Wielaard + + * TODO: Add note on shdrs after elf_cntl (ELF_C_FDREAD). + +2012-06-22 Mark Wielaard + + * configure.ac: Set version to 0.154. + +2012-01-24 Mark Wielaard + + * COPYING: Fix address. Updated version from gnulib. + +2012-01-23 Mark Wielaard + + * configure.ac: Set version to 0.153, update copyright years. + +2012-01-20 Roland McGrath + + * configure.ac: Handle --enable-deterministic-archives. + +2011-10-08 Roland McGrath + + * configure.ac (eu_version): Use sed instead of ${x/y/z} syntax. + Use POSIX.2 $((...)) syntax instead of $[...]. + Reported by Mike Frysinger . + +2011-10-08 Mike Frysinger + + * configure.ac: Fix use of AC_ARG_ENABLE to handle $enableval correctly. + +2011-10-02 Ulrich Drepper + + * configure.ac: Check for __cxa_demangle in libstdc++. + +2011-02-08 Roland McGrath + + * configure.ac (C99 check): Use AC_LANG_SOURCE. + + * configure.ac (ALL_LINGUAS): Remove variable, now obsolete. + +2010-09-13 Ulrich Drepper + + * configure.ac (ALL_LINGUAS): Add languages which have some + translations. + +2010-04-15 Roland McGrath + + * configure.ac (LOCALEDIR, DATADIRNAME): Removed. + +2009-09-21 Ulrich Drepper + + * configure.ac: Update for more modern autoconf. + +2009-08-26 Roland McGrath + + * configure.ac (zip_LIBS): Check for liblzma too. + +2009-04-19 Roland McGrath + + * configure.ac (eu_version): Round down here, not in version.h macros. + +2009-04-17 Roland McGrath + + * configure.ac (eu_version): Compute number 1000 times larger, + let $PACKAGE_VERSION be x.y.z as well as x.y (implied x.y.0). + +2009-01-23 Roland McGrath + + * configure.ac (zlib check): Check for gzdirect, need zlib >= 1.2.2.3. + + * configure.ac (__thread check): Use AC_LINK_IFELSE, in case of + building with compiler support but no working runtime support. + +2009-01-22 Ulrich Drepper + + * Makefile.am (rpm): The tarball is now bzip2-compressed. + +2009-01-10 Ulrich Drepper + + * configure.ac: Require gcc with TLS support. + Rename USE_TLS to USE_LOCKS. The option is renamed to + --enable-thread-safety. + +2009-01-08 Roland McGrath + + * configure.ac (eu_ZIPLIB): Moved to m4/zip.am. + +2009-01-05 Roland McGrath + + * configure.ac (eu_ZIPLIB): New macro. + Use it to test for -lz, -lbz2, set .am ZLIB, BZLIB, zip_LIBS. + +2008-12-30 Ulrich Drepper + + * configure.ac: We need automake 1.8 now. + +2008-12-24 Roland McGrath + + * configure.ac: Use automake flags dist-bzip2 no-dist-gzip, + distribute only in .tar.bz2 form now. + +2008-12-16 Roland McGrath + + * Makefile.am (pkginclude_HEADERS): New variable, install version.h. + * configure.ac: Create it, substituting @eu_version@ with + PACKAGE_VERSION canonicalized to four digits of decimal. + +2008-08-25 Roland McGrath + + * configure.ac (--enable-tls): Set AM_CONDITIONAL USE_TLS too. + +2008-08-21 Roland McGrath + + * configure.ac (AH_BOTTOM): Emit #include and + move the contents to lib/eu-config.h instead of keeping them here. + +2007-12-20 Ulrich Drepper + + * configure.ac: Add support for --enable-debugpred. + Update likely/unlikely macros for it. + +2007-06-05 Ulrich Drepper + + * Makefile.am: Remove traces of mini builds. + * configure.ac: Don't use libelf-po/POTFILES.in as config file + anymore. + +2007-05-16 Roland McGrath + + * configure.ac (AM_INIT_AUTOMAKE): Use -Wno-portability. + +2006-11-02 Roland McGrath + + * Makefile.am (EXTRA_DIST): Add EXCEPTION file. + +2006-08-29 Roland McGrath + + * configure.ac: Use AM_MAINTAINER_MODE. + +2006-07-12 Ulrich Drepper + + * configure.ac (internal_function): Don't use internal visibility. + +2006-07-05 Ulrich Drepper + + * configure.ac: Add dummy automake conditional to get dependencies + for non-generic linker right. See src/Makefile.am. + +2005-11-18 Roland McGrath + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): New variable. + +2005-11-16 Roland McGrath + + * configure.ac: Define HAVE_LIBASM and STANDALONE conditionals. + In config.h, define ELFUTILS_HEADER macro. + +2005-11-15 Roland McGrath + + * Makefile.am (all_SUBDIRS): Add backends. + * configure.ac: Write backends/Makefile. + + * configure.ac: Add --enable-tests-rpath option. + +2005-09-16 Roland McGrath + + * configure.ac (ALLOW_UNALIGNED) [__ia64__ || __alpha__]: + Don't set it, since on IA64 you get error messages for unaligned + accesses, and on Alpha it's at least very slow. + +2005-08-29 Ulrich Drepper + + * configure.ac: Fix GCOV make condition generation. + +2005-08-28 Ulrich Drepper + + * configure.ac: Add --enable-gcov option. + +2005-08-06 Ulrich Drepper + + * configure.ac: Add --enable-gprof option. + +2005-07-27 Roland McGrath + + * Makefile.am (all_SUBDIRS): Put libdwfl before libdw. + +2005-07-21 Roland McGrath + + * configure.ac: Take --enable-libebl-subdir=DIR to set LIBEBL_SUBDIR. + +2005-06-01 Roland McGrath + + * Makefile.am (all_SUBDIRS): Add libdwfl. + * configure.ac: Write libdwfl/Makefile. + +2005-05-19 Roland McGrath + + * configure.ac [AH_BOTTOM] (INTDECL, _INTDECL): New macros. + +2005-05-10 Ulrich Drepper + + * configure.ac: Define MODVERSION in config.h. + +2005-02-22 Ulrich Drepper + + * Makefile.am (all_SUBDIRS): Don't add doc subdir for now. + * configure.ac: Don't use doc subdir for now. + +2005-02-15 Ulrich Drepper + + * configure.ac: Remove AM_GNU_GETTEXT use. Use only AM_PO_SUBDIRS. + +2005-02-06 Ulrich Drepper + + * configure.ac (AM_INIT_AUTOMAKE): Removed dist-bzip2. + + * Makefile.am (EXTRA_DIST): Remove splint.rc. + * splint.rc: Removed. + +2004-09-25 Ulrich Drepper + + * configure.ac: Make compile with gcc 4.0. + +2004-03-06 Ulrich Drepper + + * configure.ac: Use AS_HELP_STRING where applicable. + +2004-01-23 Ulrich Drepper + + * configure.ac: Check for C99 compiler. + + * configure.ac: Change locking macros in config.h to at least + evaluate the parameter. Define base_cpu to none for generic linker. + +2004-01-21 Ulrich Drepper + + * configure.ac: Print error message in case --disable-generic is + used if no linker support for the architecture is available. + +2004-01-18 Ulrich Drepper + + * configure.ac: Dont generate libebl-po/Makefile.in, + libdw-po/Makefile.in, libasm-po/Makefile.in. + + * Makefile.am (all_SUBDIRS): Remove libebl-po, libdw-po, libasm-po. + +2004-01-17 Ulrich Drepper + + * configure.ac: Pretty printing of help message. + + * configure.ac: Move AC_SYS_LARGEFILE test to the front. + + * configure.ac: Add --enable-mudflap option. + +2004-01-17 Ulrich Drepper + + * configure.ac: Major cleanups. Use aux dir. + * config.guess: Moved to new config subdir. + * config.rpath: Likewise. + * config.sub: Likewise. + * depcomp: Likewise. + * install-sh: Likewise. + * missing: Likewise. + * mkinstalldirs: Likewise. + * Makefile.am (mini_SUBDIRS): Add config. + (EXTRA_DIST): Remove config.rpath. + + * configure.ac: Add AC_REVISION. + + * configure.ac: Add --enable-mudflap option. + +2004-01-11 Ulrich Drepper + + * configure.ac: Drop libdwarf directory. Add libdw-po. + * Makefile.am (all_SUBDIRS): Likewise. + * elfutils.spec: Don't distribute anything from libdwarf. + +2004-01-05 Ulrich Drepper + + * Makefile.am: Support separate libelf built. + + * elfutils.spec.in: Create separata elfutils-libelf-devel package. + Install libdw DSOs. + + * configure.ac (AC_CONFIG_SRCDIR): Use libelf/libelf.h as the file + name. + +2003-08-13 Ulrich Drepper + + * elfutils.spec.in: Remove references to libebl.so. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. + +2000-08-25 Ulrich Drepper + + * The beginning. See the NEWS file for the time being. diff --git a/GPG-KEY b/GPG-KEY new file mode 100644 index 00000000..671373e6 --- /dev/null +++ b/GPG-KEY @@ -0,0 +1,114 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +1tvZxQ== +=l2J7 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..8865734f --- /dev/null +++ b/INSTALL @@ -0,0 +1,368 @@ +Installation Instructions +************************* + + Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software +Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell command './configure && make && make install' +should configure, build, and install this package. The following +more-detailed instructions are generic; see the 'README' file for +instructions specific to this package. Some packages provide this +'INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The 'configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a 'Makefile' in each directory of the package. +It may also create one or more '.h' files containing system-dependent +definitions. Finally, it creates a shell script 'config.status' that +you can run in the future to recreate the current configuration, and a +file 'config.log' containing compiler output (useful mainly for +debugging 'configure'). + + It can also use an optional file (typically called 'config.cache' and +enabled with '--cache-file=config.cache' or simply '-C') that saves the +results of its tests to speed up reconfiguring. Caching is disabled by +default to prevent problems with accidental use of stale cache files. + + If you need to do unusual things to compile the package, please try +to figure out how 'configure' could check whether to do them, and mail +diffs or instructions to the address given in the 'README' so they can +be considered for the next release. If you are using the cache, and at +some point 'config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file 'configure.ac' (or 'configure.in') is used to create +'configure' by a program called 'autoconf'. You need 'configure.ac' if +you want to change it or regenerate 'configure' using a newer version of +'autoconf'. + + The simplest way to compile this package is: + + 1. 'cd' to the directory containing the package's source code and type + './configure' to configure the package for your system. + + Running 'configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type 'make' to compile the package. + + 3. Optionally, type 'make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type 'make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the 'make install' phase executed with root + privileges. + + 5. Optionally, type 'make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior 'make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing 'make clean'. To also remove the + files that 'configure' created (so you can compile the package for + a different kind of computer), type 'make distclean'. There is + also a 'make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type 'make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide 'make + distcheck', which can by used by developers to test that all other + targets like 'make install' and 'make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the 'configure' script does not know about. Run './configure --help' +for details on some of the pertinent environment variables. + + You can give 'configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here is +an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU 'make'. 'cd' to the +directory where you want the object files and executables to go and run +the 'configure' script. 'configure' automatically checks for the source +code in the directory that 'configure' is in and in '..'. This is known +as a "VPATH" build. + + With a non-GNU 'make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use 'make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the 'lipo' tool if you have problems. + +Installation Names +================== + + By default, 'make install' installs the package's commands under +'/usr/local/bin', include files under '/usr/local/include', etc. You +can specify an installation prefix other than '/usr/local' by giving +'configure' the option '--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option '--exec-prefix=PREFIX' to 'configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like '--bindir=DIR' to specify different values for particular +kinds of files. Run 'configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the default +for these options is expressed in terms of '${prefix}', so that +specifying just '--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to 'configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +'make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, 'make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +'${prefix}'. Any directories that were specified during 'configure', +but not in terms of '${prefix}', must each be overridden at install time +for the entire installation to be relocated. The approach of makefile +variable overrides for each directory variable is required by the GNU +Coding Standards, and ideally causes no recompilation. However, some +platforms have known limitations with the semantics of shared libraries +that end up requiring recompilation when using this method, particularly +noticeable in packages that use GNU Libtool. + + The second method involves providing the 'DESTDIR' variable. For +example, 'make install DESTDIR=/alternate/directory' will prepend +'/alternate/directory' before all installation names. The approach of +'DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of '${prefix}' +at 'configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving 'configure' the +option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. + + Some packages pay attention to '--enable-FEATURE' options to +'configure', where FEATURE indicates an optional part of the package. +They may also pay attention to '--with-PACKAGE' options, where PACKAGE +is something like 'gnu-as' or 'x' (for the X Window System). The +'README' should mention any '--enable-' and '--with-' options that the +package recognizes. + + For packages that use the X Window System, 'configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the 'configure' options '--x-includes=DIR' and +'--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of 'make' will be. For these packages, running './configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with 'make V=1'; while running './configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with 'make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX 'make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated +files such as 'configure' are involved. Use GNU 'make' instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its '' header file. The option '-nodtk' can be used as a +workaround. If GNU CC is not installed, it is therefore recommended to +try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put '/usr/ucb' early in your 'PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in '/usr/bin'. So, if you need '/usr/ucb' +in your 'PATH', put it _after_ '/usr/bin'. + + On Haiku, software installed for all users goes in '/boot/common', +not '/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features 'configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, 'configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +'--build=TYPE' option. TYPE can either be a short name for the system +type, such as 'sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file 'config.sub' for the possible values of each field. If +'config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option '--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with '--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for 'configure' scripts to share, +you can create a site shell script called 'config.site' that gives +default values for variables like 'CC', 'cache_file', and 'prefix'. +'configure' looks for 'PREFIX/share/config.site' if it exists, then +'PREFIX/etc/config.site' if it exists. Or, you can set the +'CONFIG_SITE' environment variable to the location of the site script. +A warning: not all 'configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to 'configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the 'configure' command line, using 'VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified 'gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an +Autoconf limitation. Until the limitation is lifted, you can use this +workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +'configure' Invocation +====================== + + 'configure' recognizes the following options to control how it +operates. + +'--help' +'-h' + Print a summary of all of the options to 'configure', and exit. + +'--help=short' +'--help=recursive' + Print a summary of the options unique to this package's + 'configure', and exit. The 'short' variant lists options used only + in the top level, while the 'recursive' variant lists options also + present in any nested packages. + +'--version' +'-V' + Print the version of Autoconf used to generate the 'configure' + script, and exit. + +'--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally 'config.cache'. FILE defaults to '/dev/null' to + disable caching. + +'--config-cache' +'-C' + Alias for '--cache-file=config.cache'. + +'--quiet' +'--silent' +'-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to '/dev/null' (any error + messages will still be shown). + +'--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + 'configure' can determine that directory automatically. + +'--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: for + more details, including other options available for fine-tuning the + installation locations. + +'--no-create' +'-n' + Run the configure checks, but stop before creating any output + files. + +'configure' also accepts some other, not widely useful, options. Run +'configure --help' for more details. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..9c47afa9 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,103 @@ +## Process this file with automake to create Makefile.in +## Configure input file for elfutils. +## +## Copyright (C) 1996-2006, 2008, 2009, 2015 Red Hat, Inc. +## +## This file is part of elfutils. +## +## 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 3 of the License, or +## (at your option) any later version. +## +## elfutils 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, see . +## +ACLOCAL_AMFLAGS = -I m4 + +# automake already tells which subdir is being entered. +# Don't make make repeat. +AM_MAKEFLAGS = --no-print-directory + +pkginclude_HEADERS = version.h + +SUBDIRS = config lib libelf libcpu backends libebl libdwelf libdwfl libdw \ + libasm debuginfod src po doc tests + +EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \ + COPYING COPYING-GPLV2 COPYING-LGPLV3 + +# Make sure the test install uses lib64 when $LIB will yield lib64. +# Make sure the test build uses the same compiler, which on e.g. ppc64 +# determines which platform we are actually testing. +# Run all tests under valgrind. +AM_DISTCHECK_CONFIGURE_FLAGS = \ + --libdir=`echo $(libdir) | sed "s,^$(exec_prefix),$$dc_install_base,"`\ + --enable-valgrind --enable-sanitize-undefined \ + CC="$(CC)" + +distcheck-hook: + chmod -R u+w $(distdir) + +rpm: dist + rpmbuild -ts --sign elfutils-@PACKAGE_VERSION@.tar.bz2 + +if GCOV + +COVERAGE_OUTPUT_FILE = $(PACKAGE_NAME).lcov +COVERAGE_OUTPUT_DIRECTORY = coverage +COVERAGE_OUTPUT_INDEX_HTML = $(COVERAGE_OUTPUT_DIRECTORY)/index.html +COVERAGE_TITLE = $(PACKAGE_NAME)-$(PACKAGE_VERSION) + +COVERAGE_DIRS = $(filter-out tests,$(SUBDIRS)) +src_COVERAGE_DIRS = $(patsubst %,$(srcdir)/%,$(COVERAGE_DIRS)) +build_COVERAGE_DIRS = $(patsubst %,$(builddir)/%,$(COVERAGE_DIRS)) +all_COVERAGE_DIRS = $(sort $(src_COVERAGE_DIRS) $(build_COVERAGE_DIRS)) +LCOV_DIRS_ARGS = $(patsubst %,--directory=%,$(all_COVERAGE_DIRS)) + +CLEANFILES = $(COVERAGE_OUTPUT_FILE) + +.PHONY: coverage coverage-clean + +clean-local: coverage-clean +distclean-local: coverage-clean + +coverage-clean: + -rm -rf $(COVERAGE_OUTPUT_DIRECTORY) + +coverage: $(COVERAGE_OUTPUT_INDEX_HTML) + @echo 'file://$(abs_builddir)/$(COVERAGE_OUTPUT_INDEX_HTML)' + +$(COVERAGE_OUTPUT_INDEX_HTML): $(COVERAGE_OUTPUT_FILE) + LC_ALL=C $(GENHTML) \ + --legend \ + --show-details \ + --rc=genhtml_branch_coverage=1 \ + --title='$(COVERAGE_TITLE)' \ + --prefix='$(abspath $(abs_srcdir))' \ + --prefix='$(realpath $(abs_srcdir))' \ + --prefix='$(abspath $(abs_builddir)/..)' \ + --prefix='$(realpath $(abs_builddir)/..)' \ + --output-directory='$(COVERAGE_OUTPUT_DIRECTORY)' \ + $< + +$(COVERAGE_OUTPUT_FILE): + $(LCOV) \ + --capture \ + --no-external \ + --no-checksum \ + --rc=lcov_branch_coverage=1 \ + --gcov-tool='$(GCOV)' \ + --output-file='$@' \ + $(LCOV_DIRS_ARGS) + +endif + +# Tell version 3.79 and up of GNU make to not build goals in this +# directory in parallel. +.NOTPARALLEL: diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..e202c7f2 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,1013 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(pkginclude_HEADERS) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = elfutils.spec version.h +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgincludedir)" +HEADERS = $(pkginclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir distdir-am dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/config/ar-lib $(top_srcdir)/config/compile \ + $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.rpath \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/elfutils.spec.in \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/missing \ + $(top_srcdir)/config/version.h.in ABOUT-NLS AUTHORS COPYING \ + ChangeLog INSTALL NEWS README THANKS TODO +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +GZIP_ENV = --best +DIST_ARCHIVES = $(distdir).tar.bz2 +DIST_TARGETS = dist-bzip2 +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +ACLOCAL_AMFLAGS = -I m4 + +# automake already tells which subdir is being entered. +# Don't make make repeat. +AM_MAKEFLAGS = --no-print-directory +pkginclude_HEADERS = version.h +SUBDIRS = config lib libelf libcpu backends libebl libdwelf libdwfl libdw \ + libasm debuginfod src po doc tests + +EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \ + COPYING COPYING-GPLV2 COPYING-LGPLV3 + + +# Make sure the test install uses lib64 when $LIB will yield lib64. +# Make sure the test build uses the same compiler, which on e.g. ppc64 +# determines which platform we are actually testing. +# Run all tests under valgrind. +AM_DISTCHECK_CONFIGURE_FLAGS = \ + --libdir=`echo $(libdir) | sed "s,^$(exec_prefix),$$dc_install_base,"`\ + --enable-valgrind --enable-sanitize-undefined \ + CC="$(CC)" + +@GCOV_TRUE@COVERAGE_OUTPUT_FILE = $(PACKAGE_NAME).lcov +@GCOV_TRUE@COVERAGE_OUTPUT_DIRECTORY = coverage +@GCOV_TRUE@COVERAGE_OUTPUT_INDEX_HTML = $(COVERAGE_OUTPUT_DIRECTORY)/index.html +@GCOV_TRUE@COVERAGE_TITLE = $(PACKAGE_NAME)-$(PACKAGE_VERSION) +@GCOV_TRUE@COVERAGE_DIRS = $(filter-out tests,$(SUBDIRS)) +@GCOV_TRUE@src_COVERAGE_DIRS = $(patsubst %,$(srcdir)/%,$(COVERAGE_DIRS)) +@GCOV_TRUE@build_COVERAGE_DIRS = $(patsubst %,$(builddir)/%,$(COVERAGE_DIRS)) +@GCOV_TRUE@all_COVERAGE_DIRS = $(sort $(src_COVERAGE_DIRS) $(build_COVERAGE_DIRS)) +@GCOV_TRUE@LCOV_DIRS_ARGS = $(patsubst %,--directory=%,$(all_COVERAGE_DIRS)) +@GCOV_TRUE@CLEANFILES = $(COVERAGE_OUTPUT_FILE) +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnits'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnits \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +elfutils.spec: $(top_builddir)/config.status $(top_srcdir)/config/elfutils.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +version.h: $(top_builddir)/config.status $(top_srcdir)/config/version.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && $(MAKE) $(AM_MAKEFLAGS) distcheck-hook \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(HEADERS) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@GCOV_FALSE@distclean-local: +@GCOV_FALSE@clean-local: +clean: clean-recursive + +clean-am: clean-generic clean-local mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-local \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgincludeHEADERS + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-local cscope cscopelist-am ctags ctags-am dist dist-all \ + dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \ + dist-zip dist-zstd distcheck distclean distclean-generic \ + distclean-hdr distclean-local distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am \ + install-pkgincludeHEADERS install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-am uninstall uninstall-am uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +distcheck-hook: + chmod -R u+w $(distdir) + +rpm: dist + rpmbuild -ts --sign elfutils-@PACKAGE_VERSION@.tar.bz2 + +@GCOV_TRUE@.PHONY: coverage coverage-clean + +@GCOV_TRUE@clean-local: coverage-clean +@GCOV_TRUE@distclean-local: coverage-clean + +@GCOV_TRUE@coverage-clean: +@GCOV_TRUE@ -rm -rf $(COVERAGE_OUTPUT_DIRECTORY) + +@GCOV_TRUE@coverage: $(COVERAGE_OUTPUT_INDEX_HTML) +@GCOV_TRUE@ @echo 'file://$(abs_builddir)/$(COVERAGE_OUTPUT_INDEX_HTML)' + +@GCOV_TRUE@$(COVERAGE_OUTPUT_INDEX_HTML): $(COVERAGE_OUTPUT_FILE) +@GCOV_TRUE@ LC_ALL=C $(GENHTML) \ +@GCOV_TRUE@ --legend \ +@GCOV_TRUE@ --show-details \ +@GCOV_TRUE@ --rc=genhtml_branch_coverage=1 \ +@GCOV_TRUE@ --title='$(COVERAGE_TITLE)' \ +@GCOV_TRUE@ --prefix='$(abspath $(abs_srcdir))' \ +@GCOV_TRUE@ --prefix='$(realpath $(abs_srcdir))' \ +@GCOV_TRUE@ --prefix='$(abspath $(abs_builddir)/..)' \ +@GCOV_TRUE@ --prefix='$(realpath $(abs_builddir)/..)' \ +@GCOV_TRUE@ --output-directory='$(COVERAGE_OUTPUT_DIRECTORY)' \ +@GCOV_TRUE@ $< + +@GCOV_TRUE@$(COVERAGE_OUTPUT_FILE): +@GCOV_TRUE@ $(LCOV) \ +@GCOV_TRUE@ --capture \ +@GCOV_TRUE@ --no-external \ +@GCOV_TRUE@ --no-checksum \ +@GCOV_TRUE@ --rc=lcov_branch_coverage=1 \ +@GCOV_TRUE@ --gcov-tool='$(GCOV)' \ +@GCOV_TRUE@ --output-file='$@' \ +@GCOV_TRUE@ $(LCOV_DIRS_ARGS) + +# Tell version 3.79 and up of GNU make to not build goals in this +# directory in parallel. +.NOTPARALLEL: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..a73d39ec --- /dev/null +++ b/NEWS @@ -0,0 +1,1736 @@ +Version 0.185 + +debuginfod-client: Simplify curl handle reuse so downloads which + return an error are retried. + +elfcompress: Always exit with code 0 when the operation succeeds (even + when nothing was done). On error the exit code is now always 1. + +Version 0.184 + +debuginfod: Use libarchive's bsdtar as the .deb-family file unpacker. + +debuginfod-client: Client caches negative results. If a query for a + file failed with 404, an empty 000 permission + file is created in the cache. This will prevent + requesting the same file for the next 10 minutes. + + Client objects now carry long-lived curl handles + for outgoing connections. This makes it more + efficient for multiple sequential queries, because + the TCP connections and/or TLS state info are kept + around awhile, avoiding O(100ms) setup latencies. + +libdw: handle DW_FORM_indirect when reading attributes + +translations: Update Polish translation. + +Version 0.183 + +debuginfod: New thread-busy metric and more detailed error metrics. + New --fdcache-mintmp and tracking of filesystem freespace. + New increased webapi concurrency while grooming. + +debuginfod-client: DEBUGINFOD_SONAME macro added to debuginfod.h which + can be used to dlopen the libdebuginfod.so library. + New function debuginfod_set_verbose_fd and + DEBUGINFOD_VERBOSE environment variable. + +config: profile.sh and profile.csh won't export DEBUGINFOD_URLS unless + configured --enable-debuginfod-urls[=URLS] + +elflint, readelf: Recognize SHF_GNU_RETAIN. + Handle SHT_X86_64_UNWIND as valid relocation target. + +Version 0.182 + +backends: Support for tilegx has been removed. + +config: New /etc/profile.d files to provide default $DEBUGINFOD_URLS. + +debuginfod: More efficient package traversal, tolerate various errors + during scanning, grooming progress is more visible and + interruptible, more prometheus metrics. + +debuginfod-client: Now supports compressed (kernel) ELF images. + +libdwfl: Add ZSTD compression support. + +Version 0.181 + +libelf: elf_update now compensates (fixes up) a bad sh_addralign for + SHF_COMPRESSED sections. + +libdebuginfod: configure now takes --enable-libdebuginfod=dummy or + --disable-libdebuginfod for bootstrapping. + DEBUGINFOD_URLS now accepts "scheme-free" urls + (guessing at what the user meant, either http:// or file://) + +readelf, elflint: Handle aarch64 bti, pac bits in dynamic table and gnu + property notes. + +libdw, readelf: Recognize DW_CFA_AARCH64_negate_ra_state. Allows unwinding + on arm64 for code that is compiled for PAC (Pointer + Authentication Code) as long as it isn't enabled. + +Version 0.180 + +elflint: Allow SHF_EXCLUDE as generic section flag when --gnu is given. + +libdw, readelf: Handle GCC LTO .gnu.debuglto_ prefix. + +libdw: Use correct CU to resolve file names in dwarf_decl_file. + +libdwfl: Handle debugaltlink in dwfl_standard_find_debuginfo. + +size: Also obey radix printing for bsd format. + +nm: Explicitly print weak 'V' or 'T' and common 'C' symbols. + +Version 0.179 + +debuginfod-client: When DEBUGINFOD_PROGRESS is set and the program doesn't + install its own debuginfod_progressfn_t show download + progress on stderr. + DEBUGINFOD_TIMEOUT is now defined as seconds to get at + least 100K, defaults to 90 seconds. + Default to $XDG_CACHE_HOME/debuginfod_client. + New functions debuginfod_set_user_data, + debuginfod_get_user_data, debuginfod_get_url and + debuginfod_add_http_header. + Support for file:// URLs. + +debuginfod: Uses libarchive directly for reading rpm archives. + Support for indexing .deb/.ddeb archives through dpkg-deb + or bsdtar. + Generic archive support through -Z EXT[=CMD]. Which can be + used for example for arch-linux pacman files by using + -Z '.tar.zst=zstdcat'. + Better logging using User-Agent and X-Forwarded-For headers. + More prometheus metrics. + Support for eliding dots or extraneous slashes in path names. + +debuginfod-find: Accept /path/names in place of buildid hex. + +libelf: Handle PN_XNUM in elf_getphdrnum before shdr 0 is cached + Ensure zlib resource cleanup on failure. + +libdwfl: dwfl_linux_kernel_find_elf and dwfl_linux_kernel_report_offline + now find and handle a compressed vmlinuz image. + +readelf, elflint: Handle PT_GNU_PROPERTY. + +translations: Updated Ukrainian translation. + +Version 0.178 + +debuginfod: New server, client tool and library to index and fetch + ELF/DWARF files addressed by build-id through HTTP. + +doc: There are now some manual pages for functions and tools. + +backends: The libebl libraries are no longer dynamically loaded through + dlopen, but are now compiled into libdw.so directly. + +readelf: -n, --notes now takes an optional "SECTION" argument. + -p and -x now also handle section numbers. + New option --dyn-sym to show just the dynamic symbol table. + +libcpu: Add RISC-V disassembler. + +libdw: Abbrevs and DIEs can now be read concurrently by multiple + threads through the same Dwarf handle. + +libdwfl: Will try to use debuginfod when installed as fallback to + retrieve ELF and DWARF debug data files by build-id. + +Version 0.177 + +elfclassify: New tool to analyze ELF objects. + +readelf: Print DW_AT_data_member_location as decimal offset. + Decode DW_AT_discr_list block attributes. + +libdw: Add DW_AT_GNU_numerator, DW_AT_GNU_denominator and DW_AT_GNU_bias. + +libdwelf: Add dwelf_elf_e_machine_string. + dwelf_elf_begin now only returns NULL when there is an error + reading or decompressing a file. If the file is not an ELF file + an ELF handle of type ELF_K_NONE is returned. + +backends: Add support for C-SKY. + +Version 0.176 + +build: Add new --enable-install-elfh option. + Do NOT use this for system installs (it overrides glibc elf.h). + +backends: riscv improved core file and return value location support. + +Fixes CVE-2019-7146, CVE-2019-7148, CVE-2019-7149, CVE-2019-7150, + CVE-2019-7664, CVE-2019-7665 + +Version 0.175 + +readelf: Handle multiple .debug_macro sections. + Recognize and parse GNU Property notes, NT_VERSION notes + and GNU Build Attribute ELF Notes. + +strip: Handle SHT_GROUP correctly. + Add strip --reloc-debug-sections-only option. + Handle relocations against GNU compressed sections. + +libdwelf: New function dwelf_elf_begin. + +libcpu: Recognize bpf jump variants BPF_JLT, BPF_JLE, BPF_JSLT and BPF_JSLE. + +backends: RISCV handles ADD/SUB relocations. Handle SHT_X86_64_UNWIND. + +Fixes CVE-2018-18310, CVE-2018-18520 and CVE-2018-18521. + +Version 0.174 + +libelf, libdw and all tools now handle extended shnum and shstrndx correctly. + +elfcompress: Don't rewrite input file if no section data needs updating. + Try harder to keep same file mode bits (suid) on rewrite. + +strip: Handle mixed (out of order) allocated/non-allocated sections. + +unstrip: Handle SHT_GROUP sections. + +backends: RISCV and M68K now have backend implementations to generate CFI based + backtraces. + +Fixes CVE-2018-16062, CVE-2018-16402 and CVE-2018-16403. + +Version 0.173 + +More fixes for crashes and hangs found by afl-fuzz. In particular various +functions now detect and break infinite loops caused by bad DIE tree cycles. + +readelf: Will now lookup the size and signedness of constant value types + to display them correctly (and not just how they were encoded). + +libdw: New function dwarf_next_lines to read CU-less .debug_line data. + dwarf_begin_elf now accepts ELF files containing just .debug_line + or .debug_frame sections (which can be read without needing a DIE + tree from the .debug_info section). + Removed dwarf_getscn_info, which was never implemented. + +backends: Handle BPF simple relocations. + The RISCV backends now handles ABI specific CFI and knows about + RISCV register types and names. + +Version 0.172 + +No functional changes compared to 0.171. + +Various bug fixes in libdw and eu-readelf dealing with bad DWARF5 data. +Thanks to running the afl fuzzer on eu-readelf and various testcases. + +eu-readelf -N is ~15% faster. + +Version 0.171 + +DWARF5 and split dwarf, including GNU DebugFission, are supported now. +Data can be read from the new DWARF sections .debug_addr, .debug_line_str, +.debug_loclists, .debug_str_offsets and .debug_rnglists. Plus the new +DWARF5 and GNU DebugFission encodings of the existing .debug sections. +Also in split DWARF .dwo (DWARF object) files. This support is mostly +handled by existing functions (dwarf_getlocation*, dwarf_getsrclines, +dwarf_ranges, dwarf_form*, etc.) now returning the data from the new +sections and data formats. But some new functions have been added +to more easily get information about skeleton and split compile units +(dwarf_get_units and dwarf_cu_info), handle new attribute data +(dwarf_getabbrevattr_data) and to keep references to Dwarf_Dies +that might come from different sections or files (dwarf_die_addr_die). + +Not yet supported are .dwp (Dwarf Package) and .sup (Dwarf Supplementary) +files, the .debug_names index, the .debug_cu_index and .debug_tu_index +sections. Only a single .debug_info (and .debug_types) section are +currently handled. + +readelf: Handle all new DWARF5 sections. + --debug-dump=info+ will show split unit DIEs when found. + --dwarf-skeleton can be used when inspecting a .dwo file. + Recognizes GNU locviews with --debug-dump=loc. + +libdw: New functions dwarf_die_addr_die, dwarf_get_units, + dwarf_getabbrevattr_data and dwarf_cu_info. + libdw will now try to resolve the alt file on first use of + an alt attribute FORM when not set yet with dwarf_set_alt. + dwarf_aggregate_size() now works with multi-dimensional arrays. + +libdwfl: Use process_vm_readv when available instead of ptrace. + +backends: Add a RISC-V backend. + +There were various improvements to build on Windows. +The sha1 and md5 implementations have been removed, they weren't used. + +Version 0.170 + +libdw: Added new DWARF5 attribute, tag, character encoding, language code, + calling convention, defaulted member function and macro constants + to dwarf.h. + New functions dwarf_default_lower_bound and dwarf_line_file. + dwarf_peel_type now handles DWARF5 immutable, packed and shared tags. + dwarf_getmacros now handles DWARF5 .debug_macro sections. + +strip: Add -R, --remove-section=SECTION and --keep-section=SECTION. + +backends: The bpf disassembler is now always build on all platforms. + +Version 0.169 + +backends: Add support for EM_PPC64 GNU_ATTRIBUTES. + Frame pointer unwinding fallback support for i386, x86_64, aarch64. + +translations: Update Polish translation. + +Version 0.168 + +http://elfutils.org/ is now hosted at http://sourceware.org/elfutils/ + +libelf: gelf_newehdr and gelf_newehdr now return void *. + +libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1). + +readelf: Add optional --symbols[=SECTION] argument to select section name. + +Version 0.167 + +libasm: Add eBPF disassembler for EM_BPF files. + +backends: Add m68k and BPF backends. + +ld: Removed. + +dwelf: Add ELF/DWARF string table creation functions. dwelf_strtab_init, + dwelf_strtab_add, dwelf_strtab_add_len, dwelf_strtab_finalize, + dwelf_strent_off, dwelf_strent_str and dwelf_strtab_free. + +Version 0.166 + +config: The default program prefix for the installed tools is now eu-. + Use configure --program-prefix="" to not use a program prefix. + +Version 0.165 + +elfcompress: New utility to compress or decompress ELF sections. + +readelf: Add -z,--decompress option. + +libelf: Add elf_compress, elf_compress_gnu, elf32_getchdr, elf64_getchdr + and gelf_getchdr. + +libdwelf: New function dwelf_scn_gnu_compressed_size. + +config: Add libelf and libdw pkg-config files. + +backends: sparc support for core and live backtraces. + +translations: Updated Polish translation. + +Version 0.164 + +strip, unstrip: Handle ELF files with merged strtab/shstrtab tables. + Handle missing SHF_INFO_LINK section flags. + +libelf: Use int64_t for offsets in libelf.h instead of loff_t. + +libdw: dwarf.h Add preliminary DWARF5 DW_LANG_Haskell. + +libdwfl: dwfl_standard_find_debuginfo now searches any subdir of the binary + path under the debuginfo root when the separate debug file couldn't + be found by build-id. + dwfl_linux_proc_attach can now be called before any Dwfl_Modules + have been reported. + +backends: Better sparc and sparc64 support. + +translations: Updated Ukrainian translation. + +Provide default-yama-scope subpackage. + +Version 0.163 + +Bug fixes only, no new features. + +Version 0.162 + +libdw: Install new header elfutils/known-dwarf.h. + dwarf.h Add preliminary DWARF5 constants DW_TAG_atomic_type, + DW_LANG_Fortran03, DW_LANG_Fortran08. dwarf_peel_type now also + handles DW_TAG_atomic_type. + +addr2line: Input addresses are now always interpreted as hexadecimal + numbers, never as octal or decimal numbers. + New option -a, --addresses to print address before each entry. + New option -C, --demangle to show demangled symbols. + New option --pretty-print to print all information on one line. + +ar: CVE-2014-9447 Directory traversal vulnerability in ar extraction. + +backends: x32 support. + +Version 0.161 + +libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses + dwarf_peel_type to also provide the sizes of qualified types. + dwarf_getmacros will now serve either of .debug_macro and + .debug_macinfo transparently. New interfaces + dwarf_getmacros_off, dwarf_macro_getsrcfiles, + dwarf_macro_getparamcnt, and dwarf_macro_param are available + for more generalized inspection of macros and their parameters. + dwarf.h: Add DW_AT_GNU_deleted, DW_AT_noreturn, DW_LANG_C11, + DW_LANG_C_plus_plus_11 and DW_LANG_C_plus_plus_14. + +Version 0.160 + +libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die. + dwarf.h remove non-existing DW_TAG_mutable_type. + +libdwfl: Handle LZMA .ko.xz compressed kernel modules. + +unstrip: New option -F, --force to combining files even if some ELF headers + don't seem to match. + +backends: Handle ARM THUMB functions. Add support for ppc64le ELFv2 abi. + +Version 0.159 + +stack: New option -d, --debugname to lookup DWARF debuginfo name for frame. + New option -i, --inlines to show inlined frames using DWARF debuginfo. + +libdwelf: New libdwelf.h header for libdw.so DWARF ELF Low-level Functions. + New function dwelf_elf_gnu_debuglink, dwelf_dwarf_gnu_debugaltlink, + and dwelf_elf_gnu_build_id. + +libdw: Support for DWZ multifile forms DW_FORM_GNU_ref_alt and + DW_FORM_GNU_strp_alt is now enabled by default and no longer + experimental. Added new functions dwarf_getalt and dwarf_setalt + to get or set the alternative debug file used for the alt FORMs. + The dwfl_linux_proc_find_elf callback will now find ELF from + process memory for (deleted) files if the Dwfl has process state + attached. + +libdwfl: The dwfl_build_id_find_debuginfo and dwfl_standard_find_debuginfo + functions will now try to resolve and set the alternative debug file. + +backends: Add CFI unwinding for arm. Relies on .debug_frame. + Add arm process initial register state compatible mode to AARCH64. + Add aarch64 native and core unwind support. + +other: All separate elfutils-robustify patches have been merged. + CVE-2014-0172 Check overflow before calling malloc to uncompress data. + +Version 0.158 + +libdwfl: dwfl_core_file_report has new parameter executable. + New functions dwfl_module_getsymtab_first_global, + dwfl_module_getsym_info and dwfl_module_addrinfo. + Added unwinder with type Dwfl_Thread_Callbacks, opaque types + Dwfl_Thread and Dwfl_Frame and functions dwfl_attach_state, + dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread, + dwfl_thread_state_registers, dwfl_thread_state_register_pc, + dwfl_getthread_frames, dwfl_getthreads, dwfl_thread_getframes + and dwfl_frame_pc. + +addr2line: New option -x to show the section an address was found in. + +stack: New utility that uses the new unwinder for processes and cores. + +backends: Unwinder support for i386, x86_64, s390, s390x, ppc and ppc64. + aarch64 support. + +Version 0.157 + +libdw: Add new functions dwarf_getlocations, dwarf_getlocation_attr + and dwarf_getlocation_die. + +readelf: Show contents of NT_SIGINFO and NT_FILE core notes. + +addr2line: Support -i, --inlines output option. + +backends: abi_cfi hook for arm, ppc and s390. + +Version 0.156 + +lib: New macro COMPAT_VERSION_NEWPROTO. + +libdw: Handle GNU extension opcodes in dwarf_getlocation. + +libdwfl: Fix STB_GLOBAL over STB_WEAK preference in dwfl_module_addrsym. + Add minisymtab support. + Add parameter add_p_vaddr to dwfl_report_elf. + Use DT_DEBUG library search first. + +libebl: Handle new core note types in EBL. + +backends: Interpret NT_ARM_VFP. + Implement core file registers parsing for s390/s390x. + +readelf: Add --elf-section input option to inspect an embedded ELF file. + Add -U, --unresolved-address-offsets output control. + Add --debug-dump=decodedline support. + Accept version 8 .gdb_index section format. + Adjust output formatting width. + When highpc is in constant form print it also as address. + Display raw .debug_aranges. Use libdw only for decodedaranges. + +elflint: Add __bss_start__ to the list of allowed symbols. + +tests: Add configure --enable-valgrind option to run all tests under valgrind. + Enable automake parallel-tests for make check. + +translations: Updated Polish translation. + +Updates for Automake 1.13. + +Version 0.155 + +libelf: elf*_xlatetomd now works for cross-endian ELF note data. + elf_getshdr now works consistently on non-mmaped ELF files after + calling elf_cntl(ELF_C_FDREAD). + Implement support for ar archives with 64-bit symbol table. + +libdw: dwarf.h corrected the DW_LANG_ObjC constant name (was DW_LANG_Objc). + Any existing sources using the old name will have to be updated. + Add DW_MACRO_GNU .debug_macro type encodings constants, DW_ATE_UTF + and DW_OP_GNU_parameter_ref to dwarf.h. + Experimental support for DWZ multifile forms DW_FORM_GNU_ref_alt + and DW_FORM_GNU_strp_alt. Disabled by default. Use configure + --enable-dwz to test it. + +readelf: Add .debug_macro parsing support. + Add .gdb_index version 7 parsing support. + Recognize DW_OP_GNU_parameter_ref. + +backends: Add support for Tilera TILE-Gx processor. + +translations: Updated Ukrainian translation. + +Version 0.154 + +libelf: [g]elf[32|64]_offscn() do not match SHT_NOBITS sections at OFFSET. + +libdw: dwarf_highpc function now handles DWARF 4 DW_AT_high_pc constant form. + Fix bug using dwarf_next_unit to iterate over .debug_types. + +elflint: Now accepts gold linker produced executables. + +The license is now GPLv2/LGPLv3+ for the libraries and GPLv3+ for stand-alone +programs. There is now also a formal CONTRIBUTING document describing how to +submit patches. + +Version 0.153 + +libdw: Support reading .zdebug_* DWARF sections compressed via zlib. + +libdwfl: Speed up dwfl_module_addrsym. + +nm: Support C++ demangling. + +ar: Support D modifier for "deterministic output" with no uid/gid/mtime info. + The U modifier is the inverse. + elfutils can be configured with the --enable-deterministic-archives + option to make the D behavior the default when U is not specified. + +ranlib: Support -D and -U flags with same meaning. + +readelf: Improve output of -wline. Add support for printing SDT elf notes. + Add printing of .gdb_index section. + Support for typed DWARF stack, call_site and entry_value. + +strip: Add --reloc-debug-sections option. + Improved SHT_GROUP sections handling. + +Version 0.152 + +Various build and warning nits fixed for newest GCC and Autoconf. + +libdwfl: Yet another prelink-related fix for another regression. + Look for Linux kernel images in files named with compression suffixes. + +elfcmp: New flag --ignore-build-id to ignore differing build ID bits. + New flag -l/--verbose to print all differences. + +Version 0.151 + +libdwfl: Fix for more prelink cases with separate debug file. + +strip: New flag --strip-sections to remove section headers entirely. + +Version 0.150 + +libdw: Fix for handling huge .debug_aranges section. + +libdwfl: Fix for handling prelinked DSO with separate debug file. + +findtextrel: Fix diagnostics to work with usual section ordering. + +libebl: i386 backend fix for multi-register integer return value location. + +Version 0.149: + +libdw: Decode new DW_OP_GNU_implicit_pointer operation; + new function dwarf_getlocation_implicit_pointer. + +libdwfl: New function dwfl_dwarf_line. + +addr2line: New flag -F/--flags to print more DWARF line information details. + +strip: -g recognizes .gdb_index as a debugging section. + +Version 0.148: + +libdw: Accept DWARF 4 format: new functions dwarf_next_unit, dwarf_offdie_types. + New functions dwarf_lineisa, dwarf_linediscriminator, dwarf_lineop_index. + +libdwfl: Fixes in core-file handling, support cores from PIEs. + When working from build IDs, don't open a named file that mismatches. + +readelf: Handle DWARF 4 formats. + +Version 0.147: + +libdw: Fixes in CFI handling, best possible handling of bogus CFA ops. + +libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r bugs. + +Version 0.146: + +libdwfl: New function dwfl_core_file_report. + +Version 0.145: + +Fix build with --disable-dependency-tracking. + +Fix build with most recent glibc headers. + +libelf: More robust to bogus section headers. + +libdw: Fix CFI decoding. + +libdwfl: Fix address bias returned by CFI accessors. + Fix core file module layout identification. + +readelf: Fix CFI decoding. + +Version 0.144: + +libelf: New function elf_getphdrnum. + Now support using more than 65536 program headers in a file. + +libdw: New function dwarf_aggregate_size for computing (constant) type + sizes, including array_type cases with nontrivial calculation. + +readelf: Don't give errors for missing info under -a. + Handle Linux "VMCOREINFO" notes under -n. + +Version 0.143: + +libdw: Various convenience functions for individual attributes now use + dwarf_attr_integrate to look up indirect inherited attributes. + Location expression handling now supports DW_OP_implicit_value. + +libdwfl: Support automatic decompression of files in XZ format, + and of Linux kernel images made with bzip2 or LZMA (as well as gzip). + +Version 0.142: + +libelf: Add elf_getshdrnum alias for elf_getshnum and elf_getshdrstrndx alias + for elf_getshstrndx and deprecate original names. Sun screwed up + their implementation and asked for a solution. + +libebl: Add support for STB_GNU_UNIQUE. + +elflint: Add support for STB_GNU_UNIQUE. + +readelf: Add -N option, speeds up DWARF printing without address->name lookups. + +libdw: Add support for decoding DWARF CFI into location description form. + Handle some new DWARF 3 expression operations previously omitted. + Basic handling of some new encodings slated for DWARF 4. + +Version 0.141: + +libebl: sparc backend fixes; + some more arm backend support + +libdwfl: fix dwfl_module_build_id for prelinked DSO case; + fixes in core file support; + dwfl_module_getsym interface improved for non-address symbols + +strip: fix infinite loop on strange inputs with -f + +addr2line: take -j/--section=NAME option for binutils compatibility + (same effect as '(NAME)0x123' syntax already supported) + +Version 0.140: + +libelf: Fix regression in creation of section header + +libdwfl: Less strict behavior if DWARF reader is just used to display data + +Version 0.139: + +libcpu: Add Intel SSE4 disassembler support + +readelf: Implement call frame information and exception handling dumping. + Add -e option. Enable it implicitly for -a. + +elflint: Check PT_GNU_EH_FRAME program header entry. + +libdwfl: Support automatic gzip/bzip2 decompression of ELF files. + +Version 0.138: + +Install header file for applications to use in source +version compatibility checks. + +libebl: backend fixes for i386 TLS relocs; backend support for NT_386_IOPERM + +libcpu: disassembler fixes + +libdwfl: bug fixes + +libelf: bug fixes + +nm: bug fixes for handling corrupt input files + +Version 0.137: + +Minor fixes for unreleased 0.136 release. + +Version 0.136: + +libdwfl: bug fixes; new "segment" interfaces; + all the libdwfl-based tools now support --core=COREFILE option + +Version 0.135: + +libdwfl: bug fixes + +strip: changed handling of ET_REL files wrt symbol tables and relocs + +Version 0.134: + +elflint: backend improvements for sparc, alpha + +libdwfl, libelf: bug fixes + +Version 0.133: + +readelf, elflint, libebl: SHT_GNU_ATTRIBUTE section handling (readelf -A) + +readelf: core note handling for NT_386_TLS, NT_PPC_SPE, Alpha NT_AUXV + +libdwfl: bug fixes and optimization in relocation handling + +elfcmp: bug fix for non-allocated section handling + +ld: implement newer features of binutils linker. + +Version 0.132: + +libcpu: Implement x86 and x86-64 disassembler. +libasm: Add interface for disassembler. + +all programs: add debugging of branch prediction. + +libelf: new function elf_scnshndx. + +Version 0.131: + +libdw: DW_FORM_ref_addr support; dwarf_formref entry point now deprecated; + bug fixes for oddly-formatted DWARF + +libdwfl: bug fixes in offline archive support, symbol table handling; + apply partial relocations for dwfl_module_address_section on ET_REL + +libebl: powerpc backend support for Altivec registers + +Version 0.130: + +readelf: -p option can take an argument like -x for one section, + or no argument (as before) for all SHF_STRINGS sections; + new option --archive-index (or -c); + improved -n output for core files, on many machines + +libelf: new function elf_getdata_rawchunk, replaces gelf_rawchunk; + new functions gelf_getnote, gelf_getauxv, gelf_update_auxv + +readelf, elflint: handle SHT_NOTE sections without requiring phdrs + +elflint: stricter checks on debug sections + +libdwfl: new functions dwfl_build_id_find_elf, dwfl_build_id_find_debuginfo, + dwfl_module_build_id, dwfl_module_report_build_id; + support dynamic symbol tables found via phdrs; + dwfl_standard_find_debuginfo now uses build IDs when available + +unstrip: new option --list (or -n) + +libebl: backend improvements for sparc, alpha, powerpc + +Version 0.129: + +readelf: new options --hex-dump (or -x), --strings (or -p) + +addr2line: new option --symbols (or -S) + +Version 0.128: + +new program: unstrip + +elfcmp: new option --hash-inexact + +Version 0.127: + +libdw: new function dwarf_getsrcdirs + +libdwfl: new functions dwfl_module_addrsym, dwfl_report_begin_add, + dwfl_module_address_section + +Version 0.126: + +new program: ar + +Version 0.125: + +elflint: Compare DT_GNU_HASH tests. + +move archives into -static RPMs + +libelf, elflint: better support for core file handling + +Version 0.124: + +libebl: sparc backend support for return value location + +libebl, libdwfl: backend register name support extended with more info + +libelf, libdw: bug fixes for unaligned accesses on machines that care + +readelf, elflint: trivial bugs fixed + +Version 0.123: + +libebl: Backend build fixes, thanks to Stepan Kasal. + +libebl: ia64 backend support for register names, return value location + +libdwfl: Handle truncated linux kernel module section names. + +libdwfl: Look for linux kernel "vmlinux" files with ".debug" suffix. + +elflint: Fix checks to permit --hash-style=gnu format. + +Version 0.122: + +libebl: add function to test for relative relocation + +elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks + +elflint, readelf: add support for DT_GNU_HASH +libelf: add elf_gnu_hash + +elflint, readelf: add support for 64-bit SysV-style hash tables + +libdwfl: new functions dwfl_module_getsymtab, dwfl_module_getsym. + +Version 0.121: + +libelf: bug fixes for rewriting existing files when using mmap. + +make all installed headers usable in C++ code. + +readelf: better output format. + +elflint: fix tests of dynamic section content. + +ld: Implement --as-needed, --execstack, PT_GNU_STACK. Many small patches. + +libdw, libdwfl: handle files without aranges info. + +Version 0.120: + +Bug fixes. + +dwarf.h updated for DWARF 3.0 final specification. + +libdwfl: New function dwfl_version. + +The license is now GPL for most files. The libelf, libebl, libdw, +and libdwfl libraries have additional exceptions. Add reference to +OIN. + +Version 0.119: + +bug fixes + +Version 0.118: + +elflint: more tests. + +libdwfl: New function dwfl_module_register_names. + +libebl: New backend hook for register names. + +Version 0.117: + +libdwfl: New function dwfl_module_return_value_location. + +libebl: Backend improvements for several CPUs. + +Version 0.116: + +libdw: New functions dwarf_ranges, dwarf_entrypc, dwarf_diecu, + dwarf_entry_breakpoints. Removed Dwarf_Func type and functions + dwarf_func_name, dwarf_func_lowpc, dwarf_func_highpc, + dwarf_func_entrypc, dwarf_func_die; dwarf_getfuncs callback now uses + Dwarf_Die, and dwarf_func_file, dwarf_func_line, dwarf_func_col + replaced by dwarf_decl_file, dwarf_decl_line, dwarf_decl_column; + dwarf_func_inline, dwarf_func_inline_instances now take Dwarf_Die. + Type Dwarf_Loc renamed to Dwarf_Op; dwarf_getloclist, + dwarf_addrloclists renamed dwarf_getlocation, dwarf_getlocation_addr. + +Version 0.115: + +libelf: speed-ups of non-mmap reading. + +strings: New program. + +Implement --enable-gcov option for configure. + +libdw: New function dwarf_getscopes_die. + +Version 0.114: + +libelf: new function elf_getaroff + +libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_instances. + +libdwfl: New functions dwfl_report_offline, dwfl_offline_section_address, + dwfl_linux_kernel_report_offline. + +ranlib: new program + +Version 0.113: + +elflint: relax a bit. Allow version definitions for defined symbols against +DSO versions also for symbols in nobits sections. Allow .rodata section +to have STRINGS and MERGE flag set. + +strip: add some more compatibility with binutils. + +Version 0.112: + +elfcmp: some more relaxation. + +elflint: many more tests, especially regarding to symbol versioning. + +libelf: Add elfXX_offscn and gelf_offscn. + +libasm: asm_begin interface changes. + +libebl: Add three new interfaces to directly access machine, class, and +data encoding information. + +objdump: New program. Just the beginning. + +Version 0.111: + +libdw: now contains all of libdwfl. The latter is not installed anymore. + +elfcmp: little usability tweak, name and index of differing section is printed. + +Version 0.110: + +libelf: fix a number of problems with elf_update + +elfcmp: fix a few bugs. Compare gaps. + +Fix a few PLT problems and mudflap build issues. + +libebl: Don't expose Ebl structure definition in libebl.h. It's now private. + +Version 0.109: + +libebl: Check for matching modules. + +elflint: Check that copy relocations only happen for OBJECT or NOTYPE symbols. + +elfcmp: New program. + +libdwfl: New library. + +Version 0.108: + +strip: fix bug introduced in last change + +libdw: records returned by dwarf_getsrclines are now sorted by address + +Version 0.107: + +readelf: improve DWARF output format + +strip: support Linux kernel modules + +Version 0.106: + +libdw: Updated dwarf.h from DWARF3 spec +libdw: add new functions dwarf_func_entrypc, dwarf_func_file, dwarf_func_line, +dwarf_func_col, dwarf_getsrc_file + +Version 0.105: + +addr2line: New program + +libdw: add new functions: dwarf_addrdie, dwarf_macro_*, dwarf_getfuncs, +dwarf_func_*. + +findtextrel: use dwarf_addrdie + +Version 0.104: + +findtextrel: New program. + +Version 0.103: + +libdw: Fix using libdw.h with gcc < 4 and C++ code. Compiler bug. + +Version 0.102: + +More Makefile and spec file cleanups. + +Version 0.101: + +Remove most gettext autoconf handling. + +Add more warnings + +Fix resulting problems. One actual bug found and fixed this way + +Version 0.100: + +libebl: Fix x86-64 relocations. + +Add -Wunused -Wextra warnings. + +Some cleanups resulting from those additional warnings. + +Lots of Makefile cleanup. + +Version 0.99: + +libelf: add gelf_checksum prototype to + +libelf: fix elf*_checksum handling of NOBITS sections + +Finish mudflap support. + +Fix three bugs found by mudflap. + +ld: add as_needed support + +Version 0.98: + +readelf: in section to segment mapping, indicate read-only sections. + +elflint: more relaxation for GNU ld + +Version 0.97: + +Fix compiling with gcc 4.0. +Some tests called elflint without appropriate LD_LIBRARY_PATH. + +Version 0.96: + +Fix support for platforms with lib64. + +Version 0.95: + +libebl: add ppc and ppc64 support + +readelf: fix minimal memory leak. + +Add support to compile with mudflap. + +Modernize configure.ac. Move scripts in config subdir. + +Modernize *-po directory infrastructure. + +libelf: Add gelf_getlib and gelf_update_lib + +readelf: print liblist sections + +Version 0.94: + +Fix some minimal build problems. + +Version 0.93: + +ibdw: tons of new functionality and bug fixes. Several interface changes. + +readelf: use libdw now. + +libdwarf: removed completely. + +Version 0.92: + +configuration changes. + +Version 0.91: + +libdw: fix memory handling. Implement source line handling. +nm: use libdw instead of libdwarf. +libelf: change to GPL from OSL1 for now. + +Version 0.90: + +libebl: Recognize a few more section types and dynamic tags and return +appropriate strings. + +Version 0.89: + +strip: fix overwriting of symbol table in input file. + +Version 0.88: + +libebl: Add some ia64 bits. + +Version 0.87: + +Bug fixes for big endian and some 64-bit machines. + +Version 0.86: + +strip: fix handling of Alpha and s390x which use incorrect hash bucket sizes. + +ld: tons of changes, moving towards usability. + +Version 0.85: + +strip: update section group symbol index if the associated symbol table changed + +libelf: fix two problems with generating output not via mmap + +elflint: add probably 10-15 more tests +libebl: add support for some of the new tests + +ld: gazillion changes + +Version 0.84: + +elflint: deal with .rel.dyn section. Fix a problem with rela platforms. +Handle PT_GNU_STACK. Change to write messages to stdout. + +readelf: fix a problem with version information in the symbol table output. + +strip: update all version symbol table entries + +Version 0.83: + +size: fix a warning + +strip: last changed caused problems when the symbol table is before the +relocation section. Fixed. This fix also improved the asymptotic +behavior if many symbol table sections are present. + +Version 0.82: + +Run strip tests with the correct libelf and libebl. + +libelf: fix bug in verneed byte order changing code. + +Version 0.81: + +strip: Remove unused symbol table entries. This might require updating +various other sections. + +Version 0.80: + +Fix some libelf problems with ET_REL files. + +Version 0.79: + +More warning changes, mainly by jbj. + +libdw: yet more new code. dwarf_child and dwarf_sibling should now actually +work. + +Version 0.78: + +libdw: 10+ new functions. get-pubnames2 works now fully. Almost all the +code needed for nm is in place. + +Version 0.77: + +cleanups to compile cleanly with gcc 3.3 and -Werror. + +libdw: some new code. + +Version 0.76: + +libebl: Fix last patch to recognize relocation sections. We must not +use the name. + +Version 0.75: + +libebl: .debug_ranges is a DWARF 3 debug section +libebl: recognize relocation sections for debug section +Patches by Jakub Jelinek. + +Version 0.74: + +Cleanups and more SPARC support by Tom Callaway . + +Version 0.73: + +64-bit cleanups for the programs. + +Version 0.72: + +libelf: and yet more fun with endian transformation at output time. + +Version 0.71: + +libelf: more fun with endian transformation at output time. Add test for it. + +Version 0.70: + +libelf: Two little bugs left from previous patch to handle section output +order. + +libelf: add unlikely in some more places. + +Version 0.69: + +libelf: fix output routines to handle case where section indices and +ordre in the output file don't match correctly. Patch by Jakub. + +elflint: fix test of note section content for 64-bit platforms and files +with different byte order. + +Version 0.68: + +libebl: Fix SH_ENTSIZE_HASH definition (patch by Jakub) + +Version 0.67: + +libelf: correct mistake in error string handling. + +libelf: Implement ELF_F_PERMISSIVE. +strip: Implement --permissive option. + +Version 0.66: + +strip: Implement -g option. + +libelf: Handle broken hash table entry sizes. + +libebl: New function ebl_debugscn_p. Use it where appropriate. + +Version 0.65: + +libelf: Use correct file size for NOBITS section with ELF_F_LAYOUT set + +Version 0.64: + +libelf: Make error handling more robust. +libelf: Use TLS in error handler if configured with --enable-tls + +tests: input files are now distributed, not uuencoded in the shell scripts + +libdw: implement error handling, dwarf_get_pubnames + +Version 0.63: + +Build (incomplete) libdw. + +Version 0.62: + +Get rid of libtool. + +Version 0.61: + +Fix URL of OSL. + +Version 0.60: + +libebl: Handle .gnu.warning.* sections correctly. + +size: Implement -t option. + +libebl: Add IA-64 support. +libebl: Update SH relocations. +libebl: Add Alpha support. +libebl: Add Arm support. +libebl: Add support for all currently known architecture to the loader. + +Version 0.59: + +nm: Implement -S option. Correct portable output format. Implement -s option. + +libelf: Take offset of archive into account in elf_rand. + +Version 0.58: + +strip: fix handling of ET_REL files. +Add tests for strip. + +Version 0.57: + +strip: respect layout of input file + +Version 0.56: + +strip: handle files with large number of sections. + +Version 0.55: + +libelf: quite a few bug fixes by Alex Larsson. + +strip: implement -f option to place stripped sections into a separate +file. By Alex Larsson. + +Version 0.54: + +strip: don't let STT_SECTION symbols keeps sections from being removed + +elflint: local symbols are allowed in .dynsym +elflint: special case .rel.dyn a bit + +Version 0.53: + +elflint: check types and flags of special sections defined in gABI + +libebl: add x86-64 support + +Version 0.52: + +Start improvement of debug info handling in nm. + +libasm: implement asm_adduleb128 and asm_addsleb128 and a test for them + +Version 0.51: + +Fix build on 64-bit platforms. + +Version 0.50: + +nm: print file/line number also for local symbols + +use versions scripts not libtool's useless -export-symbols option + +Version 0.49: + +Update to autoconf 2.54 and automake 1.7. + +elflint: check note sections + +libdwarf: a number of bug fixes + +readelf: print .debug_info section content + +dwarf.h: Update from draft 7 + +Version 0.48: + +libcpu: beginning + +libelf: new function to read parts of the ELF file + +libebl: support for note section handling + +readelf: dump note sections + +Version 0.47: + +libelf: fix little new section-handling related bugs in elf_getshstrndx +and elf_nextscn + +elflint: tests for mandatory content of dynamic section + +libasm: better handling of absolute symbols + +Version 0.46: + +libasm: rewrite to store Elf_Scn* instead of indices + +nm: finish many-section support + +nm: use debug in to print file/line info in sysv format + +libdwarf: fix a few bugs in DIE handling + +Version 0.45: + +libelf: major rewrite to keep Elf_Scn references valid until elf_end + +Version 0.44: + +libasm: Add support for bss, ABS, and COM sections. + +libebl: ebl_section_name takes now two index arguments to distinguish +between special sections and extended sections + +Version 0.43: + +General: fix a few problem gcc 3.1 had with the code. + +libelf: implement {gelf,elf32,elf64}_checksum + +libelf: optimize DSO: fewer relocations, fewer PLTs + +add msg_tst test + +ld: use correct section header string table index; write correct index + +add dependencies for *.sym files + +Version 0.42: + +libelf: add elf_getshnum and elf_getshstrndx + +libebl: update section type name function + +elflint: tons of fixes wrt large number of sections. New tests in this area. +Same amount of other bug fixes. + +size, strip, nm: better support for large number of sections. Including +using correct section header string table + +libasm: correctly create data structures for large number of sections + +new tests asm-tst4 and asm-tst5 to check large number of sections + +libasm: implement section group generation + +elflint: more tests on section groups. Improve performance on existing +section group tests + +Version 0.41: + +ld: add undefined symbols to dynamic symbol table if --export-dynamic is +not given + +ld: fix value of e_entry + +Version 0.40: + +elflint: print section names in error messages + +elflint: mustn't warn about multiple DT_NULL + +ld: don't emit all symbols if --export-dynamic is not given + +ld: correct compute symbol address in output file (section index was off by 1) + +ld: generate correct version info in dynsym without --export-dynamic and +in symtab + +Version 0.39: + +Fix check of various e_*size entries in elflint. + +Handle text output in asm_newsym. + +Finish checks in asm-tst3. + +Version 0.38: + +Update to autoconf 2.53, automake 1.6, gettext 0.11+. + +Introduce *.sym files to restrict export from DSOs. + +Use attribute_hidden and internal_function to optimize DSO code. + +Add TLS definitions in elf.h and handle them in readelf. + +Fix bug in verdef section generation in ld. + +Add initial libasm code. + +Version 0.37: + +Implement better hash size optimization heuristic in ld. It uses a formula +taking number of tests into account. + +Lots of small bug fixes. + +Improve readelf output format. Respect various sh_link/sh_info values. +Correctly print versioning information for symbol tables. + +Version 0.36: + +Implement preprocessing of linker script. Recognize -z combreloc. + +Version 0.35: + +Implement -z ignore|record for ld. + +Implement creating of .gnu.version_r and .gnu.version sections. The +.gnu.version does not yet contain correct info for defined and versioned +symbols (means .gnu.version_d is not yet implemented). + +Implement gelf_update_* functions to create versioning data. + +Version 0.34: + +Add DT_RUNPATH/DT_RPATH entries to dynamic section. Create .plt and +.rel.plt sections (completely). Add support for all four PLT related +dynamic section entries. Add callback function for PLT creation. + +More tests in elflint. Add support for very strict checking which for +now flags level 2 (deprecated features) usage. + +Version 0.33: + +Create dynamic symbol table, dynamic string table, and hash table to ld. + +Add hash table histogram support to readelf. + +Version 0.32: + +more work on elflint + +ld now creates the dynamic section and references it. Start adding entries +to dynamic section. + +Version 0.31: + +Start implementing elflint. + +Version 0.30: + +Fix handling of NOBITS sections in elf_getdata. + +Start implementing generation of executables and DSOs in ld. +Generation of program header mostly done. Address computation done. +Extension of linker script syntax. + +Various cleanups. + +Implement section group handling in readelf. + +Version 0.29: + +Implement section groups. This involved a lot of code moving. The +new code is entirely untested since gas/gcc are currently not able to +create section groups. ld works fine on files without section groups. + +Version 0.28: + +Fix problem with adding more section in elf_newscn. The section pointers +for the data buffers wasn't adjusted. + +Fix elf_getdata with nonzero second parameter. Correctly handle creation +of internal data buffer for machines without unaligned access. + +Version 0.27: + +Start adding support to selectively add sections. Includes support for +section groups. +Add --gc-sections/--no-gc-sections options. +Add general section merging support. + +Fix a bug in section group support in strip. + +Fix some potential problems with hash value in dynamic hash implementation. + +Version 0.26: + +section merging works in ld. + +Version 0.25: + +Actually create data structures from version map file and use it to hide +symbols in ld. + +Implement -s -s for ld. + +Version 0.24: + +Improve relocation table output in readelf. Avoid some crashes. +Finish many section handling in readelf. + +Finish: finish implementation of ld -r. At least some simple tests pass. + +Version 0.23: + +Fix a number of errors in ELF_C_WRITE handling. + +Almost finished implementation of ld -r. The data sections are all copied. +Handling of symbol tables is missing. + +Version 0.22: + +Handle DSO and archive input files correctly if -r option is given. + +Gracefully deal with no phdr in new file in libelf. +Fix various small error handling problems. +Don't mmap file for output unless the command says so. + +Add code to create ELF section header table to ld finalize routines. + +Version 0.21: + +Fix some problems with recursive handling of archives in libelf. + +Improve messages printed by nm. + +Add symbol binding name handling to libebl. Fix section name handling in +libebl. + +readelf and nm use more libebl functions. + +Handle XINDEX correctly in nm and string. + +Add first machine ld backend library (i386). +Use it. Recognize -r and --shared. Avoid using -lxxx parameters for -r. +Create ELF header in output file. Change mode of output file according to +output file type. Reorganize callback initialization in ld. + +Version 0.20: + +Fix some memory leaks in libelf. + +Version 0.19: + +Implement reading version script. Both inside linker scripts and via the +--version-script command line parameter. Uses the same code. +What remains to be done is to implement a data structure which allows +efficient matching against the version names to decide which pattern +matches. + +Beginning of output generation and output writing functions. + +Version 0.18: + +Finish implementation for DSO input file handling. Implement rpath, runpath, +and LD_LIBRARY_PATH handling. + +Version 0.17: + +make handling of e_shnum overflow in libelf standard conforming + +ld now actually can handle DSOs in linker scripts. Handling of DT_RUNPATH, +DT_RPATH, -rpath, -rpath-link still remains to be implemented. + +fix handling of -L parameters. Make actual use of the default_paths element. + +make re-definition of symbols in and from DSO compatible with existing linker + +Version 0.16: + +more work on assigning input sections to output sections. + +Add gelf_xlatetof and gelf_xlatetom which were accidentally left out. + +Fix memory handling of section headers. + +Version 0.15: + +Add many-section support to ld. Add various new command line parameters. +Allow pagesize to be specified in linker script or on the command line. +Collect input sections in list for the output section according to the rules +specified in the linker script. + +Version 0.14: + +Fix some problems in the internal list handling which had the result +that we didn't look for some of the unresolved symbols. + +Free some memory if we know we don't need it anymore. + +Optimize the list of unresolved symbols. Throw out symbols which are +meanwhile resolved. + +Version 0.13: + +Got file reading correct now. The files are all read while parsing +the parameters. No creating of data structures to describe the linker +command line. The symbol table is built up while reading the files. +DSOs are handled now. -( -) handling is optimized. + +Version 0.12: + +Linker read linker scripts everywhere. Handles --whole-archive. Recognizes +--dynamic and --static. Collects defined and undefined symbols. Recognizes +conflicts. + +libebl now defines functions to call the callbacks. Add generic name handling +in these new functions. Remove the code from readelf and call the new +functions. + +Version 0.11: + +Start of linker. Basic argument parsing, finding of input files, +linker script reading. + +Version 0.10: + +Implement dwarf_get_fde_n(), dwarf_get_abbrev(), dwarf_get_abbrev_tag(), +dwarf_get_abbrev_code(), dwarf_get_abbrev_children_flag(), +dwarf_get_abbrev_entry(), dwarf_get_fde_at_pc(), and tests for it. + +Version 0.9: + +Implement dwarf_get_fde_list_eh(), dwarf_get_cie_of_fde(), +dwarf_get_fde_range(), dwarf_get_cie_info(), dwarf_get_fde_instr_bytes(), +and tests for them. + +Version 0.8: + +Make handling of binaries in other byte order work and add tests for it. + +Version 0.7: + +Implement dwarf_get_aranges(), dwarf_get_arange(), dwarf_get_cu_die_offset(), +dwarf_get_arange_info(), and tests for them. + +Version 0.6: + +Implement dwarf_get_global(), dwarf_globname(), dwarf_global_die_offset(), +dwarf_global_cu_offset(), dwarf_global_name_offsets(), and tests for them + +Version 0.5: + +Implemented dwarf_srclines(), dwarf_srcfiles(), dwarf_linebeginstatement(), +dwarf_lineendsequence(), dwarf_lineno(), dwarf_lineaddr(), dwarf_lineoff(), +dwarf_linesrc(), dwarf_lineblock(), dwarf_lineprologueend(), +dwarf_lineepiloguebegin(), and tests for them. + +Version 0.4: + +Implemented dwarf_loclist(). + +Version 0.3: + +Implemented dwarf_dieoffset(), dwarf_die_CU_offset(), dwarf_diename() and +tests. + +Implemented dwarf_attrlist(), dwarf_hasattr(), dwarf_attr(), dwarf_lowpc(), +dwarf_highpc(), dwarf_bytesize(), dwarf_bitsize(), dwarf_bitoffset(), +dwarf_srclang(), dwarf_arrayorder(), dwarf_hasform(), dwarf_whatform(), +dwarf_whatattr(), dwarf_formref(), dwarf_global_formref(), dwarf_formaddr(), +dwarf_formflag(), dwarf_formudata(), dwarf_formsdata(), dwarf_formblock, +dwarf_formstring() and tests for them. + +Version 0.2: + +Implemented dwarf_offdie()), dwarf_tag(), dwarf_dieoffset(), +dwarf_die_CU_offset(), dwarf_diename() and tests for them. + +Version 0.1: + +First libdwarf functions work. + +Version 0.0: + +libelf and parts of libebl are done. diff --git a/NOTES b/NOTES new file mode 100644 index 00000000..deae6435 --- /dev/null +++ b/NOTES @@ -0,0 +1,95 @@ +Fundamental design decision: + +- the sizes of external and internal types are assumed to be the same. + This leaves byte ordering aside. While assuming this the code can be + greatly simplified and speed increases. Since no change violating this + assumption is in sight this is believed to be a worthwhile optimization. + +- the ABI of the backend modules is not guaranteed. Really, no guarantee + whatsoever. We are enforcing this in the code. The modules and their + users must match. No third-party EBL module are supported or allowed. + The only reason there are separate modules is to not have the code for + all architectures in all the binaries. + +- although the public libraries (libasm, libdw) have a stable API and are + backwards ABI compatible they, and the elfutils tools, do depend on each + others internals, and on internals of libelf to provide their interfaces. + So they should always be upgraded in lockstep when packaging the tools + and libraries separately. For one example of how to do that, see the + config/elfutils.spec. + +Some notes: + +- old GNU ld's behavior wrt DSOs seems to be severely broken. + + y.o reference foo() + y1.o defines foo(), references bar() + y2.o defines bar() + libbar.so defines bar() + + Running + + gcc -o y y.o -lbar y1.o y2.o + + uses the bar() definition from libbar.so and does not mention the definition + in y2.o at all (no duplicate symbol message). Correct is to use the + definition in y2.o. + + + y.o reference foo() + y1.o defines foo(), references bar() + y2.o in liby2.a defines bar() + libbar.so defines bar() + + Running + + gcc -o y y.o -lbar y1.o -ly3 + + has to use the definition in -lbar and not pull the definition from liby3.a. + + +- the old linker follows DT_NEEDED entries and adds the objects referenced + this way which define a symbol which is needed as a DT_NEEDED to the + generated binary. This is wrong since the DT_NEEDED changes the search + path in the object (which is breadth first). + + +- the old linker supported extern "C++", extern "java" in version scripts. + I believe this implementation is severely broken and needs a redesign + (how do wildcards work with these languages*?). Therefore it is left + out for now. + + +- what should happen if two sections in different files with the same + name have different types and/or the flags are different + + +- section names in input files are mostly irrelevant. Exceptions: + + .comment/SHT_PROGBITS in strip, ld + + .debug \ + .line | + .debug_srcinfo | + .debug_sfnames | + .debug_aranges | + .debug_pubnames | + .debug_info | + .debug_abbrev | + .debug_line | + .debug_abbrev > DWARF sections in ld + .debug_line | + .debug_frame | + .debug_str | + .debug_loc | + .debug_macinfo | + .debug_weaknames | + .debug_funcnames | + .debug_typenames | + .debug_varnames / + + Sections created in output files follow the naming of special section + from the gABI. + + In no place is a section solely identified by its name. Internal + references always use the section index. diff --git a/README b/README new file mode 100644 index 00000000..06a9fcd0 --- /dev/null +++ b/README @@ -0,0 +1,31 @@ +The elfutils project provides libraries and tools for ELF files and DWARF data. + +The project home is http://elfutils.org/ + +Releases are published at ftp://sourceware.org/pub/elfutils/ +Which can also be found at https://sourceware.org/elfutils/ftp/ + +To build a release do: ./configure && make && make check +Please check the configure summary to make sure all recommended +features are enabled. There should be no failures after make check. + +Please reports bugs at https://sourceware.org/bugzilla/ + +The current elfutils source code can be checked out with +git clone git://sourceware.org/git/elfutils.git + +To build a git checkout do: + autoreconf -i -f && \ + ./configure --enable-maintainer-mode && \ + make && make check + +The developer mailinglist to send patches to is +elfutils-devel@sourceware.org. +https://sourceware.org/ml/elfutils-devel/ + +To subscribe send an email to elfutils-devel-subscribe@sourceware.org +Or use the form at https://sourceware.org/mailman/listinfo/elfutils-devel + +See the CONTRIBUTING file for how to propose patches to the code. + +See the NOTES files for some design decisions and notes. diff --git a/README.en.md b/README.en.md deleted file mode 100644 index dd3c4c6f..00000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# third_party_elfutils - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 29a1acce..00000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# third_party_elfutils - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/THANKS b/THANKS new file mode 100644 index 00000000..887c067a --- /dev/null +++ b/THANKS @@ -0,0 +1,6 @@ +At least the following have submitted valuable patches: + +Jeff Johnson building. rpm wrestling +Alexander Larsson separate debug info +Jakub Jelinek bug fixes, testing +Denys Vlasenko bug fuxes diff --git a/TODO b/TODO new file mode 100644 index 00000000..5ed5e215 --- /dev/null +++ b/TODO @@ -0,0 +1,195 @@ + ToDo list for elfutils -*-outline-*- + ---------------------- + +Time-stamp: <2009-02-05 22:08:01 drepper> + +* mkinstalldirs + + Remove everywhere. Use mkdir -p. + +* libelf: + +** verify section + + Currently the elf_update function trusts the user blindly if the + ELF_F_LAYOUT flag is set. This is OK if the data is prepared by a + ELF_C_NULL call but not if the user prepared the data herself + +** break out archive handling from elf_begin + + The handling of archives (especially of the symbol tables) must be + broken out of elf_begin. There are several different forms of + archives and only when having the archive handling separately this + remains maintainable. + +** shdrs in read-only files + + When reading (ELF_C_READ*) then there is no need to malloc Shdr + structure in elfXX_getshdr if file is mmaped and unaligned access + is allowed or the structure is aligned. Use ELF_F_MALLOCED flag + to differentiate. + +** shdrs after elf_cntl (ELF_C_FDREAD) + + Similar to the above. After ELF_C_FDREAD the file is completely + in memory. See also this mailing list thread: + https://fedorahosted.org/pipermail/elfutils-devel/2012-July/002368.html + +* libdw + +** More memory access checks needed + + All accesses to the debug sections should make sure the offsets are + valid. This is currently especially a problem with leb128 accesses. + +** Low level macro information operations + + in 5.11.3 are not implemented. gcc currently does not emit this + information so I cannot test it. + +** Rename dwarf_getabbrev + + +* libcpu + +** x86 + +*** Opcodes + + crc32 + extractps + pextrb + pextrd/pextrq + pextrw + pinsrq + popcnt 64-bit reg + +* nm: + +** add demangler support + + Use demangler from libiberty. + +** add support to read debugging symbols + + Implement -l option for BSD and POSIX format + + +* strip: + +** support SHT_SYMTAB_SHNDX + + should be removed if not needed anymore + +* ld: + +** sanity check .rel sh_info content + + the sh_info of all .rel sections with the same name must point to + sections which also have the same name + +** use ld.so.conf + + to locate shared libraries also use /etc/ld.so.conf + +** handle object files for different architectures + + ld.so is expected to ignore object files for different architectures and + continue looking for a matching file (e.g., ignore 32-bit binaries on + 64-bit platforms and vice versa). We probably need the same in ld. + +** reuse after elf_end + + Some files are closed using elf_end. They are removed from memory only + if no reference is left (especially for archives this is a problem). + The old mapping should be reused in that case. The problem is worse + for files which are not mapped read-only (archives again). + +** size for STT_SECTION entries + + The STT_SECTION entries have zero for the size but can easily get + the size of the section. + +** .eh_frame_hdr + + Not implemented at all in the moment except for recognition of the option + itself. + +** variables with aliases in executables + + When linking an executable with a references against a variable in a + DSO, create symbol table entries for all the aliases of the variable + in the DSO and create a relocation for one of them (a non-weak + definition) + +* elflint + +** additional checks + + 1st GOT entry == _DYNAMIC + + check versioning info: + + always BASE in verdef + sh_size/sh_entsize matches last offset != 0 + + check whether any relocation is for a merge-able section + + check TLS relocation dependencies + + Check content of .eh_frame_hdr, .eh_frame, .gcc_except_table + +*** for x86 + + check that R_386_TLS_GD is followed by R_386_PLT32 for __tls_get_addr + +** relax + + prelink generated files + +* elfcmp + +** treat relocation sections special + + Differences in the relocation sections can be ignored if all + the same symbols with the same targets are present and the order + of overlapping relocations doesn't change. There really never + should be overlapping relocations but who knows. + +* mcs + + Sun has it. Can modify sections which are not in segments. + + -a string + Append string to the comment section of the ELF object + files. If string contains embedded blanks, it must be + enclosed in quotation marks. + + -c Compress the contents of the comment section of the + ELF object files. All duplicate entries are removed. + The ordering of the remaining entries is not dis- + turbed. + + -d Delete the contents of the comment section from the + ELF object files. The section header for the comment + section is also removed. + + -n name + Specify the name of the comment section to access if + other than .comment. By default, mcs deals with the + section named .comment. This option can be used to + specify another section. mcs can take multiple -n + options to allow for specification of multiple sec- + tion comments. + + -p Print the contents of the comment section on the stan- + dard output. Each section printed is tagged by the + name of the file from which it was extracted, using + the format file[member_name]: for archive files and + file: for other files. + + -V Print on standard error the version number of mcs. + +Local Variables: +eval:(hide-sublevels 3) +End: diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 00000000..ebe2c9da --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1535 @@ +# generated automatically by aclocal 1.16.3 -*- Autoconf -*- + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +# Copyright (C) 2002-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# Copyright (C) 2011-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Copyright (C) 1998-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_LEX +# ----------- +# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a +# "missing" invocation, for better error output. +AC_DEFUN([AM_PROG_LEX], +[AC_PREREQ([2.50])dnl +AC_REQUIRE([AM_MISSING_HAS_RUN])dnl +AC_REQUIRE([AC_PROG_LEX])dnl +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_cxx_compile_stdcxx.m4]) +m4_include([m4/biarch.m4]) +m4_include([m4/gettext.m4]) +m4_include([m4/host-cpu-c-abi.m4]) +m4_include([m4/iconv.m4]) +m4_include([m4/intlmacosx.m4]) +m4_include([m4/lib-ld.m4]) +m4_include([m4/lib-link.m4]) +m4_include([m4/lib-prefix.m4]) +m4_include([m4/nls.m4]) +m4_include([m4/po.m4]) +m4_include([m4/progtest.m4]) +m4_include([m4/zip.m4]) diff --git a/backends/ChangeLog b/backends/ChangeLog new file mode 100644 index 00000000..ac0e3187 --- /dev/null +++ b/backends/ChangeLog @@ -0,0 +1,1369 @@ +2021-04-19 Martin Liska + + * aarch64_symbol.c (aarch64_data_marker_symbol): Use startswith. + * arm_symbol.c (arm_data_marker_symbol): Likewise. + +2021-02-01 Érico Nogueira + + * ppc_initreg.c: Also include . + +2020-12-12 Dmitry V. Levin + + * aarch64_retval.c (aarch64_return_value_location): Fix spelling typo + in comment. + * ppc_cfi.c (ppc_abi_cfi): Likewise. + +2020-11-17 Mark Wielard + + * x86_64_symbol.c (x86_64_check_reloc_target_type): New function. + * x86_64_init.c (x86_64_init): Hook check_reloc_target_type. + +2020-10-19 Mark Wielard + + * Makefile.am (modules): Remove tilegx. + (tilegx_SRCS): Removed. + (libebl_backends_a_SOURCES): Remove tilegx_SRCS. + * tilegx_corenote.c: Removed. + * tilegx_init.c: Removed. + * tilegx_regs.c: Removed. + * tilegx_reloc.def: Removed. + * tilegx_retval.c: Removed. + * tilegx_symbol.c: Removed. + +2020-10-19 Mark Wielard + + * Makefile.am (i386_SRCS): Remove i386_syscall.c. + (x86_64_SRCS): Remove x86_64_syscall.c. + (ppc_SRCS): Remove ppc_syscall.c. + * i386_init.c (i386_init): Remove syscall_abi HOOK. + * i386_syscall.c: Delete. + * ppc64_init.c (ppc64_init): Remove syscall_abi HOOK. + * ppc_syscall.c: Delete. + * x86_64_init.c (x86_64_init): Remove syscall_abi HOOK. + * x86_64_syscall.c: Delete. + +2020-08-28 Mark Wielard + + * aarch64_init.c (aarch64_init): Hook dynamic_tag_name and + dynamic_tag_check. + * aarch64_symbol.c (aarch64_dynamic_tag_name): New function. + (aarch64_dynamic_tag_check): Likewise. + +2020-06-16 Mark Wielard + + * common-reloc.c (reloc_nametable): Make zero a 1 char array. + Initialize it as an array { '\0' }. + (reloc_type_name): Access zero as an array. + +2020-06-10 Mark Wielard + + * aarch64_init.c (aarch64_init): Remove ehlen, return eh. + * alpha_init.c (alpha_init): Likewise. + * arm_init.c (arm_init): Likewise. + * bpf_init.c (bpf_init): Likewise. + * csky_init.c (csky_init): Likewise. + * i386_init.c (i386_init): Likewise. + * ia64_init.c (ia64_init): Likewise. + * m68k_init.c (m68k_init): Likewise. + * ppc64_init.c (ppc64_init): Likewise. + * ppc_init.c (ppc_init): Likewise. + * riscv_init.c (riscv_init): Likewise. + * s390_init.c (s390_init): Likewise. + * sh_init.c (sh_init): Likewise. + * sparc_init.c (sparc_init): Likewise. + * tilegx_init.c (tilegx_init): Likewise. + * x86_64_init.c (x86_64_init): Likewise. + * libebl_CPU.h (init): Adjust EBLHOOK signature. + +2019-07-05 Omar Sandoval + + * Makefile.am: Replace libcpu_{i386,x86_64,bpf}.a with libcpu.a. + Replace libcpu.a with libcpu_pic.a. + Combine libebl_CPU.so modules into libebl_backends{,_pic}.a. + +2019-07-13 Mao Han + + * Makefile.am: Add C-SKY. + * csky_attrs.c: New file. + * csky_cfi.c: New file. + * csky_corenote.c: Likewise. + * csky_init.c: Likewise. + * csky_initreg.c: Likewise. + * csky_regs.c: Likewise. + * csky_reloc.def: Likewise. + * csky_symbol.c: Likewise. + +2019-06-28 Mark Wielaard + + * aarch64_init.c (aarch64_init.c): Remove eh->name; + * alpha_init.c (alpha_init.c): Remove eh->name; + * arm_init.c (arm_init.c): Remove eh->name; + * bpf_init.c (bpf_init.c): Remove eh->name; + * i386_init.c (i386_init.c): Remove eh->name; + * ia64_init.c (ia64_init.c): Remove eh->name; + * m68k_init.c (m68k_init.c): Remove eh->name; + * ppc64_init.c (ppc64_init.c): Remove eh->name; + * ppc_init.c (ppc_init.c): Remove eh->name; + * riscv_init.c (riscv_init.c): Remove eh->name; + * s390_init.c (s390_init.c): Remove eh->name; + * sh_init.c (sh_init.c): Remove eh->name; + * sparc_init.c (sparc_init.c): Remove eh->name; + * tilegx_init.c (tilegx_init.c): Remove eh->name; + * x86_64_init.c (x86_64_init.c): Remove eh->name; + +2019-04-14 Mark Wielaard + + * riscv_cfi.c: Fix BACKEND define. + +2019-02-15 Mark Wielaard + + * s390_init.c (s390_init): Hook check_special_symbol. + * s390_symbol.c (s390_check_sepcial_symbol): New function. + +2018-12-27 Jim Wilson + + * Makefile.am (riscv_SRCS): Add riscv64_corenote.c. + * riscv64_corenote.c: New file. + * riscv_corenote.c (BITS): New. + (BACKEND): Conditional on BITS. + (ULONG, UID_T, GID_T, ALIGN_ULONG, ALIGN_UID_T, ALIGN_GID_T): Likewise. + (TYPE_ULONG, TYPE_UID_T, TYPE_GID_T): Likewise. + (prstatus_regs): Use BITS/8 instead of 8. + (PRSTATUS_REGS_SIZE): Likewise. + * riscv_init.c (riscv64_core_note): Declare. + (riscv_init): If ELFCLASS64 then use riscv64_core_note hook. + + * Makefile.am (riscv_SRCS): Add riscv_retval.c. + * riscv_init.c: Include libelfP.h. + (riscv_return_value_location_lp64d): Declare. + (riscv_init): Delete unused attribute from elf parameter. Register + riscv_return_value_location_lp64d hook if 64-bit ELF and 64-bit FP + registers. + * riscv_retval.c: New file. + + * riscv_corenote.c (prstatus_regs): Change offset from 1 to 8. + (PRSTATUS_REGSET_ITEMS): New. + +2018-11-06 Mark Wielaard + + * x86_64_symbol.c (x86_64_section_type_name): New function. + * x86_64_init.c (x86_64_int): Hook section_type_name. + +2018-10-20 Mark Wielaard + + * ppc_initreg.c (ppc_set_initial_registers_tid): Use define instead of + const for size of dwarf_regs array. + +2018-10-02 Andreas Schwab + + * riscv_symbol.c (riscv_reloc_simple_type): Add parameter addsub. + Set it for ADD and SUB relocations. + * aarch64_symbol.c (aarch64_reloc_simple_type): Add and ignore + third parameter. + * alpha_symbol.c (alpha_reloc_simple_type): Likewise. + * arm_symbol.c (arm_reloc_simple_type): Likewise. + * bpf_symbol.c (bpf_reloc_simple_type): Likewise. + * i386_symbol.c (i386_reloc_simple_type): Likewise. + * ia64_symbol.c (ia64_reloc_simple_type): Likewise. + * m68k_symbol.c (m68k_reloc_simple_type): Likewise. + * ppc64_symbol.c (ppc64_reloc_simple_type): Likewise. + * ppc_symbol.c (ppc_reloc_simple_type): Likewise. + * s390_symbol.c (s390_reloc_simple_type): Likewise. + * sh_symbol.c (sh_reloc_simple_type): Likewise. + * sparc_symbol.c (sparc_reloc_simple_type): Likewise. + * tilegx_symbol.c (tilegx_reloc_simple_type): Likewise. + * x86_64_symbol.c (x86_64_reloc_simple_type): Likewise. + +2018-09-12 Mark Wielaard + + * ppc64_init.c (ppc64_init): Use elf_getshdrstrndx. + +2018-09-12 Mark Wielaard + + * aarch64_symbol.c (aarch64_check_special_symbol): Drop ehdr argument, + use elf_getshdrstrndx. + * alpha_symbol.c (alpha_check_special_symbol): Drop ehdr argument. + * ppc64_symbol.c (ppc64_check_special_symbol): Likewise and use + elf_getshdrstrndx. + * ppc_symbol.c (ppc_check_special_symbol): Likewise. + * riscv_symbol.c (riscv_check_special_symbol): Likewise. + +2018-07-21 Andreas Schwab + + * Makefile.am (m68k_SRCS): Add m68k_cfi.c and m68k_initreg.c. + * m68k_cfi.c: New file. + * m68k_initreg.c: New file. + * m68k_init.c (m68k_init): Hook abi_cfi and + set_initial_registers_tid. + +2018-07-19 Andreas Schwab + + * riscv_regs.c (riscv_register_info): Fix typo. + +2018-07-17 Andreas Schwab + + * Makefile.am (riscv_SRCS): Add riscv_corenote.c. + * riscv_corenote.c: New file. + * riscv_init.c (riscv_init): Hook core_note. + +2018-07-11 Andreas Schwab + + * Makefile.am (riscv_SRCS): Add riscv_initreg.c. + * riscv_initreg.c: New file. + * riscv_init.c (riscv_init): Hook set_initial_registers_tid. + +2018-06-16 Yonghong Song + + * Makefile.am (bpf_SRCS): Add bpf_symbol.c. + * bpf_init.c (bpf_init): Add reloc_simple_type HOOK. + * bpf_reloc.def: Add RELOC_TYPE 64_64 and 64_32. + * bpf_symbol.c: New file. + +2018-06-21 Mark Wielaard + + * bpf_reloc.def: Remove MAP_FD. + +2018-06-13 Andreas Schwab + + * Makefile.am (riscv_SRCS): Add riscv_cfi.c and riscv_regs.c. + * riscv_cfi.c: New file. + * riscv_regs.c: Likewise. + * riscv_init.c (riscv_init): Hook register_info and abi_cfi. + +2018-05-15 Andreas Schwab + + * riscv_init.c (riscv_init): Hook check_special_symbol. + * riscv_symbol.c (riscv_check_special_symbol): New function. + +2018-04-19 Andreas Schwab + + * Makefile.am (modules): Add riscv. + * riscv_init.c: New file. + * riscv_reloc.def: New file. + * riscv_symbol.c: New file. + +2018-04-11 Mark Wielaard + + * aarch64_cfi.c (aarch64_abi_cfi): Add rule for restoring SP from + CFA address. + +2018-02-15 Mark Wielaard + + * ppc_initreg.c: Include ptrace.h before system.h and sys/user.h. + +2018-02-09 Joshua Watt + + * aarch64_retval.c (aarch64_return_value_location): Use FALLTHROUGH + macro instead of comment. + * alpha_retval.c (alpha_return_value_location): Likewise. + * arm_regs.c (arm_register_info): Likewise. + * arm_retval.c (arm_return_value_location): Likewise. + * i386_regs.c (i386_register_info): Likewise. + * i386_retval.c (i386_return_value_location): Likewise. + * ia64_retval.c (ia64_return_value_location): Likewise. + * linux-core-note.c (core_note): Likewise. + * m68k_retval.c (m68k_return_value_location): Likewise. + * ppc64_retval.c (ppc64_return_value_location): Likewise. + * ppc_regs.c (ppc_register_info): Likewise. + * ppc_retval.c (ppc_return_value_location): Likewise. + * s390_retval.c (s390_return_value_location): Likewise. + * sh_retval.c (sh_return_value_location): Likewise. + * sparc_retval.c (sparc_return_value_location): Likewise. + * tilegx_retval.c (tilegx_return_value_location): Likewise. + * x86_64_regs.c (x86_64_register_info): Likewise. + * x86_64_retval.c (x86_64_return_value_location): Likewise. + +2017-10-24 Mark Wielaard + + * Makefile.am (m68k_corenote_no_Wpacked_not_aligned): New variable. + +2017-08-18 Ulf Hermann + + * linux-core-note.c: Use attribute_packed. + +2017-04-27 Ulf Hermann + + * Makefile.am: Use dso_LDFLAGS. + +2017-07-27 Mark Wielaard + + * sparc_reloc.def: GOTDATA_OP_HIX22, GOTDATA_OP_LOX10 and + GOTDATA_OP can be used in ET_REL files. + +2017-07-19 Gustavo Romero + + * ppc_corenote.c: Add offsets for ppc64 HTM SPRs: thfar, tfiar, + and texasr. + * ppc_regs.c: Add names for ppc64 HTM SPRs mappings. + +2017-07-20 Mark Wielaard + + * aarch64_init.c (aarch64_init): Hook data_marker_symbol. + * aarch64_symbol.c (aarch64_data_marker_symbol): New function. + * arm_init.c (arm_init): Hook data_marker_symbol. + * arm_symbol.c (aarch64_data_marker_symbol): New function. + +2017-07-18 Mark Wielaard + + * Makefile.am (cpu_bpf): Always define. + * bpf_init.c (disasm): Always hook. + * bpf_regs.c: Include bpf.h instead of linux/bpf.h. Don't define + MAX_BPF_REG. + +2017-02-17 Ulf Hermann + + * Makefile.am: Add libeu. + (libebl_%so): Link with --no-undefined,-z,defs,-z,relro + and libeu.a. + +2017-06-17 Mark Wielaard + + * s390_initreg.c: Swap sys/ptrace.h and asm/ptrace.h include order. + +2017-06-15 Andreas Schwab + + * ppc_symbol.c (ppc_machine_flag_check): New function. + * ppc_init.c (ppc_init): Hook it. + +2017-05-30 Mark Wielaard + + * ppc64_unwind.c: New file. + * ppc64_init.c (pcc64_init): Hook unwind. + * Makefile.am (ppc64_SRCS): Add ppc64_unwind.c + +2017-04-06 Mark Wielaard + + * i386_unwind.c: New file. + * i386_init.c: Hook i386_unwind. + * Makefile.am (i386_SRCS): Add i386_unwind.c + +2017-02-09 Ulf Hermann + + * aarch64_unwind.c: New file + * Makefile.am (aarch64_SRCS): Add aarch64_unwind.c + * aarch64_init.c (aarch64_init): Hook aarch64_unwind + +2017-02-09 Ulf Hermann + + * x86_64_unwind.c: New file + * Makefile.am (x86_64_SRCS): Add x86_64_unwind.c + * x86_64_init.c (x86_64_init): Hook x86_64_unwind + +2017-04-20 Ulf Hermann + + * aarch64_initreg.c: Compile register initialization only on linux. + * arm_initreg.c: Likewise. + * ppc_initreg.c: Likewise. + * s390_initreg.c: Likewise. + * x86_64_initreg.c: Likewise. + +2017-02-15 Mark Wielaard + + * ppc64_init.c (ppc64_init): Add check_object_attribute HOOK. + * ppc_attrs.c (ppc_check_object_attribute): Add Single-precision hard + float. + +2016-11-02 Mark Wielaard + + * i386_regs.c (i386_register_info): Add fallthrough comment. + * i386_retval.c (i386_return_value_location): Move fallthrough + comment. + * linux-core-note.c (core_note): Adjust fallthrough comment. + * m68k_retval.c (m68k_return_value_location): Move fallthrough + comment. + * ppc_regs.c (ppc_register_info): Add fallthrough comment. + * x86_64_regs.c (x86_64_register_info): Likewise. + +2016-08-09 Jose E. Marchesi + + * sparc_attrs.c (sparc_check_object_attribute): Fix the + calculation of GNU_SParc_HWCAPS and GNU_SParc_HWCAPS2 values as + comma-separated list of hw capability names. + +2016-07-10 Andreas Schwab + + * m68k_corenote.c (ALIGN_PRSTATUS): Define. + * linux-core-note.c (struct EBLHOOK(prstatus)): Set alignment to + ALIGN_PRSTATUS if defined. + +2016-06-28 Richard Henderson + + * Makefile.am (modules): Add bpf. + (libebl_pic): Add libebl_bpf_pic.a. + (am_libebl_bpf_pic_a_OBJECTS): New. + * bpf_init.c, bpf_regs.c, bpf_reloc.def: New files. + * common-reloc.c (copy_reloc_p): Honor NO_COPY_RELOC. + (init_reloc): Likewise. + +2016-05-20 Andreas Schwab + + * Makefile.am (modules): Add m68k. + (libebl_pic): Add libebl_m68k_pic.a. + (m68k_SRCS, libebl_m68k_pic_a_SOURCES) + (am_libebl_m68k_pic_a_OBJECTS): Define. + * m68k_init.c: New file. + * m68k_symbol.c: New file. + * m68k_regs.c: New file. + * m68k_retval.c: New file. + * m68k_corenote.c: New file. + * m68k_reloc.def: New file. + * linux-core-note.c (ALIGN_INT): Only define if not defined. + +2016-02-26 Jose E. Marchesi + + * sparc_initreg.c (EBLHOOK): Provide a dummy + sparc_set_initial_registers_tid for sparc32. This fixes the build + in sparcv9-*-* targets. + +2016-02-26 Andreas Schwab + + * ppc_symbol.c (ppc_dynamic_tag_name): Add DT_PPC_OPT. + (ppc_dynamic_tag_check): Likewise. + +2015-12-28 Mark Wielaard + + * i386_reloc.def: Add GOT32X. + * x86_64_reloc.def: Add GOTPCRELX and REX_GOTPCRELX. + +2016-02-12 Mark Wielaard + + * aarch64_corenote.c (aarch64_syscall_items): New Ebl_Core_Item[]. + (EXTRA_NOTES): Add NT_ARM_SYSTEM_CALL. + * eblcorenotetypename.c (ebl_core_note_type_name): + Add ARM_SYSTEM_CALL. + +2015-12-08 Jose E. Marchesi + + * sparc_init.c (sparc_init): Hook sparc_set_initial_registers_tid. + * sparc_initreg.c: New file. + * Makefile.am (sparc_SRCS): Added sparc_initreg.c. + +2015-12-08 Jose E. Marchesi + + * sparc_corenote.c: Header comment typo fixed. + (PRSTATUS_REGSET_ITEMS): Defined, so the PC can be fetched from + core files. + * Makefile.am (sparc_SRCS): Added sparc_cfi.c + * sparc_cfi.c: New file. + * sparc_init.c (sparc_init): Set eh->frame_nregs, eh->ra_offset + and hook sparc_abi_cfi. + +2015-10-21 Chih-Hung Hsieh + + * ia64_retval.c (hfa_type): Move nested function 'hfa' to file scope. + * aarch64_regs.c (aarch64_register_info): Move nested function 'regtype' + to file scope. + +2015-10-16 Mark Wielaard + + * ppc_symbol.c (ppc_check_special_symbol): Also allow _SDA_BASE_ + in .data section. + +2015-10-05 Josh Stone + + * Makefile.am (libebl_%.so): Add AM_V_at and AM_V_CCLD silencers. + +2015-10-06 Jose E. Marchesi + + * sparc_attrs.c: New file. + * Makefile.am (sparc_SRCS): Added sparc_attrs.c + * sparc_init.c (sparc_init): Hook sparc_check_object_attribute. + +2015-10-02 Jose E. Marchesi + + * sparc_init.c (RELOC_TYPE_ID): Defined. + * common-reloc.c (reloc_type_name): Apply target-specific + relocation ID extractors if defined. + (reloc_type_check): Likewise. + (reloc_valid_use): Likewise. + +2015-10-02 Jose E. Marchesi + + * sparc_reloc.def: Added relocation types WDISP10, JMP_IREL and + IRELATIVE. + +2015-09-22 Mark Wielaard + + * arm_attrs.c: Remove old-style function definitions. + * linux-core-note.c: Likewise. + * ppc_attrs.c: Likewise. + +2015-09-04 Chih-Hung Hsieh + + * aarch64_init.c (aarch64_init): Replace K&R function definition + with ansi-C definitions. + * alpha_init.c (alpha_init): Likewise. + * arm_init.c (arm_init): Likewise. + * i386_init.c (i386_init): Likewise. + * ia64_init.c (ia64_init): Likewise. + * ppc64_init.c (ppc64_init): Likewise. + * ppc_init.c (ppc_init): Likewise. + * s390_init.c (s390_init): Likewise. + * sh_init.c (sh_init): Likewise. + * sparc_init.c (sparc_init): Likewise. + * tilegx_init.c (tilegx_init): Likewise. + * x86_64_init.c (x86_64_init): Likewise. + +2015-09-03 Mark Wielaard + + * sparc_regs.c (sparc_register_info): Use ebl->class not ebl->machine. + +2015-06-26 Pino Toscano + + * i386_initreg.c: Reduce scope of some includes to match their usage. + +2015-04-28 Mark Wielaard + + * aarch64_reloc.def: Drop "64" from TLS_DTPMOD64, TLS_DTPREL64 and + TLS_TPREL64. + +2015-04-01 H.J. Lu + + * Makefile.am (x86_64_SRCS): Add x32_corenote.c. + * linux-core-note.c (PR_REG): New. + (PRPSINFO_UID_T): Likewise. + (ALIGN_PRPSINFO_UID_T): Likewise. + (TYPE_PRPSINFO_UID_T): Likewise. + (PRPSINFO_GID_T): Likewise. + (ALIGN_PRPSINFO_GID_T): Likewise. + (TYPE_PRPSINFO_GID_T): Likewise. + (pr_reg): Replace ULONG with PR_REG. + (pr_uid): Replace UID_T with PRPSINFO_UID_T. + (uid): Likewise. + (pr_gid): Replace GID_T with PRPSINFO_GID_T. + (gid): Likewise. + * x32_corenote.c: New file. + * x86_64_corenote.c (BITS): New. Support x32. + (BACKEND): Support x32. + (ULONG): Likewise. + (ALIGN_ULONG): Likewise. + (TYPE_ULONG): Likewise. + (PRPSINFO_UID_T): New. + (ALIGN_PRPSINFO_UID_T): Likewise. + (TYPE_PRPSINFO_UID_T): Likewise. + (PRPSINFO_GID_T): Likewise. + (ALIGN_PRPSINFO_GID_T): Likewise. + (TYPE_PRPSINFO_GID_T): Likewise. + (PR_REG): Likewise. + (ALIGN_PR_REG): Likewise. + * x86_64_init.c (x32_core_note): New. + (x86_64_init): Set eh->core_note to x32_core_note for x32. + +2015-03-23 Mark Wielaard + + * aarch64_symbol.c (aarch64_check_special_symbol): Accept + _GLOBAL_OFFSET_TABLE_ pointing anywhere in .got. + +2015-03-09 Mark Wielaard + + * aarch64_reloc.def (COPY): Add DYN. + * arm_reloc.def (COPY): Likewise. + * i386_reloc.def (COPY): Likewise. + * ia64_reloc.def (COPY): Likewise. + * ppc64_reloc.def (COPY): Likewise. + * ppc_reloc.def (COPY): Likewise. + * s390_reloc.def (COPY): Likewise. + * sh_reloc.def (COPY): Likewise. + * sparc_reloc.def (COPY): Likewise. + * tilegx_reloc.def (COPY): Likewise. + * x86_64_reloc.def (COPY): Likewise. + +2015-02-23 Petr Machata + + * arm_symbol.c (arm_symbol_type_name): New function. + * arm_init.c (arm_init): Initialize the hook. + +2014-12-30 Mark Wielaard + + * ppc_symbol.c (find_dyn_got): Check sh_entsize is not zero. + +2014-12-18 Ulrich Drepper + + * Makefile.am: Suppress output of textrel_check command. + +2014-11-22 Mark Wielaard + + * ppc64_symbol.c (ppc64_bss_plt_p): Remove ehdr argument. + * ppc_symbol.c (find_dyn_got): Likewise. Use elf_getphdrnum. + (ppc_check_special_symbol): Call find_dyn_got without ehdr. + (ppc_bss_plt_p): Remove ehdr argument. + +2014-11-17 Mark Wielaard + + * ppc64_init.c (ppc64_init): Check section name is not NULL. + +2014-10-06 Mark Wielaard + + * libebl_CPU.h (dwarf_peel_type): Removed. + (dwarf_peeled_die_type): Use libdw dwarf_peel_type. + +2014-07-18 Kyle McMartin + Mark Wielaard + + * aarch64_initreg.c: Check HAVE_SYS_USER_REGS. + (aarch64_set_initial_registers_tid): Use user_regs_struct and + user_fpsimd_struct. + * arm_initreg.c: Check HAVE_SYS_USER_REGS. + (arm_set_initial_registers_tid): Use user_regs_struct in compat mode. + +2014-07-04 Menanteau Guy + Mark Wielaard + + * ppc64_init.c (ppc64_init): Hook check_st_other_bits. + * ppc64_reloc.def: TLSGD, TLSLD, TOCSAVE, ADDR16_HIGH, ADDR16_HIGHA, + TPREL16_HIGH, TPREL16_HIGHA, DTPREL16_HIGH, DTPREL16_HIGHA, JMP_IREL, + IRELATIVE, REL16, REL16_LO, REL16_HI and REL16_HA. + * ppc64_symbol.c (ppc64_dynamic_tag_name): Recognize DT_PPC64_OPT. + (ppc64_dynamic_tag_check): Likewise. + (ppc64_check_st_other_bits): New function. + +2014-07-04 Mark Wielaard + + * aarch64_retval.c (aarch64_return_value_location): Handle + DW_ATE_boolean. + +2014-06-18 Mark Wielaard + + * libebl_CPU.h (dwarf_peel_type): Remove DW_TAG_mutable_type + handling. + +2014-06-17 Mark Wielaard + + * arm_init.c (arm_init): Set func_addr_mask. + +2014-06-20 Petr Machata + + * alpha_retval.c (alpha_return_value_location): Call + dwarf_peeled_die_type instead of inlining equivalent code. + * arm_retval.c (arm_return_value_location): Likewise. + * i386_retval.c (i386_return_value_location): Likewise. + * ia64_retval.c (ia64_return_value_location): Likewise. + * ppc64_retval.c (ppc64_return_value_location): Likewise. + * ppc_retval.c (ppc_return_value_location): Likewise. + * s390_retval.c (s390_return_value_location): Likewise. + * sh_retval.c (sh_return_value_location): Likewise. + * sparc_retval.c (sparc_return_value_location): Likewise. + * tilegx_retval.c (tilegx_return_value_location): Likewise. + * x86_64_retval.c (x86_64_return_value_location): Likewise. + +2014-05-19 Mark Wielaard + + * arm_init.c (arm_init): Hook check_reloc_target_type. + * arm_symbol.c (arm_check_reloc_target_type): New function. + * ia64_init.c (ia64_init): Hook check_reloc_target_type. + * ia64_symbol.c (ia64_check_reloc_target_type): New function. + +2014-04-22 Kurt Roeckx + + * i386_initreg.c: Make Linux only. + * x86_64_initreg.c: Make Linux only. + +2014-04-13 Mark Wielaard + + * Makefile.am: Remove libelf and libdw definitions when MUDFLAP + is defined. Remove libmudflap from LINK line. + +2014-04-09 Mark Wielaard + + * Makefile.am (aarch64_SRCS): Add aarch64_initreg.c. + * aarch64_corenote.c (prstatus_regs): Mark pc_register. + * aarch64_init.c: Assign frame_nregs. Hook set_initial_registers_tid. + * aarch64_initreg: New file. + +2014-03-28 Jean Pihet + + * arm_initreg.c (arm_set_initial_registers_tid): Handle compat mode. + ARM compatible code running on AARCH64. + +2014-03-19 Mark Wielaard + + * aarch64_reloc.def: AARCH64_ABS32 and AARCH64_ABS64 are also valid + in ET_REL. + +2014-01-30 Petr Machata + + * aarch64_regs.c (aarch64_register_info.regtype): Make this + variadic printf-like function. Call one vsnprintf instead of two + snprintf's. + (regtyper, regtypen): Drop. + (aarch64_register_info): Adjust callers. + +2014-01-26 Mark Wielaard + + * Makefile.am (arm_SRCS): Add arm_initreg.c. + * arm_init.c (arm_init): Define frame_nregs and hook + set_initial_registers_tid. + * arm_initreg.c: New file. + +2014-01-25 Mark Wielaard + + * arm_cfi.c (arm_abi_cfi): Restore SP (r13) from CFA. + +2014-01-24 Mark Wielaard + + * arm_reloc.def: Update list. + +2014-01-22 Mark Wielaard + + * Makefile.am (aarch64_regs_no_Wformat): Removed. + * aarch64_regs.c (regtype): Add bool nr argument. snprintf arg + when nr is true. + (regtyper): New function. + (regtypen): Likewise. + (aarch64_register_info): Call either regtyper or regtypen not + regtype directly. + +2014-01-14 Mark Wielaard + + * aarch64_symbol.c (aarch64_check_special_symbol): Check shdr is + not NULL before usage. + +2014-01-04 Mark Wielaard + + * ppc64_symbol.c (ppc64_machine_flag_check): New function. + * ppc64_init.c (ppc64_init): Hook machine_flag_check. + +2014-01-03 Mark Wielaard + + * Makefile.am (aarch64_SRCS): Add aarch64_cfi.c. + * aarch64_cfi.c: New file. + * aarch64_init.c (aarch64_init): Hook abi_cfi. + * aarch64_regs.c (aarch64_register_info): Set *prefix to "". + +2013-12-19 Mark Wielaard + + * aarch64_init.c (aarch64_init): Hook check_special_symbol. + * aarch64_symbol.c (aarch64_check_special_symbol): New function. + +2013-12-18 Mark Wielaard + + * Makefile.am (ppc64_SRCS): Add ppc64_resolve_sym.c. + * ppc64_resolve_sym.c: New file. + * ppc64_init.c: Hook resolve_sym_value and find function descriptor + table. + +2013-12-18 Mark Wielaard + + * s390_initreg.c (s390_set_initial_registers_tid): Use union + to avoid type-punning when assigning a double to a Dwarf_Word. + +2013-12-18 Jan Kratochvil + + unwinder: s390 and s390x + * Makefile.am (s390_SRCS): Add s390_initreg.c and s390_unwind.c. + * s390_corenote.c (prstatus_regs): Set PC_REGISTER. Reindent all the + entries. + * s390_init.c (s390_init): Initialize frame_nregs, + set_initial_registers_tid, normalize_pc and unwind. + * s390_initreg.c: New file. + * s390_unwind.c: New file. + +2013-12-15 Jan Kratochvil + + unwinder: ppc and ppc64 + * Makefile.am (ppc_SRCS, ppc64_SRCS): Add ppc_initreg.c. + * ppc64_init.c (ppc64_init): Initialize also frame_nregs, + set_initial_registers_tid and dwarf_to_regno. + * ppc_corenote.c (PRSTATUS_REGSET_ITEMS) : Set PC_REGISTER. + * ppc_init.c (ppc64_init): Initialize also frame_nregs, + set_initial_registers_tid and dwarf_to_regno. + * ppc_initreg.c: New file. + +2013-11-25 Petr Machata + + * Makefile.am (modules): Add aarch64. + (libebl_pic): Add libebl_aarch64_pic.a. + (aarch64_SRCS): New variable. + (libebl_aarch64_pic_a_SOURCES): Likewise. + (am_libebl_aarch64_pic_a_OBJECTS): Likewise. + (aarch64_regs_no_Wformat): Likewise. + * aarch64_corenote.c, aarch64_init.c: New files. + * aarch64_regs.c, aarch64_reloc.def: Likewise. + * aarch64_retval.c, aarch64_symbol.c: Likewise. + * libebl_CPU.h (dwarf_peel_type): New function. + (dwarf_peeled_die_type): Likewise. + +2013-11-07 Jan Kratochvil + Mark Wielaard + + * Makefile.am (i386_SRCS): Add i386_initreg.c. + (x86_64_SRCS): Add x86_64_initreg.c. + * i386_initreg.c: New file. + * i386_init.c (i386_init): Initialize frame_nregs and + set_initial_registers_tid. + * x86_64_initreg.c: New file. + * x86_64_init.c (x86_64_init): Initialize frame_nregs and + set_initial_registers_tid. + +2013-10-06 Mark Wielaard + + * ppc_cfi.c (ppc_abi_cfi): Use DW_CFA_val_offset for reg1, not + DW_CFA_val_expression. + +2013-08-29 Mark Wielaard + + * Makefile.am (arm_SRCS): Add arm_cfi.c. + * arm_cfi.c: New file. + * arm_init.c (arm_init): Initialize abi_cfi. + +2013-08-27 Jan Kratochvil + + * Makefile.am (ppc_SRCS, ppc64_SRCS): Add ppc_cfi.c. + (s390_SRCS): Add s390_cfi.c. + * ppc64_init.c (ppc64_init): Initialize abi_cfi. + * ppc_cfi.c: New file. + * ppc_init.c (ppc_init): Initialize abi_cfi. + * s390_cfi.c: New file. + * s390_init.c (s390_init): Initialize abi_cfi. + +2013-08-28 Mark Wielaard + + * arm_regs.c (arm_register_info): Set *prefix to "". + * ppc_regs.c (ppc_register_info): Likewise. + * sh_regs.c (sh_register_info): Likewise. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2013-02-06 Mark Wielaard + + * libebl_CPU.h (DWARF_TAG_OR_RETURN): New macro. + * backends/alpha_retval.c (alpha_return_value_location): Use new + DWARF_TAG_OR_RETURN macro instead of dwarf_tag (). + * backends/arm_retval.c (arm_return_value_location): Likewise. + * backends/i386_retval.c (i386_return_value_location): Likewise. + * backends/ia64_retval.c (hfa_type): Likewise. + (ia64_return_value_location): Likewise. + * backends/ppc64_retval.c (ppc64_return_value_location): Likewise. + * backends/ppc_retval.c (ppc_return_value_location): Likewise. + * backends/s390_retval.c (s390_return_value_location): Likewise. + * backends/sh_retval.c (sh_return_value_location): Likewise. + * backends/sparc_retval.c (sparc_return_value_location): Likewise. + * backends/tilegx_retval.c (tilegx_return_value_location): Likewise. + * backends/x86_64_retval.c (x86_64_return_value_location): Likewise. + +2013-01-29 Jan Kratochvil + Roland McGrath + + * Makefile.am (s390_SRCS): Add s390_corenote.c and s390x_corenote.c. + * linux-core-note.c (ALIGN_PR_REG): New definitions. + (struct EBLHOOK(prstatus)): Change field pr_reg to anonymous struct with + ALIGN_PR_REG. + (EXTRA_ITEMS): New macro. + * s390_corenote.c: New file. + * s390_init.c (s390x_core_note): New declaration. + (s390_init): Install s390x_core_note and s390_core_note. + * s390x_corenote.c: New file. + +2013-01-30 Jan Kratochvil + + * arm_corenote.c (vfp_items): Remove zero COUNT initializer. + +2012-10-12 Jan Kratochvil + + * linux-core-note.c (prstatus_items): Rename groups of sigpend and + sighold to signal2 and signal3. + +2012-09-24 Petr Machata + + * arm_corenote.c (vfp_items, vfp_regs): New const variables. + (EXTRA_NOTES): Use it for NT_ARM_VFP. + * linux-core-note.c (EXTRA_REGSET_ITEMS): New macro. + +2012-09-17 Petr Machata + + * arm_corenote.c (FPREGSET_SIZE): Change to 116. + +2012-08-22 Jeff Kenton + + * Makefile.am (modules): Add tilegx. + (libebl_pic): Add libebl_tilegx_pic.a. + (tilegx_SRCS): New variable. + (libebl_tilegx_pic_a_SOURCES): Likewise. + (am_libebl_tilegx_pic_a_OBJECTS): Likewise. + * tilegx_corenote.c: New file. + * tilegx_regs.c: New file. + * tilegx_reloc.def: New file. + * tilegx_init.c: New file. + * tilegx_retval.c: New file. + * tilegx_symbol.c: New file. + +2011-03-09 Mark Wielaard + + * alpha_init.c (alpha_init): Initialize check_st_other_bits hook. + * alpha_symbol.c (alpha_check_st_other_bits): New function. + +2011-03-09 Roland McGrath + + * alpha_symbol.c (alpha_check_special_symbol): New function. + * alpha_init.c (alpha_init): Initialize hook. + +2010-11-08 Roland McGrath + + * i386_retval.c (loc_intreg): Typo fix. + Reported by Thorsten Glaser . + +2010-04-10 Matt Fleming + + * sh_corenote.c: New file. + * sh_regs.c: New file. + * sh_retval.c: New file. + * sh_symbol.c (sh_machine_flag_check): New function. + * Makefile.am (sh_SRCS): Add new files. + * sh_init.c (sh_init): Add initializers. + +2010-04-07 Roland McGrath + + * arm_reloc.def: Accept PC24 and ABS32 in EXEC|DYN too. + +2010-03-04 Ulrich Drepper + + * x86_64_reloc.def: Add entries for R_X86_64_SIZE32 and + R_X86_64_SIZE64. + +2010-02-18 Roland McGrath + + * Makefile.am (libebl_%.so): Use multi-target pattern rule instead of + intermediate dependency file for libebl_%.map, working around apparent + make -j timing-sensitive bugs. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2010-01-05 Roland McGrath + + * arm_retval.c (arm_return_value_location): Use dwarf_aggregate_size. + * ia64_retval.c (ia64_return_value_location): Likewise. + * ppc_retval.c (ppc_return_value_location): Likewise. + * ppc64_retval.c (ppc64_return_value_location): Likewise. + * sparc_retval.c (sparc_return_value_location): Likewise. + + * ppc64_retval.c (ppc64_return_value_location): + Use vr2 for DW_TAG_array_type with DW_AT_GNU_vector. + * ppc_retval.c (ppc_return_value_location): Likewise. + +2010-01-04 Roland McGrath + + * linux-core-note.c (vmcoreinfo_items): New static const variable. + (EBLHOOK(core_note)): Update arguments for new protocol. + Validate the name as "CORE" or "LINUX" for known n_type cases. + Handle name "VMCOREINFO" n_type=0 with vmcoreinfo_items. + * i386_corenote.c (EXTRA_NOTES): Update parameter usage. + * x86_corenote.c (EXTRA_NOTES_IOPERM): Likewise. + +2009-09-10 Mark Wielaard + + * sparc_retval.c: Fix license header. + +2009-08-07 Roland McGrath + + * x86_64_reloc.def: Add PC64, GOTOFF64, GOTPC32, GOTPC32_TLSDESC, + TLSDESC_CALL, TLSDESC. + +2009-07-08 Roland McGrath + + * x86_64_cfi.c (x86_64_abi_cfi): New file. + * Makefile.am (x86_64_SRCS): Add it. + * x86_64_init.c (x86_64_init): Add initializer. + + * i386_cfi.c (i386_abi_cfi): New file. + * Makefile.am (i386_SRCS): Add it. + * i386_init.c (i386_init): Initialize abi_cfi hook. + +2009-06-01 Ulrich Drepper + + * i386_reloc.def: Add IRELATIVE entry. + * x86_64_reloc.def: Likewise. + +2009-04-16 Roland McGrath + + * arm_regs.c (arm_register_info): Handle VFP registers. + + * i386_corenote.c (EXTRA_NOTES): NT_PRXFPREG -> NT_PRXFPREG + +2009-04-14 Roland McGrath + + * arm_retval.c: New file. + * arm_attrs.c: New file. + * Makefile.am (arm_SRCS): Add them. + * arm_symbol.c (arm_segment_type_name): New function. + (arm_section_type_name): New function. + (arm_machine_flag_check): New function. + * arm_init.c (arm_init): Initialize those hooks. + + * arm_regs.c: New file. + * arm_corenote.c: New file. + * arm_auxv.c: New file. + * Makefile.am (arm_SRCS): Add them. + * arm_init.c (arm_init): Initialize core_note, register_info, + and auxv_info hooks. + + * ia64_symbol.c (ia64_section_type_name): Remove "SHT_" prefixes. + +2009-04-01 Roland McGrath + + * sparc_reloc.def: Update table. + Data from Dave Miller . + +2009-02-15 Roland McGrath + + * ppc_attrs.c (ppc_check_object_attribute): Handle tag + GNU_Power_ABI_Struct_Return. + +2008-10-04 Ulrich Drepper + + * i386_reloc.def: Fix entries for TLS_GOTDESC, TLS_DESC_CALL, and + TLS_DESC. + +2008-08-01 Roland McGrath + + * x86_corenote.c: New file. + * Makefile.am (noinst_HEADERS): Add it. + * i386_corenote.c: Include it, use EXTRA_NOTES_IOPERM in EXTRA_NOTES. + * x86_64_corenote.c: Likewise. + + * linux-core-note.c (prstatus_items): Use 'B' instead of 'b' + for sigpend and sighold. + +2008-07-04 Roland McGrath + + * i386_syscall.c: New file. + * x86_64_syscall.c: New file. + * ppc_syscall.c: New file. + * Makefile.am (i386_SRCS, x86_64_SRCS, ppc_SRCS, ppc64_SRCS): Add them. + * i386_init.c (i386_init): Initialize syscall_abi hook. + * x86_64_init.c (x86_64_init): Likewise. + * ppc_init.c (ppc_init): Likewise. + * ppc64_init.c (ppc64_init): Likewise. + + * ppc_corenote.c (PRSTATUS_REGSET_ITEMS): Add nip. + Fix offset calculation for 64-bit case. + +2008-04-04 Roland McGrath + + * alpha_symbol.c (alpha_check_special_section): New function. + * alpha_init.c (alpha_init): Initialize check_special_section hook. + +2008-03-31 Roland McGrath + + * sparc_symbol.c (sparc_symbol_type_name): New function. + (sparc_dynamic_tag_name): New function. + (sparc_dynamic_tag_check): New function. + * sparc_init.c (sparc_init): Initialize those hooks. + + * sparc_symbol.c (sparc_check_special_section): New function. + * sparc_init.c (sparc_init): Initialize check_special_section hook. + +2008-02-20 Roland McGrath + + * ppc_attrs.c: New file. + * Makefile.am (ppc_SRCS, ppc64_SRCS): Add it. + * ppc_init.c (ppc_init): Initialize check_object_attribute hook. + +2008-02-14 Roland McGrath + + * alpha_auxv.c: New file. + * Makefile.am (alpha_SRCS): Add it. + * alpha_init.c (alpha_init): Initialize auxv_info hook. + +2008-02-08 Roland McGrath + + * ppc_corenote.c (spe_regs): New const variable. + (EXTRA_NOTES): Use it for NT_PPC_SPE. + +2008-01-02 Roland McGrath + + * i386_corenote.c (tls_items): New const table. + (tls_info): New function, uses it. + (EXTRA_NOTES): Use it to handle NT_386_TLS. + +2008-01-08 Ulrich Drepper + + * Makefile.am: Add x86-64 disassembler. + * x86_64_init.c (x86_64_init): Hook up disassembler. + +2007-12-28 Ulrich Drepper + + * Makefile.am: Add x86 disassembler. + * i386_init.c (i386_init): Hook up disassembler. + +2007-12-15 Roland McGrath + + * ppc_regs.c (ppc_register_info): Return "spefscr", not "spr512". + +2007-10-18 Roland McGrath + + * ppc_regs.c (ppc_register_info): Assign 67 to "vscr". + Return "vector" and 32 bits for vscr and vrsave. + * ppc_corenote.c (altivec_regs): New variable. + (EXTRA_NOTES): New macro, handle NT_PPC_VMX. + + * linux-core-note.c (EXTRA_REGSET): New macro. + Remove NT_PRXFPREG case. Instead, use EXTRA_NOTES if defined. + * i386_corenote.c (EXTRA_NOTES): Define it. + +2007-10-09 Roland McGrath + + * sparc_auxv.c: New file. + * Makefile.am (sparc_SRCS): Add it. + * sparc_init.c (sparc_init): Initialize auxv_info hook. + +2007-10-08 Roland McGrath + + * linux-core-note.c (TIMEVAL_FIELD): New macro. + (prstatus_items): Use it. + * sparc_corenote.c: New file. + * sparc64_corenote.c: New file. + * Makefile.am (sparc_SRCS): Add them. + * sparc_init.c (sparc_init): Initialize core_note hook. + + * sparc_symbol.c (sparc_machine_flag_check): New function. + * sparc_init.c (sparc_init): Use it. + +2007-09-27 Roland McGrath + + * alpha_retval.c: Use dwarf_attr_integrate and dwarf_hasattr_integrate. + * i386_retval.c: Likewise. + * ia64_retval.c: Likewise. + * ppc64_retval.c: Likewise. + * ppc_retval.c: Likewise. + * s390_retval.c: Likewise. + * sparc_retval.c: Likewise. + * x86_64_retval.c: Likewise. + +2007-10-31 Ulrich Drepper + + * Makefile.am: More dependencies for the libebl_* libraries. + +2007-08-23 Roland McGrath + + * x86_64_regs.c (x86_64_register_info): Put %rflags in "integer" set. + +2007-08-22 Roland McGrath + + * linux-core-note.c (prstatus_items): Add .group initializers. + (prpsinfo_items): Likewise. + * x86_64_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise. + * i386_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise. + * ppc_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise. + +2007-08-20 Roland McGrath + + * ppc_symbol.c (ppc_check_special_symbol): For _GLOBAL_OFFSET_TABLE_ + when DT_PPC_GOT is not found, anywhere in the section is valid. + +2007-08-19 Roland McGrath + + * i386_auxv.c: New file. + * Makefile.am (i386_SRCS, x86_64_SRCS): Add it. + * ppc_auxv.c: New file. + * Makefile.am (ppc_SRCS, ppc64_SRCS): Add it. + * i386_init.c (i386_init): Initialize auxv_info hook. + * x86_64_init.c (x86_64_init): Likewise. + * ppc_init.c (ppc_init): Likewise. + * ppc64_init.c (ppc64_init): Likewise. + + * alpha_corenote.c: New file. + * Makefile.am (alpha_SRCS): Add it. + * alpha_init.c (alpha_init): Initialize core_note hook. + + * ppc_corenote.c: New file. + * ppc64_corenote.c: New file. + * Makefile.am (ppc_SRCS, ppc64_SRCS): Add them. + * ppc_init.c (ppc_init): Initialize core_note hook. + * ppc64_init.c (ppc64_init): Likewise. + + * linux-core-note.c: New file. + * Makefile.am (noinst_HEADERS): Add it. + * i386_corenote.c: Rewritten. + * x86_64_corenote.c: Likewise. + +2007-05-23 Roland McGrath + + * alpha_regs.c (alpha_register_info): fp -> s6 + +2007-04-26 Roland McGrath + + * alpha_symbol.c (alpha_machine_section_flag_check): New function. + * alpha_init.c (alpha_init): Initialize hook. + + * alpha_regs.c: New file. + * Makefile.am (alpha_SRCS): Add it. + * alpha_init.c (alpha_init): Initialize register_info hook. + +2007-04-22 Roland McGrath + + * ppc_regs.c (ppc_register_info): Use some names instead of sprNNN: + mq, xer, lr, ctr, dsisr, dar, dec, vrsave. + Set *BITS to 64 for FPU registers. + + * i386_regs.c (i386_register_info): Set *BITS to 16 for fctrl, fstat. + * x86_64_regs.c (x86_64_register_info): Likewise for fcw, fsw. + +2007-04-01 Roland McGrath + + * x86_64_regs.c (x86_64_register_info): Add more registers from newer + ABI spec. + +2007-01-11 Roland McGrath + + * ia64_symbol.c (ia64_machine_section_flag_check): New function. + * ia64_init.c (ia64_init): Use it. + + * ia64_symbol.c (ia64_section_type_name): Typo fix in string. + +2006-10-09 Roland McGrath + + * ia64_symbol.c (ia64_reloc_simple_type): Treat SECREL types as simple. + +2006-08-29 Roland McGrath + + * sparc_retval.c: New file. + * Makefile.am (sparc_SRCS): Add it. + * sparc_init.c (sparc_init): Initialize return_value_location hook. + +2006-08-22 Roland McGrath + + * i386_regs.c (i386_register_name): Renamed i386_register_info. + Take new args, yield more info. + * i386_init.c (i386_init): Update initializer. + * ia64_regs.c (ia64_register_name): Likewise. + * ia64_init.c (ia64_init): Likewise. + * ppc_regs.c (ppc_register_name): Likewise. + * ppc64_init.c (ppc64_init): Likewise. + * ppc_init.c (ppc_init): Likewise. + * s390_regs.c (s390_register_name): Likewise. + * s390_init.c (s390_init): Likewise. + * sparc_regs.c (sparc_register_name): Likewise. + * sparc_init.c (sparc_init): Likewise. + * x86_64_regs.c (x86_64_register_name): Likewise. + * x86_64_init.c (x86_64_init): Likewise. + +2006-08-08 Roland McGrath + + * Makefile.am (%.os): Don't depend on %.o, since we don't actually + need static object for anything here. This rule is the only source of + .deps/ files. + +2006-06-23 Stepan Kasal + + * Makefile.am (PACKAGE_VERSION): Remove superfluous definition. + +2006-08-03 Roland McGrath + + * sparc_regs.c (sparc_register_name): List 32 FPU regs only for + EM_SPARC. EM_SPARC32PLUS also has 64. + +2006-07-21 Roland McGrath + + * i386_regs.c (i386_register_name): Fix return value when using stpcpy. + * ppc_regs.c (ppc_register_name): Likewise. + * s390_regs.c (s390_register_name): Likewise. + + * ia64_retval.c: New file. + * Makefile.am (ia64_SRCS): Add it. + * ia64_init.c (ia64_init): Install return_value_location hook. + + * ia64_regs.c: New file. + * Makefile.am (ia64_SRCS): Add it. + * ia64_init.c (ia64_init): Install register_name hook. + +2006-07-05 Ulrich Drepper + + * alpha_init.c: Initialize sysvhash_entrysize. + * s390_init.c: Likewise. + +2006-07-04 Ulrich Drepper + + * common-reloc.c (relative_reloc_p): New function. + (init_reloc): Hook it up. + * ia64_reloc.def: Define NO_RELATIVE_RELOC. + +2006-06-13 Roland McGrath + + * ppc64_retval.c: Remove SVR4_STRUCT_RETURN braino. + +2006-06-12 Ulrich Drepper + + * common-reloc.c (none_reloc_p): New function. + (init_reloc): Hook it up. + +2006-02-22 Roland McGrath + + * ppc64_retval.c (SVR4_STRUCT_RETURN): New macro. + (ppc64_return_value_location): Use registers for aggregate conditional + on that. + * ppc_retval.c (SVR4_STRUCT_RETURN): New macro. + (ppc_return_value_location): Use registers for aggregate conditional + on that. + +2006-01-12 Roland McGrath + + * s390_retval.c: New file. + * Makefile.am (s390_SRCS): Add it. + * s390_init.c (s390_init): Install return_value_location hook. + +2006-01-11 Roland McGrath + + * s390_regs.c: New file. + * Makefile.am (s390_SRCS): Add it. + * s390_init.c (s390_init): Install register_name hook. + + * s390_reloc.def: Update bits per + Martin Schwidefsky . + +2005-12-10 Ulrich Drepper + + * common-reloc.c (R_NAME): Generate string correctly. + +2005-12-05 Roland McGrath + + * i386_regs.c (i386_register_name): Use a table for the first 8 regs. + * x86_64_regs.c (x86_64_register_name): Likewise. + +2005-11-25 Roland McGrath + + * i386_regs.c (i386_register_name): Return 0, not 1, for gaps. + + * i386_regs.c: New file. + * ppc_regs.c: New file. + * sparc_regs.c: New file. + * x86_64_regs.c: New file. + * Makefile.am + (i386_SRCS, x86_64_SRCS, ppc_SRCS, ppc64_SRCS, sparc_SRCS): Add them. + * i386_init.c: Initialize register_name hook. + * ppc_init.c: Likewise. + * ppc64_init.c: Likewise. + * sparc_init.c: Likewise. + * x86_64_init.c: Likewise. + +2005-11-19 Roland McGrath + + * ppc64_reloc.def: REL30 -> ADDR30. + +2005-11-18 Roland McGrath + + * alpha_init.c: Use HOOK macro. + * arm_init.c: Likewise. + * i386_init.c: Likewise. + * ia64_init.c: Likewise. + * ppc64_init.c: Likewise. + * ppc_init.c: Likewise. + * s390_init.c: Likewise. + * sh_init.c: Likewise. + * sparc_init.c: Likewise. + * x86_64_init.c: Likewise. + +2005-11-17 Roland McGrath + + * Makefile.am (uninstall): Don't try to remove $(pkgincludedir). + (CLEANFILES): Add libebl_$(m).so. + + * ppc_reloc.def: Update bits per Alan Modra . + * ppc64_reloc.def: Likewise. + +2005-11-15 Roland McGrath + + * Contents moved here from ../libebl. diff --git a/backends/Makefile.am b/backends/Makefile.am new file mode 100644 index 00000000..62916c9c --- /dev/null +++ b/backends/Makefile.am @@ -0,0 +1,110 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2000-2010, 2013, 2014 Red Hat, Inc. +## Copyright (C) 2012 Tilera Corporation +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +include $(top_srcdir)/config/eu.am +if BUILD_STATIC +AM_CFLAGS += $(fpic_CFLAGS) +endif +AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \ + -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw + +noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a + +modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \ + m68k bpf riscv csky + +i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \ + i386_retval.c i386_regs.c i386_auxv.c \ + i386_initreg.c i386_unwind.c + +sh_SRCS = sh_init.c sh_symbol.c sh_corenote.c sh_regs.c sh_retval.c + +x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \ + x86_64_retval.c x86_64_regs.c x86_64_initreg.c \ + x86_64_unwind.c x32_corenote.c + + +ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c + +alpha_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c alpha_regs.c \ + alpha_corenote.c alpha_auxv.c + +arm_SRCS = arm_init.c arm_symbol.c arm_regs.c arm_corenote.c \ + arm_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c + +aarch64_SRCS = aarch64_init.c aarch64_regs.c aarch64_symbol.c \ + aarch64_corenote.c aarch64_retval.c aarch64_cfi.c \ + aarch64_initreg.c aarch64_unwind.c + +sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c \ + sparc_corenote.c sparc64_corenote.c sparc_auxv.c sparc_attrs.c \ + sparc_cfi.c sparc_initreg.c + +ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \ + ppc_corenote.c ppc_auxv.c ppc_attrs.c \ + ppc_cfi.c ppc_initreg.c + +ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c ppc64_corenote.c \ + ppc64_unwind.c ppc64_resolve_sym.c + +s390_SRCS = s390_init.c s390_symbol.c s390_regs.c s390_retval.c \ + s390_corenote.c s390x_corenote.c s390_cfi.c s390_initreg.c \ + s390_unwind.c + +m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c \ + m68k_retval.c m68k_corenote.c m68k_cfi.c m68k_initreg.c + +# m68k prstatus core notes are described by a packed structure +# which has not naturally aligned fields. Since we don't access +# these fields directly, but take their offset to be used later +# to extract the data through elfxx_xlatetom/memmove, this isn't +# an issue. +m68k_corenote_no_Wpacked_not_aligned = yes + +bpf_SRCS = bpf_init.c bpf_regs.c bpf_symbol.c + +riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c \ + riscv_initreg.c riscv_corenote.c riscv64_corenote.c riscv_retval.c + +csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \ + csky_regs.c csky_initreg.c csky_corenote.c + +libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \ + $(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \ + $(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \ + $(ppc64_SRCS) $(s390_SRCS) \ + $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) + +libebl_backends_pic_a_SOURCES = +am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os) + +noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c +EXTRA_DIST = $(modules:=_reloc.def) + +MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS) diff --git a/backends/Makefile.in b/backends/Makefile.in new file mode 100644 index 00000000..31041b79 --- /dev/null +++ b/backends/Makefile.in @@ -0,0 +1,1206 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@BUILD_STATIC_TRUE@am__append_2 = $(fpic_CFLAGS) +subdir = backends +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libebl_backends_a_AR = $(AR) $(ARFLAGS) +libebl_backends_a_LIBADD = +am__objects_1 = i386_init.$(OBJEXT) i386_symbol.$(OBJEXT) \ + i386_corenote.$(OBJEXT) i386_cfi.$(OBJEXT) \ + i386_retval.$(OBJEXT) i386_regs.$(OBJEXT) i386_auxv.$(OBJEXT) \ + i386_initreg.$(OBJEXT) i386_unwind.$(OBJEXT) +am__objects_2 = sh_init.$(OBJEXT) sh_symbol.$(OBJEXT) \ + sh_corenote.$(OBJEXT) sh_regs.$(OBJEXT) sh_retval.$(OBJEXT) +am__objects_3 = x86_64_init.$(OBJEXT) x86_64_symbol.$(OBJEXT) \ + x86_64_corenote.$(OBJEXT) x86_64_cfi.$(OBJEXT) \ + x86_64_retval.$(OBJEXT) x86_64_regs.$(OBJEXT) \ + x86_64_initreg.$(OBJEXT) x86_64_unwind.$(OBJEXT) \ + x32_corenote.$(OBJEXT) +am__objects_4 = ia64_init.$(OBJEXT) ia64_symbol.$(OBJEXT) \ + ia64_regs.$(OBJEXT) ia64_retval.$(OBJEXT) +am__objects_5 = alpha_init.$(OBJEXT) alpha_symbol.$(OBJEXT) \ + alpha_retval.$(OBJEXT) alpha_regs.$(OBJEXT) \ + alpha_corenote.$(OBJEXT) alpha_auxv.$(OBJEXT) +am__objects_6 = arm_init.$(OBJEXT) arm_symbol.$(OBJEXT) \ + arm_regs.$(OBJEXT) arm_corenote.$(OBJEXT) arm_auxv.$(OBJEXT) \ + arm_attrs.$(OBJEXT) arm_retval.$(OBJEXT) arm_cfi.$(OBJEXT) \ + arm_initreg.$(OBJEXT) +am__objects_7 = aarch64_init.$(OBJEXT) aarch64_regs.$(OBJEXT) \ + aarch64_symbol.$(OBJEXT) aarch64_corenote.$(OBJEXT) \ + aarch64_retval.$(OBJEXT) aarch64_cfi.$(OBJEXT) \ + aarch64_initreg.$(OBJEXT) aarch64_unwind.$(OBJEXT) +am__objects_8 = sparc_init.$(OBJEXT) sparc_symbol.$(OBJEXT) \ + sparc_regs.$(OBJEXT) sparc_retval.$(OBJEXT) \ + sparc_corenote.$(OBJEXT) sparc64_corenote.$(OBJEXT) \ + sparc_auxv.$(OBJEXT) sparc_attrs.$(OBJEXT) sparc_cfi.$(OBJEXT) \ + sparc_initreg.$(OBJEXT) +am__objects_9 = ppc_init.$(OBJEXT) ppc_symbol.$(OBJEXT) \ + ppc_retval.$(OBJEXT) ppc_regs.$(OBJEXT) ppc_corenote.$(OBJEXT) \ + ppc_auxv.$(OBJEXT) ppc_attrs.$(OBJEXT) ppc_cfi.$(OBJEXT) \ + ppc_initreg.$(OBJEXT) +am__objects_10 = ppc64_init.$(OBJEXT) ppc64_symbol.$(OBJEXT) \ + ppc64_retval.$(OBJEXT) ppc64_corenote.$(OBJEXT) \ + ppc64_unwind.$(OBJEXT) ppc64_resolve_sym.$(OBJEXT) +am__objects_11 = s390_init.$(OBJEXT) s390_symbol.$(OBJEXT) \ + s390_regs.$(OBJEXT) s390_retval.$(OBJEXT) \ + s390_corenote.$(OBJEXT) s390x_corenote.$(OBJEXT) \ + s390_cfi.$(OBJEXT) s390_initreg.$(OBJEXT) \ + s390_unwind.$(OBJEXT) +am__objects_12 = m68k_init.$(OBJEXT) m68k_symbol.$(OBJEXT) \ + m68k_regs.$(OBJEXT) m68k_retval.$(OBJEXT) \ + m68k_corenote.$(OBJEXT) m68k_cfi.$(OBJEXT) \ + m68k_initreg.$(OBJEXT) +am__objects_13 = bpf_init.$(OBJEXT) bpf_regs.$(OBJEXT) \ + bpf_symbol.$(OBJEXT) +am__objects_14 = riscv_init.$(OBJEXT) riscv_symbol.$(OBJEXT) \ + riscv_cfi.$(OBJEXT) riscv_regs.$(OBJEXT) \ + riscv_initreg.$(OBJEXT) riscv_corenote.$(OBJEXT) \ + riscv64_corenote.$(OBJEXT) riscv_retval.$(OBJEXT) +am__objects_15 = csky_attrs.$(OBJEXT) csky_init.$(OBJEXT) \ + csky_symbol.$(OBJEXT) csky_cfi.$(OBJEXT) csky_regs.$(OBJEXT) \ + csky_initreg.$(OBJEXT) csky_corenote.$(OBJEXT) +am_libebl_backends_a_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) $(am__objects_14) \ + $(am__objects_15) +libebl_backends_a_OBJECTS = $(am_libebl_backends_a_OBJECTS) +libebl_backends_pic_a_AR = $(AR) $(ARFLAGS) +libebl_backends_pic_a_LIBADD = +libebl_backends_pic_a_OBJECTS = $(am_libebl_backends_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/aarch64_cfi.Po \ + ./$(DEPDIR)/aarch64_corenote.Po ./$(DEPDIR)/aarch64_init.Po \ + ./$(DEPDIR)/aarch64_initreg.Po ./$(DEPDIR)/aarch64_regs.Po \ + ./$(DEPDIR)/aarch64_retval.Po ./$(DEPDIR)/aarch64_symbol.Po \ + ./$(DEPDIR)/aarch64_unwind.Po ./$(DEPDIR)/alpha_auxv.Po \ + ./$(DEPDIR)/alpha_corenote.Po ./$(DEPDIR)/alpha_init.Po \ + ./$(DEPDIR)/alpha_regs.Po ./$(DEPDIR)/alpha_retval.Po \ + ./$(DEPDIR)/alpha_symbol.Po ./$(DEPDIR)/arm_attrs.Po \ + ./$(DEPDIR)/arm_auxv.Po ./$(DEPDIR)/arm_cfi.Po \ + ./$(DEPDIR)/arm_corenote.Po ./$(DEPDIR)/arm_init.Po \ + ./$(DEPDIR)/arm_initreg.Po ./$(DEPDIR)/arm_regs.Po \ + ./$(DEPDIR)/arm_retval.Po ./$(DEPDIR)/arm_symbol.Po \ + ./$(DEPDIR)/bpf_init.Po ./$(DEPDIR)/bpf_regs.Po \ + ./$(DEPDIR)/bpf_symbol.Po ./$(DEPDIR)/csky_attrs.Po \ + ./$(DEPDIR)/csky_cfi.Po ./$(DEPDIR)/csky_corenote.Po \ + ./$(DEPDIR)/csky_init.Po ./$(DEPDIR)/csky_initreg.Po \ + ./$(DEPDIR)/csky_regs.Po ./$(DEPDIR)/csky_symbol.Po \ + ./$(DEPDIR)/i386_auxv.Po ./$(DEPDIR)/i386_cfi.Po \ + ./$(DEPDIR)/i386_corenote.Po ./$(DEPDIR)/i386_init.Po \ + ./$(DEPDIR)/i386_initreg.Po ./$(DEPDIR)/i386_regs.Po \ + ./$(DEPDIR)/i386_retval.Po ./$(DEPDIR)/i386_symbol.Po \ + ./$(DEPDIR)/i386_unwind.Po ./$(DEPDIR)/ia64_init.Po \ + ./$(DEPDIR)/ia64_regs.Po ./$(DEPDIR)/ia64_retval.Po \ + ./$(DEPDIR)/ia64_symbol.Po ./$(DEPDIR)/m68k_cfi.Po \ + ./$(DEPDIR)/m68k_corenote.Po ./$(DEPDIR)/m68k_init.Po \ + ./$(DEPDIR)/m68k_initreg.Po ./$(DEPDIR)/m68k_regs.Po \ + ./$(DEPDIR)/m68k_retval.Po ./$(DEPDIR)/m68k_symbol.Po \ + ./$(DEPDIR)/ppc64_corenote.Po ./$(DEPDIR)/ppc64_init.Po \ + ./$(DEPDIR)/ppc64_resolve_sym.Po ./$(DEPDIR)/ppc64_retval.Po \ + ./$(DEPDIR)/ppc64_symbol.Po ./$(DEPDIR)/ppc64_unwind.Po \ + ./$(DEPDIR)/ppc_attrs.Po ./$(DEPDIR)/ppc_auxv.Po \ + ./$(DEPDIR)/ppc_cfi.Po ./$(DEPDIR)/ppc_corenote.Po \ + ./$(DEPDIR)/ppc_init.Po ./$(DEPDIR)/ppc_initreg.Po \ + ./$(DEPDIR)/ppc_regs.Po ./$(DEPDIR)/ppc_retval.Po \ + ./$(DEPDIR)/ppc_symbol.Po ./$(DEPDIR)/riscv64_corenote.Po \ + ./$(DEPDIR)/riscv_cfi.Po ./$(DEPDIR)/riscv_corenote.Po \ + ./$(DEPDIR)/riscv_init.Po ./$(DEPDIR)/riscv_initreg.Po \ + ./$(DEPDIR)/riscv_regs.Po ./$(DEPDIR)/riscv_retval.Po \ + ./$(DEPDIR)/riscv_symbol.Po ./$(DEPDIR)/s390_cfi.Po \ + ./$(DEPDIR)/s390_corenote.Po ./$(DEPDIR)/s390_init.Po \ + ./$(DEPDIR)/s390_initreg.Po ./$(DEPDIR)/s390_regs.Po \ + ./$(DEPDIR)/s390_retval.Po ./$(DEPDIR)/s390_symbol.Po \ + ./$(DEPDIR)/s390_unwind.Po ./$(DEPDIR)/s390x_corenote.Po \ + ./$(DEPDIR)/sh_corenote.Po ./$(DEPDIR)/sh_init.Po \ + ./$(DEPDIR)/sh_regs.Po ./$(DEPDIR)/sh_retval.Po \ + ./$(DEPDIR)/sh_symbol.Po ./$(DEPDIR)/sparc64_corenote.Po \ + ./$(DEPDIR)/sparc_attrs.Po ./$(DEPDIR)/sparc_auxv.Po \ + ./$(DEPDIR)/sparc_cfi.Po ./$(DEPDIR)/sparc_corenote.Po \ + ./$(DEPDIR)/sparc_init.Po ./$(DEPDIR)/sparc_initreg.Po \ + ./$(DEPDIR)/sparc_regs.Po ./$(DEPDIR)/sparc_retval.Po \ + ./$(DEPDIR)/sparc_symbol.Po ./$(DEPDIR)/x32_corenote.Po \ + ./$(DEPDIR)/x86_64_cfi.Po ./$(DEPDIR)/x86_64_corenote.Po \ + ./$(DEPDIR)/x86_64_init.Po ./$(DEPDIR)/x86_64_initreg.Po \ + ./$(DEPDIR)/x86_64_regs.Po ./$(DEPDIR)/x86_64_retval.Po \ + ./$(DEPDIR)/x86_64_symbol.Po ./$(DEPDIR)/x86_64_unwind.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libebl_backends_a_SOURCES) \ + $(libebl_backends_pic_a_SOURCES) +DIST_SOURCES = $(libebl_backends_a_SOURCES) \ + $(libebl_backends_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \ + -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes \ + $(TRAMPOLINES_WARNING) $(LOGICAL_OP_WARNING) \ + $(DUPLICATED_COND_WARNING) $(NULL_DEREFERENCE_WARNING) \ + $(IMPLICIT_FALLTHROUGH_WARNING) $(if \ + $($(*F)_no_Werror),,-Werror) $(if \ + $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \ + $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) $(if \ + $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) $(am__append_2) +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a +modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \ + m68k bpf riscv csky + +i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \ + i386_retval.c i386_regs.c i386_auxv.c \ + i386_initreg.c i386_unwind.c + +sh_SRCS = sh_init.c sh_symbol.c sh_corenote.c sh_regs.c sh_retval.c +x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \ + x86_64_retval.c x86_64_regs.c x86_64_initreg.c \ + x86_64_unwind.c x32_corenote.c + +ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c +alpha_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c alpha_regs.c \ + alpha_corenote.c alpha_auxv.c + +arm_SRCS = arm_init.c arm_symbol.c arm_regs.c arm_corenote.c \ + arm_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c + +aarch64_SRCS = aarch64_init.c aarch64_regs.c aarch64_symbol.c \ + aarch64_corenote.c aarch64_retval.c aarch64_cfi.c \ + aarch64_initreg.c aarch64_unwind.c + +sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c \ + sparc_corenote.c sparc64_corenote.c sparc_auxv.c sparc_attrs.c \ + sparc_cfi.c sparc_initreg.c + +ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \ + ppc_corenote.c ppc_auxv.c ppc_attrs.c \ + ppc_cfi.c ppc_initreg.c + +ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c ppc64_corenote.c \ + ppc64_unwind.c ppc64_resolve_sym.c + +s390_SRCS = s390_init.c s390_symbol.c s390_regs.c s390_retval.c \ + s390_corenote.c s390x_corenote.c s390_cfi.c s390_initreg.c \ + s390_unwind.c + +m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c \ + m68k_retval.c m68k_corenote.c m68k_cfi.c m68k_initreg.c + + +# m68k prstatus core notes are described by a packed structure +# which has not naturally aligned fields. Since we don't access +# these fields directly, but take their offset to be used later +# to extract the data through elfxx_xlatetom/memmove, this isn't +# an issue. +m68k_corenote_no_Wpacked_not_aligned = yes +bpf_SRCS = bpf_init.c bpf_regs.c bpf_symbol.c +riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c \ + riscv_initreg.c riscv_corenote.c riscv64_corenote.c riscv_retval.c + +csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \ + csky_regs.c csky_initreg.c csky_corenote.c + +libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \ + $(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \ + $(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \ + $(ppc64_SRCS) $(s390_SRCS) \ + $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) + +libebl_backends_pic_a_SOURCES = +am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os) +noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c +EXTRA_DIST = $(modules:=_reloc.def) +MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits backends/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits backends/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libebl_backends.a: $(libebl_backends_a_OBJECTS) $(libebl_backends_a_DEPENDENCIES) $(EXTRA_libebl_backends_a_DEPENDENCIES) + $(AM_V_at)-rm -f libebl_backends.a + $(AM_V_AR)$(libebl_backends_a_AR) libebl_backends.a $(libebl_backends_a_OBJECTS) $(libebl_backends_a_LIBADD) + $(AM_V_at)$(RANLIB) libebl_backends.a + +libebl_backends_pic.a: $(libebl_backends_pic_a_OBJECTS) $(libebl_backends_pic_a_DEPENDENCIES) $(EXTRA_libebl_backends_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libebl_backends_pic.a + $(AM_V_AR)$(libebl_backends_pic_a_AR) libebl_backends_pic.a $(libebl_backends_pic_a_OBJECTS) $(libebl_backends_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libebl_backends_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64_unwind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_auxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_attrs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_auxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpf_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpf_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpf_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_attrs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csky_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_auxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386_unwind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia64_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_resolve_sym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_unwind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_attrs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_auxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv64_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390_unwind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s390x_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc64_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_attrs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_auxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x32_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_corenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_initreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_retval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_64_unwind.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/aarch64_cfi.Po + -rm -f ./$(DEPDIR)/aarch64_corenote.Po + -rm -f ./$(DEPDIR)/aarch64_init.Po + -rm -f ./$(DEPDIR)/aarch64_initreg.Po + -rm -f ./$(DEPDIR)/aarch64_regs.Po + -rm -f ./$(DEPDIR)/aarch64_retval.Po + -rm -f ./$(DEPDIR)/aarch64_symbol.Po + -rm -f ./$(DEPDIR)/aarch64_unwind.Po + -rm -f ./$(DEPDIR)/alpha_auxv.Po + -rm -f ./$(DEPDIR)/alpha_corenote.Po + -rm -f ./$(DEPDIR)/alpha_init.Po + -rm -f ./$(DEPDIR)/alpha_regs.Po + -rm -f ./$(DEPDIR)/alpha_retval.Po + -rm -f ./$(DEPDIR)/alpha_symbol.Po + -rm -f ./$(DEPDIR)/arm_attrs.Po + -rm -f ./$(DEPDIR)/arm_auxv.Po + -rm -f ./$(DEPDIR)/arm_cfi.Po + -rm -f ./$(DEPDIR)/arm_corenote.Po + -rm -f ./$(DEPDIR)/arm_init.Po + -rm -f ./$(DEPDIR)/arm_initreg.Po + -rm -f ./$(DEPDIR)/arm_regs.Po + -rm -f ./$(DEPDIR)/arm_retval.Po + -rm -f ./$(DEPDIR)/arm_symbol.Po + -rm -f ./$(DEPDIR)/bpf_init.Po + -rm -f ./$(DEPDIR)/bpf_regs.Po + -rm -f ./$(DEPDIR)/bpf_symbol.Po + -rm -f ./$(DEPDIR)/csky_attrs.Po + -rm -f ./$(DEPDIR)/csky_cfi.Po + -rm -f ./$(DEPDIR)/csky_corenote.Po + -rm -f ./$(DEPDIR)/csky_init.Po + -rm -f ./$(DEPDIR)/csky_initreg.Po + -rm -f ./$(DEPDIR)/csky_regs.Po + -rm -f ./$(DEPDIR)/csky_symbol.Po + -rm -f ./$(DEPDIR)/i386_auxv.Po + -rm -f ./$(DEPDIR)/i386_cfi.Po + -rm -f ./$(DEPDIR)/i386_corenote.Po + -rm -f ./$(DEPDIR)/i386_init.Po + -rm -f ./$(DEPDIR)/i386_initreg.Po + -rm -f ./$(DEPDIR)/i386_regs.Po + -rm -f ./$(DEPDIR)/i386_retval.Po + -rm -f ./$(DEPDIR)/i386_symbol.Po + -rm -f ./$(DEPDIR)/i386_unwind.Po + -rm -f ./$(DEPDIR)/ia64_init.Po + -rm -f ./$(DEPDIR)/ia64_regs.Po + -rm -f ./$(DEPDIR)/ia64_retval.Po + -rm -f ./$(DEPDIR)/ia64_symbol.Po + -rm -f ./$(DEPDIR)/m68k_cfi.Po + -rm -f ./$(DEPDIR)/m68k_corenote.Po + -rm -f ./$(DEPDIR)/m68k_init.Po + -rm -f ./$(DEPDIR)/m68k_initreg.Po + -rm -f ./$(DEPDIR)/m68k_regs.Po + -rm -f ./$(DEPDIR)/m68k_retval.Po + -rm -f ./$(DEPDIR)/m68k_symbol.Po + -rm -f ./$(DEPDIR)/ppc64_corenote.Po + -rm -f ./$(DEPDIR)/ppc64_init.Po + -rm -f ./$(DEPDIR)/ppc64_resolve_sym.Po + -rm -f ./$(DEPDIR)/ppc64_retval.Po + -rm -f ./$(DEPDIR)/ppc64_symbol.Po + -rm -f ./$(DEPDIR)/ppc64_unwind.Po + -rm -f ./$(DEPDIR)/ppc_attrs.Po + -rm -f ./$(DEPDIR)/ppc_auxv.Po + -rm -f ./$(DEPDIR)/ppc_cfi.Po + -rm -f ./$(DEPDIR)/ppc_corenote.Po + -rm -f ./$(DEPDIR)/ppc_init.Po + -rm -f ./$(DEPDIR)/ppc_initreg.Po + -rm -f ./$(DEPDIR)/ppc_regs.Po + -rm -f ./$(DEPDIR)/ppc_retval.Po + -rm -f ./$(DEPDIR)/ppc_symbol.Po + -rm -f ./$(DEPDIR)/riscv64_corenote.Po + -rm -f ./$(DEPDIR)/riscv_cfi.Po + -rm -f ./$(DEPDIR)/riscv_corenote.Po + -rm -f ./$(DEPDIR)/riscv_init.Po + -rm -f ./$(DEPDIR)/riscv_initreg.Po + -rm -f ./$(DEPDIR)/riscv_regs.Po + -rm -f ./$(DEPDIR)/riscv_retval.Po + -rm -f ./$(DEPDIR)/riscv_symbol.Po + -rm -f ./$(DEPDIR)/s390_cfi.Po + -rm -f ./$(DEPDIR)/s390_corenote.Po + -rm -f ./$(DEPDIR)/s390_init.Po + -rm -f ./$(DEPDIR)/s390_initreg.Po + -rm -f ./$(DEPDIR)/s390_regs.Po + -rm -f ./$(DEPDIR)/s390_retval.Po + -rm -f ./$(DEPDIR)/s390_symbol.Po + -rm -f ./$(DEPDIR)/s390_unwind.Po + -rm -f ./$(DEPDIR)/s390x_corenote.Po + -rm -f ./$(DEPDIR)/sh_corenote.Po + -rm -f ./$(DEPDIR)/sh_init.Po + -rm -f ./$(DEPDIR)/sh_regs.Po + -rm -f ./$(DEPDIR)/sh_retval.Po + -rm -f ./$(DEPDIR)/sh_symbol.Po + -rm -f ./$(DEPDIR)/sparc64_corenote.Po + -rm -f ./$(DEPDIR)/sparc_attrs.Po + -rm -f ./$(DEPDIR)/sparc_auxv.Po + -rm -f ./$(DEPDIR)/sparc_cfi.Po + -rm -f ./$(DEPDIR)/sparc_corenote.Po + -rm -f ./$(DEPDIR)/sparc_init.Po + -rm -f ./$(DEPDIR)/sparc_initreg.Po + -rm -f ./$(DEPDIR)/sparc_regs.Po + -rm -f ./$(DEPDIR)/sparc_retval.Po + -rm -f ./$(DEPDIR)/sparc_symbol.Po + -rm -f ./$(DEPDIR)/x32_corenote.Po + -rm -f ./$(DEPDIR)/x86_64_cfi.Po + -rm -f ./$(DEPDIR)/x86_64_corenote.Po + -rm -f ./$(DEPDIR)/x86_64_init.Po + -rm -f ./$(DEPDIR)/x86_64_initreg.Po + -rm -f ./$(DEPDIR)/x86_64_regs.Po + -rm -f ./$(DEPDIR)/x86_64_retval.Po + -rm -f ./$(DEPDIR)/x86_64_symbol.Po + -rm -f ./$(DEPDIR)/x86_64_unwind.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/aarch64_cfi.Po + -rm -f ./$(DEPDIR)/aarch64_corenote.Po + -rm -f ./$(DEPDIR)/aarch64_init.Po + -rm -f ./$(DEPDIR)/aarch64_initreg.Po + -rm -f ./$(DEPDIR)/aarch64_regs.Po + -rm -f ./$(DEPDIR)/aarch64_retval.Po + -rm -f ./$(DEPDIR)/aarch64_symbol.Po + -rm -f ./$(DEPDIR)/aarch64_unwind.Po + -rm -f ./$(DEPDIR)/alpha_auxv.Po + -rm -f ./$(DEPDIR)/alpha_corenote.Po + -rm -f ./$(DEPDIR)/alpha_init.Po + -rm -f ./$(DEPDIR)/alpha_regs.Po + -rm -f ./$(DEPDIR)/alpha_retval.Po + -rm -f ./$(DEPDIR)/alpha_symbol.Po + -rm -f ./$(DEPDIR)/arm_attrs.Po + -rm -f ./$(DEPDIR)/arm_auxv.Po + -rm -f ./$(DEPDIR)/arm_cfi.Po + -rm -f ./$(DEPDIR)/arm_corenote.Po + -rm -f ./$(DEPDIR)/arm_init.Po + -rm -f ./$(DEPDIR)/arm_initreg.Po + -rm -f ./$(DEPDIR)/arm_regs.Po + -rm -f ./$(DEPDIR)/arm_retval.Po + -rm -f ./$(DEPDIR)/arm_symbol.Po + -rm -f ./$(DEPDIR)/bpf_init.Po + -rm -f ./$(DEPDIR)/bpf_regs.Po + -rm -f ./$(DEPDIR)/bpf_symbol.Po + -rm -f ./$(DEPDIR)/csky_attrs.Po + -rm -f ./$(DEPDIR)/csky_cfi.Po + -rm -f ./$(DEPDIR)/csky_corenote.Po + -rm -f ./$(DEPDIR)/csky_init.Po + -rm -f ./$(DEPDIR)/csky_initreg.Po + -rm -f ./$(DEPDIR)/csky_regs.Po + -rm -f ./$(DEPDIR)/csky_symbol.Po + -rm -f ./$(DEPDIR)/i386_auxv.Po + -rm -f ./$(DEPDIR)/i386_cfi.Po + -rm -f ./$(DEPDIR)/i386_corenote.Po + -rm -f ./$(DEPDIR)/i386_init.Po + -rm -f ./$(DEPDIR)/i386_initreg.Po + -rm -f ./$(DEPDIR)/i386_regs.Po + -rm -f ./$(DEPDIR)/i386_retval.Po + -rm -f ./$(DEPDIR)/i386_symbol.Po + -rm -f ./$(DEPDIR)/i386_unwind.Po + -rm -f ./$(DEPDIR)/ia64_init.Po + -rm -f ./$(DEPDIR)/ia64_regs.Po + -rm -f ./$(DEPDIR)/ia64_retval.Po + -rm -f ./$(DEPDIR)/ia64_symbol.Po + -rm -f ./$(DEPDIR)/m68k_cfi.Po + -rm -f ./$(DEPDIR)/m68k_corenote.Po + -rm -f ./$(DEPDIR)/m68k_init.Po + -rm -f ./$(DEPDIR)/m68k_initreg.Po + -rm -f ./$(DEPDIR)/m68k_regs.Po + -rm -f ./$(DEPDIR)/m68k_retval.Po + -rm -f ./$(DEPDIR)/m68k_symbol.Po + -rm -f ./$(DEPDIR)/ppc64_corenote.Po + -rm -f ./$(DEPDIR)/ppc64_init.Po + -rm -f ./$(DEPDIR)/ppc64_resolve_sym.Po + -rm -f ./$(DEPDIR)/ppc64_retval.Po + -rm -f ./$(DEPDIR)/ppc64_symbol.Po + -rm -f ./$(DEPDIR)/ppc64_unwind.Po + -rm -f ./$(DEPDIR)/ppc_attrs.Po + -rm -f ./$(DEPDIR)/ppc_auxv.Po + -rm -f ./$(DEPDIR)/ppc_cfi.Po + -rm -f ./$(DEPDIR)/ppc_corenote.Po + -rm -f ./$(DEPDIR)/ppc_init.Po + -rm -f ./$(DEPDIR)/ppc_initreg.Po + -rm -f ./$(DEPDIR)/ppc_regs.Po + -rm -f ./$(DEPDIR)/ppc_retval.Po + -rm -f ./$(DEPDIR)/ppc_symbol.Po + -rm -f ./$(DEPDIR)/riscv64_corenote.Po + -rm -f ./$(DEPDIR)/riscv_cfi.Po + -rm -f ./$(DEPDIR)/riscv_corenote.Po + -rm -f ./$(DEPDIR)/riscv_init.Po + -rm -f ./$(DEPDIR)/riscv_initreg.Po + -rm -f ./$(DEPDIR)/riscv_regs.Po + -rm -f ./$(DEPDIR)/riscv_retval.Po + -rm -f ./$(DEPDIR)/riscv_symbol.Po + -rm -f ./$(DEPDIR)/s390_cfi.Po + -rm -f ./$(DEPDIR)/s390_corenote.Po + -rm -f ./$(DEPDIR)/s390_init.Po + -rm -f ./$(DEPDIR)/s390_initreg.Po + -rm -f ./$(DEPDIR)/s390_regs.Po + -rm -f ./$(DEPDIR)/s390_retval.Po + -rm -f ./$(DEPDIR)/s390_symbol.Po + -rm -f ./$(DEPDIR)/s390_unwind.Po + -rm -f ./$(DEPDIR)/s390x_corenote.Po + -rm -f ./$(DEPDIR)/sh_corenote.Po + -rm -f ./$(DEPDIR)/sh_init.Po + -rm -f ./$(DEPDIR)/sh_regs.Po + -rm -f ./$(DEPDIR)/sh_retval.Po + -rm -f ./$(DEPDIR)/sh_symbol.Po + -rm -f ./$(DEPDIR)/sparc64_corenote.Po + -rm -f ./$(DEPDIR)/sparc_attrs.Po + -rm -f ./$(DEPDIR)/sparc_auxv.Po + -rm -f ./$(DEPDIR)/sparc_cfi.Po + -rm -f ./$(DEPDIR)/sparc_corenote.Po + -rm -f ./$(DEPDIR)/sparc_init.Po + -rm -f ./$(DEPDIR)/sparc_initreg.Po + -rm -f ./$(DEPDIR)/sparc_regs.Po + -rm -f ./$(DEPDIR)/sparc_retval.Po + -rm -f ./$(DEPDIR)/sparc_symbol.Po + -rm -f ./$(DEPDIR)/x32_corenote.Po + -rm -f ./$(DEPDIR)/x86_64_cfi.Po + -rm -f ./$(DEPDIR)/x86_64_corenote.Po + -rm -f ./$(DEPDIR)/x86_64_init.Po + -rm -f ./$(DEPDIR)/x86_64_initreg.Po + -rm -f ./$(DEPDIR)/x86_64_regs.Po + -rm -f ./$(DEPDIR)/x86_64_retval.Po + -rm -f ./$(DEPDIR)/x86_64_symbol.Po + -rm -f ./$(DEPDIR)/x86_64_unwind.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/backends/aarch64_cfi.c b/backends/aarch64_cfi.c new file mode 100644 index 00000000..a5579ab1 --- /dev/null +++ b/backends/aarch64_cfi.c @@ -0,0 +1,85 @@ +/* arm64 ABI-specified defaults for DWARF CFI. + Copyright (C) 2013, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + + +/* ABI-specified state of DWARF CFI based on: + + "DWARF for the ARM 64 bit architecture (AArch64) 1.0" +http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf + + "Procedure Call Standard for the ARM 64 bit Architecture 1.0" +http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf +*/ + +int +aarch64_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* The initial Canonical Frame Address is the value of the + Stack Pointer (r31) as setup in the previous frame. */ + DW_CFA_def_cfa, ULEB128_7 (30), ULEB128_7 (0), + +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + /* Callee-saved regs r19-r28. */ + SV (19), SV (20), SV (21), SV (22), SV (23), + SV (24), SV (25), SV (26), SV (27), SV (28), + + /* The Frame Pointer (FP, r29) and Link Register (LR, r30). */ + SV (29), SV (30), + + /* The Stack Pointer (r31) is restored from CFA address by default. */ + DW_CFA_val_offset, ULEB128_7 (31), ULEB128_7 (0), + + /* Callee-saved fpregs v8-v15. v0 == 64. */ + SV (72), SV (73), SV (74), SV (75), + SV (76), SV (77), SV (78), SV (79), +#undef SV + + /* XXX Note: registers intentionally unused by the program, + for example as a consequence of the procedure call standard + should be initialized as if by DW_CFA_same_value. */ + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = -4; + + abi_info->return_address_register = 30; /* lr. */ + + return 0; +} diff --git a/backends/aarch64_corenote.c b/backends/aarch64_corenote.c new file mode 100644 index 00000000..905a4b8a --- /dev/null +++ b/backends/aarch64_corenote.c @@ -0,0 +1,172 @@ +/* AArch64 specific core note handling. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + +#define ULONG uint64_t +#define PID_T int32_t +#define UID_T uint32_t +#define GID_T uint32_t +#define ALIGN_ULONG 8 +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 4 +#define ALIGN_GID_T 4 +#define TYPE_ULONG ELF_T_XWORD +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_WORD +#define TYPE_GID_T ELF_T_WORD + +#define PRSTATUS_REGS_SIZE (34 * 8) + +static const Ebl_Register_Location prstatus_regs[] = + { + { .offset = 0, .regno = 0, .count = 32, .bits = 64 }, /* x0..x30, sp */ + }; + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "pc", .type = ELF_T_XWORD, .format = 'x', \ + .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg) \ + + PRSTATUS_REGS_SIZE - 16), \ + .group = "register", \ + .pc_register = true \ + }, \ + { \ + .name = "pstate", .type = ELF_T_XWORD, .format = 'x', \ + .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg) \ + + PRSTATUS_REGS_SIZE - 8), \ + .group = "register" \ + } + +static const Ebl_Register_Location aarch64_fpregset_regs[] = + { + { .offset = 0, .regno = 64, .count = 32, .bits = 128 }, /* v0..v31 */ + }; + +static const Ebl_Core_Item aarch64_fpregset_items[] = + { + { + .name = "fpsr", .type = ELF_T_WORD, .format = 'x', + .offset = 512, .group = "register" + }, + { + .name = "fpcr", .type = ELF_T_WORD, .format = 'x', + .offset = 516, .group = "register" + } + }; + +static const Ebl_Core_Item aarch64_tls_items[] = + { + { + .name = "tls", .type = ELF_T_XWORD, .format = 'x', + .offset = 0, .group = "register" + } + }; + +static const Ebl_Core_Item aarch64_syscall_items [] = + { + { + .name = "syscall", .type = ELF_T_WORD, .format = 'x', + .offset = 0, .group = "register" + } + }; + +#define AARCH64_HWBP_REG(KIND, N) \ + { \ + .name = "DBG" KIND "VR" #N "_EL1", .type = ELF_T_XWORD, .format = 'x', \ + .offset = 8 + N * 16, .group = "register" \ + }, \ + { \ + .name = "DBG" KIND "CR" #N "_EL1", .type = ELF_T_WORD, .format = 'x', \ + .offset = 16 + N * 16, .group = "register" \ + } + +#define AARCH64_BP_WP_GROUP(KIND, NAME) \ + static const Ebl_Core_Item NAME[] = \ + { \ + { \ + .name = "dbg_info", .type = ELF_T_WORD, .format = 'x', \ + .offset = 0, .group = "control" \ + }, \ + /* N.B.: 4 bytes of padding here. */ \ + \ + AARCH64_HWBP_REG(KIND, 0), \ + AARCH64_HWBP_REG(KIND, 1), \ + AARCH64_HWBP_REG(KIND, 2), \ + AARCH64_HWBP_REG(KIND, 3), \ + AARCH64_HWBP_REG(KIND, 4), \ + AARCH64_HWBP_REG(KIND, 5), \ + AARCH64_HWBP_REG(KIND, 6), \ + AARCH64_HWBP_REG(KIND, 7), \ + AARCH64_HWBP_REG(KIND, 8), \ + AARCH64_HWBP_REG(KIND, 9), \ + AARCH64_HWBP_REG(KIND, 10), \ + AARCH64_HWBP_REG(KIND, 11), \ + AARCH64_HWBP_REG(KIND, 12), \ + AARCH64_HWBP_REG(KIND, 13), \ + AARCH64_HWBP_REG(KIND, 14), \ + AARCH64_HWBP_REG(KIND, 15), \ + \ + /* The DBGBVR+DBGBCR pair only takes 12 bytes. There are 4 bytes \ + of padding at the end of each pair. The item formatter in \ + readelf can skip those, but the missing 4 bytes at the end of \ + the whole block cause it to assume the whole item bunch \ + repeats, so it loops around to read more. Insert an explicit \ + (but invisible) padding word. */ \ + { \ + .name = "", .type = ELF_T_WORD, .format = 'h', \ + .offset = 260, .group = "register" \ + } \ + } + +AARCH64_BP_WP_GROUP ("B", aarch64_hw_bp_items); +AARCH64_BP_WP_GROUP ("W", aarch64_hw_wp_items); + +#undef AARCH64_BP_WP_GROUP +#undef AARCH64_HWBP_REG + +#define EXTRA_NOTES \ + EXTRA_REGSET_ITEMS (NT_FPREGSET, 528, \ + aarch64_fpregset_regs, aarch64_fpregset_items) \ + EXTRA_ITEMS (NT_ARM_TLS, 8, aarch64_tls_items) \ + EXTRA_ITEMS (NT_ARM_HW_BREAK, 264, aarch64_hw_bp_items) \ + EXTRA_ITEMS (NT_ARM_HW_WATCH, 264, aarch64_hw_wp_items) \ + EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items) + +#include "linux-core-note.c" diff --git a/backends/aarch64_init.c b/backends/aarch64_init.c new file mode 100644 index 00000000..bed92954 --- /dev/null +++ b/backends/aarch64_init.c @@ -0,0 +1,66 @@ +/* Initialization of AArch64 specific backend library. + Copyright (C) 2013, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND aarch64_ +#define RELOC_PREFIX R_AARCH64_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on aarch64_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +aarch64_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + aarch64_init_reloc (eh); + HOOK (eh, register_info); + HOOK (eh, core_note); + HOOK (eh, reloc_simple_type); + HOOK (eh, return_value_location); + HOOK (eh, check_special_symbol); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); + HOOK (eh, data_marker_symbol); + HOOK (eh, abi_cfi); + + /* X0-X30 (31 regs) + SP + 1 Reserved + ELR, 30 Reserved regs (34-43) + + V0-V31 (32 regs, least significant 64 bits only) + + ALT_FRAME_RETURN_COLUMN (used when LR isn't used) = 97 DWARF regs. */ + eh->frame_nregs = 97; + HOOK (eh, set_initial_registers_tid); + HOOK (eh, unwind); + + return eh; +} diff --git a/backends/aarch64_initreg.c b/backends/aarch64_initreg.c new file mode 100644 index 00000000..daf6f375 --- /dev/null +++ b/backends/aarch64_initreg.c @@ -0,0 +1,92 @@ +/* Fetch live process registers from TID. + Copyright (C) 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "system.h" +#include +#if defined(__aarch64__) && defined(__linux__) +# include +# include +# include +/* Deal with old glibc defining user_pt_regs instead of user_regs_struct. */ +# ifndef HAVE_SYS_USER_REGS +# define user_regs_struct user_pt_regs +# define user_fpsimd_struct user_fpsimd_state +# endif +#endif + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + +bool +aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined(__aarch64__) || !defined(__linux__) + return false; +#else /* __aarch64__ */ + + /* General registers. */ + struct user_regs_struct gregs; + struct iovec iovec; + iovec.iov_base = &gregs; + iovec.iov_len = sizeof (gregs); + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0) + return false; + + /* X0..X30 plus SP. */ + if (! setfunc (0, 32, (Dwarf_Word *) &gregs.regs[0], arg)) + return false; + + /* PC. */ + if (! setfunc (-1, 1, (Dwarf_Word *) &gregs.pc, arg)) + return false; + + /* ELR cannot be found. */ + + /* FP registers (only 64bits are used). */ + struct user_fpsimd_struct fregs; + iovec.iov_base = &fregs; + iovec.iov_len = sizeof (fregs); + if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec) != 0) + return false; + + Dwarf_Word dwarf_fregs[32]; + for (int r = 0; r < 32; r++) + dwarf_fregs[r] = fregs.vregs[r] & 0xFFFFFFFF; + + if (! setfunc (64, 32, dwarf_fregs, arg)) + return false; + + return true; +#endif /* __aarch64__ */ +} diff --git a/backends/aarch64_regs.c b/backends/aarch64_regs.c new file mode 100644 index 00000000..23014bfc --- /dev/null +++ b/backends/aarch64_regs.c @@ -0,0 +1,108 @@ +/* Register names and numbers for AArch64 DWARF. + Copyright (C) 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + +__attribute__ ((format (printf, 7, 8))) +static ssize_t +do_regtype (const char *setname, int type, + const char **setnamep, int *typep, + char *name, size_t namelen, const char *fmt, ...) +{ + *setnamep = setname; + *typep = type; + + va_list ap; + va_start (ap, fmt); + int s = vsnprintf (name, namelen, fmt, ap); + va_end(ap); + + if (s < 0 || (unsigned) s >= namelen) + return -1; + return s + 1; +} + +ssize_t +aarch64_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setnamep, + int *bits, int *typep) +{ + if (name == NULL) + return 128; + + + *prefix = ""; + *bits = 64; + +#define regtype(setname, type, ...) \ + do_regtype(setname, type, setnamep, typep, name, namelen, __VA_ARGS__) + + switch (regno) + { + case 0 ... 30: + return regtype ("integer", DW_ATE_signed, "x%d", regno); + + case 31: + return regtype ("integer", DW_ATE_address, "sp"); + + case 32: + return 0; + + case 33: + return regtype ("integer", DW_ATE_address, "elr"); + + case 34 ... 63: + return 0; + + case 64 ... 95: + /* FP/SIMD register file supports a variety of data types--it + can be thought of as a register holding a single integer or + floating-point value, or a vector of 8-, 16-, 32- or 64-bit + integers. 128-bit quad-word is the only singular value that + covers the whole register, so mark the register thus. */ + *bits = 128; + return regtype ("FP/SIMD", DW_ATE_unsigned, "v%d", regno - 64); + + case 96 ... 127: + return 0; + + default: + return -1; + } +} diff --git a/backends/aarch64_reloc.def b/backends/aarch64_reloc.def new file mode 100644 index 00000000..f8946877 --- /dev/null +++ b/backends/aarch64_reloc.def @@ -0,0 +1,157 @@ +/* List the relocation types for AArch64. -*- C -*- + Copyright (C) 2013, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (ABS64, REL|EXEC|DYN) +RELOC_TYPE (ABS32, REL|EXEC|DYN) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JUMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (TLS_DTPMOD, EXEC|DYN) +RELOC_TYPE (TLS_DTPREL, EXEC|DYN) +RELOC_TYPE (TLS_TPREL, EXEC|DYN) +RELOC_TYPE (TLSDESC, EXEC|DYN) + +/* R_AARCH64_NONE records that the section containing the place to be + relocated depends on the section defining the symbol mentioned in + the relocation directive[.] (ARM IHI 0056B). */ +RELOC_TYPE (NONE, REL) + +RELOC_TYPE (ABS16, REL) +RELOC_TYPE (PREL64, REL) +RELOC_TYPE (PREL32, REL) +RELOC_TYPE (PREL16, REL) +RELOC_TYPE (MOVW_UABS_G0, REL) +RELOC_TYPE (MOVW_UABS_G0_NC, REL) +RELOC_TYPE (MOVW_UABS_G1, REL) +RELOC_TYPE (MOVW_UABS_G1_NC, REL) +RELOC_TYPE (MOVW_UABS_G2, REL) +RELOC_TYPE (MOVW_UABS_G2_NC, REL) +RELOC_TYPE (MOVW_UABS_G3, REL) +RELOC_TYPE (MOVW_SABS_G0, REL) +RELOC_TYPE (MOVW_SABS_G1, REL) +RELOC_TYPE (MOVW_SABS_G2, REL) +RELOC_TYPE (LD_PREL_LO19, REL) +RELOC_TYPE (ADR_PREL_LO21, REL) +RELOC_TYPE (ADR_PREL_PG_HI21, REL) +RELOC_TYPE (ADR_PREL_PG_HI21_NC, REL) +RELOC_TYPE (ADD_ABS_LO12_NC, REL) +RELOC_TYPE (LDST8_ABS_LO12_NC, REL) +RELOC_TYPE (LDST16_ABS_LO12_NC, REL) +RELOC_TYPE (LDST32_ABS_LO12_NC, REL) +RELOC_TYPE (LDST64_ABS_LO12_NC, REL) +RELOC_TYPE (LDST128_ABS_LO12_NC, REL) +RELOC_TYPE (TSTBR14, REL) +RELOC_TYPE (CONDBR19, REL) +RELOC_TYPE (JUMP26, REL) +RELOC_TYPE (CALL26, REL) +RELOC_TYPE (MOVW_PREL_G0, REL) +RELOC_TYPE (MOVW_PREL_G0_NC, REL) +RELOC_TYPE (MOVW_PREL_G1, REL) +RELOC_TYPE (MOVW_PREL_G1_NC, REL) +RELOC_TYPE (MOVW_PREL_G2, REL) +RELOC_TYPE (MOVW_PREL_G2_NC, REL) +RELOC_TYPE (MOVW_PREL_G3, REL) +RELOC_TYPE (MOVW_GOTOFF_G0, REL) +RELOC_TYPE (MOVW_GOTOFF_G0_NC, REL) +RELOC_TYPE (MOVW_GOTOFF_G1, REL) +RELOC_TYPE (MOVW_GOTOFF_G1_NC, REL) +RELOC_TYPE (MOVW_GOTOFF_G2, REL) +RELOC_TYPE (MOVW_GOTOFF_G2_NC, REL) +RELOC_TYPE (MOVW_GOTOFF_G3, REL) +RELOC_TYPE (GOTREL64, REL) +RELOC_TYPE (GOTREL32, REL) +RELOC_TYPE (GOT_LD_PREL19, REL) +RELOC_TYPE (LD64_GOTOFF_LO15, REL) +RELOC_TYPE (ADR_GOT_PAGE, REL) +RELOC_TYPE (LD64_GOT_LO12_NC, REL) +RELOC_TYPE (LD64_GOTPAGE_LO15, REL) +RELOC_TYPE (TLSGD_ADR_PREL21, REL) +RELOC_TYPE (TLSGD_ADR_PAGE21, REL) +RELOC_TYPE (TLSGD_ADD_LO12_NC, REL) +RELOC_TYPE (TLSGD_MOVW_G1, REL) +RELOC_TYPE (TLSGD_MOVW_G0_NC, REL) +RELOC_TYPE (TLSLD_ADR_PREL21, REL) +RELOC_TYPE (TLSLD_ADR_PAGE21, REL) +RELOC_TYPE (TLSLD_ADD_LO12_NC, REL) +RELOC_TYPE (TLSLD_MOVW_G1, REL) +RELOC_TYPE (TLSLD_MOVW_G0_NC, REL) +RELOC_TYPE (TLSLD_LD_PREL19, REL) +RELOC_TYPE (TLSLD_MOVW_DTPREL_G2, REL) +RELOC_TYPE (TLSLD_MOVW_DTPREL_G1, REL) +RELOC_TYPE (TLSLD_MOVW_DTPREL_G1_NC, REL) +RELOC_TYPE (TLSLD_MOVW_DTPREL_G0, REL) +RELOC_TYPE (TLSLD_MOVW_DTPREL_G0_NC, REL) +RELOC_TYPE (TLSLD_ADD_DTPREL_HI12, REL) +RELOC_TYPE (TLSLD_ADD_DTPREL_LO12, REL) +RELOC_TYPE (TLSLD_ADD_DTPREL_LO12_NC, REL) +RELOC_TYPE (TLSLD_LDST8_DTPREL_LO12, REL) +RELOC_TYPE (TLSLD_LDST8_DTPREL_LO12_NC, REL) +RELOC_TYPE (TLSLD_LDST16_DTPREL_LO12, REL) +RELOC_TYPE (TLSLD_LDST16_DTPREL_LO12_NC, REL) +RELOC_TYPE (TLSLD_LDST32_DTPREL_LO12, REL) +RELOC_TYPE (TLSLD_LDST32_DTPREL_LO12_NC, REL) +RELOC_TYPE (TLSLD_LDST64_DTPREL_LO12, REL) +RELOC_TYPE (TLSLD_LDST64_DTPREL_LO12_NC, REL) +RELOC_TYPE (TLSLD_LDST128_DTPREL_LO12, REL) +RELOC_TYPE (TLSLD_LDST128_DTPREL_LO12_NC, REL) +RELOC_TYPE (TLSIE_MOVW_GOTTPREL_G1, REL) +RELOC_TYPE (TLSIE_MOVW_GOTTPREL_G0_NC, REL) +RELOC_TYPE (TLSIE_ADR_GOTTPREL_PAGE21, REL) +RELOC_TYPE (TLSIE_LD64_GOTTPREL_LO12_NC, REL) +RELOC_TYPE (TLSIE_LD_GOTTPREL_PREL19, REL) +RELOC_TYPE (TLSLE_MOVW_TPREL_G2, REL) +RELOC_TYPE (TLSLE_MOVW_TPREL_G1, REL) +RELOC_TYPE (TLSLE_MOVW_TPREL_G1_NC, REL) +RELOC_TYPE (TLSLE_MOVW_TPREL_G0, REL) +RELOC_TYPE (TLSLE_MOVW_TPREL_G0_NC, REL) +RELOC_TYPE (TLSLE_ADD_TPREL_HI12, REL) +RELOC_TYPE (TLSLE_ADD_TPREL_LO12, REL) +RELOC_TYPE (TLSLE_ADD_TPREL_LO12_NC, REL) +RELOC_TYPE (TLSLE_LDST8_TPREL_LO12, REL) +RELOC_TYPE (TLSLE_LDST8_TPREL_LO12_NC, REL) +RELOC_TYPE (TLSLE_LDST16_TPREL_LO12, REL) +RELOC_TYPE (TLSLE_LDST16_TPREL_LO12_NC, REL) +RELOC_TYPE (TLSLE_LDST32_TPREL_LO12, REL) +RELOC_TYPE (TLSLE_LDST32_TPREL_LO12_NC, REL) +RELOC_TYPE (TLSLE_LDST64_TPREL_LO12, REL) +RELOC_TYPE (TLSLE_LDST64_TPREL_LO12_NC, REL) +RELOC_TYPE (TLSLE_LDST128_TPREL_LO12, REL) +RELOC_TYPE (TLSLE_LDST128_TPREL_LO12_NC, REL) +RELOC_TYPE (TLSDESC_LD_PREL19, REL) +RELOC_TYPE (TLSDESC_ADR_PREL21, REL) +RELOC_TYPE (TLSDESC_ADR_PAGE21, REL) +RELOC_TYPE (TLSDESC_LD64_LO12, REL) +RELOC_TYPE (TLSDESC_ADD_LO12, REL) +RELOC_TYPE (TLSDESC_OFF_G1, REL) +RELOC_TYPE (TLSDESC_OFF_G0_NC, REL) +RELOC_TYPE (TLSDESC_LDR, REL) +RELOC_TYPE (TLSDESC_ADD, REL) +RELOC_TYPE (TLSDESC_CALL, REL) diff --git a/backends/aarch64_retval.c b/backends/aarch64_retval.c new file mode 100644 index 00000000..72d4e8a3 --- /dev/null +++ b/backends/aarch64_retval.c @@ -0,0 +1,376 @@ +/* Function return value location for Linux/AArch64 ABI. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + +static int +skip_until (Dwarf_Die *child, int tag) +{ + int i; + while (DWARF_TAG_OR_RETURN (child) != tag) + if ((i = dwarf_siblingof (child, child)) != 0) + /* If there are no members, then this is not a HFA. Errors + are propagated. */ + return i; + return 0; +} + +static int +dwarf_bytesize_aux (Dwarf_Die *die, Dwarf_Word *sizep) +{ + int bits; + if (((bits = 8 * dwarf_bytesize (die)) < 0 + && (bits = dwarf_bitsize (die)) < 0) + || bits % 8 != 0) + return -1; + + *sizep = bits / 8; + return 0; +} + +/* HFA (Homogeneous Floating-point Aggregate) is an aggregate type + whose members are all of the same floating-point type, which is + then base type of this HFA. Instead of being floating-point types + directly, members can instead themselves be HFA. Such HFA fields + are handled as if their type were HFA base type. + + This function returns 0 if TYPEDIE is HFA, 1 if it is not, or -1 if + there were errors. In the former case, *SIZEP contains byte size + of the base type (e.g. 8 for IEEE double). *COUNT is set to the + number of leaf members of the HFA. */ +static int hfa_type (Dwarf_Die *ftypedie, int tag, + Dwarf_Word *sizep, Dwarf_Word *countp); + +/* Return 0 if MEMBDIE refers to a member with a floating-point or HFA + type, or 1 if it's not. Return -1 for errors. The meaning of the + remaining arguments is as documented at hfa_type. */ +static int +member_is_fp (Dwarf_Die *membdie, Dwarf_Word *sizep, Dwarf_Word *countp) +{ + Dwarf_Die typedie; + int tag = dwarf_peeled_die_type (membdie, &typedie); + switch (tag) + { + case DW_TAG_base_type:; + Dwarf_Word encoding; + Dwarf_Attribute attr_mem; + if (dwarf_attr_integrate (&typedie, DW_AT_encoding, &attr_mem) == NULL + || dwarf_formudata (&attr_mem, &encoding) != 0) + return -1; + + switch (encoding) + { + case DW_ATE_complex_float: + *countp = 2; + break; + + case DW_ATE_float: + *countp = 1; + break; + + default: + return 1; + } + + if (dwarf_bytesize_aux (&typedie, sizep) < 0) + return -1; + + *sizep /= *countp; + return 0; + + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + return hfa_type (&typedie, tag, sizep, countp); + } + + return 1; +} + +static int +hfa_type (Dwarf_Die *ftypedie, int tag, Dwarf_Word *sizep, Dwarf_Word *countp) +{ + assert (tag == DW_TAG_structure_type || tag == DW_TAG_class_type + || tag == DW_TAG_union_type || tag == DW_TAG_array_type); + + int i; + if (tag == DW_TAG_array_type) + { + Dwarf_Word tot_size; + if (dwarf_aggregate_size (ftypedie, &tot_size) < 0) + return -1; + + /* For vector types, we don't care about the underlying + type, but only about the vector type itself. */ + bool vec; + Dwarf_Attribute attr_mem; + if (dwarf_formflag (dwarf_attr_integrate (ftypedie, DW_AT_GNU_vector, + &attr_mem), &vec) == 0 + && vec) + { + *sizep = tot_size; + *countp = 1; + + return 0; + } + + if ((i = member_is_fp (ftypedie, sizep, countp)) == 0) + { + *countp = tot_size / *sizep; + return 0; + } + + return i; + } + + /* Find first DW_TAG_member and determine its type. */ + Dwarf_Die member; + if ((i = dwarf_child (ftypedie, &member) != 0)) + return i; + + if ((i = skip_until (&member, DW_TAG_member)) != 0) + return i; + + *countp = 0; + if ((i = member_is_fp (&member, sizep, countp)) != 0) + return i; + + while ((i = dwarf_siblingof (&member, &member)) == 0 + && (i = skip_until (&member, DW_TAG_member)) == 0) + { + Dwarf_Word size, count; + if ((i = member_is_fp (&member, &size, &count)) != 0) + return i; + + if (*sizep != size) + return 1; + + *countp += count; + } + + /* At this point we already have at least one FP member, which means + FTYPEDIE is an HFA. So either return 0, or propagate error. */ + return i < 0 ? i : 0; +} + +static int +pass_in_gpr (const Dwarf_Op **locp, Dwarf_Word size) +{ + static const Dwarf_Op loc[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 8 } + }; + + *locp = loc; + return size <= 8 ? 1 : 4; +} + +static int +pass_by_ref (const Dwarf_Op **locp) +{ + static const Dwarf_Op loc[] = { { .atom = DW_OP_breg0 } }; + + *locp = loc; + return 1; +} + +static int +pass_hfa (const Dwarf_Op **locp, Dwarf_Word size, Dwarf_Word count) +{ + assert (count >= 1 && count <= 4); + assert (size == 2 || size == 4 || size == 8 || size == 16); + +#define DEFINE_FPREG(NAME, SIZE) \ + static const Dwarf_Op NAME[] = { \ + { .atom = DW_OP_regx, .number = 64 }, \ + { .atom = DW_OP_piece, .number = SIZE }, \ + { .atom = DW_OP_regx, .number = 65 }, \ + { .atom = DW_OP_piece, .number = SIZE }, \ + { .atom = DW_OP_regx, .number = 66 }, \ + { .atom = DW_OP_piece, .number = SIZE }, \ + { .atom = DW_OP_regx, .number = 67 }, \ + { .atom = DW_OP_piece, .number = SIZE } \ + } + + switch (size) + { + case 2:; + DEFINE_FPREG (loc_hfa_2, 2); + *locp = loc_hfa_2; + break; + + case 4:; + DEFINE_FPREG (loc_hfa_4, 4); + *locp = loc_hfa_4; + break; + + case 8:; + DEFINE_FPREG (loc_hfa_8, 8); + *locp = loc_hfa_8; + break; + + case 16:; + DEFINE_FPREG (loc_hfa_16, 16); + *locp = loc_hfa_16; + break; + } +#undef DEFINE_FPREG + + return count == 1 ? 1 : 2 * count; +} + +static int +pass_in_simd (const Dwarf_Op **locp) +{ + /* This is like passing single-element HFA. Size doesn't matter, so + pretend it's for example double. */ + return pass_hfa (locp, 8, 1); +} + +int +aarch64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die typedie; + int tag = dwarf_peeled_die_type (functypedie, &typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size = (Dwarf_Word)-1; + + /* If the argument type is a Composite Type that is larger than 16 + bytes, then the argument is copied to memory allocated by the + caller and the argument is replaced by a pointer to the copy. */ + if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type + || tag == DW_TAG_class_type || tag == DW_TAG_array_type) + { + Dwarf_Word base_size, count; + switch (hfa_type (&typedie, tag, &base_size, &count)) + { + default: + return -1; + + case 0: + assert (count > 0); + if (count <= 4) + return pass_hfa (locp, base_size, count); + FALLTHROUGH; + + case 1: + /* Not a HFA. */ + if (dwarf_aggregate_size (&typedie, &size) < 0) + return -1; + if (size > 16) + return pass_by_ref (locp); + } + } + + if (tag == DW_TAG_base_type + || tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + { + if (dwarf_bytesize_aux (&typedie, &size) < 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 8; + else + return -1; + } + + Dwarf_Attribute attr_mem; + if (tag == DW_TAG_base_type) + { + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (&typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + + switch (encoding) + { + /* If the argument is a Half-, Single-, Double- or Quad- + precision Floating-point [...] the argument is allocated + to the least significant bits of register v[NSRN]. */ + case DW_ATE_float: + switch (size) + { + case 2: /* half */ + case 4: /* single */ + case 8: /* double */ + case 16: /* quad */ + return pass_in_simd (locp); + + default: + return -2; + } + + case DW_ATE_complex_float: + switch (size) + { + case 8: /* float _Complex */ + case 16: /* double _Complex */ + case 32: /* long double _Complex */ + return pass_hfa (locp, size / 2, 2); + + default: + return -2; + } + + /* If the argument is an Integral or Pointer Type, the + size of the argument is less than or equal to 8 bytes + [...] the argument is copied to the least significant + bits in x[NGRN]. */ + case DW_ATE_boolean: + case DW_ATE_signed: + case DW_ATE_unsigned: + case DW_ATE_unsigned_char: + case DW_ATE_signed_char: + return pass_in_gpr (locp, size); + } + + return -2; + } + else + return pass_in_gpr (locp, size); + } + + *locp = NULL; + return 0; +} diff --git a/backends/aarch64_symbol.c b/backends/aarch64_symbol.c new file mode 100644 index 00000000..15e0805b --- /dev/null +++ b/backends/aarch64_symbol.c @@ -0,0 +1,136 @@ +/* AArch64 specific symbolic name handling. + Copyright (C) 2013, 2015, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_AARCH64_ABS64: + return ELF_T_XWORD; + case R_AARCH64_ABS32: + return ELF_T_WORD; + case R_AARCH64_ABS16: + return ELF_T_HALF; + + default: + return ELF_T_NUM; + } +} + +/* If this is the _GLOBAL_OFFSET_TABLE_ symbol, then it should point in + the .got even if there is a .got.plt section. + https://sourceware.org/ml/libc-ports/2013-06/msg00057.html + https://bugzilla.redhat.com/show_bug.cgi?id=1201778 + */ +bool +aarch64_check_special_symbol (Elf *elf, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) +{ + if (name != NULL + && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + { + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); + if (sname != NULL + && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0)) + { + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + { + sname = elf_strptr (elf, shstrndx, shdr->sh_name); + if (sname != NULL && strcmp (sname, ".got") == 0) + return (sym->st_value >= shdr->sh_addr + && sym->st_value < shdr->sh_addr + shdr->sh_size); + } + } + } + } + + return false; +} + +/* A data mapping symbol is a symbol with "$d" name or "$d." name, + STT_NOTYPE, STB_LOCAL and st_size of zero. The indicate the stat of a + sequence of data items. */ +bool +aarch64_data_marker_symbol (const GElf_Sym *sym, const char *sname) +{ + return (sym != NULL && sname != NULL + && sym->st_size == 0 && GELF_ST_BIND (sym->st_info) == STB_LOCAL + && GELF_ST_TYPE (sym->st_info) == STT_NOTYPE + && (strcmp (sname, "$d") == 0 || startswith (sname, "$d."))); +} + +const char * +aarch64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_AARCH64_BTI_PLT: + return "AARCH64_BTI_PLT"; + case DT_AARCH64_PAC_PLT: + return "AARCH64_PAC_PLT"; + case DT_AARCH64_VARIANT_PCS: + return "AARCH64_VARIANT_PCS"; + default: + break; + } + return NULL; +} + +bool +aarch64_dynamic_tag_check (int64_t tag) +{ + return (tag == DT_AARCH64_BTI_PLT + || tag == DT_AARCH64_PAC_PLT + || tag == DT_AARCH64_VARIANT_PCS); +} diff --git a/backends/aarch64_unwind.c b/backends/aarch64_unwind.c new file mode 100644 index 00000000..e0a7e96e --- /dev/null +++ b/backends/aarch64_unwind.c @@ -0,0 +1,83 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2016 The Qt Company Ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND aarch64_ +#define FP_REG 29 +#define LR_REG 30 +#define SP_REG 31 +#define FP_OFFSET 0 +#define LR_OFFSET 8 +#define SP_OFFSET 16 + +#include "libebl_CPU.h" + +/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that? */ + +bool +EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc __attribute__ ((unused)), + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep __attribute__ ((unused))) +{ + Dwarf_Word fp, lr, sp; + + if (!getfunc(LR_REG, 1, &lr, arg)) + return false; + + if (lr == 0 || !setfunc(-1, 1, &lr, arg)) + return false; + + if (!getfunc(FP_REG, 1, &fp, arg)) + fp = 0; + + if (!getfunc(SP_REG, 1, &sp, arg)) + sp = 0; + + Dwarf_Word newLr, newFp, newSp; + + if (!readfunc(fp + LR_OFFSET, &newLr, arg)) + newLr = 0; + + if (!readfunc(fp + FP_OFFSET, &newFp, arg)) + newFp = 0; + + newSp = fp + SP_OFFSET; + + // These are not fatal if they don't work. They will just prevent unwinding at the next frame. + setfunc(LR_REG, 1, &newLr, arg); + setfunc(FP_REG, 1, &newFp, arg); + setfunc(SP_REG, 1, &newSp, arg); + + // If the fp is invalid, we might still have a valid lr. + // But if the fp is valid, then the stack should be moving in the right direction. + return fp == 0 || newSp > sp; +} diff --git a/backends/alpha_auxv.c b/backends/alpha_auxv.c new file mode 100644 index 00000000..83e71997 --- /dev/null +++ b/backends/alpha_auxv.c @@ -0,0 +1,49 @@ +/* Alpha-specific auxv handling. + Copyright (C) 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND alpha_ +#include "libebl_CPU.h" + +int +EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format) +{ + if (a_type != AT_HWCAP) + return 0; + + *name = "HWCAP"; + *format = "b" + "bwx\0" "fix\0" "cix\0" "0x08\0" + "0x10\0" "0x20\0" "0x40\0" "0x80\0" + "max\0" "precise_trap\0" + "\0"; + return 1; +} diff --git a/backends/alpha_corenote.c b/backends/alpha_corenote.c new file mode 100644 index 00000000..6190df37 --- /dev/null +++ b/backends/alpha_corenote.c @@ -0,0 +1,70 @@ +/* PowerPC specific core note handling. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND alpha_ +#include "libebl_CPU.h" + +static const Ebl_Register_Location prstatus_regs[] = + { + { .offset = 0, .regno = 0, .count = 31, .bits = 64 }, /* r0-r30 */ + { .offset = 32 * 8, .regno = 64, .count = 1, .bits = 64 }, /* pc */ + { .offset = 33 * 8, .regno = 66, .count = 1, .bits = 64 }, /* unique */ + }; +#define PRSTATUS_REGS_SIZE (33 * 8) + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 32, .count = 32, .bits = 64 }, /* f0-f30, fpcr */ + }; +#define FPREGSET_SIZE (32 * 8) + +#define ULONG uint64_t +#define ALIGN_ULONG 8 +#define TYPE_ULONG ELF_T_XWORD +#define TYPE_LONG ELF_T_SXWORD +#define PID_T int32_t +#define UID_T uint32_t +#define GID_T uint32_t +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 4 +#define ALIGN_GID_T 4 +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_WORD +#define TYPE_GID_T ELF_T_WORD + +#include "linux-core-note.c" diff --git a/backends/alpha_init.c b/backends/alpha_init.c new file mode 100644 index 00000000..c69aec6d --- /dev/null +++ b/backends/alpha_init.c @@ -0,0 +1,63 @@ +/* Initialization of Alpha specific backend library. + Copyright (C) 2002-2011 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND alpha_ +#define RELOC_PREFIX R_ALPHA_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on alpha_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +alpha_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + alpha_init_reloc (eh); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); + HOOK (eh, reloc_simple_type); + HOOK (eh, return_value_location); + HOOK (eh, machine_section_flag_check); + HOOK (eh, check_special_section); + HOOK (eh, check_special_symbol); + HOOK (eh, check_st_other_bits); + HOOK (eh, register_info); + HOOK (eh, core_note); + HOOK (eh, auxv_info); + eh->sysvhash_entrysize = sizeof (Elf64_Xword); + + return eh; +} diff --git a/backends/alpha_regs.c b/backends/alpha_regs.c new file mode 100644 index 00000000..436af3b1 --- /dev/null +++ b/backends/alpha_regs.c @@ -0,0 +1,164 @@ +/* Register names and numbers for Alpha DWARF. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND alpha_ +#include "libebl_CPU.h" + +ssize_t +alpha_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 67; + + if (regno < 0 || regno > 66 || namelen < 7) + return -1; + + *prefix = "$"; + + *bits = 64; + *type = DW_ATE_signed; + *setname = "integer"; + if (regno >= 32 && regno < 64) + { + *setname = "FPU"; + *type = DW_ATE_float; + } + + switch (regno) + { + case 0: + name[0] = 'v'; + name[1] = '0'; + namelen = 2; + break; + + case 1 ... 8: + name[0] = 't'; + name[1] = regno - 1 + '0'; + namelen = 2; + break; + + case 9 ... 15: + name[0] = 's'; + name[1] = regno - 9 + '0'; + namelen = 2; + break; + + case 16 ... 21: + name[0] = 'a'; + name[1] = regno - 16 + '0'; + namelen = 2; + break; + + case 22 ... 23: + name[0] = 't'; + name[1] = regno - 22 + '8'; + namelen = 2; + break; + + case 24 ... 25: + name[0] = 't'; + name[1] = '1'; + name[2] = regno - 24 + '0'; + namelen = 3; + break; + + case 26: + *type = DW_ATE_address; + return stpcpy (name, "ra") + 1 - name; + + case 27: + return stpcpy (name, "t12") + 1 - name; + + case 28: + return stpcpy (name, "at") + 1 - name; + + case 29: + *type = DW_ATE_address; + return stpcpy (name, "gp") + 1 - name; + + case 30: + *type = DW_ATE_address; + return stpcpy (name, "sp") + 1 - name; + + case 31: + return stpcpy (name, "zero") + 1 - name; + + case 32 ... 32 + 9: + name[0] = 'f'; + name[1] = regno - 32 + '0'; + namelen = 2; + break; + + case 32 + 10 ... 32 + 19: + name[0] = 'f'; + name[1] = '1'; + name[2] = regno - 32 - 10 + '0'; + namelen = 3; + break; + + case 32 + 20 ... 32 + 29: + name[0] = 'f'; + name[1] = '2'; + name[2] = regno - 32 - 20 + '0'; + namelen = 3; + break; + + case 32 + 30: + return stpcpy (name, "f30") + 1 - name; + + case 32 + 31: + *type = DW_ATE_unsigned; + return stpcpy (name, "fpcr") + 1 - name; + + case 64: + *type = DW_ATE_address; + return stpcpy (name, "pc") + 1 - name; + + case 66: + *type = DW_ATE_address; + return stpcpy (name, "unique") + 1 - name; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/alpha_reloc.def b/backends/alpha_reloc.def new file mode 100644 index 00000000..ed7e5c32 --- /dev/null +++ b/backends/alpha_reloc.def @@ -0,0 +1,63 @@ +/* List the relocation types for alpha. -*- C -*- + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (REFLONG, REL|EXEC|DYN) +RELOC_TYPE (REFQUAD, REL|EXEC|DYN) +RELOC_TYPE (GPREL32, REL) +RELOC_TYPE (LITERAL, REL) +RELOC_TYPE (LITUSE, REL) +RELOC_TYPE (GPDISP, REL) +RELOC_TYPE (BRADDR, REL) +RELOC_TYPE (HINT, REL) +RELOC_TYPE (SREL16, REL) +RELOC_TYPE (SREL32, REL) +RELOC_TYPE (SREL64, REL) +RELOC_TYPE (GPRELHIGH, REL) +RELOC_TYPE (GPRELLOW, REL) +RELOC_TYPE (GPREL16, REL) +RELOC_TYPE (COPY, 0) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (TLS_GD_HI, REL) +RELOC_TYPE (TLSGD, REL) +RELOC_TYPE (TLS_LDM, REL) +RELOC_TYPE (DTPMOD64, REL|EXEC|DYN) +RELOC_TYPE (GOTDTPREL, REL) +RELOC_TYPE (DTPREL64, REL|EXEC|DYN) +RELOC_TYPE (DTPRELHI, REL) +RELOC_TYPE (DTPRELLO, REL) +RELOC_TYPE (DTPREL16, REL) +RELOC_TYPE (GOTTPREL, REL) +RELOC_TYPE (TPREL64, REL|EXEC|DYN) +RELOC_TYPE (TPRELHI, REL) +RELOC_TYPE (TPRELLO, REL) +RELOC_TYPE (TPREL16, REL) diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c new file mode 100644 index 00000000..d9bae3bc --- /dev/null +++ b/backends/alpha_retval.c @@ -0,0 +1,150 @@ +/* Function return value location for Alpha ELF ABI. + Copyright (C) 2005, 2007, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND alpha_ +#include "libebl_CPU.h" + + +/* $0. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 } + }; +#define nloc_intreg 1 + +/* $f0, or pair $f0, $f1. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_fpreg 1 +#define nloc_fpregpair 4 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in $0. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + +int +alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + Dwarf_Word size; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 8; + else + return -1; + } + if (tag == DW_TAG_base_type) + { + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + + *locp = loc_fpreg; + if (encoding == DW_ATE_float) + { + if (size <= 8) + return nloc_fpreg; + goto aggregate; + } + if (encoding == DW_ATE_complex_float) + { + if (size <= 8 * 2) + return nloc_fpregpair; + goto aggregate; + } + } + if (size <= 8) + { + *locp = loc_intreg; + return nloc_intreg; + } + } + + FALLTHROUGH; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_string_type: + case DW_TAG_array_type: + aggregate: + *locp = loc_aggregate; + return nloc_aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/alpha_symbol.c b/backends/alpha_symbol.c new file mode 100644 index 00000000..53a9e7b7 --- /dev/null +++ b/backends/alpha_symbol.c @@ -0,0 +1,156 @@ +/* Alpha specific symbolic name handling. + Copyright (C) 2002-2011 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND alpha_ +#include "libebl_CPU.h" + + +const char * +alpha_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_ALPHA_PLTRO: + return "ALPHA_PLTRO"; + default: + break; + } + return NULL; +} + +bool +alpha_dynamic_tag_check (int64_t tag) +{ + return tag == DT_ALPHA_PLTRO; +} + +/* Check for the simple reloc types. */ +Elf_Type +alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_ALPHA_REFLONG: + return ELF_T_WORD; + case R_ALPHA_REFQUAD: + return ELF_T_XWORD; + default: + return ELF_T_NUM; + } +} + + +/* Check whether SHF_MASKPROC flags are valid. */ +bool +alpha_machine_section_flag_check (GElf_Xword sh_flags) +{ + return (sh_flags &~ (SHF_ALPHA_GPREL)) == 0; +} + +bool +alpha_check_special_section (Ebl *ebl, + int ndx __attribute__ ((unused)), + const GElf_Shdr *shdr, + const char *sname __attribute__ ((unused))) +{ + if ((shdr->sh_flags + & (SHF_WRITE | SHF_EXECINSTR)) == (SHF_WRITE | SHF_EXECINSTR) + && shdr->sh_addr != 0) + { + /* This is ordinarily flagged, but is valid for an old-style PLT. + + Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it. + Its d_ptr should match the .plt section's sh_addr. */ + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr scn_shdr; + if (likely (gelf_getshdr (scn, &scn_shdr) != NULL) + && scn_shdr.sh_type == SHT_DYNAMIC + && scn_shdr.sh_entsize != 0) + { + GElf_Addr pltgot = 0; + Elf_Data *data = elf_getdata (scn, NULL); + if (data != NULL) + for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i) + { + GElf_Dyn dyn; + if (unlikely (gelf_getdyn (data, i, &dyn) == NULL)) + break; + if (dyn.d_tag == DT_PLTGOT) + pltgot = dyn.d_un.d_ptr; + else if (dyn.d_tag == DT_ALPHA_PLTRO && dyn.d_un.d_val != 0) + return false; /* This PLT should not be writable. */ + } + return pltgot == shdr->sh_addr; + } + } + } + + return false; +} + +/* Check whether given symbol's st_value and st_size are OK despite failing + normal checks. */ +bool +alpha_check_special_symbol (Elf *elf __attribute__ ((unused)), + const GElf_Sym *sym __attribute__ ((unused)), + const char *name, + const GElf_Shdr *destshdr __attribute__ ((unused))) +{ + if (name == NULL) + return false; + + if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + /* On Alpha any place in the section is valid. */ + return true; + + return false; +} + +/* Check whether only valid bits are set on the st_other symbol flag. + Standard ST_VISIBILITY have already been masked off. */ +bool +alpha_check_st_other_bits (unsigned char st_other) +{ + return ((((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV) + || ((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)) + && (st_other &~ STO_ALPHA_STD_GPLOAD) == 0); +} diff --git a/backends/arm_attrs.c b/backends/arm_attrs.c new file mode 100644 index 00000000..6842b771 --- /dev/null +++ b/backends/arm_attrs.c @@ -0,0 +1,241 @@ +/* Object attribute tags for ARM. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND arm_ +#include "libebl_CPU.h" + +#define KNOWN_VALUES(...) do \ + { \ + static const char *table[] = { __VA_ARGS__ }; \ + if (value < sizeof table / sizeof table[0]) \ + *value_name = table[value]; \ + } while (0) + +bool +arm_check_object_attribute (Ebl *ebl __attribute__ ((unused)), + const char *vendor, int tag, uint64_t value, + const char **tag_name, const char **value_name) +{ + if (!strcmp (vendor, "aeabi")) + switch (tag) + { + case 4: + *tag_name = "CPU_raw_name"; + return true; + case 5: + *tag_name = "CPU_name"; + return true; + case 6: + *tag_name = "CPU_arch"; + KNOWN_VALUES ("Pre-v4", + "v4", + "v4T", + "v5T", + "v5TE", + "v5TEJ", + "v6", + "v6KZ", + "v6T2", + "v6K", + "v7", + "v6-M", + "v6S-M"); + return true; + case 7: + *tag_name = "CPU_arch_profile"; + switch (value) + { + case 'A': + *value_name = "Application"; + break; + case 'R': + *value_name = "Realtime"; + break; + case 'M': + *value_name = "Microcontroller"; + break; + } + return true; + case 8: + *tag_name = "ARM_ISA_use"; + KNOWN_VALUES ("No", "Yes"); + return true; + case 9: + *tag_name = "THUMB_ISA_use"; + KNOWN_VALUES ("No", "Thumb-1", "Thumb-2"); + return true; + case 10: + *tag_name = "VFP_arch"; + KNOWN_VALUES ("No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"); + return true; + case 11: + *tag_name = "WMMX_arch"; + KNOWN_VALUES ("No", "WMMXv1", "WMMXv2"); + return true; + case 12: + *tag_name = "Advanced_SIMD_arch"; + KNOWN_VALUES ("No", "NEONv1"); + return true; + case 13: + *tag_name = "PCS_config"; + KNOWN_VALUES ("None", + "Bare platform", + "Linux application", + "Linux DSO", + "PalmOS 2004", + "PalmOS (reserved)", + "SymbianOS 2004", + "SymbianOS (reserved)"); + return true; + case 14: + *tag_name = "ABI_PCS_R9_use"; + KNOWN_VALUES ("V6", "SB", "TLS", "Unused"); + return true; + case 15: + *tag_name = "ABI_PCS_RW_data"; + KNOWN_VALUES ("Absolute", "PC-relative", "SB-relative", "None"); + return true; + case 16: + *tag_name = "ABI_PCS_RO_data"; + KNOWN_VALUES ("Absolute", "PC-relative", "None"); + return true; + case 17: + *tag_name = "ABI_PCS_GOT_use"; + KNOWN_VALUES ("None", "direct", "GOT-indirect"); + return true; + case 18: + *tag_name = "ABI_PCS_wchar_t"; + return true; + case 19: + *tag_name = "ABI_FP_rounding"; + KNOWN_VALUES ("Unused", "Needed"); + return true; + case 20: + *tag_name = "ABI_FP_denormal"; + KNOWN_VALUES ("Unused", "Needed", "Sign only"); + return true; + case 21: + *tag_name = "ABI_FP_exceptions"; + KNOWN_VALUES ("Unused", "Needed"); + return true; + case 22: + *tag_name = "ABI_FP_user_exceptions"; + KNOWN_VALUES ("Unused", "Needed"); + return true; + case 23: + *tag_name = "ABI_FP_number_model"; + KNOWN_VALUES ("Unused", "Finite", "RTABI", "IEEE 754"); + return true; + case 24: + *tag_name = "ABI_align8_needed"; + KNOWN_VALUES ("No", "Yes", "4-byte"); + return true; + case 25: + *tag_name = "ABI_align8_preserved"; + KNOWN_VALUES ("No", "Yes, except leaf SP", "Yes"); + return true; + case 26: + *tag_name = "ABI_enum_size"; + KNOWN_VALUES ("Unused", "small", "int", "forced to int"); + return true; + case 27: + *tag_name = "ABI_HardFP_use"; + KNOWN_VALUES ("as VFP_arch", "SP only", "DP only", "SP and DP"); + return true; + case 28: + *tag_name = "ABI_VFP_args"; + KNOWN_VALUES ("AAPCS", "VFP registers", "custom"); + return true; + case 29: + *tag_name = "ABI_WMMX_args"; + KNOWN_VALUES ("AAPCS", "WMMX registers", "custom"); + return true; + case 30: + *tag_name = "ABI_optimization_goals"; + KNOWN_VALUES ("None", + "Prefer Speed", + "Aggressive Speed", + "Prefer Size", + "Aggressive Size", + "Prefer Debug", + "Aggressive Debug"); + return true; + case 31: + *tag_name = "ABI_FP_optimization_goals"; + KNOWN_VALUES ("None", + "Prefer Speed", + "Aggressive Speed", + "Prefer Size", + "Aggressive Size", + "Prefer Accuracy", + "Aggressive Accuracy"); + return true; + case 34: + *tag_name = "CPU_unaligned_access"; + KNOWN_VALUES ("None", "v6"); + return true; + case 36: + *tag_name = "VFP_HP_extension"; + KNOWN_VALUES ("Not Allowed", "Allowed"); + return true; + case 38: + *tag_name = "ABI_FP_16bit_format"; + KNOWN_VALUES ("None", "IEEE 754", "Alternative Format"); + return true; + case 64: + *tag_name = "nodefaults"; + return true; + case 65: + *tag_name = "also_compatible_with"; + return true; + case 66: + *tag_name = "T2EE_use"; + KNOWN_VALUES ("Not Allowed", "Allowed"); + return true; + case 67: + *tag_name = "conformance"; + return true; + case 68: + *tag_name = "Virtualization_use"; + KNOWN_VALUES ("Not Allowed", "Allowed"); + return true; + case 70: + *tag_name = "MPextension_use"; + KNOWN_VALUES ("Not Allowed", "Allowed"); + return true; + } + + return false; +} diff --git a/backends/arm_auxv.c b/backends/arm_auxv.c new file mode 100644 index 00000000..3282bafc --- /dev/null +++ b/backends/arm_auxv.c @@ -0,0 +1,49 @@ +/* ARM-specific auxv handling. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND arm_ +#include "libebl_CPU.h" + +int +EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format) +{ + if (a_type != AT_HWCAP) + return 0; + + *name = "HWCAP"; + *format = "b" + "swp\0" "half\0" "thumb\0" "26bit\0" + "fast-mult\0" "fpa\0" "vfp\0" "edsp\0" + "java\0" "iwmmxt\0" + "\0"; + return 1; +} diff --git a/backends/arm_cfi.c b/backends/arm_cfi.c new file mode 100644 index 00000000..971a1fc4 --- /dev/null +++ b/backends/arm_cfi.c @@ -0,0 +1,90 @@ +/* arm ABI-specified defaults for DWARF CFI. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND arm_ +#include "libebl_CPU.h" + + +/* ABI-specified state of DWARF CFI based on: + + "DWARF for the ARM Architecture ABI r2.09" +http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040b/IHI0040B_aadwarf.pdf + + "Procedure Call Standard for the ARM Architecture ABI r2.09" +http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf +*/ + +int +arm_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* The initial Canonical Frame Address is the value of the + Stack Pointer (r13) as setup in the previous frame. */ + DW_CFA_def_cfa, ULEB128_7 (13), ULEB128_7 (0), + + /* The Stack Pointer (r13) is restored from CFA address by default. */ + DW_CFA_val_offset, ULEB128_7 (13), ULEB128_7 (0), + +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + /* Callee-saved regs r4-r8, r10, r11. */ + SV (4), SV (5), SV (6), SV (7), SV (8), SV (10), SV (11), + + /* The link register contains the return address setup by caller. */ + SV (14), + DW_CFA_register, ULEB128_7 (15), ULEB128_7 (14), /* pc = lr */ +#undef SV + + /* VFP S16-S31/D8-D15/Q4-Q7 are callee saved. + And uleb128 encoded with two bytes. */ +#define ULEB128_8_2(x) ((x & 0x7f) | 0x80), 0x02 +#define SV(n) DW_CFA_same_value, ULEB128_8_2 (n) + SV (264), SV (265), SV (266), SV (267), + SV (268), SV (269), SV (270), SV (271), + + /* XXX Note: registers intentionally unused by the program, + for example as a consequence of the procedure call standard + should be initialized as if by DW_CFA_same_value. */ + }; +#undef ULEB128_8_2 +#undef SV + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = 4; + + abi_info->return_address_register = 15; /* pc. */ + + return 0; +} diff --git a/backends/arm_corenote.c b/backends/arm_corenote.c new file mode 100644 index 00000000..c5d8d887 --- /dev/null +++ b/backends/arm_corenote.c @@ -0,0 +1,94 @@ +/* ARM specific core note handling. + Copyright (C) 2009, 2012 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND arm_ +#include "libebl_CPU.h" + + +static const Ebl_Register_Location prstatus_regs[] = + { + { .offset = 0, .regno = 0, .count = 16, .bits = 32 }, /* r0..r15 */ + { .offset = 16 * 4, .regno = 128, .count = 1, .bits = 32 }, /* cpsr */ + }; +#define PRSTATUS_REGS_SIZE (18 * 4) + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "orig_r0", .type = ELF_T_SWORD, .format = 'd', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 17), \ + .group = "register" \ + } + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 96, .count = 8, .bits = 96 }, /* f0..f7 */ + }; +#define FPREGSET_SIZE 116 + +#define ULONG uint32_t +#define PID_T int32_t +#define UID_T uint16_t +#define GID_T uint16_t +#define ALIGN_ULONG 4 +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 2 +#define ALIGN_GID_T 2 +#define TYPE_ULONG ELF_T_WORD +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_HALF +#define TYPE_GID_T ELF_T_HALF + +#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ ) +static const Ebl_Register_Location vfp_regs[] = + { + { .offset = 0, .regno = 256, .count = 32, .bits = 64 }, /* fpregs */ + }; + +static const Ebl_Core_Item vfp_items[] = + { + { + .name = "fpscr", .group = "register", + .offset = 0, + .type = ELF_T_WORD, .format = 'x', + }, + }; + +#define EXTRA_NOTES \ + EXTRA_REGSET_ITEMS (NT_ARM_VFP, ARM_VFPREGS_SIZE, vfp_regs, vfp_items) + +#include "linux-core-note.c" diff --git a/backends/arm_init.c b/backends/arm_init.c new file mode 100644 index 00000000..edd53b75 --- /dev/null +++ b/backends/arm_init.c @@ -0,0 +1,71 @@ +/* Initialization of Arm specific backend library. + Copyright (C) 2002, 2005, 2009, 2013, 2014, 2015, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND arm_ +#define RELOC_PREFIX R_ARM_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on arm_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +arm_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + arm_init_reloc (eh); + HOOK (eh, segment_type_name); + HOOK (eh, section_type_name); + HOOK (eh, machine_flag_check); + HOOK (eh, reloc_simple_type); + HOOK (eh, register_info); + HOOK (eh, core_note); + HOOK (eh, auxv_info); + HOOK (eh, check_object_attribute); + HOOK (eh, return_value_location); + HOOK (eh, abi_cfi); + HOOK (eh, check_reloc_target_type); + HOOK (eh, symbol_type_name); + HOOK (eh, data_marker_symbol); + + /* We only unwind the core integer registers. */ + eh->frame_nregs = 16; + HOOK (eh, set_initial_registers_tid); + + /* Bit zero encodes whether an function address is THUMB or ARM. */ + eh->func_addr_mask = ~(GElf_Addr)1; + + return eh; +} diff --git a/backends/arm_initreg.c b/backends/arm_initreg.c new file mode 100644 index 00000000..efcabaf6 --- /dev/null +++ b/backends/arm_initreg.c @@ -0,0 +1,94 @@ +/* Fetch live process registers from TID. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef __linux__ +#if defined __arm__ +# include +# include +# include +#endif + +#ifdef __aarch64__ +# include +# include +# include +/* Deal with old glibc defining user_pt_regs instead of user_regs_struct. */ +# ifndef HAVE_SYS_USER_REGS +# define user_regs_struct user_pt_regs +# endif +#endif +#endif + +#define BACKEND arm_ +#include "libebl_CPU.h" + +bool +arm_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined(__linux__) || (!defined __arm__ && !defined __aarch64__) + return false; +#else /* __arm__ || __aarch64__ */ +#if defined __arm__ + struct user_regs user_regs; + if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0) + return false; + + Dwarf_Word dwarf_regs[16]; + /* R0..R12 SP LR PC */ + for (int i = 0; i < 16; i++) + dwarf_regs[i] = user_regs.uregs[i]; + + return setfunc (0, 16, dwarf_regs, arg); +#elif defined __aarch64__ + /* Compat mode: arm compatible code running on aarch64 */ + int i; + struct user_regs_struct gregs; + struct iovec iovec; + iovec.iov_base = &gregs; + iovec.iov_len = sizeof (gregs); + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0) + return false; + + Dwarf_Word dwarf_regs[16]; + /* R0..R12 SP LR PC, encoded as 32 bit quantities */ + uint32_t *u32_ptr = (uint32_t *) &gregs.regs[0]; + for (i = 0; i < 16; i++) + dwarf_regs[i] = u32_ptr[i]; + + return setfunc (0, 16, dwarf_regs, arg); +#else +# error "source file error, it cannot happen" +#endif +#endif +} diff --git a/backends/arm_regs.c b/backends/arm_regs.c new file mode 100644 index 00000000..a46a4c99 --- /dev/null +++ b/backends/arm_regs.c @@ -0,0 +1,120 @@ +/* Register names and numbers for ARM DWARF. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND arm_ +#include "libebl_CPU.h" + +ssize_t +arm_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 320; + + if (regno < 0 || regno > 320 || namelen < 5) + return -1; + + *prefix = ""; + *bits = 32; + *type = DW_ATE_signed; + *setname = "integer"; + + switch (regno) + { + case 0 ... 9: + name[0] = 'r'; + name[1] = regno + '0'; + namelen = 2; + break; + + case 10 ... 12: + name[0] = 'r'; + name[1] = '1'; + name[2] = regno % 10 + '0'; + namelen = 3; + break; + + case 13 ... 15: + *type = DW_ATE_address; + name[0] = "slp"[regno - 13]; + name[1] = "prc"[regno - 13]; + namelen = 2; + break; + + case 16 + 0 ... 16 + 7: + regno += 96 - 16; + FALLTHROUGH; + case 96 + 0 ... 96 + 7: + *setname = "FPA"; + *type = DW_ATE_float; + *bits = 96; + name[0] = 'f'; + name[1] = regno - 96 + '0'; + namelen = 2; + break; + + case 128: + *type = DW_ATE_unsigned; + return stpcpy (name, "spsr") + 1 - name; + + case 256 + 0 ... 256 + 9: + *setname = "VFP"; + *type = DW_ATE_float; + *bits = 64; + name[0] = 'd'; + name[1] = regno - 256 + '0'; + namelen = 2; + break; + + case 256 + 10 ... 256 + 31: + *setname = "VFP"; + *type = DW_ATE_float; + *bits = 64; + name[0] = 'd'; + name[1] = (regno - 256) / 10 + '0'; + name[2] = (regno - 256) % 10 + '0'; + namelen = 3; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/arm_reloc.def b/backends/arm_reloc.def new file mode 100644 index 00000000..113648e6 --- /dev/null +++ b/backends/arm_reloc.def @@ -0,0 +1,157 @@ +/* List the relocation types for arm. -*- C -*- + Copyright (C) 2005-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, REL) /* It really is used in ET_REL on ARM. */ +RELOC_TYPE (PC24, REL|EXEC|DYN) +RELOC_TYPE (ABS32, REL|EXEC|DYN) +RELOC_TYPE (REL32, REL) +RELOC_TYPE (PC13, REL) +RELOC_TYPE (ABS16, REL) +RELOC_TYPE (ABS12, REL) +RELOC_TYPE (THM_ABS5, REL) +RELOC_TYPE (ABS8, REL) +RELOC_TYPE (SBREL32, REL) +RELOC_TYPE (THM_PC22, REL) +RELOC_TYPE (THM_PC8, REL) +RELOC_TYPE (AMP_VCALL9, REL) +RELOC_TYPE (TLS_DESC, EXEC|DYN) +RELOC_TYPE (THM_SWI8, REL) +RELOC_TYPE (XPC25, REL) +RELOC_TYPE (THM_XPC22, REL) +RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN) +RELOC_TYPE (TLS_DTPOFF32, EXEC|DYN) +RELOC_TYPE (TLS_TPOFF32, EXEC|DYN) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JUMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (GOTOFF, REL) +RELOC_TYPE (GOTPC, REL) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (CALL, REL) +RELOC_TYPE (JUMP24, REL) +RELOC_TYPE (THM_JUMP24, REL) +RELOC_TYPE (BASE_ABS, REL) +RELOC_TYPE (ALU_PCREL_7_0, REL) +RELOC_TYPE (ALU_PCREL_15_8, REL) +RELOC_TYPE (ALU_PCREL_23_15, REL) +RELOC_TYPE (LDR_SBREL_11_0, REL) +RELOC_TYPE (ALU_SBREL_19_12, REL) +RELOC_TYPE (ALU_SBREL_27_20, REL) +RELOC_TYPE (TARGET1, REL) +RELOC_TYPE (SBREL31, REL) +RELOC_TYPE (V4BX, REL) +RELOC_TYPE (TARGET2, REL) +RELOC_TYPE (PREL31, REL) +RELOC_TYPE (MOVW_ABS_NC, REL) +RELOC_TYPE (MOVT_ABS, REL) +RELOC_TYPE (MOVW_PREL_NC, REL) +RELOC_TYPE (MOVT_PREL, REL) +RELOC_TYPE (THM_MOVW_ABS_NC, REL) +RELOC_TYPE (THM_MOVT_ABS, REL) +RELOC_TYPE (THM_MOVW_PREL_NC, REL) +RELOC_TYPE (THM_MOVT_PREL, REL) +RELOC_TYPE (THM_JUMP19, REL) +RELOC_TYPE (THM_JUMP6, REL) +RELOC_TYPE (THM_ALU_PREL_11_0, REL) +RELOC_TYPE (THM_PC12, REL) +RELOC_TYPE (ABS32_NOI, REL) +RELOC_TYPE (REL32_NOI, REL) +RELOC_TYPE (ALU_PC_G0_NC, REL) +RELOC_TYPE (ALU_PC_G0, REL) +RELOC_TYPE (ALU_PC_G1_NC, REL) +RELOC_TYPE (ALU_PC_G1, REL) +RELOC_TYPE (ALU_PC_G2, REL) +RELOC_TYPE (LDR_PC_G1, REL) +RELOC_TYPE (LDR_PC_G2, REL) +RELOC_TYPE (LDRS_PC_G0, REL) +RELOC_TYPE (LDRS_PC_G1, REL) +RELOC_TYPE (LDRS_PC_G2, REL) +RELOC_TYPE (LDC_PC_G0, REL) +RELOC_TYPE (LDC_PC_G1, REL) +RELOC_TYPE (LDC_PC_G2, REL) +RELOC_TYPE (ALU_SB_G0_NC, REL) +RELOC_TYPE (ALU_SB_G0, REL) +RELOC_TYPE (ALU_SB_G1_NC, REL) +RELOC_TYPE (ALU_SB_G1, REL) +RELOC_TYPE (ALU_SB_G2, REL) +RELOC_TYPE (LDR_SB_G0, REL) +RELOC_TYPE (LDR_SB_G1, REL) +RELOC_TYPE (LDR_SB_G2, REL) +RELOC_TYPE (LDRS_SB_G0, REL) +RELOC_TYPE (LDRS_SB_G1, REL) +RELOC_TYPE (LDRS_SB_G2, REL) +RELOC_TYPE (LDC_SB_G0, REL) +RELOC_TYPE (LDC_SB_G1, REL) +RELOC_TYPE (LDC_SB_G2, REL) +RELOC_TYPE (MOVW_BREL_NC, REL) +RELOC_TYPE (MOVT_BREL, REL) +RELOC_TYPE (MOVW_BREL, REL) +RELOC_TYPE (THM_MOVW_BREL_NC, REL) +RELOC_TYPE (THM_MOVT_BREL, REL) +RELOC_TYPE (THM_MOVW_BREL, REL) +RELOC_TYPE (TLS_GOTDESC, REL) +RELOC_TYPE (TLS_CALL, REL) +RELOC_TYPE (TLS_DESCSEQ, REL) +RELOC_TYPE (THM_TLS_CALL, REL) +RELOC_TYPE (PLT32_ABS, REL) +RELOC_TYPE (GOT_ABS, REL) +RELOC_TYPE (GOT_PREL, REL) +RELOC_TYPE (GOT_BREL12, REL) +RELOC_TYPE (GOTOFF12, REL) +RELOC_TYPE (GOTRELAX, REL) +RELOC_TYPE (GNU_VTENTRY, REL) +RELOC_TYPE (GNU_VTINHERIT, REL) +RELOC_TYPE (THM_PC11, REL) +RELOC_TYPE (THM_PC9, REL) +RELOC_TYPE (TLS_GD32, REL) +RELOC_TYPE (TLS_LDM32, REL) +RELOC_TYPE (TLS_LDO32, REL) +RELOC_TYPE (TLS_IE32, REL) +RELOC_TYPE (TLS_LE32, REL) +RELOC_TYPE (TLS_LDO12, REL) +RELOC_TYPE (TLS_LE12, REL) +RELOC_TYPE (TLS_IE12GP, REL) + +RELOC_TYPE (ME_TOO, REL) +RELOC_TYPE (THM_TLS_DESCSEQ16, REL) +RELOC_TYPE (THM_TLS_DESCSEQ32, REL) +RELOC_TYPE (THM_GOT_BREL12, REL) + +RELOC_TYPE (IRELATIVE, EXEC|DYN) + +RELOC_TYPE (RXPC25, REL) +RELOC_TYPE (RSBREL32, REL) +RELOC_TYPE (THM_RPC22, REL) +RELOC_TYPE (RREL32, REL) +RELOC_TYPE (RABS22, REL) +RELOC_TYPE (RPC24, REL) +RELOC_TYPE (RBASE, REL) diff --git a/backends/arm_retval.c b/backends/arm_retval.c new file mode 100644 index 00000000..1c28f016 --- /dev/null +++ b/backends/arm_retval.c @@ -0,0 +1,127 @@ +/* Function return value location for ARM EABI. + Copyright (C) 2009-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND arm_ +#include "libebl_CPU.h" + + +/* r0, or pair r0, r1, or aggregate up to r0-r3. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregs(n) (2 * (n)) + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in r0. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + + +int +arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 4; + else + return -1; + } + if (size <= 16) + { + intreg: + *locp = loc_intreg; + return size <= 4 ? nloc_intreg : nloc_intregs ((size + 3) / 4); + } + + aggregate: + *locp = loc_aggregate; + return nloc_aggregate; + } + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + if (dwarf_aggregate_size (typedie, &size) == 0 + && size > 0 && size <= 4) + goto intreg; + goto aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/arm_symbol.c b/backends/arm_symbol.c new file mode 100644 index 00000000..a733cfff --- /dev/null +++ b/backends/arm_symbol.c @@ -0,0 +1,160 @@ +/* Arm specific symbolic name handling. + Copyright (C) 2002-2009, 2014, 2015, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include + +#define BACKEND arm_ +#include "libebl_CPU.h" + + +const char * +arm_segment_type_name (int segment, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (segment) + { + case PT_ARM_EXIDX: + return "ARM_EXIDX"; + } + return NULL; +} + +/* Return symbolic representation of section type. */ +const char * +arm_section_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (type) + { + case SHT_ARM_EXIDX: + return "ARM_EXIDX"; + case SHT_ARM_PREEMPTMAP: + return "ARM_PREEMPTMAP"; + case SHT_ARM_ATTRIBUTES: + return "ARM_ATTRIBUTES"; + } + + return NULL; +} + +/* Check whether machine flags are valid. */ +bool +arm_machine_flag_check (GElf_Word flags) +{ + switch (flags & EF_ARM_EABIMASK) + { + case EF_ARM_EABI_UNKNOWN: + case EF_ARM_EABI_VER1: + case EF_ARM_EABI_VER2: + case EF_ARM_EABI_VER3: + case EF_ARM_EABI_VER4: + case EF_ARM_EABI_VER5: + break; + default: + return false; + } + + return ((flags &~ (EF_ARM_EABIMASK + | EF_ARM_RELEXEC + | EF_ARM_HASENTRY + | EF_ARM_INTERWORK + | EF_ARM_APCS_26 + | EF_ARM_APCS_FLOAT + | EF_ARM_PIC + | EF_ARM_ALIGN8 + | EF_ARM_NEW_ABI + | EF_ARM_OLD_ABI + | EF_ARM_SOFT_FLOAT + | EF_ARM_VFP_FLOAT + | EF_ARM_MAVERICK_FLOAT + | EF_ARM_SYMSARESORTED + | EF_ARM_DYNSYMSUSESEGIDX + | EF_ARM_MAPSYMSFIRST + | EF_ARM_EABIMASK + | EF_ARM_BE8 + | EF_ARM_LE8)) == 0); +} + +/* Check for the simple reloc types. */ +Elf_Type +arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_ARM_ABS32: + return ELF_T_WORD; + case R_ARM_ABS16: + return ELF_T_HALF; + case R_ARM_ABS8: + return ELF_T_BYTE; + default: + return ELF_T_NUM; + } +} + +/* The SHT_ARM_EXIDX section type is a valid target for relocation. */ +bool +arm_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type) +{ + return sh_type == SHT_ARM_EXIDX; +} + +const char * +arm_symbol_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (type) + { + case STT_ARM_TFUNC: + return "ARM_TFUNC"; + } + return NULL; +} + +/* A data mapping symbol is a symbol with "$d" name or "$d." name, + * STT_NOTYPE, STB_LOCAL and st_size of zero. The indicate the stat of a + * sequence of data items. */ +bool +arm_data_marker_symbol (const GElf_Sym *sym, const char *sname) +{ + return (sym != NULL && sname != NULL + && sym->st_size == 0 && GELF_ST_BIND (sym->st_info) == STB_LOCAL + && GELF_ST_TYPE (sym->st_info) == STT_NOTYPE + && (strcmp (sname, "$d") == 0 || startswith (sname, "$d."))); +} diff --git a/backends/bpf_init.c b/backends/bpf_init.c new file mode 100644 index 00000000..f20f339e --- /dev/null +++ b/backends/bpf_init.c @@ -0,0 +1,54 @@ +/* Initialization of BPF specific backend library. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND bpf_ +#define RELOC_PREFIX R_BPF_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on bpf_reloc.def. */ +#define NO_RELATIVE_RELOC +#define NO_COPY_RELOC +#include "common-reloc.c" + + +Ebl * +bpf_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + bpf_init_reloc (eh); + HOOK (eh, register_info); + HOOK (eh, disasm); + HOOK (eh, reloc_simple_type); + + return eh; +} diff --git a/backends/bpf_regs.c b/backends/bpf_regs.c new file mode 100644 index 00000000..1863a164 --- /dev/null +++ b/backends/bpf_regs.c @@ -0,0 +1,60 @@ +/* Register names and numbers for BPF DWARF. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "bpf.h" + +#define BACKEND bpf_ +#include "libebl_CPU.h" + +ssize_t +bpf_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + ssize_t len; + + if (name == NULL) + return MAX_BPF_REG; + if (regno < 0 || regno >= MAX_BPF_REG) + return -1; + + *prefix = ""; + *setname = "integer"; + *bits = 64; + *type = DW_ATE_signed; + + len = snprintf(name, namelen, "r%d", regno); + return ((size_t)len < namelen ? len : -1); +} diff --git a/backends/bpf_reloc.def b/backends/bpf_reloc.def new file mode 100644 index 00000000..59f519b5 --- /dev/null +++ b/backends/bpf_reloc.def @@ -0,0 +1,32 @@ +/* List the relocation types for BPF. -*- C -*- + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, EXEC|DYN) +RELOC_TYPE (64_64, REL) +RELOC_TYPE (64_32, REL) diff --git a/backends/bpf_symbol.c b/backends/bpf_symbol.c new file mode 100644 index 00000000..85c948ab --- /dev/null +++ b/backends/bpf_symbol.c @@ -0,0 +1,55 @@ +/* BPF specific symbolic name handling. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND bpf_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_BPF_64_64: + return ELF_T_XWORD; + case R_BPF_64_32: + return ELF_T_WORD; + default: + return ELF_T_NUM; + } +} diff --git a/backends/common-reloc.c b/backends/common-reloc.c new file mode 100644 index 00000000..a91bc87d --- /dev/null +++ b/backends/common-reloc.c @@ -0,0 +1,162 @@ +/* Common code for ebl reloc functions. + Copyright (C) 2005, 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include "libebl_CPU.h" +#include + +#define R_TYPE(name) PASTE (RELOC_PREFIX, name) +#define PASTE(a, b) PASTE_1 (a, b) +#define PASTE_1(a, b) a##b +#define R_NAME(name) R_NAME_1 (RELOC_PREFIX, name) +#define R_NAME_1(prefix, type) R_NAME_2 (prefix, type) +#define R_NAME_2(prefix, type) #prefix #type + +#define RELOC_TYPES STRINGIFIED_PASTE (BACKEND, reloc.def) +#define STRINGIFIED_PASTE(a, b) STRINGIFY (PASTE (a, b)) +#define STRINGIFY(x) STRINGIFY_1 (x) +#define STRINGIFY_1(x) #x + +/* Provide a table of reloc type names, in a PIC-friendly fashion. */ + +static const struct EBLHOOK(reloc_nametable) +{ + char zero[1]; +#define RELOC_TYPE(type, uses) \ + char name_##type[sizeof R_NAME (type)]; +#include RELOC_TYPES +#undef RELOC_TYPE +} EBLHOOK(reloc_nametable) = + { + { '\0' }, +#define RELOC_TYPE(type, uses) R_NAME (type), +#include RELOC_TYPES +#undef RELOC_TYPE + }; +#define reloc_namestr (&EBLHOOK(reloc_nametable).zero) + +static const uint_fast16_t EBLHOOK(reloc_nameidx)[] = +{ +#define RELOC_TYPE(type, uses) \ + [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type), +#include RELOC_TYPES +#undef RELOC_TYPE +}; +#define nreloc \ + ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0])) + +#define REL (1 << (ET_REL - 1)) +#define EXEC (1 << (ET_EXEC - 1)) +#define DYN (1 << (ET_DYN - 1)) +static const uint8_t EBLHOOK(reloc_valid)[] = +{ +#define RELOC_TYPE(type, uses) [R_TYPE (type)] = uses, +#include RELOC_TYPES +#undef RELOC_TYPE +}; +#undef REL +#undef EXEC +#undef DYN + +const char * +EBLHOOK(reloc_type_name) (int reloc, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ +#ifdef RELOC_TYPE_ID + reloc = RELOC_TYPE_ID (reloc); +#endif + + if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0) + return reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]]; + return NULL; +} + +bool +EBLHOOK(reloc_type_check) (int reloc) +{ +#ifdef RELOC_TYPE_ID + reloc = RELOC_TYPE_ID (reloc); +#endif + + return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0; +} + +bool +EBLHOOK(reloc_valid_use) (Elf *elf, int reloc) +{ + uint8_t uses; + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + assert (ehdr != NULL); + uint8_t type = ehdr->e_type; + +#ifdef RELOC_TYPE_ID + reloc = RELOC_TYPE_ID (reloc); +#endif + + uses = EBLHOOK(reloc_valid)[reloc]; + return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1))); +} + +#ifndef NO_COPY_RELOC +bool +EBLHOOK(copy_reloc_p) (int reloc) +{ + return reloc == R_TYPE (COPY); +} +#endif + +bool +EBLHOOK(none_reloc_p) (int reloc) +{ + return reloc == R_TYPE (NONE); +} + +#ifndef NO_RELATIVE_RELOC +bool +EBLHOOK(relative_reloc_p) (int reloc) +{ + return reloc == R_TYPE (RELATIVE); +} +#endif + +static void +EBLHOOK(init_reloc) (Ebl *ebl) +{ + ebl->reloc_type_name = EBLHOOK(reloc_type_name); + ebl->reloc_type_check = EBLHOOK(reloc_type_check); + ebl->reloc_valid_use = EBLHOOK(reloc_valid_use); + ebl->none_reloc_p = EBLHOOK(none_reloc_p); +#ifndef NO_COPY_RELOC + ebl->copy_reloc_p = EBLHOOK(copy_reloc_p); +#endif +#ifndef NO_RELATIVE_RELOC + ebl->relative_reloc_p = EBLHOOK(relative_reloc_p); +#endif +} diff --git a/backends/csky_attrs.c b/backends/csky_attrs.c new file mode 100644 index 00000000..177f0ba2 --- /dev/null +++ b/backends/csky_attrs.c @@ -0,0 +1,67 @@ +/* C-SKY ABI-specified defaults for DWARF CFI. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND csky_ +#include "libebl_CPU.h" + +bool +csky_check_object_attribute (Ebl *ebl __attribute__ ((unused)), + const char *vendor, int tag, + uint64_t value __attribute__ ((unused)), + const char **tag_name, + const char **value_name __attribute__ ((unused))) +{ + if (!strcmp (vendor, "csky")) + switch (tag) + { + case 4: + *tag_name = "CSKY_ARCH_NAME"; + return true; + + case 5: + *tag_name = "CSKY_CPU_NAME"; + return true; + + case 6: + *tag_name = "CSKY_ISA_FLAGS"; + return true; + + case 7: + *tag_name = "CSKY_ISA_EXT_FLAGS"; + return true; + } + + return false; +} diff --git a/backends/csky_cfi.c b/backends/csky_cfi.c new file mode 100644 index 00000000..7277dbd4 --- /dev/null +++ b/backends/csky_cfi.c @@ -0,0 +1,60 @@ +/* C-SKY ABI-specified defaults for DWARF CFI. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND csky_ +#include "libebl_CPU.h" + + +int +csky_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + DW_CFA_def_cfa, ULEB128_7 (14), ULEB128_7 (0), + DW_CFA_val_offset, ULEB128_7 (14), ULEB128_7 (0), + +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + SV(4), SV (5), SV (6), SV (7), SV (8), SV (9), + SV(10), SV (11), SV (15), SV (16), SV (17) +#undef SV + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = -4; + + abi_info->return_address_register = 15; /* lr. */ + + return 0; +} diff --git a/backends/csky_corenote.c b/backends/csky_corenote.c new file mode 100644 index 00000000..a1479bd3 --- /dev/null +++ b/backends/csky_corenote.c @@ -0,0 +1,61 @@ +/* C-SKY specific core note handling. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND csky_ +#include "libebl_CPU.h" + +#define ULONG uint32_t +#define PID_T int32_t +#define UID_T uint32_t +#define GID_T uint32_t +#define ALIGN_ULONG 4 +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 4 +#define ALIGN_GID_T 4 +#define TYPE_ULONG ELF_T_WORD +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_WORD +#define TYPE_GID_T ELF_T_WORD + +static const Ebl_Register_Location prstatus_regs[] = + { + { .offset = 0, .regno = 0, .count = 36, .bits = 32 } /* r0..r31 */ + }; +#define PRSTATUS_REGS_SIZE (36 * 4) + +#include "linux-core-note.c" diff --git a/backends/csky_init.c b/backends/csky_init.c new file mode 100644 index 00000000..b2863ced --- /dev/null +++ b/backends/csky_init.c @@ -0,0 +1,60 @@ +/* Initialization of C-SKY specific backend library. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND csky_ +#define RELOC_PREFIX R_CKCORE_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on csky_reloc.def. */ +#include "common-reloc.c" + +Ebl * +csky_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + csky_init_reloc (eh); + HOOK (eh, abi_cfi); + HOOK (eh, core_note); + HOOK (eh, check_object_attribute); + HOOK (eh, machine_flag_check); + HOOK (eh, reloc_simple_type); + HOOK (eh, register_info); + HOOK (eh, section_type_name); + HOOK (eh, set_initial_registers_tid); + + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = 38; + + return eh; +} diff --git a/backends/csky_initreg.c b/backends/csky_initreg.c new file mode 100644 index 00000000..81a0da33 --- /dev/null +++ b/backends/csky_initreg.c @@ -0,0 +1,87 @@ +/* Fetch live process registers from TID. C-SKY version. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "system.h" +#include +#if defined __CSKY__ && defined __linux__ +# include +# include +# include +#endif + +#define BACKEND csky_ +#include "libebl_CPU.h" + +bool +csky_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined __CSKY__ || !defined __linux__ + return false; +#else /* __CSKY__ */ + struct pt_regs user_regs; + struct iovec iovec; + iovec.iov_base = &user_regs; + iovec.iov_len = sizeof (user_regs); + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0) + return false; + + Dwarf_Word dwarf_regs[38]; + + /* lr. */ + dwarf_regs[15] = user_regs.lr; + /* sp. */ + dwarf_regs[14] = user_regs.usp; + /* r0 ~ r13. */ + dwarf_regs[0] = user_regs.a0; + dwarf_regs[1] = user_regs.a1; + dwarf_regs[2] = user_regs.a2; + dwarf_regs[3] = user_regs.a3; + for (int i = 4; i < 14; i++) + dwarf_regs[i] = user_regs.regs[i - 4]; + /* r ~ r13. */ + for (int i = 16; i < 31; i++) + dwarf_regs[i] = user_regs.exregs[i - 16]; + /* tls. */ + dwarf_regs[31] = user_regs.tls; + /* hi. */ + dwarf_regs[36] = user_regs.rhi; + /* lo. */ + dwarf_regs[37] = user_regs.rlo; + /* pc. */ + dwarf_regs[32] = user_regs.pc; + setfunc (-1, 1, &dwarf_regs[32], arg); + + return setfunc (0, 38, dwarf_regs, arg); +#endif +} diff --git a/backends/csky_regs.c b/backends/csky_regs.c new file mode 100644 index 00000000..6d45c04b --- /dev/null +++ b/backends/csky_regs.c @@ -0,0 +1,101 @@ +/* Register names and numbers for C-SKY DWARF. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND csky_ +#include "libebl_CPU.h" + +ssize_t +csky_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 38; + + *prefix = ""; + *bits = 32; + *type = DW_ATE_signed; + *setname = "integer"; + + switch (regno) + { + case 0 ... 9: + name[0] = 'r'; + name[1] = regno + '0'; + namelen = 2; + break; + + case 10 ... 13: + case 16 ... 30: + name[0] = 'r'; + name[1] = regno / 10 + '0'; + name[2] = regno % 10 + '0'; + namelen = 3; + break; + + case 14: + stpcpy (name, "sp"); + namelen = 2; + break; + + case 15: + stpcpy (name, "lr"); + namelen = 2; + break; + + case 31: + stpcpy (name, "tls"); + namelen = 3; + break; + + case 36: + stpcpy (name, "hi"); + namelen = 2; + break; + + case 37: + stpcpy (name, "lo"); + namelen = 2; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/csky_reloc.def b/backends/csky_reloc.def new file mode 100644 index 00000000..1108f0c2 --- /dev/null +++ b/backends/csky_reloc.def @@ -0,0 +1,86 @@ +/* List the relocation types for csky. -*- C -*- + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + + +RELOC_TYPE (NONE, REL|EXEC|DYN) +RELOC_TYPE (ADDR32, REL|EXEC|DYN) +RELOC_TYPE (PCRELIMM8BY4, REL) +RELOC_TYPE (PCRELIMM11BY2, REL) +RELOC_TYPE (PCREL32, REL|DYN) +RELOC_TYPE (PCRELJSR_IMM11BY2, REL) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JUMP_SLOT, EXEC|DYN) +RELOC_TYPE (GOTOFF, REL) +RELOC_TYPE (GOTPC, REL) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (ADDRGOT, REL) +RELOC_TYPE (ADDRPLT, REL) +RELOC_TYPE (PCREL_IMM26BY2, REL) +RELOC_TYPE (PCREL_IMM16BY2, REL) +RELOC_TYPE (PCREL_IMM16BY4, REL) +RELOC_TYPE (PCREL_IMM10BY2, REL) +RELOC_TYPE (PCREL_IMM10BY4, REL) +RELOC_TYPE (ADDR_HI16, REL|DYN) +RELOC_TYPE (ADDR_LO16, REL|DYN) +RELOC_TYPE (GOTPC_HI16, REL) +RELOC_TYPE (GOTPC_LO16, REL) +RELOC_TYPE (GOTOFF_HI16, REL) +RELOC_TYPE (GOTOFF_LO16, REL) +RELOC_TYPE (GOT12, REL) +RELOC_TYPE (GOT_HI16, REL) +RELOC_TYPE (GOT_LO16, REL) +RELOC_TYPE (PLT12, REL) +RELOC_TYPE (PLT_HI16, REL) +RELOC_TYPE (PLT_LO16, REL) +RELOC_TYPE (ADDRGOT_HI16, REL) +RELOC_TYPE (ADDRGOT_LO16, REL) +RELOC_TYPE (ADDRPLT_HI16, REL) +RELOC_TYPE (ADDRPLT_LO16, REL) +RELOC_TYPE (PCREL_JSR_IMM26BY2, REL|DYN) +RELOC_TYPE (TOFFSET_LO16, REL) +RELOC_TYPE (DOFFSET_LO16, REL) +RELOC_TYPE (PCREL_IMM18BY2, REL) +RELOC_TYPE (DOFFSET_IMM18, REL) +RELOC_TYPE (DOFFSET_IMM18BY2, REL) +RELOC_TYPE (DOFFSET_IMM18BY4, REL) +RELOC_TYPE (GOT_IMM18BY4, REL) +RELOC_TYPE (PLT_IMM18BY4, REL) +RELOC_TYPE (PCREL_IMM7BY4, REL) +RELOC_TYPE (TLS_LE32, REL) +RELOC_TYPE (TLS_IE32, REL) +RELOC_TYPE (TLS_GD32, REL) +RELOC_TYPE (TLS_LDM32, REL) +RELOC_TYPE (TLS_LDO32, REL) +RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN) +RELOC_TYPE (TLS_DTPOFF32, EXEC|DYN) +RELOC_TYPE (TLS_TPOFF32, EXEC|DYN) diff --git a/backends/csky_symbol.c b/backends/csky_symbol.c new file mode 100644 index 00000000..79b5bf9e --- /dev/null +++ b/backends/csky_symbol.c @@ -0,0 +1,77 @@ +/* C-SKY specific symbolic name handling. + Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND csky_ +#include "libebl_CPU.h" + +/* Check for the simple reloc types. */ +Elf_Type +csky_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_CKCORE_ADDR32: + return ELF_T_WORD; + default: + return ELF_T_NUM; + } +} + +bool +csky_machine_flag_check (GElf_Word flags) +{ + switch (flags & EF_CSKY_ABIMASK) + { + case EF_CSKY_ABIV2: + return true; + case EF_CSKY_ABIV1: + default: + return false; + } +} + +const char * +csky_section_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type == SHT_CSKY_ATTRIBUTES) + return "CSKY_ATTRIBUTES"; + + return NULL; +} diff --git a/backends/i386_auxv.c b/backends/i386_auxv.c new file mode 100644 index 00000000..dba63fe0 --- /dev/null +++ b/backends/i386_auxv.c @@ -0,0 +1,52 @@ +/* i386 specific auxv handling. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND i386_ +#include "libebl_CPU.h" + +int +EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format) +{ + if (a_type != AT_HWCAP) + return 0; + + *name = "HWCAP"; + *format = "b" + "fpu\0" "vme\0" "de\0" "pse\0" "tsc\0" "msr\0" "pae\0" "mce\0" + "cx8\0" "apic\0" "10\0" "sep\0" "mtrr\0" "pge\0" "mca\0" "cmov\0" + "pat\0" "pse36\0" "pn\0" "clflush\0" "20\0" "dts\0" "acpi\0" "mmx\0" + "fxsr\0" "sse\0" "sse2\0" "ss\0" "ht\0" "tm\0" "ia64\0" "pbe\0" "\0"; + return 1; +} + +__typeof (i386_auxv_info) x86_64_auxv_info + __attribute__ ((alias ("i386_auxv_info"))); diff --git a/backends/i386_cfi.c b/backends/i386_cfi.c new file mode 100644 index 00000000..31f85f7e --- /dev/null +++ b/backends/i386_cfi.c @@ -0,0 +1,68 @@ +/* i386 ABI-specified defaults for DWARF CFI. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + +int +i386_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* Call-saved regs. */ + DW_CFA_same_value, ULEB128_7 (3), /* %ebx */ + DW_CFA_same_value, ULEB128_7 (5), /* %ebp */ + DW_CFA_same_value, ULEB128_7 (6), /* %esi */ + DW_CFA_same_value, ULEB128_7 (7), /* %edi */ + + /* The CFA is the SP. */ + DW_CFA_val_offset, ULEB128_7 (4), ULEB128_7 (0), + + /* Segment registers are call-saved if ever used at all. */ + DW_CFA_same_value, ULEB128_7 (40), /* %es */ + DW_CFA_same_value, ULEB128_7 (41), /* %cs */ + DW_CFA_same_value, ULEB128_7 (42), /* %ss */ + DW_CFA_same_value, ULEB128_7 (43), /* %ds */ + DW_CFA_same_value, ULEB128_7 (44), /* %fs */ + DW_CFA_same_value, ULEB128_7 (45), /* %gs */ + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = 4; + + abi_info->return_address_register = 8; /* %eip */ + + return 0; +} diff --git a/backends/i386_corenote.c b/backends/i386_corenote.c new file mode 100644 index 00000000..15cd66b5 --- /dev/null +++ b/backends/i386_corenote.c @@ -0,0 +1,138 @@ +/* i386 specific core note handling. + Copyright (C) 2007-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + + +static const Ebl_Register_Location prstatus_regs[] = + { +#define GR(at, n, dwreg) \ + { .offset = at * 4, .regno = dwreg, .count = n, .bits = 32 } +#define SR(at, n, dwreg) \ + { .offset = at * 4, .regno = dwreg, .count = n, .bits = 16, .pad = 2 } + + GR (0, 1, 3), /* %ebx */ + GR (1, 2, 1), /* %ecx-%edx */ + GR (3, 2, 6), /* %esi-%edi */ + GR (5, 1, 5), /* %ebp */ + GR (6, 1, 0), /* %eax */ + SR (7, 1, 43), /* %ds */ + SR (8, 1, 40), /* %es */ + SR (9, 1, 44), /* %fs */ + SR (10, 1, 45), /* %gs */ + /* 11, 1, orig_eax */ + GR (12, 1, 8), /* %eip */ + SR (13, 1, 41), /* %cs */ + GR (14, 1, 9), /* eflags */ + GR (15, 1, 4), /* %esp */ + SR (16, 1, 42), /* %ss */ + +#undef GR +#undef SR + }; +#define PRSTATUS_REGS_SIZE (17 * 4) + +#define ULONG uint32_t +#define PID_T int32_t +#define UID_T uint16_t +#define GID_T uint16_t +#define ALIGN_ULONG 4 +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 2 +#define ALIGN_GID_T 2 +#define TYPE_ULONG ELF_T_WORD +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_HALF +#define TYPE_GID_T ELF_T_HALF + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "orig_eax", .type = ELF_T_SWORD, .format = 'd', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 11), \ + .group = "register" \ + } + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 37, .count = 2, .bits = 32 }, /* fctrl-fstat */ + { .offset = 7 * 4, .regno = 11, .count = 8, .bits = 80 }, /* stN */ + }; +#define FPREGSET_SIZE 108 + +static const Ebl_Register_Location prxfpreg_regs[] = + { + { .offset = 0, .regno = 37, .count = 2, .bits = 16 }, /* fctrl-fstat */ + { .offset = 24, .regno = 39, .count = 1, .bits = 32 }, /* mxcsr */ + { .offset = 32, .regno = 11, .count = 8, .bits = 80, .pad = 6 }, /* stN */ + { .offset = 32 + 128, .regno = 21, .count = 8, .bits = 128 }, /* xmm */ + }; + +#define EXTRA_NOTES \ + EXTRA_REGSET (NT_PRXFPREG, 512, prxfpreg_regs) \ + case NT_386_TLS: \ + return tls_info (nhdr->n_descsz, regs_offset, nregloc, reglocs, \ + nitems, items); \ + EXTRA_NOTES_IOPERM + +static const Ebl_Core_Item tls_items[] = + { + { .type = ELF_T_WORD, .offset = 0x0, .format = 'd', .name = "index" }, + { .type = ELF_T_WORD, .offset = 0x4, .format = 'x', .name = "base" }, + { .type = ELF_T_WORD, .offset = 0x8, .format = 'x', .name = "limit" }, + { .type = ELF_T_WORD, .offset = 0xc, .format = 'x', .name = "flags" }, + }; + +static int +tls_info (GElf_Word descsz, GElf_Word *regs_offset, + size_t *nregloc, const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **items) +{ + if (descsz % 16 != 0) + return 0; + + *regs_offset = 0; + *nregloc = 0; + *reglocs = NULL; + *nitems = sizeof tls_items / sizeof tls_items[0]; + *items = tls_items; + return 1; +} + +#include "x86_corenote.c" +#include "linux-core-note.c" diff --git a/backends/i386_init.c b/backends/i386_init.c new file mode 100644 index 00000000..579e5fad --- /dev/null +++ b/backends/i386_init.c @@ -0,0 +1,64 @@ +/* Initialization of i386 specific backend library. + Copyright (C) 2000-2009, 2013, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND i386_ +#define RELOC_PREFIX R_386_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on i386_reloc.def. */ +#include "common-reloc.c" + +Ebl * +i386_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + i386_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, gotpc_reloc_check); + HOOK (eh, core_note); + generic_debugscn_p = eh->debugscn_p; + HOOK (eh, debugscn_p); + HOOK (eh, return_value_location); + HOOK (eh, register_info); + HOOK (eh, auxv_info); + HOOK (eh, disasm); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. For i386 it is 17, why? */ + eh->frame_nregs = 9; + HOOK (eh, set_initial_registers_tid); + HOOK (eh, unwind); + + return eh; +} diff --git a/backends/i386_initreg.c b/backends/i386_initreg.c new file mode 100644 index 00000000..c3442823 --- /dev/null +++ b/backends/i386_initreg.c @@ -0,0 +1,79 @@ +/* Fetch live process registers from TID. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if (defined __i386__ || defined __x86_64__) && defined(__linux__) +# include +# include +# include +#endif + +#define BACKEND i386_ +#include "libebl_CPU.h" + +bool +i386_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if (!defined __i386__ && !defined __x86_64__) || !defined(__linux__) + return false; +#else /* __i386__ || __x86_64__ */ + struct user_regs_struct user_regs; + if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0) + return false; + Dwarf_Word dwarf_regs[9]; +# if defined __i386__ + dwarf_regs[0] = user_regs.eax; + dwarf_regs[1] = user_regs.ecx; + dwarf_regs[2] = user_regs.edx; + dwarf_regs[3] = user_regs.ebx; + dwarf_regs[4] = user_regs.esp; + dwarf_regs[5] = user_regs.ebp; + dwarf_regs[6] = user_regs.esi; + dwarf_regs[7] = user_regs.edi; + dwarf_regs[8] = user_regs.eip; +# elif defined __x86_64__ + dwarf_regs[0] = user_regs.rax; + dwarf_regs[1] = user_regs.rcx; + dwarf_regs[2] = user_regs.rdx; + dwarf_regs[3] = user_regs.rbx; + dwarf_regs[4] = user_regs.rsp; + dwarf_regs[5] = user_regs.rbp; + dwarf_regs[6] = user_regs.rsi; + dwarf_regs[7] = user_regs.rdi; + dwarf_regs[8] = user_regs.rip; +# else /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */ +# error "source file error, it cannot happen" +# endif /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */ + return setfunc (0, 9, dwarf_regs, arg); +#endif /* __i386__ || __x86_64__ */ +} diff --git a/backends/i386_regs.c b/backends/i386_regs.c new file mode 100644 index 00000000..7ec93bb9 --- /dev/null +++ b/backends/i386_regs.c @@ -0,0 +1,153 @@ +/* Register names and numbers for i386 DWARF. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + +ssize_t +i386_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 46; + + if (regno < 0 || regno > 45 || namelen < 6) + return -1; + + *prefix = "%"; + *bits = 32; + *type = DW_ATE_unsigned; + if (regno < 11) + { + *setname = "integer"; + if (regno < 9) + *type = DW_ATE_signed; + } + else if (regno < 19) + { + *setname = "x87"; + *type = DW_ATE_float; + *bits = 80; + } + else if (regno < 29) + { + *setname = "SSE"; + *bits = 128; + } + else if (regno < 37) + { + *setname = "MMX"; + *bits = 64; + } + else if (regno < 40) + *setname = "FPU-control"; + else + { + *setname = "segment"; + *bits = 16; + } + + switch (regno) + { + static const char baseregs[][2] = + { + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "ip" + }; + + case 4: + case 5: + case 8: + *type = DW_ATE_address; + FALLTHROUGH; + case 0 ... 3: + case 6 ... 7: + name[0] = 'e'; + name[1] = baseregs[regno][0]; + name[2] = baseregs[regno][1]; + namelen = 3; + break; + + case 9: + return stpcpy (name, "eflags") + 1 - name; + case 10: + return stpcpy (name, "trapno") + 1 - name; + + case 11 ... 18: + name[0] = 's'; + name[1] = 't'; + name[2] = regno - 11 + '0'; + namelen = 3; + break; + + case 21 ... 28: + name[0] = 'x'; + name[1] = 'm'; + name[2] = 'm'; + name[3] = regno - 21 + '0'; + namelen = 4; + break; + + case 29 ... 36: + name[0] = 'm'; + name[1] = 'm'; + name[2] = regno - 29 + '0'; + namelen = 3; + break; + + case 37: + *bits = 16; + return stpcpy (name, "fctrl") + 1 - name; + case 38: + *bits = 16; + return stpcpy (name, "fstat") + 1 - name; + case 39: + return stpcpy (name, "mxcsr") + 1 - name; + + case 40 ... 45: + name[0] = "ecsdfg"[regno - 40]; + name[1] = 's'; + namelen = 2; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/i386_reloc.def b/backends/i386_reloc.def new file mode 100644 index 00000000..a6a03f32 --- /dev/null +++ b/backends/i386_reloc.def @@ -0,0 +1,71 @@ +/* List the relocation types for i386. -*- C -*- + Copyright (C) 2000, 2001, 2002, 2003, 2005, 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (32, REL|EXEC|DYN) +RELOC_TYPE (PC32, REL|EXEC|DYN) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (GOTOFF, REL) +RELOC_TYPE (GOTPC, REL) +RELOC_TYPE (32PLT, REL) +RELOC_TYPE (TLS_TPOFF, EXEC|DYN) +RELOC_TYPE (TLS_IE, REL) +RELOC_TYPE (TLS_GOTIE, REL) +RELOC_TYPE (TLS_LE, REL) +RELOC_TYPE (TLS_GD, REL) +RELOC_TYPE (TLS_LDM, REL) +RELOC_TYPE (16, REL) +RELOC_TYPE (PC16, REL) +RELOC_TYPE (8, REL) +RELOC_TYPE (PC8, REL) +RELOC_TYPE (TLS_GD_32, REL) +RELOC_TYPE (TLS_GD_PUSH, REL) +RELOC_TYPE (TLS_GD_CALL, REL) +RELOC_TYPE (TLS_GD_POP, REL) +RELOC_TYPE (TLS_LDM_32, REL) +RELOC_TYPE (TLS_LDM_PUSH, REL) +RELOC_TYPE (TLS_LDM_CALL, REL) +RELOC_TYPE (TLS_LDM_POP, REL) +RELOC_TYPE (TLS_LDO_32, REL) +RELOC_TYPE (TLS_IE_32, REL) +RELOC_TYPE (TLS_LE_32, REL) +RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN) +RELOC_TYPE (TLS_DTPOFF32, EXEC|DYN) +RELOC_TYPE (TLS_TPOFF32, EXEC|DYN) +RELOC_TYPE (TLS_GOTDESC, REL) +RELOC_TYPE (TLS_DESC_CALL, REL) +RELOC_TYPE (TLS_DESC, EXEC) +RELOC_TYPE (IRELATIVE, EXEC|DYN) +RELOC_TYPE (GOT32X, REL) diff --git a/backends/i386_retval.c b/backends/i386_retval.c new file mode 100644 index 00000000..32fec728 --- /dev/null +++ b/backends/i386_retval.c @@ -0,0 +1,140 @@ +/* Function return value location for Linux/i386 ABI. + Copyright (C) 2005-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + + +/* %eax, or pair %eax, %edx. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %st(0). */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_reg11 } + }; +#define nloc_fpreg 1 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in %eax. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + +int +i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Word size; + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 4; + else + return -1; + } + if (tag == DW_TAG_base_type) + { + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + if (encoding == DW_ATE_float) + { + if (size > 16) + return -2; + *locp = loc_fpreg; + return nloc_fpreg; + } + } + *locp = loc_intreg; + if (size <= 4) + return nloc_intreg; + if (size <= 8) + return nloc_intregpair; + } + FALLTHROUGH; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + *locp = loc_aggregate; + return nloc_aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/i386_symbol.c b/backends/i386_symbol.c new file mode 100644 index 00000000..a4b6ec08 --- /dev/null +++ b/backends/i386_symbol.c @@ -0,0 +1,76 @@ +/* i386 specific symbolic name handling. + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + + +/* Return true if the symbol type is that referencing the GOT. */ +bool +i386_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type) +{ + return type == R_386_GOTPC; +} + +/* Check for the simple reloc types. */ +Elf_Type +i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_386_32: + return ELF_T_SWORD; + case R_386_16: + return ELF_T_HALF; + case R_386_8: + return ELF_T_BYTE; + default: + return ELF_T_NUM; + } +} + +/* Check section name for being that of a debug information section. */ +bool (*generic_debugscn_p) (const char *); +bool +i386_debugscn_p (const char *name) +{ + return (generic_debugscn_p (name) + || strcmp (name, ".stab") == 0 + || strcmp (name, ".stabstr") == 0); +} diff --git a/backends/i386_unwind.c b/backends/i386_unwind.c new file mode 100644 index 00000000..5c9a5de0 --- /dev/null +++ b/backends/i386_unwind.c @@ -0,0 +1,84 @@ +/* Get previous frame state for an existing frame state using frame pointers. + Copyright (C) 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + +/* Register numbers for frame and stack pointers. We take advantage of + them being next to each other when calling getfunc and setfunc. */ +#define ESP 4 +#define EBP (ESP + 1) + +/* Most basic frame pointer chasing with EBP as frame pointer. + PC = *(FP + 4), SP = FP + 8, FP = *FP. */ +bool +i386_unwind (Ebl *ebl __attribute__ ((unused)), + Dwarf_Addr pc __attribute__ ((unused)), + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep __attribute__ ((unused))) +{ + /* sp = 0, fp = 1 */ + Dwarf_Word regs[2]; + + /* Get current stack and frame pointers. */ + if (! getfunc (ESP, 2, regs, arg)) + return false; + + Dwarf_Word sp = regs[0]; + Dwarf_Word fp = regs[1]; + + /* Sanity check. We only support traditional stack frames. */ + if (fp == 0 || sp == 0 || fp < sp) + return false; + + /* Get the return address from the stack, it is our new pc. */ + Dwarf_Word ret_addr; + if (! readfunc (fp + 4, &ret_addr, arg) || ret_addr == 0) + return false; + + /* Get new sp and fp. Sanity check again. */ + sp = fp + 8; + if (! readfunc (fp, &fp, arg) || fp == 0 || sp >= fp) + return false; + + /* Set new sp, fp and pc. */ + regs[0] = sp; + regs[1] = fp; + if (! setfunc (ESP, 2, regs, arg) || ! setfunc (-1, 1, &ret_addr, arg)) + return false; + + return true; +} diff --git a/backends/ia64_init.c b/backends/ia64_init.c new file mode 100644 index 00000000..b46b35cc --- /dev/null +++ b/backends/ia64_init.c @@ -0,0 +1,60 @@ +/* Initialization of IA-64 specific backend library. + Copyright (C) 2002, 2003, 2005, 2006, 2007, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND ia64_ +#define RELOC_PREFIX R_IA64_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on ia64_reloc.def. */ +#include "common-reloc.c" + +Ebl * +ia64_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + ia64_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, segment_type_name); + HOOK (eh, section_type_name); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); + HOOK (eh, machine_flag_check); + HOOK (eh, machine_section_flag_check); + HOOK (eh, register_info); + HOOK (eh, return_value_location); + HOOK (eh, check_reloc_target_type); + + return eh; +} diff --git a/backends/ia64_regs.c b/backends/ia64_regs.c new file mode 100644 index 00000000..a27fe63d --- /dev/null +++ b/backends/ia64_regs.c @@ -0,0 +1,273 @@ +/* Register names and numbers for IA64 DWARF. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND i386_ +#include "libebl_CPU.h" + +ssize_t +ia64_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 687 + 64; + + if (regno < 0 || regno > 687 + 63 || namelen < 12) + return -1; + + *prefix = "ar."; + *setname = "application"; + *bits = 64; + *type = DW_ATE_signed; + switch (regno) + { + case 0 ... 9: + name[0] = 'r'; + name[1] = (regno - 0) + '0'; + namelen = 2; + *setname = "integer"; + *prefix = ""; + break; + + case 10 ... 99: + name[0] = 'r'; + name[1] = (regno - 0) / 10 + '0'; + name[2] = (regno - 0) % 10 + '0'; + namelen = 3; + *setname = "integer"; + *prefix = ""; + break; + + case 100 ... 127: + name[0] = 'r'; + name[1] = '1'; + name[2] = (regno - 100) / 10 + '0'; + name[3] = (regno - 0) % 10 + '0'; + namelen = 4; + *setname = "integer"; + *prefix = ""; + break; + + case 128 + 0 ... 128 + 9: + name[0] = 'f'; + name[1] = (regno - 128) + '0'; + namelen = 2; + *type = DW_ATE_float; + *bits = 128; + *setname = "FPU"; + *prefix = ""; + break; + + case 128 + 10 ... 128 + 99: + name[0] = 'f'; + name[1] = (regno - 128) / 10 + '0'; + name[2] = (regno - 128) % 10 + '0'; + namelen = 3; + *setname = "FPU"; + *prefix = ""; + break; + + case 128 + 100 ... 128 + 127: + name[0] = 'f'; + name[1] = '1'; + name[2] = (regno - 128 - 100) / 10 + '0'; + name[3] = (regno - 128) % 10 + '0'; + namelen = 4; + *type = DW_ATE_float; + *bits = 128; + *setname = "FPU"; + *prefix = ""; + break; + + case 320 + 0 ... 320 + 7: + name[0] = 'b'; + name[1] = (regno - 320) + '0'; + namelen = 2; + *type = DW_ATE_address; + *setname = "branch"; + *prefix = ""; + break; + + case 328 ... 333: + { + static const char named_special[][5] = + { + "vfp", "vrap", "pr", "ip", "psr", "cfm" + }; + *setname = "special"; + *prefix = ""; + *type = regno == 331 ? DW_ATE_address : DW_ATE_unsigned; + return stpcpy (name, named_special[regno - 328]) + 1 - name; + } + + case 590: + *setname = "special"; + *prefix = ""; + *type = DW_ATE_unsigned; + return stpcpy (name, "bof") + 1 - name; + + case 334 + 0 ... 334 + 7: + name[0] = 'k'; + name[1] = 'r'; + name[2] = (regno - 334) + '0'; + namelen = 3; + *prefix = ""; + break; + + case 334 + 8 ... 334 + 127: + { + static const char named_ar[][9] = + { + [16 - 8] = "rsc", + [17 - 8] = "bsp", + [18 - 8] = "bspstore", + [19 - 8] = "rnat", + [21 - 8] = "fcr", + [24 - 8] = "eflag", + [25 - 8] = "csd", + [26 - 8] = "ssd", + [27 - 8] = "cflg", + [28 - 8] = "fsr", + [29 - 8] = "fir", + [30 - 8] = "fdr", + [32 - 8] = "ccv", + [36 - 8] = "unat", + [40 - 8] = "fpsr", + [44 - 8] = "itc", + [64 - 8] = "pfs", + [65 - 8] = "lc", + [66 - 8] = "ec", + }; + const size_t idx = regno - (334 + 8); + *type = DW_ATE_unsigned; + if (idx == 1 || idx == 2) + *type = DW_ATE_address; + if (idx < sizeof named_ar / sizeof named_ar[0] + && named_ar[idx][0] != '\0') + return stpcpy (name, named_ar[idx]) + 1 - name; + + name[0] = 'a'; + name[1] = 'r'; + switch (regno - 334) + { + case 0 ... 9: + name[2] = (regno - 334) + '0'; + namelen = 3; + break; + case 10 ... 99: + name[2] = (regno - 334) / 10 + '0'; + name[3] = (regno - 334) % 10 + '0'; + namelen = 4; + break; + case 100 ... 127: + name[2] = '1'; + name[3] = (regno - 334 - 100) / 10 + '0'; + name[4] = (regno - 334) % 10 + '0'; + namelen = 5; + break; + } + *prefix = ""; + break; + } + + case 462 + 0 ... 462 + 9: + name[0] = 'n'; + name[1] = 'a'; + name[2] = 't'; + name[3] = (regno - 462) + '0'; + namelen = 4; + *setname = "NAT"; + *type = DW_ATE_boolean; + *bits = 1; + *prefix = ""; + break; + + case 462 + 10 ... 462 + 99: + name[0] = 'n'; + name[1] = 'a'; + name[2] = 't'; + name[3] = (regno - 462) / 10 + '0'; + name[4] = (regno - 462) % 10 + '0'; + namelen = 5; + *setname = "NAT"; + *type = DW_ATE_boolean; + *bits = 1; + *prefix = ""; + break; + + case 462 + 100 ... 462 + 127: + name[0] = 'n'; + name[1] = 'a'; + name[2] = 't'; + name[3] = '1'; + name[4] = (regno - 462 - 100) / 10 + '0'; + name[5] = (regno - 462) % 10 + '0'; + namelen = 6; + *setname = "NAT"; + *type = DW_ATE_boolean; + *bits = 1; + *prefix = ""; + break; + + case 687 + 0 ... 687 + 9: + name[0] = 'p'; + name[1] = (regno - 687) + '0'; + namelen = 2; + *setname = "predicate"; + *type = DW_ATE_boolean; + *bits = 1; + *prefix = ""; + break; + + case 687 + 10 ... 687 + 63: + name[0] = 'p'; + name[1] = (regno - 687) / 10 + '0'; + name[2] = (regno - 687) % 10 + '0'; + namelen = 3; + *setname = "predicate"; + *type = DW_ATE_boolean; + *bits = 1; + *prefix = ""; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/ia64_reloc.def b/backends/ia64_reloc.def new file mode 100644 index 00000000..24289251 --- /dev/null +++ b/backends/ia64_reloc.def @@ -0,0 +1,113 @@ +/* List the relocation types for ia64. -*- C -*- + Copyright (C) 2005, 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (IMM14, REL) +RELOC_TYPE (IMM22, REL) +RELOC_TYPE (IMM64, REL) +RELOC_TYPE (DIR32MSB, REL|EXEC|DYN) +RELOC_TYPE (DIR32LSB, REL|EXEC|DYN) +RELOC_TYPE (DIR64MSB, REL|EXEC|DYN) +RELOC_TYPE (DIR64LSB, REL|EXEC|DYN) +RELOC_TYPE (GPREL22, REL) +RELOC_TYPE (GPREL64I, REL) +RELOC_TYPE (GPREL32MSB, REL) +RELOC_TYPE (GPREL32LSB, REL) +RELOC_TYPE (GPREL64MSB, REL) +RELOC_TYPE (GPREL64LSB, REL) +RELOC_TYPE (LTOFF22, REL) +RELOC_TYPE (LTOFF64I, REL) +RELOC_TYPE (PLTOFF22, REL) +RELOC_TYPE (PLTOFF64I, REL) +RELOC_TYPE (PLTOFF64MSB, REL) +RELOC_TYPE (PLTOFF64LSB, REL) +RELOC_TYPE (FPTR64I, REL) +RELOC_TYPE (FPTR32MSB, REL|EXEC|DYN) +RELOC_TYPE (FPTR32LSB, REL|EXEC|DYN) +RELOC_TYPE (FPTR64MSB, REL|EXEC|DYN) +RELOC_TYPE (FPTR64LSB, REL|EXEC|DYN) +RELOC_TYPE (PCREL60B, REL) +RELOC_TYPE (PCREL21B, REL) +RELOC_TYPE (PCREL21M, REL) +RELOC_TYPE (PCREL21F, REL) +RELOC_TYPE (PCREL32MSB, REL|EXEC|DYN) +RELOC_TYPE (PCREL32LSB, REL|EXEC|DYN) +RELOC_TYPE (PCREL64MSB, REL|EXEC|DYN) +RELOC_TYPE (PCREL64LSB, REL|EXEC|DYN) +RELOC_TYPE (LTOFF_FPTR22, REL) +RELOC_TYPE (LTOFF_FPTR64I, REL) +RELOC_TYPE (LTOFF_FPTR32MSB, REL) +RELOC_TYPE (LTOFF_FPTR32LSB, REL) +RELOC_TYPE (LTOFF_FPTR64MSB, REL) +RELOC_TYPE (LTOFF_FPTR64LSB, REL) +RELOC_TYPE (SEGREL32MSB, REL) +RELOC_TYPE (SEGREL32LSB, REL) +RELOC_TYPE (SEGREL64MSB, REL) +RELOC_TYPE (SEGREL64LSB, REL) +RELOC_TYPE (SECREL32MSB, REL) +RELOC_TYPE (SECREL32LSB, REL) +RELOC_TYPE (SECREL64MSB, REL) +RELOC_TYPE (SECREL64LSB, REL) +RELOC_TYPE (REL32MSB, EXEC|DYN) +RELOC_TYPE (REL32LSB, EXEC|DYN) +RELOC_TYPE (REL64MSB, EXEC|DYN) +RELOC_TYPE (REL64LSB, EXEC|DYN) +RELOC_TYPE (LTV32MSB, REL) +RELOC_TYPE (LTV32LSB, REL) +RELOC_TYPE (LTV64MSB, REL) +RELOC_TYPE (LTV64LSB, REL) +RELOC_TYPE (PCREL21BI, REL) +RELOC_TYPE (PCREL22, REL) +RELOC_TYPE (PCREL64I, REL) +RELOC_TYPE (IPLTMSB, REL|EXEC|DYN) +RELOC_TYPE (IPLTLSB, REL|EXEC|DYN) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (SUB, 0) +RELOC_TYPE (LTOFF22X, REL) +RELOC_TYPE (LDXMOV, REL) +RELOC_TYPE (TPREL14, REL) +RELOC_TYPE (TPREL22, REL) +RELOC_TYPE (TPREL64I, REL) +RELOC_TYPE (TPREL64MSB, REL|EXEC|DYN) +RELOC_TYPE (TPREL64LSB, REL|EXEC|DYN) +RELOC_TYPE (LTOFF_TPREL22, REL) +RELOC_TYPE (DTPMOD64MSB, REL|EXEC|DYN) +RELOC_TYPE (DTPMOD64LSB, REL|EXEC|DYN) +RELOC_TYPE (LTOFF_DTPMOD22, REL) +RELOC_TYPE (DTPREL14, REL) +RELOC_TYPE (DTPREL22, REL) +RELOC_TYPE (DTPREL64I, REL) +RELOC_TYPE (DTPREL32MSB, REL|EXEC|DYN) +RELOC_TYPE (DTPREL32LSB, REL|EXEC|DYN) +RELOC_TYPE (DTPREL64MSB, REL|EXEC|DYN) +RELOC_TYPE (DTPREL64LSB, REL|EXEC|DYN) +RELOC_TYPE (LTOFF_DTPREL22, REL) + +#define NO_RELATIVE_RELOC 1 diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c new file mode 100644 index 00000000..03ea4d89 --- /dev/null +++ b/backends/ia64_retval.c @@ -0,0 +1,366 @@ +/* Function return value location for IA64 ABI. + Copyright (C) 2006-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND ia64_ +#include "libebl_CPU.h" + + +/* r8, or pair r8, r9, or aggregate up to r8-r11. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg8 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg9 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg10 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg11 }, { .atom = DW_OP_piece, .number = 8 }, + }; +#define nloc_intreg 1 +#define nloc_intregs(n) (2 * (n)) + +/* f8, or aggregate up to f8-f15. */ +#define DEFINE_FPREG(size) \ + static const Dwarf_Op loc_fpreg_##size[] = \ + { \ + { .atom = DW_OP_regx, .number = 128 + 8 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 9 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 10 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 11 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 12 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 13 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 14 }, \ + { .atom = DW_OP_piece, .number = size }, \ + { .atom = DW_OP_regx, .number = 128 + 15 }, \ + { .atom = DW_OP_piece, .number = size }, \ + } +#define nloc_fpreg 1 +#define nloc_fpregs(n) (2 * (n)) + +DEFINE_FPREG (4); +DEFINE_FPREG (8); +DEFINE_FPREG (10); + +#undef DEFINE_FPREG + + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in r8. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg8, .number = 0 } + }; +#define nloc_aggregate 1 + + +static inline int +compute_hfa (const Dwarf_Op *loc, int nregs, + const Dwarf_Op **locp, int fpregs_used) +{ + if (fpregs_used == 0) + *locp = loc; + else if (*locp != loc) + return 9; + return fpregs_used + nregs; +} + +/* If this type is an HFA small enough to be returned in FP registers, + return the number of registers to use. Otherwise 9, or -1 for errors. */ +static int +hfa_type (Dwarf_Die *typedie, Dwarf_Word size, + const Dwarf_Op **locp, int fpregs_used) +{ + /* Descend the type structure, counting elements and finding their types. + If we find a datum that's not an FP type (and not quad FP), punt. + If we find a datum that's not the same FP type as the first datum, punt. + If we count more than eight total homogeneous FP data, punt. */ + + int tag = DWARF_TAG_OR_RETURN (typedie); + switch (tag) + { + Dwarf_Attribute attr_mem; + + case -1: + return -1; + + case DW_TAG_base_type:; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), &encoding) != 0) + return -1; + +#define hfa(loc, nregs) compute_hfa(loc, nregs, locp, fpregs_used) + switch (encoding) + { + case DW_ATE_float: + switch (size) + { + case 4: /* float */ + return hfa (loc_fpreg_4, 1); + case 8: /* double */ + return hfa (loc_fpreg_8, 1); + case 10: /* x86-style long double, not really used */ + return hfa (loc_fpreg_10, 1); + } + break; + + case DW_ATE_complex_float: + switch (size) + { + case 4 * 2: /* complex float */ + return hfa (loc_fpreg_4, 2); + case 8 * 2: /* complex double */ + return hfa (loc_fpreg_8, 2); + case 10 * 2: /* complex long double (x86-style) */ + return hfa (loc_fpreg_10, 2); + } + break; + } + break; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type:; + Dwarf_Die child_mem; + switch (dwarf_child (typedie, &child_mem)) + { + default: + return -1; + + case 1: /* No children: empty struct. */ + break; + + case 0:; /* Look at each element. */ + int max_used = fpregs_used; + do + switch (dwarf_tag (&child_mem)) + { + case -1: + return -1; + + case DW_TAG_member:; + Dwarf_Die child_type_mem; + Dwarf_Die *child_typedie + = dwarf_formref_die (dwarf_attr_integrate (&child_mem, + DW_AT_type, + &attr_mem), + &child_type_mem); + Dwarf_Word child_size; + if (dwarf_aggregate_size (child_typedie, &child_size) != 0) + return -1; + if (tag == DW_TAG_union_type) + { + int used = hfa_type (child_typedie, child_size, + locp, fpregs_used); + if (used < 0 || used > 8) + return used; + if (used > max_used) + max_used = used; + } + else + { + fpregs_used = hfa_type (child_typedie, child_size, + locp, fpregs_used); + if (fpregs_used < 0 || fpregs_used > 8) + return fpregs_used; + } + } + while (dwarf_siblingof (&child_mem, &child_mem) == 0); + if (tag == DW_TAG_union_type) + fpregs_used = max_used; + break; + } + break; + + case DW_TAG_array_type: + if (size == 0) + break; + + Dwarf_Die base_type_mem; + Dwarf_Die *base_typedie + = dwarf_formref_die (dwarf_attr_integrate (typedie, DW_AT_type, + &attr_mem), + &base_type_mem); + Dwarf_Word base_size; + if (dwarf_aggregate_size (base_typedie, &base_size) != 0) + return -1; + + int used = hfa_type (base_typedie, base_size, locp, 0); + if (used < 0 || used > 8) + return used; + if (size % (*locp)[1].number != 0) + return 0; + fpregs_used += used * (size / (*locp)[1].number); + break; + + default: + return 9; + } + + return fpregs_used; +} + +int +ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 8; + else + return -1; + } + } + + if (tag == DW_TAG_base_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + + switch (encoding) + { + case DW_ATE_float: + switch (size) + { + case 4: /* float */ + *locp = loc_fpreg_4; + return nloc_fpreg; + case 8: /* double */ + *locp = loc_fpreg_8; + return nloc_fpreg; + case 10: /* x86-style long double, not really used */ + *locp = loc_fpreg_10; + return nloc_fpreg; + case 16: /* long double, IEEE quad format */ + *locp = loc_intreg; + return nloc_intregs (2); + } + return -2; + + case DW_ATE_complex_float: + switch (size) + { + case 4 * 2: /* complex float */ + *locp = loc_fpreg_4; + return nloc_fpregs (2); + case 8 * 2: /* complex double */ + *locp = loc_fpreg_8; + return nloc_fpregs (2); + case 10 * 2: /* complex long double (x86-style) */ + *locp = loc_fpreg_10; + return nloc_fpregs (2); + case 16 * 2: /* complex long double (IEEE quad) */ + *locp = loc_intreg; + return nloc_intregs (4); + } + return -2; + } + } + + intreg: + *locp = loc_intreg; + if (size <= 8) + return nloc_intreg; + if (size <= 32) + return nloc_intregs ((size + 7) / 8); + + large: + *locp = loc_aggregate; + return nloc_aggregate; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + if (dwarf_aggregate_size (typedie, &size) != 0) + return -1; + + /* If this qualifies as an homogeneous floating-point aggregate + (HFA), then it should be returned in FP regs. */ + int nfpreg = hfa_type (typedie, size, locp, 0); + if (nfpreg < 0) + return nfpreg; + else if (nfpreg > 0 && nfpreg <= 8) + return nfpreg == 1 ? nloc_fpreg : nloc_fpregs (nfpreg); + + if (size > 32) + goto large; + + goto intreg; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/ia64_symbol.c b/backends/ia64_symbol.c new file mode 100644 index 00000000..0c038f0d --- /dev/null +++ b/backends/ia64_symbol.c @@ -0,0 +1,158 @@ +/* IA-64 specific symbolic name handling. + Copyright (C) 2002-2009, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND ia64_ +#include "libebl_CPU.h" + + +const char * +ia64_segment_type_name (int segment, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (segment) + { + case PT_IA_64_ARCHEXT: + return "IA_64_ARCHEXT"; + case PT_IA_64_UNWIND: + return "IA_64_UNWIND"; + case PT_IA_64_HP_OPT_ANOT: + return "IA_64_HP_OPT_ANOT"; + case PT_IA_64_HP_HSL_ANOT: + return "IA_64_HP_HSL_ANOT"; + case PT_IA_64_HP_STACK: + return "IA_64_HP_STACK"; + default: + break; + } + return NULL; +} + +const char * +ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_IA_64_PLT_RESERVE: + return "IA_64_PLT_RESERVE"; + default: + break; + } + return NULL; +} + +/* Check dynamic tag. */ +bool +ia64_dynamic_tag_check (int64_t tag) +{ + return tag == DT_IA_64_PLT_RESERVE; +} + +/* Check whether machine flags are valid. */ +bool +ia64_machine_flag_check (GElf_Word flags) +{ + return ((flags &~ EF_IA_64_ABI64) == 0); +} + +/* Check whether SHF_MASKPROC flags are valid. */ +bool +ia64_machine_section_flag_check (GElf_Xword sh_flags) +{ + return (sh_flags &~ (SHF_IA_64_SHORT | SHF_IA_64_NORECOV)) == 0; +} + +/* Return symbolic representation of section type. */ +const char * +ia64_section_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (type) + { + case SHT_IA_64_EXT: + return "IA_64_EXT"; + case SHT_IA_64_UNWIND: + return "IA_64_UNWIND"; + } + + return NULL; +} + +/* Check for the simple reloc types. */ +Elf_Type +ia64_reloc_simple_type (Ebl *ebl, int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + /* The SECREL types when used with non-allocated sections + like .debug_* are the same as direct absolute relocs + applied to those sections, since a 0 section address is assumed. + So we treat them the same here. */ + + case R_IA64_SECREL32MSB: + case R_IA64_DIR32MSB: + if (ebl->data == ELFDATA2MSB) + return ELF_T_WORD; + break; + case R_IA64_SECREL32LSB: + case R_IA64_DIR32LSB: + if (ebl->data == ELFDATA2LSB) + return ELF_T_WORD; + break; + case R_IA64_DIR64MSB: + case R_IA64_SECREL64MSB: + if (ebl->data == ELFDATA2MSB) + return ELF_T_XWORD; + break; + case R_IA64_SECREL64LSB: + case R_IA64_DIR64LSB: + if (ebl->data == ELFDATA2LSB) + return ELF_T_XWORD; + break; + } + + return ELF_T_NUM; +} + +/* The SHT_IA_64_UNWIND section type is a valid target for relocation. */ +bool +ia64_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type) +{ + return sh_type == SHT_IA_64_UNWIND; +} diff --git a/backends/libebl_CPU.h b/backends/libebl_CPU.h new file mode 100644 index 00000000..0e507bd3 --- /dev/null +++ b/backends/libebl_CPU.h @@ -0,0 +1,75 @@ +/* Common interface for libebl modules. + Copyright (C) 2000, 2001, 2002, 2003, 2005, 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBEBL_CPU_H +#define _LIBEBL_CPU_H 1 + +#include +#include + +#define EBLHOOK(name) EBLHOOK_1(BACKEND, name) +#define EBLHOOK_1(a, b) EBLHOOK_2(a, b) +#define EBLHOOK_2(a, b) a##b + +/* Constructor. */ +extern Ebl *EBLHOOK(init) (Elf *elf, GElf_Half machine, Ebl *eh); + +#include "ebl-hooks.h" + +#define HOOK(eh, name) eh->name = EBLHOOK(name) + +extern bool (*generic_debugscn_p) (const char *) attribute_hidden; + +/* Helper for retval. Return dwarf_tag (die), but calls return -1 + if there where previous errors that leave die NULL. */ +#define DWARF_TAG_OR_RETURN(die) \ + ({ Dwarf_Die *_die = (die); \ + if (_die == NULL) return -1; \ + dwarf_tag (_die); }) + +/* Get a type die corresponding to DIE. Peel CV qualifiers off + it. */ +static inline int +dwarf_peeled_die_type (Dwarf_Die *die, Dwarf_Die *result) +{ + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = dwarf_attr_integrate (die, DW_AT_type, &attr_mem); + if (attr == NULL) + /* The function has no return value, like a `void' function in C. */ + return 0; + + if (dwarf_formref_die (attr, result) == NULL) + return -1; + + if (dwarf_peel_type (result, result) != 0) + return -1; + + return DWARF_TAG_OR_RETURN (result); +} + +#endif /* libebl_CPU.h */ diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c new file mode 100644 index 00000000..9faae4c3 --- /dev/null +++ b/backends/linux-core-note.c @@ -0,0 +1,315 @@ +/* Common core note type descriptions for Linux. + Copyright (C) 2007-2010 Red Hat, Inc. + Copyright (C) H.J. Lu , 2015. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include + +/* The including CPU_corenote.c file provides prstatus_regs and + defines macros ULONG, [PUG]ID_T, and ALIGN_*, TYPE_*. + + Here we describe the common layout used in . */ + +#define CHAR int8_t +#define ALIGN_CHAR 1 +#define TYPE_CHAR ELF_T_BYTE +#define SHORT uint16_t +#define ALIGN_SHORT 2 +#define TYPE_SHORT ELF_T_HALF +#define INT int32_t +#ifndef ALIGN_INT +# define ALIGN_INT 4 +#endif +#define TYPE_INT ELF_T_SWORD +#ifndef PR_REG +# define PR_REG ULONG +#endif +#ifndef ALIGN_PR_REG +# define ALIGN_PR_REG ALIGN_ULONG +#endif +#ifndef PRPSINFO_UID_T +# define PRPSINFO_UID_T UID_T +# define ALIGN_PRPSINFO_UID_T ALIGN_UID_T +# define TYPE_PRPSINFO_UID_T TYPE_UID_T +#endif +#ifndef PRPSINFO_GID_T +# define PRPSINFO_GID_T GID_T +# define ALIGN_PRPSINFO_GID_T ALIGN_GID_T +# define TYPE_PRPSINFO_GID_T TYPE_GID_T +#endif + +#define FIELD(type, name) type name __attribute__ ((aligned (ALIGN_##type))) + +struct EBLHOOK(siginfo) +{ + FIELD (INT, si_signo); + FIELD (INT, si_code); + FIELD (INT, si_errno); +}; + +struct EBLHOOK(timeval) +{ + FIELD (ULONG, tv_sec); + FIELD (ULONG, tv_usec); +}; + +/* On sparc64, tv_usec (suseconds_t) is actually 32 bits with 32 bits padding. + The 'T'|0x80 value for .format indicates this as a special kludge. */ +#if SUSECONDS_HALF +# define TIMEVAL_FIELD(name) FIELD (time, ULONG, name, 'T'|0x80, .count = 2) +#else +# define TIMEVAL_FIELD(name) FIELD (time, ULONG, name, 'T', .count = 2) +#endif + + +struct EBLHOOK(prstatus) +{ + struct EBLHOOK(siginfo) pr_info; + FIELD (SHORT, pr_cursig); + FIELD (ULONG, pr_sigpend); + FIELD (ULONG, pr_sighold); + FIELD (PID_T, pr_pid); + FIELD (PID_T, pr_ppid); + FIELD (PID_T, pr_pgrp); + FIELD (PID_T, pr_sid); + struct EBLHOOK(timeval) pr_utime; + struct EBLHOOK(timeval) pr_stime; + struct EBLHOOK(timeval) pr_cutime; + struct EBLHOOK(timeval) pr_cstime; + struct + { + FIELD (PR_REG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (PR_REG)]); + } +#ifdef ALIGN_PR_REG + __attribute__ ((aligned (ALIGN_PR_REG))) +#endif + ; + FIELD (INT, pr_fpvalid); +} +#ifdef ALIGN_PRSTATUS + attribute_packed __attribute__ ((aligned (ALIGN_PRSTATUS))) +#endif +; + +#define FNAMESZ 16 +#define PRARGSZ 80 + +struct EBLHOOK(prpsinfo) +{ + FIELD (CHAR, pr_state); + FIELD (CHAR, pr_sname); + FIELD (CHAR, pr_zomb); + FIELD (CHAR, pr_nice); + FIELD (ULONG, pr_flag); + FIELD (PRPSINFO_UID_T, pr_uid); + FIELD (PRPSINFO_GID_T, pr_gid); + FIELD (PID_T, pr_pid); + FIELD (PID_T, pr_ppid); + FIELD (PID_T, pr_pgrp); + FIELD (PID_T, pr_sid); + FIELD (CHAR, pr_fname[FNAMESZ]); + FIELD (CHAR, pr_psargs[PRARGSZ]); +}; + +#undef FIELD + +#define FIELD(igroup, itype, item, fmt, ...) \ + { \ + .name = #item, \ + .group = #igroup, \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_##item), \ + .type = TYPE_##itype, \ + .format = fmt, \ + __VA_ARGS__ \ + } + +static const Ebl_Core_Item prstatus_items[] = + { + FIELD (signal, INT, info.si_signo, 'd'), + FIELD (signal, INT, info.si_code, 'd'), + FIELD (signal, INT, info.si_errno, 'd'), + FIELD (signal, SHORT, cursig, 'd'), + + /* Use different group name for a newline delimiter. */ + FIELD (signal2, ULONG, sigpend, 'B'), + FIELD (signal3, ULONG, sighold, 'B'), + FIELD (identity, PID_T, pid, 'd', .thread_identifier = true), + FIELD (identity, PID_T, ppid, 'd'), + FIELD (identity, PID_T, pgrp, 'd'), + FIELD (identity, PID_T, sid, 'd'), + TIMEVAL_FIELD (utime), + TIMEVAL_FIELD (stime), + TIMEVAL_FIELD (cutime), + TIMEVAL_FIELD (cstime), +#ifdef PRSTATUS_REGSET_ITEMS + PRSTATUS_REGSET_ITEMS, +#endif + FIELD (register, INT, fpvalid, 'd'), + }; + +#undef FIELD + +#define FIELD(igroup, itype, item, fmt, ...) \ + { \ + .name = #item, \ + .group = #igroup, \ + .offset = offsetof (struct EBLHOOK(prpsinfo), pr_##item), \ + .type = TYPE_##itype, \ + .format = fmt, \ + __VA_ARGS__ \ + } + +static const Ebl_Core_Item prpsinfo_items[] = + { + FIELD (state, CHAR, state, 'd'), + FIELD (state, CHAR, sname, 'c'), + FIELD (state, CHAR, zomb, 'd'), + FIELD (state, CHAR, nice, 'd'), + FIELD (state, ULONG, flag, 'x'), + FIELD (identity, PRPSINFO_UID_T, uid, 'd'), + FIELD (identity, PRPSINFO_GID_T, gid, 'd'), + FIELD (identity, PID_T, pid, 'd'), + FIELD (identity, PID_T, ppid, 'd'), + FIELD (identity, PID_T, pgrp, 'd'), + FIELD (identity, PID_T, sid, 'd'), + FIELD (command, CHAR, fname, 's', .count = FNAMESZ), + FIELD (command, CHAR, psargs, 's', .count = PRARGSZ), + }; + +static const Ebl_Core_Item vmcoreinfo_items[] = + { + { + .type = ELF_T_BYTE, .format = '\n' + } + }; + +#undef FIELD + +int +EBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name, + GElf_Word *regs_offset, size_t *nregloc, + const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **items) +{ + switch (nhdr->n_namesz) + { + case sizeof "CORE" - 1: /* Buggy old Linux kernels. */ + if (memcmp (name, "CORE", nhdr->n_namesz) == 0) + break; + return 0; + + case sizeof "CORE": + if (memcmp (name, "CORE", nhdr->n_namesz) == 0) + break; + /* Buggy old Linux kernels didn't terminate "LINUX". */ + FALLTHROUGH; + + case sizeof "LINUX": + if (memcmp (name, "LINUX", nhdr->n_namesz) == 0) + break; + return 0; + + case sizeof "VMCOREINFO": + if (nhdr->n_type != 0 + || memcmp (name, "VMCOREINFO", sizeof "VMCOREINFO") != 0) + return 0; + *regs_offset = 0; + *nregloc = 0; + *nitems = 1; + *items = vmcoreinfo_items; + return 1; + + default: + return 0; + } + + switch (nhdr->n_type) + { + case NT_PRSTATUS: + if (nhdr->n_descsz != sizeof (struct EBLHOOK(prstatus))) + return 0; + *regs_offset = offsetof (struct EBLHOOK(prstatus), pr_reg); + *nregloc = sizeof prstatus_regs / sizeof prstatus_regs[0]; + *reglocs = prstatus_regs; + *nitems = sizeof prstatus_items / sizeof prstatus_items[0]; + *items = prstatus_items; + return 1; + + case NT_PRPSINFO: + if (nhdr->n_descsz != sizeof (struct EBLHOOK(prpsinfo))) + return 0; + *regs_offset = 0; + *nregloc = 0; + *reglocs = NULL; + *nitems = sizeof prpsinfo_items / sizeof prpsinfo_items[0]; + *items = prpsinfo_items; + return 1; + +#define EXTRA_REGSET(type, size, table) \ + case type: \ + if (nhdr->n_descsz != size) \ + return 0; \ + *regs_offset = 0; \ + *nregloc = sizeof table / sizeof table[0]; \ + *reglocs = table; \ + *nitems = 0; \ + *items = NULL; \ + return 1; + +#define EXTRA_REGSET_ITEMS(type, size, table, extra_items) \ + case type: \ + if (nhdr->n_descsz != size) \ + return 0; \ + *regs_offset = 0; \ + *nregloc = sizeof table / sizeof table[0]; \ + *reglocs = table; \ + *nitems = sizeof extra_items / sizeof extra_items[0]; \ + *items = extra_items; \ + return 1; + +#define EXTRA_ITEMS(type, size, extra_items) \ + case type: \ + if (nhdr->n_descsz != size) \ + return 0; \ + *regs_offset = 0; \ + *nregloc = 0; \ + *reglocs = NULL; \ + *nitems = sizeof extra_items / sizeof extra_items[0]; \ + *items = extra_items; \ + return 1; + +#ifdef FPREGSET_SIZE + EXTRA_REGSET (NT_FPREGSET, FPREGSET_SIZE, fpregset_regs) +#endif + +#ifdef EXTRA_NOTES + EXTRA_NOTES +#endif + } + + return 0; +} diff --git a/backends/m68k_cfi.c b/backends/m68k_cfi.c new file mode 100644 index 00000000..9303fb22 --- /dev/null +++ b/backends/m68k_cfi.c @@ -0,0 +1,58 @@ +/* m68k ABI-specified defaults for DWARF CFI. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND m68k_ +#include "libebl_CPU.h" + +int +m68k_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + /* Call-saved registers %d2-%d7, %a2-%a6. */ + SV (2), SV (3), SV (4), SV (5), SV (6), SV (7), + SV (10), SV (11), SV (12), SV (13), SV (14), + + /* The CFA is the SP. */ + DW_CFA_val_offset, ULEB128_7 (15), ULEB128_7 (0), + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = -4; + + abi_info->return_address_register = 24; /* %pc */ + + return 0; +} diff --git a/backends/m68k_corenote.c b/backends/m68k_corenote.c new file mode 100644 index 00000000..3c1d019f --- /dev/null +++ b/backends/m68k_corenote.c @@ -0,0 +1,72 @@ +/* M68K specific core note handling. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND m68k_ +#include "libebl_CPU.h" + +static const Ebl_Register_Location prstatus_regs[] = + { + { .offset = 0, .regno = 1, .count = 14, .bits = 32 }, /* d1-d7, a0-a6 */ + { .offset = 14 * 4, .regno = 0, .count = 1, .bits = 32 }, /* d0 */ + { .offset = 15 * 4, .regno = 15, .count = 1, .bits = 32 }, /* a7 */ + { .offset = 18 * 4, .regno = 24, .count = 1, .bits = 32 } /* pc */ + }; +#define PRSTATUS_REGS_SIZE (20 * 4) + +#define ULONG uint32_t +#define PID_T int32_t +#define UID_T uint16_t +#define GID_T uint16_t +#define ALIGN_INT 2 +#define ALIGN_ULONG 2 +#define ALIGN_PID_T 2 +#define ALIGN_UID_T 2 +#define ALIGN_GID_T 2 +#define ALIGN_PRSTATUS 2 +#define TYPE_ULONG ELF_T_WORD +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_HALF +#define TYPE_GID_T ELF_T_HALF + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 16, .count = 8, .bits = 96 }, /* fp0-fp7 */ + }; +#define FPREGSET_SIZE (27 * 4) + +#include "linux-core-note.c" diff --git a/backends/m68k_init.c b/backends/m68k_init.c new file mode 100644 index 00000000..7b94f23a --- /dev/null +++ b/backends/m68k_init.c @@ -0,0 +1,58 @@ +/* Initialization of M68K specific backend library. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND m68k_ +#define RELOC_PREFIX R_68K_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on m68k_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +m68k_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + m68k_init_reloc (eh); + HOOK (eh, gotpc_reloc_check); + HOOK (eh, reloc_simple_type); + HOOK (eh, return_value_location); + HOOK (eh, register_info); + HOOK (eh, core_note); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = 25; + HOOK (eh, set_initial_registers_tid); + + return eh; +} diff --git a/backends/m68k_initreg.c b/backends/m68k_initreg.c new file mode 100644 index 00000000..61f260f6 --- /dev/null +++ b/backends/m68k_initreg.c @@ -0,0 +1,82 @@ +/* Fetch live process registers from TID. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined __m68k__ && defined __linux__ +# include +# include +# include +#endif + +#define BACKEND m68k_ +#include "libebl_CPU.h" + +bool +m68k_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined __m68k__ || !defined __linux__ + return false; +#else /* __m68k__ */ + struct user_regs_struct user_regs; + if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0) + return false; + + Dwarf_Word dwarf_regs[16]; + dwarf_regs[0] = user_regs.d0; + dwarf_regs[1] = user_regs.d1; + dwarf_regs[2] = user_regs.d2; + dwarf_regs[3] = user_regs.d3; + dwarf_regs[4] = user_regs.d4; + dwarf_regs[5] = user_regs.d5; + dwarf_regs[6] = user_regs.d6; + dwarf_regs[7] = user_regs.d7; + dwarf_regs[8] = user_regs.a0; + dwarf_regs[9] = user_regs.a1; + dwarf_regs[10] = user_regs.a2; + dwarf_regs[11] = user_regs.a3; + dwarf_regs[12] = user_regs.a4; + dwarf_regs[13] = user_regs.a5; + dwarf_regs[14] = user_regs.a6; + dwarf_regs[15] = user_regs.usp; + + /* D0..D7, A0..A7. */ + if (! setfunc (0, 16, dwarf_regs, arg)) + return false; + + /* PC. */ + dwarf_regs[0] = user_regs.pc; + if (! setfunc (24, 1, dwarf_regs, arg)) + return false; + + return true; +#endif /* __m68k__ */ +} diff --git a/backends/m68k_regs.c b/backends/m68k_regs.c new file mode 100644 index 00000000..cb99f552 --- /dev/null +++ b/backends/m68k_regs.c @@ -0,0 +1,96 @@ +/* Register names and numbers for M68K DWARF. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND m68k_ +#include "libebl_CPU.h" + +ssize_t +m68k_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 25; + + if (regno < 0 || regno > 24 || namelen < 5) + return -1; + + *prefix = "%"; + *setname = "integer"; + *bits = 32; + + switch (regno) + { + case 0 ... 7: + *type = DW_ATE_signed; + name[0] = 'd'; + name[1] = regno + '0'; + namelen = 2; + break; + + case 8 ... 15: + *type = DW_ATE_address; + name[0] = 'a'; + name[1] = regno - 8 + '0'; + namelen = 2; + break; + + case 16 ... 23: + *type = DW_ATE_float; + *setname = "FPU"; + *bits = 96; + name[0] = 'f'; + name[1] = 'p'; + name[2] = regno - 16 + '0'; + namelen = 3; + break; + + case 24: + *type = DW_ATE_address; + name[0] = 'p'; + name[1] = 'c'; + namelen = 2; + break; + + /* Can't happen. */ + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/m68k_reloc.def b/backends/m68k_reloc.def new file mode 100644 index 00000000..b7cc4df8 --- /dev/null +++ b/backends/m68k_reloc.def @@ -0,0 +1,70 @@ +/* List the relocation types for m68k. -*- C -*- + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, EXEC|DYN) +RELOC_TYPE (32, REL|EXEC|DYN) +RELOC_TYPE (16, REL|EXEC|DYN) +RELOC_TYPE (8, REL|EXEC|DYN) +RELOC_TYPE (PC32, REL|EXEC|DYN) +RELOC_TYPE (PC16, REL|EXEC|DYN) +RELOC_TYPE (PC8, REL|EXEC|DYN) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (GOT16, REL) +RELOC_TYPE (GOT8, REL) +RELOC_TYPE (GOT32O, REL) +RELOC_TYPE (GOT16O, REL) +RELOC_TYPE (GOT8O, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (PLT16, REL) +RELOC_TYPE (PLT8, REL) +RELOC_TYPE (PLT32O, REL) +RELOC_TYPE (PLT16O, REL) +RELOC_TYPE (PLT8O, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (TLS_GD32, REL) +RELOC_TYPE (TLS_GD16, REL) +RELOC_TYPE (TLS_GD8, REL) +RELOC_TYPE (TLS_LDM32, REL) +RELOC_TYPE (TLS_LDM16, REL) +RELOC_TYPE (TLS_LDM8, REL) +RELOC_TYPE (TLS_LDO32, REL) +RELOC_TYPE (TLS_LDO16, REL) +RELOC_TYPE (TLS_LDO8, REL) +RELOC_TYPE (TLS_IE32, REL) +RELOC_TYPE (TLS_IE16, REL) +RELOC_TYPE (TLS_IE8, REL) +RELOC_TYPE (TLS_LE32, REL) +RELOC_TYPE (TLS_LE16, REL) +RELOC_TYPE (TLS_LE8, REL) +RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN) +RELOC_TYPE (TLS_DTPREL32, EXEC|DYN) +RELOC_TYPE (TLS_TPREL32, EXEC|DYN) diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c new file mode 100644 index 00000000..a653ba3a --- /dev/null +++ b/backends/m68k_retval.c @@ -0,0 +1,151 @@ +/* Function return value location for Linux/m68k ABI. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND m68k_ +#include "libebl_CPU.h" + + +/* %d0, or pair %d0, %d1. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %a0. */ +static const Dwarf_Op loc_ptrreg[] = + { + { .atom = DW_OP_reg8 } + }; +#define nloc_ptrreg 1 + +/* %fp0. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_reg16 } + }; +#define nloc_fpreg 1 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in %a0. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_reg8 } + }; +#define nloc_aggregate 1 + +int +m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Word size; + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 4; + else + return -1; + } + if (tag == DW_TAG_base_type) + { + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + if (encoding == DW_ATE_float) + { + if (size > 12) + return -2; + *locp = loc_fpreg; + return nloc_fpreg; + } + } + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + { + *locp = loc_ptrreg; + return nloc_ptrreg; + } + *locp = loc_intreg; + if (size <= 4) + return nloc_intreg; + if (size <= 8) + return nloc_intregpair; + } + FALLTHROUGH; + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + *locp = loc_aggregate; + return nloc_aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/m68k_symbol.c b/backends/m68k_symbol.c new file mode 100644 index 00000000..9551cdfe --- /dev/null +++ b/backends/m68k_symbol.c @@ -0,0 +1,71 @@ +/* m68k specific symbolic name handling. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND m68k_ +#include "libebl_CPU.h" + + +/* Return true if the symbol type is that referencing the GOT. */ +bool +m68k_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_68K_GOT32: + case R_68K_GOT16: + case R_68K_GOT8: + return true; + } + return false; +} + +/* Check for the simple reloc types. */ +Elf_Type +m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_68K_32: + return ELF_T_SWORD; + case R_68K_16: + return ELF_T_HALF; + case R_68K_8: + return ELF_T_BYTE; + default: + return ELF_T_NUM; + } +} diff --git a/backends/ppc64_corenote.c b/backends/ppc64_corenote.c new file mode 100644 index 00000000..9d6a6a44 --- /dev/null +++ b/backends/ppc64_corenote.c @@ -0,0 +1,2 @@ +#define BITS 64 +#include "ppc_corenote.c" diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c new file mode 100644 index 00000000..ffc9842c --- /dev/null +++ b/backends/ppc64_init.c @@ -0,0 +1,105 @@ +/* Initialization of PPC64 specific backend library. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND ppc64_ +#define RELOC_PREFIX R_PPC64_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on ppc64_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +ppc64_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + ppc64_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); + HOOK (eh, machine_flag_check); + HOOK (eh, copy_reloc_p); + HOOK (eh, check_special_symbol); + HOOK (eh, check_st_other_bits); + HOOK (eh, bss_plt_p); + HOOK (eh, return_value_location); + HOOK (eh, register_info); + HOOK (eh, core_note); + HOOK (eh, auxv_info); + HOOK (eh, check_object_attribute); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = (114 - 1) + 32; + HOOK (eh, set_initial_registers_tid); + HOOK (eh, dwarf_to_regno); + HOOK (eh, unwind); + HOOK (eh, resolve_sym_value); + + /* Find the function descriptor .opd table for resolve_sym_value. */ + if (elf != NULL) + { + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); + size_t shstrndx; + if (ehdr != NULL && ehdr->e_type != ET_REL + && elf_getshdrstrndx (elf, &shstrndx) == 0) + { + /* We could also try through DT_PPC64_OPD and DT_PPC64_OPDSZ. */ + GElf_Shdr opd_shdr_mem, *opd_shdr; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + opd_shdr = gelf_getshdr (scn, &opd_shdr_mem); + if (opd_shdr != NULL + && (opd_shdr->sh_flags & SHF_ALLOC) != 0 + && opd_shdr->sh_type == SHT_PROGBITS + && opd_shdr->sh_size > 0) + { + const char *name = elf_strptr (elf, shstrndx, + opd_shdr->sh_name); + if (name != NULL && strcmp (name, ".opd") == 0) + { + eh->fd_addr = opd_shdr->sh_addr; + eh->fd_data = elf_getdata (scn, NULL); + break; + } + } + } + } + } + + return eh; +} diff --git a/backends/ppc64_reloc.def b/backends/ppc64_reloc.def new file mode 100644 index 00000000..15a73ba5 --- /dev/null +++ b/backends/ppc64_reloc.def @@ -0,0 +1,161 @@ +/* List the relocation types for ppc64. -*- C -*- + Copyright (C) 2005, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (ADDR32, REL|EXEC|DYN) +RELOC_TYPE (ADDR24, REL) +RELOC_TYPE (ADDR16, REL) /* note 1 */ +RELOC_TYPE (ADDR16_LO, REL) /* note 1 */ +RELOC_TYPE (ADDR16_HI, REL) /* note 1 */ +RELOC_TYPE (ADDR16_HA, REL) /* note 1 */ +RELOC_TYPE (ADDR14, REL) /* note 1 */ +RELOC_TYPE (ADDR14_BRTAKEN, REL) /* note 1 */ +RELOC_TYPE (ADDR14_BRNTAKEN, REL) /* note 1 */ +RELOC_TYPE (REL24, REL) +RELOC_TYPE (REL14, REL) +RELOC_TYPE (REL14_BRTAKEN, REL) +RELOC_TYPE (REL14_BRNTAKEN, REL) +RELOC_TYPE (GOT16, REL) +RELOC_TYPE (GOT16_LO, REL) +RELOC_TYPE (GOT16_HI, REL) +RELOC_TYPE (GOT16_HA, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (UADDR32, REL|EXEC|DYN) +RELOC_TYPE (UADDR16, REL) +RELOC_TYPE (REL32, REL|EXEC|DYN) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (PLTREL32, REL) +RELOC_TYPE (PLT16_LO, REL) +RELOC_TYPE (PLT16_HI, REL) +RELOC_TYPE (PLT16_HA, REL) +RELOC_TYPE (SECTOFF, REL) +RELOC_TYPE (SECTOFF_LO, REL) +RELOC_TYPE (SECTOFF_HI, REL) +RELOC_TYPE (SECTOFF_HA, REL) +RELOC_TYPE (ADDR30, REL) /* note 1 */ +RELOC_TYPE (ADDR64, REL|EXEC|DYN) +RELOC_TYPE (ADDR16_HIGHER, REL) /* note 1 */ +RELOC_TYPE (ADDR16_HIGHERA, REL) /* note 1 */ +RELOC_TYPE (ADDR16_HIGHEST, REL) /* note 1 */ +RELOC_TYPE (ADDR16_HIGHESTA, REL) /* note 1 */ +RELOC_TYPE (UADDR64, REL|EXEC|DYN) +RELOC_TYPE (REL64, REL|EXEC|DYN) +RELOC_TYPE (PLT64, REL) +RELOC_TYPE (PLTREL64, REL) +RELOC_TYPE (TOC16, REL) +RELOC_TYPE (TOC16_LO, REL) +RELOC_TYPE (TOC16_HI, REL) +RELOC_TYPE (TOC16_HA, REL) +RELOC_TYPE (TOC, REL) +RELOC_TYPE (PLTGOT16, REL) +RELOC_TYPE (PLTGOT16_LO, REL) +RELOC_TYPE (PLTGOT16_HI, REL) +RELOC_TYPE (PLTGOT16_HA, REL) +RELOC_TYPE (ADDR16_DS, REL) /* note 1 */ +RELOC_TYPE (ADDR16_LO_DS, REL) /* note 1 */ +RELOC_TYPE (GOT16_DS, REL) +RELOC_TYPE (GOT16_LO_DS, REL) +RELOC_TYPE (PLT16_LO_DS, REL) +RELOC_TYPE (SECTOFF_DS, REL) +RELOC_TYPE (SECTOFF_LO_DS, REL) +RELOC_TYPE (TOC16_DS, REL) +RELOC_TYPE (TOC16_LO_DS, REL) +RELOC_TYPE (PLTGOT16_DS, REL) +RELOC_TYPE (PLTGOT16_LO_DS, REL) +RELOC_TYPE (TLS, REL) +RELOC_TYPE (DTPMOD64, REL|EXEC|DYN) /* note 3 */ +RELOC_TYPE (TPREL16, REL) /* note 2 */ +RELOC_TYPE (TPREL16_LO, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HI, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HA, REL) /* note 2 */ +RELOC_TYPE (TPREL64, REL|EXEC|DYN) /* note 3 */ +RELOC_TYPE (DTPREL16, REL) +RELOC_TYPE (DTPREL16_LO, REL) +RELOC_TYPE (DTPREL16_HI, REL) +RELOC_TYPE (DTPREL16_HA, REL) +RELOC_TYPE (DTPREL64, REL|EXEC|DYN) /* note 3 */ +RELOC_TYPE (GOT_TLSGD16, REL) +RELOC_TYPE (GOT_TLSGD16_LO, REL) +RELOC_TYPE (GOT_TLSGD16_HI, REL) +RELOC_TYPE (GOT_TLSGD16_HA, REL) +RELOC_TYPE (GOT_TLSLD16, REL) +RELOC_TYPE (GOT_TLSLD16_LO, REL) +RELOC_TYPE (GOT_TLSLD16_HI, REL) +RELOC_TYPE (GOT_TLSLD16_HA, REL) +RELOC_TYPE (GOT_TPREL16_DS, REL) +RELOC_TYPE (GOT_TPREL16_LO_DS, REL) +RELOC_TYPE (GOT_TPREL16_HI, REL) +RELOC_TYPE (GOT_TPREL16_HA, REL) +RELOC_TYPE (GOT_DTPREL16_DS, REL) +RELOC_TYPE (GOT_DTPREL16_LO_DS, REL) +RELOC_TYPE (GOT_DTPREL16_HI, REL) +RELOC_TYPE (GOT_DTPREL16_HA, REL) +RELOC_TYPE (TPREL16_DS, REL) /* note 2 */ +RELOC_TYPE (TPREL16_LO_DS, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HIGHER, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HIGHERA, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HIGHEST, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HIGHESTA, REL) /* note 2 */ +RELOC_TYPE (DTPREL16_DS, REL) +RELOC_TYPE (DTPREL16_LO_DS, REL) +RELOC_TYPE (DTPREL16_HIGHER, REL) +RELOC_TYPE (DTPREL16_HIGHERA, REL) +RELOC_TYPE (DTPREL16_HIGHEST, REL) +RELOC_TYPE (DTPREL16_HIGHESTA, REL) +RELOC_TYPE (TLSGD, REL) +RELOC_TYPE (TLSLD, REL) +RELOC_TYPE (TOCSAVE, REL) +RELOC_TYPE (ADDR16_HIGH, REL) +RELOC_TYPE (ADDR16_HIGHA, REL) +RELOC_TYPE (TPREL16_HIGH, REL) +RELOC_TYPE (TPREL16_HIGHA, REL) +RELOC_TYPE (DTPREL16_HIGH, REL) +RELOC_TYPE (DTPREL16_HIGHA, REL) +RELOC_TYPE (JMP_IREL, REL) +RELOC_TYPE (IRELATIVE, REL) +RELOC_TYPE (REL16, REL) +RELOC_TYPE (REL16_LO, REL) +RELOC_TYPE (REL16_HI, REL) +RELOC_TYPE (REL16_HA, REL) + +/* Notes from Alan Modra: + + 1) These can appear in DYN and EXEC with improper assembly, but they + aren't really kosher. + + 2) These can appear in DYN with improper assembly (or silly gcc + attributes, I think). Again, not kosher. + + 3) These are legal in REL for PowerOpen compatible assembler syntax, + ie. TOC managed by compiler. +*/ diff --git a/backends/ppc64_resolve_sym.c b/backends/ppc64_resolve_sym.c new file mode 100644 index 00000000..03f65584 --- /dev/null +++ b/backends/ppc64_resolve_sym.c @@ -0,0 +1,63 @@ +/* Resolve symbol values through .opd function descriptors. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND ppc64_ +#include "libebl_CPU.h" + +/* Resolve a function descriptor if addr points into the .opd section. + The .opd section contains function descriptors consisting of 3 addresses. + function, toc and chain. We are just interested in the first. + http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES + + Returns true if the given address could be resolved, false otherwise. +*/ +bool +ppc64_resolve_sym_value (Ebl *ebl, GElf_Addr *addr) +{ + if (ebl->fd_data != NULL && *addr >= ebl->fd_addr + && *addr + sizeof (Elf64_Addr) <= ebl->fd_addr + ebl->fd_data->d_size) + { + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem); + if (ehdr != NULL) + { + Elf_Data opd_in, opd_out; + opd_in.d_buf = ebl->fd_data->d_buf + (*addr - ebl->fd_addr); + opd_out.d_buf = addr; + opd_out.d_size = opd_in.d_size = sizeof (Elf64_Addr); + opd_out.d_type = opd_in.d_type = ELF_T_ADDR; + if (elf64_xlatetom (&opd_out, &opd_in, + ehdr->e_ident[EI_DATA]) != NULL) + return true; + } + } + return false; +} diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c new file mode 100644 index 00000000..eb1c11ec --- /dev/null +++ b/backends/ppc64_retval.c @@ -0,0 +1,195 @@ +/* Function return value location for Linux/PPC64 ABI. + Copyright (C) 2005-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND ppc64_ +#include "libebl_CPU.h" + + +/* r3. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg3 } + }; +#define nloc_intreg 1 + +/* f1, or f1:f2, or f1:f4. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 36 }, { .atom = DW_OP_piece, .number = 8 }, + }; +#define nloc_fpreg 1 +#define nloc_fp2regs 4 +#define nloc_fp4regs 8 + +/* vr2. */ +static const Dwarf_Op loc_vmxreg[] = + { + { .atom = DW_OP_regx, .number = 1124 + 2 } + }; +#define nloc_vmxreg 1 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in r3. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg3, .number = 0 } + }; +#define nloc_aggregate 1 + +int +ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 8; + else + return -1; + } + } + + if (tag == DW_TAG_base_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + + if (encoding == DW_ATE_float || encoding == DW_ATE_complex_float) + { + *locp = loc_fpreg; + if (size <= 8) + return nloc_fpreg; + if (size <= 16) + return nloc_fp2regs; + if (size <= 32) + return nloc_fp4regs; + } + } + if (size <= 8) + { + intreg: + *locp = loc_intreg; + return nloc_intreg; + } + + FALLTHROUGH; + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + aggregate: + *locp = loc_aggregate; + return nloc_aggregate; + + case DW_TAG_array_type: + { + Dwarf_Attribute attr_mem; + bool is_vector; + if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector, + &attr_mem), &is_vector) == 0 + && is_vector) + { + *locp = loc_vmxreg; + return nloc_vmxreg; + } + } + FALLTHROUGH; + + case DW_TAG_string_type: + if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8) + { + if (tag == DW_TAG_array_type) + { + /* Check if it's a character array. */ + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + if (tag != DW_TAG_base_type) + goto aggregate; + if (dwarf_formudata (dwarf_attr_integrate (typedie, + DW_AT_byte_size, + &attr_mem), + &size) != 0) + return -1; + if (size != 1) + goto aggregate; + } + goto intreg; + } + goto aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/ppc64_symbol.c b/backends/ppc64_symbol.c new file mode 100644 index 00000000..81b94cfd --- /dev/null +++ b/backends/ppc64_symbol.c @@ -0,0 +1,134 @@ +/* PPC64 specific symbolic name handling. + Copyright (C) 2004, 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND ppc64_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_PPC64_ADDR64: + case R_PPC64_UADDR64: + return ELF_T_XWORD; + case R_PPC64_ADDR32: + case R_PPC64_UADDR32: + return ELF_T_WORD; + case R_PPC64_UADDR16: + return ELF_T_HALF; + default: + return ELF_T_NUM; + } +} + + +const char * +ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_PPC64_GLINK: + return "PPC64_GLINK"; + case DT_PPC64_OPD: + return "PPC64_OPD"; + case DT_PPC64_OPDSZ: + return "PPC64_OPDSZ"; + case DT_PPC64_OPT: + return "PPC64_OPT"; + default: + break; + } + return NULL; +} + + +bool +ppc64_dynamic_tag_check (int64_t tag) +{ + return (tag == DT_PPC64_GLINK + || tag == DT_PPC64_OPD + || tag == DT_PPC64_OPDSZ + || tag == DT_PPC64_OPT); +} + + +/* Check whether given symbol's st_value and st_size are OK despite failing + normal checks. */ +bool +ppc64_check_special_symbol (Elf *elf, + const GElf_Sym *sym __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + const GElf_Shdr *destshdr) +{ + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); + if (sname == NULL) + return false; + return strcmp (sname, ".opd") == 0; +} + + +/* Check if backend uses a bss PLT in this file. */ +bool +ppc64_bss_plt_p (Elf *elf __attribute__ ((unused))) +{ + return true; +} + +/* Check whether machine flags are valid. PPC64 has three possible values: + 0 - for unspecified ABI, or not using any specific ABI features. + 1 - for the original ELF PPC64 ABI using function descriptors. + 2 - for the revised ELFv2 PPC64 ABI without function descriptors. */ +bool +ppc64_machine_flag_check (GElf_Word flags) +{ + return flags == 0 || flags == 1 || flags == 2; +} + +bool +ppc64_check_st_other_bits (unsigned char st_other) +{ + return (PPC64_LOCAL_ENTRY_OFFSET (st_other) != 0); +} diff --git a/backends/ppc64_unwind.c b/backends/ppc64_unwind.c new file mode 100644 index 00000000..4fa0b5a9 --- /dev/null +++ b/backends/ppc64_unwind.c @@ -0,0 +1,76 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND ppc64_ + +#define LR_REG 65 /* Not 108, see ppc_dwarf_to_regno. */ +#define SP_REG 1 + +#define LR_OFFSET 16 + +#include "libebl_CPU.h" + +/* Simplistic fallback frame unwinder. SP points to the backchain (contains + address of previous stack pointer). At SP offset 16 is the LR save area + (contains the value of the previous LR). */ + +bool +EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), + Dwarf_Addr pc __attribute__ ((unused)), + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep __attribute__ ((unused))) +{ + Dwarf_Word sp, newSp, lr, newLr; + + /* Stack pointer points to the backchain which contains the previous sp. */ + if (! getfunc (SP_REG, 1, &sp, arg)) + sp = 0; + + /* Link register contains previous program counter. */ + if (! getfunc (LR_REG, 1, &lr, arg) + || lr == 0 + || ! setfunc (-1, 1, &lr, arg)) + return false; + + if (! readfunc(sp, &newSp, arg)) + newSp = 0; + + if (! readfunc(newSp + LR_OFFSET, &newLr, arg)) + newLr = 0; + + setfunc(SP_REG, 1, &newSp, arg); + setfunc(LR_REG, 1, &newLr, arg); + + /* Sanity check the stack grows down. */ + return newSp > sp; +} diff --git a/backends/ppc_attrs.c b/backends/ppc_attrs.c new file mode 100644 index 00000000..48d7129d --- /dev/null +++ b/backends/ppc_attrs.c @@ -0,0 +1,86 @@ +/* Object attribute tags for PowerPC. + Copyright (C) 2008, 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND ppc_ +#include "libebl_CPU.h" + +bool +ppc_check_object_attribute (Ebl *ebl __attribute__ ((unused)), + const char *vendor, int tag, uint64_t value, + const char **tag_name, const char **value_name) +{ + if (!strcmp (vendor, "gnu")) + switch (tag) + { + case 4: + *tag_name = "GNU_Power_ABI_FP"; + static const char *fp_kinds[] = + { + "Hard or soft float", + "Hard float", + "Soft float", + "Single-precision hard float", + }; + if (value < sizeof fp_kinds / sizeof fp_kinds[0]) + *value_name = fp_kinds[value]; + return true; + + case 8: + *tag_name = "GNU_Power_ABI_Vector"; + static const char *vector_kinds[] = + { + "Any", "Generic", "AltiVec", "SPE" + }; + if (value < sizeof vector_kinds / sizeof vector_kinds[0]) + *value_name = vector_kinds[value]; + return true; + + case 12: + *tag_name = "GNU_Power_ABI_Struct_Return"; + static const char *struct_return_kinds[] = + { + "Any", "r3/r4", "Memory" + }; + if (value < sizeof struct_return_kinds / sizeof struct_return_kinds[0]) + *value_name = struct_return_kinds[value]; + return true; + } + + return false; +} + +__typeof (ppc_check_object_attribute) + ppc64_check_object_attribute + __attribute__ ((alias ("ppc_check_object_attribute"))); diff --git a/backends/ppc_auxv.c b/backends/ppc_auxv.c new file mode 100644 index 00000000..a27a1da4 --- /dev/null +++ b/backends/ppc_auxv.c @@ -0,0 +1,55 @@ +/* i386 specific auxv handling. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND ppc_ +#include "libebl_CPU.h" + +int +EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format) +{ + if (a_type != AT_HWCAP) + return 0; + + *name = "HWCAP"; + *format = "b" + "ppcle\0" "truele\0" "3\0" "4\0" "5\0" "6\0" "7\0" "8\0" "9\0" + "power6x\0" "dfp\0" "pa6t\0" "arch_2_05\0" + "ic_snoop\0" "smt\0" "booke\0" "cellbe\0" + "power5+\0" "power5\0" "power4\0" "notb\0" + "efpdouble\0" "efpsingle\0" "spe\0" "ucache\0" + "4xxmac\0" "mmu\0" "fpu\0" "altivec\0" + "ppc601\0" "ppc64\0" "ppc32\0" "\0"; + return 1; +} + +__typeof (ppc_auxv_info) ppc64_auxv_info + __attribute__ ((alias ("ppc_auxv_info"))); diff --git a/backends/ppc_cfi.c b/backends/ppc_cfi.c new file mode 100644 index 00000000..b4700360 --- /dev/null +++ b/backends/ppc_cfi.c @@ -0,0 +1,77 @@ +/* ppc ABI-specified defaults for DWARF CFI. + Copyright (C) 2012, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND ppc_ +#include "libebl_CPU.h" + +int +ppc_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* This instruction is provided in every CIE. It is not repeated here: + DW_CFA_def_cfa, ULEB128_7 (1), ULEB128_7 (0) */ + /* r1 is assumed to be restored from cfa address, + r1 acts as a stack frame pointer. */ + DW_CFA_val_offset, ULEB128_7 (1), ULEB128_7 (0), + /* lr is not callee-saved but it needs to be preserved as it is pre-set + by the caller. */ + DW_CFA_same_value, ULEB128_7 (65), /* lr */ + + /* Callee-saved regs. */ +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + SV (2), /* r2 is TOC pointer. */ + SV (13), /* Reserved as system thread id (is it for CFI?). */ + /* r14-r31 are non-volatile registers. */ + SV (14), SV (15), SV (16), SV (17), SV (18), SV (19), SV (20), SV (21), + SV (22), SV (23), SV (24), SV (25), SV (26), SV (27), SV (28), SV (29), + SV (30), SV (31) + /* VMX registers v20-v31 and vrsave are non-volatile but they are + assigned DWARF registers 1144-1156 (v20-v31) which is outside of the + CFI supported range. */ +#undef SV + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = ebl->class == ELFCLASS64 ? 8 : 4; + + abi_info->return_address_register = 65; + + return 0; +} + +__typeof (ppc_abi_cfi) + ppc64_abi_cfi + __attribute__ ((alias ("ppc_abi_cfi"))); diff --git a/backends/ppc_corenote.c b/backends/ppc_corenote.c new file mode 100644 index 00000000..2b4ada7a --- /dev/null +++ b/backends/ppc_corenote.c @@ -0,0 +1,145 @@ +/* PowerPC specific core note handling. + Copyright (C) 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef BITS +# define BITS 32 +# define BACKEND ppc_ +#else +# define BITS 64 +# define BACKEND ppc64_ +#endif +#include "libebl_CPU.h" + +static const Ebl_Register_Location prstatus_regs[] = + { +#define GR(at, n, dwreg) \ + { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = BITS } + + GR (0, 32, 0), /* r0-r31 */ + /* 32, 1, nip */ + GR (33, 1, 66), /* msr */ + /* 34, 1, orig_gpr3 */ + GR (35, 1, 109), /* ctr */ + GR (36, 1, 108), /* lr */ + GR (37, 1, 101), /* xer */ + GR (38, 1, 64), /* cr */ + GR (39, 1, 100), /* mq */ + /* 40, 1, trap */ + GR (41, 1, 119), /* dar */ + GR (42, 1, 118), /* dsisr */ + +#undef GR + }; +#define PRSTATUS_REGS_SIZE (BITS / 8 * 48) + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 32, .count = 32, .bits = 64 }, /* f0-f31 */ + { .offset = 32 * 8 + 4, .regno = 65, .count = 1, .bits = 32 } /* fpscr */ + }; +#define FPREGSET_SIZE (33 * 8) + +static const Ebl_Register_Location altivec_regs[] = + { + /* vr0-vr31 */ + { .offset = 0, .regno = 1124, .count = 32, .bits = 128 }, + /* vscr XXX 67 is an unofficial assignment */ + { .offset = 32 * 16, .regno = 67, .count = 1, .bits = 32, .pad = 12 }, + /* vrsave */ + { .offset = 33 * 16, .regno = 356, .count = 1, .bits = 32, .pad = 12 } + }; + +static const Ebl_Register_Location spe_regs[] = + { + /* evr0-evr31 + { .offset = 0, .regno = ???, .count = 32, .bits = 32 }, + * acc * + { .offset = 32 * 4, .regno = ???, .count = 1, .bits = 64 }, */ + /* spefscr */ + { .offset = 34 * 4, .regno = 612, .count = 1, .bits = 32 } + }; + +static const Ebl_Register_Location tm_spr_regs[] = + { + /* tfhar */ + { .offset = 0, .regno = 114, .count = 1, .bits = 64 }, + /* texasr */ + { .offset = 8, .regno = 116, .count = 1, .bits = 64 }, + /* tfiar */ + { .offset = 16, .regno = 115, .count = 1, .bits = 64 } + }; + +#define EXTRA_NOTES \ + EXTRA_REGSET (NT_PPC_VMX, 34 * 16, altivec_regs) \ + EXTRA_REGSET (NT_PPC_SPE, 35 * 4, spe_regs) \ + EXTRA_REGSET (NT_PPC_TM_SPR, 3 * 8, tm_spr_regs) + +#if BITS == 32 +# define ULONG uint32_t +# define ALIGN_ULONG 4 +# define TYPE_ULONG ELF_T_WORD +# define TYPE_LONG ELF_T_SWORD +#else +# define ULONG uint64_t +# define ALIGN_ULONG 8 +# define TYPE_ULONG ELF_T_XWORD +# define TYPE_LONG ELF_T_SXWORD +#endif +#define PID_T int32_t +#define UID_T uint32_t +#define GID_T uint32_t +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 4 +#define ALIGN_GID_T 4 +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_WORD +#define TYPE_GID_T ELF_T_WORD + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "nip", .type = ELF_T_ADDR, .format = 'x', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[32]), \ + .group = "register", .pc_register = true \ + }, \ + { \ + .name = "orig_gpr3", .type = TYPE_LONG, .format = 'd', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[34]), \ + .group = "register" \ + } + +#include "linux-core-note.c" diff --git a/backends/ppc_init.c b/backends/ppc_init.c new file mode 100644 index 00000000..08468f8f --- /dev/null +++ b/backends/ppc_init.c @@ -0,0 +1,67 @@ +/* Initialization of PPC specific backend library. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND ppc_ +#define RELOC_PREFIX R_PPC_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on ppc_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +ppc_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + ppc_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, machine_flag_check); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); + HOOK (eh, check_special_symbol); + HOOK (eh, bss_plt_p); + HOOK (eh, return_value_location); + HOOK (eh, register_info); + HOOK (eh, core_note); + HOOK (eh, auxv_info); + HOOK (eh, check_object_attribute); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = (114 - 1) + 32; + HOOK (eh, set_initial_registers_tid); + HOOK (eh, dwarf_to_regno); + + return eh; +} diff --git a/backends/ppc_initreg.c b/backends/ppc_initreg.c new file mode 100644 index 00000000..e5cca7e1 --- /dev/null +++ b/backends/ppc_initreg.c @@ -0,0 +1,116 @@ +/* Fetch live process registers from TID. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if defined(__powerpc__) && defined(__linux__) +# include +# include +# include +#endif + +#include "system.h" + +#define BACKEND ppc_ +#include "libebl_CPU.h" + +bool +ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno) +{ + switch (*regno) + { + case 108: + // LR uses both 65 and 108 numbers, there is no consistency for it. + *regno = 65; + return true; + case 0 ... 107: + case 109 ... (114 - 1) -1: + return true; + case 1200 ... 1231: + *regno = *regno - 1200 + (114 - 1); + return true; + default: + return false; + } + abort (); +} + +__typeof (ppc_dwarf_to_regno) + ppc64_dwarf_to_regno + __attribute__ ((alias ("ppc_dwarf_to_regno"))); + +bool +ppc_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined(__powerpc__) || !defined(__linux__) + return false; +#else /* __powerpc__ */ + union + { + struct pt_regs r; + long l[sizeof (struct pt_regs) / sizeof (long)]; + } + user_regs; + eu_static_assert (sizeof (struct pt_regs) % sizeof (long) == 0); + /* PTRACE_GETREGS is EIO on kernel-2.6.18-308.el5.ppc64. */ + errno = 0; + for (unsigned regno = 0; regno < sizeof (user_regs) / sizeof (long); + regno++) + { + user_regs.l[regno] = ptrace (PTRACE_PEEKUSER, tid, + (void *) (uintptr_t) (regno + * sizeof (long)), + NULL); + if (errno != 0) + return false; + } +#define GPRS (sizeof (user_regs.r.gpr) / sizeof (*user_regs.r.gpr)) + Dwarf_Word dwarf_regs[GPRS]; + for (unsigned gpr = 0; gpr < GPRS; gpr++) + dwarf_regs[gpr] = user_regs.r.gpr[gpr]; + if (! setfunc (0, GPRS, dwarf_regs, arg)) + return false; + dwarf_regs[0] = user_regs.r.link; + // LR uses both 65 and 108 numbers, there is no consistency for it. + if (! setfunc (65, 1, dwarf_regs, arg)) + return false; + /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant + for CFI. */ + dwarf_regs[0] = user_regs.r.nip; + return setfunc (-1, 1, dwarf_regs, arg); +#endif /* __powerpc__ */ +} + +__typeof (ppc_set_initial_registers_tid) + ppc64_set_initial_registers_tid + __attribute__ ((alias ("ppc_set_initial_registers_tid"))); diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c new file mode 100644 index 00000000..43d2534f --- /dev/null +++ b/backends/ppc_regs.c @@ -0,0 +1,208 @@ +/* Register names and numbers for PowerPC DWARF. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND ppc_ +#include "libebl_CPU.h" + +ssize_t +ppc_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 1156; + + if (regno < 0 || regno > 1155 || namelen < 8) + return -1; + + *prefix = ""; + *bits = ebl->machine == EM_PPC64 ? 64 : 32; + *type = (regno < 32 ? DW_ATE_signed + : regno < 64 ? DW_ATE_float : DW_ATE_unsigned); + + if (regno < 32 || regno == 64 || regno == 66) + *setname = "integer"; + else if (regno < 64 || regno == 65) + { + *setname = "FPU"; + if (ebl->machine != EM_PPC64 && regno < 64) + *bits = 64; + } + else if (regno == 67 || regno == 356 || regno == 612 || regno >= 1124) + { + *setname = "vector"; + *bits = regno >= 1124 ? 128 : 32; + } + else + *setname = "privileged"; + + switch (regno) + { + case 0 ... 9: + name[0] = 'r'; + name[1] = regno + '0'; + namelen = 2; + break; + + case 10 ... 31: + name[0] = 'r'; + name[1] = regno / 10 + '0'; + name[2] = regno % 10 + '0'; + namelen = 3; + break; + + case 32 + 0 ... 32 + 9: + name[0] = 'f'; + name[1] = (regno - 32) + '0'; + namelen = 2; + break; + + case 32 + 10 ... 32 + 31: + name[0] = 'f'; + name[1] = (regno - 32) / 10 + '0'; + name[2] = (regno - 32) % 10 + '0'; + namelen = 3; + break; + + case 64: + return stpcpy (name, "cr") + 1 - name; + case 65: + return stpcpy (name, "fpscr") + 1 - name; + case 66: + return stpcpy (name, "msr") + 1 - name; + case 67: /* XXX unofficial assignment */ + return stpcpy (name, "vscr") + 1 - name; + + case 70 + 0 ... 70 + 9: + name[0] = 's'; + name[1] = 'r'; + name[2] = (regno - 70) + '0'; + namelen = 3; + break; + + case 70 + 10 ... 70 + 15: + name[0] = 's'; + name[1] = 'r'; + name[2] = (regno - 70) / 10 + '0'; + name[3] = (regno - 70) % 10 + '0'; + namelen = 4; + break; + + case 101: + return stpcpy (name, "xer") + 1 - name; + case 108: + return stpcpy (name, "lr") + 1 - name; + case 109: + return stpcpy (name, "ctr") + 1 - name; + case 118: + return stpcpy (name, "dsisr") + 1 - name; + case 119: + return stpcpy (name, "dar") + 1 - name; + case 122: + return stpcpy (name, "dec") + 1 - name; + case 356: + return stpcpy (name, "vrsave") + 1 - name; + case 612: + return stpcpy (name, "spefscr") + 1 - name; + case 100: + if (*bits == 32) + return stpcpy (name, "mq") + 1 - name; + FALLTHROUGH; + case 102 ... 107: + name[0] = 's'; + name[1] = 'p'; + name[2] = 'r'; + name[3] = (regno - 100) + '0'; + namelen = 4; + break; + + case 114: + return stpcpy (name, "tfhar") + 1 - name; + case 115: + return stpcpy (name, "tfiar") + 1 - name; + case 116: + return stpcpy (name, "texasr") + 1 - name; + + case 110 ... 113: + case 117: + case 120 ... 121: + case 123 ... 199: + name[0] = 's'; + name[1] = 'p'; + name[2] = 'r'; + name[3] = (regno - 100) / 10 + '0'; + name[4] = (regno - 100) % 10 + '0'; + namelen = 5; + break; + + case 200 ... 355: + case 357 ... 611: + case 613 ... 999: + name[0] = 's'; + name[1] = 'p'; + name[2] = 'r'; + name[3] = (regno - 100) / 100 + '0'; + name[4] = ((regno - 100) % 100 / 10) + '0'; + name[5] = (regno - 100) % 10 + '0'; + namelen = 6; + break; + + case 1124 + 0 ... 1124 + 9: + name[0] = 'v'; + name[1] = 'r'; + name[2] = (regno - 1124) + '0'; + namelen = 3; + break; + + case 1124 + 10 ... 1124 + 31: + name[0] = 'v'; + name[1] = 'r'; + name[2] = (regno - 1124) / 10 + '0'; + name[3] = (regno - 1124) % 10 + '0'; + namelen = 4; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} + +__typeof (ppc_register_info) + ppc64_register_info __attribute__ ((alias ("ppc_register_info"))); diff --git a/backends/ppc_reloc.def b/backends/ppc_reloc.def new file mode 100644 index 00000000..3723a9cc --- /dev/null +++ b/backends/ppc_reloc.def @@ -0,0 +1,137 @@ +/* List the relocation types for ppc. -*- C -*- + Copyright (C) 2005, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (ADDR32, REL|EXEC|DYN) +RELOC_TYPE (ADDR24, REL) +RELOC_TYPE (ADDR16, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (ADDR16_LO, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (ADDR16_HI, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (ADDR16_HA, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (ADDR14, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (ADDR14_BRTAKEN, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (ADDR14_BRNTAKEN, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (REL24, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (REL14, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (REL14_BRTAKEN, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (REL14_BRNTAKEN, REL|EXEC|DYN) /* note 1 */ +RELOC_TYPE (GOT16, REL) +RELOC_TYPE (GOT16_LO, REL) +RELOC_TYPE (GOT16_HI, REL) +RELOC_TYPE (GOT16_HA, REL) +RELOC_TYPE (PLTREL24, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (LOCAL24PC, REL) +RELOC_TYPE (UADDR32, REL|EXEC|DYN) +RELOC_TYPE (UADDR16, REL) /* note 2 */ +RELOC_TYPE (REL32, REL|EXEC|DYN) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (PLTREL32, REL) +RELOC_TYPE (PLT16_LO, REL) +RELOC_TYPE (PLT16_HI, REL) +RELOC_TYPE (PLT16_HA, REL) +RELOC_TYPE (SDAREL16, REL) +RELOC_TYPE (SECTOFF, REL) +RELOC_TYPE (SECTOFF_LO, REL) +RELOC_TYPE (SECTOFF_HI, REL) +RELOC_TYPE (SECTOFF_HA, REL) +RELOC_TYPE (TLS, REL) +RELOC_TYPE (DTPMOD32, EXEC|DYN) /* note 2 */ +RELOC_TYPE (TPREL16, REL) /* note 2 */ +RELOC_TYPE (TPREL16_LO, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HI, REL) /* note 2 */ +RELOC_TYPE (TPREL16_HA, REL) /* note 2 */ +RELOC_TYPE (TPREL32, EXEC|DYN) /* note 2 */ +RELOC_TYPE (DTPREL16, REL) +RELOC_TYPE (DTPREL16_LO, REL) +RELOC_TYPE (DTPREL16_HI, REL) +RELOC_TYPE (DTPREL16_HA, REL) +RELOC_TYPE (DTPREL32, EXEC|DYN) /* note 2 */ +RELOC_TYPE (GOT_TLSGD16, REL) +RELOC_TYPE (GOT_TLSGD16_LO, REL) +RELOC_TYPE (GOT_TLSGD16_HI, REL) +RELOC_TYPE (GOT_TLSGD16_HA, REL) +RELOC_TYPE (GOT_TLSLD16, REL) +RELOC_TYPE (GOT_TLSLD16_LO, REL) +RELOC_TYPE (GOT_TLSLD16_HI, REL) +RELOC_TYPE (GOT_TLSLD16_HA, REL) +RELOC_TYPE (GOT_TPREL16, REL) +RELOC_TYPE (GOT_TPREL16_LO, REL) +RELOC_TYPE (GOT_TPREL16_HI, REL) +RELOC_TYPE (GOT_TPREL16_HA, REL) +RELOC_TYPE (GOT_DTPREL16, REL) +RELOC_TYPE (GOT_DTPREL16_LO, REL) +RELOC_TYPE (GOT_DTPREL16_HI, REL) +RELOC_TYPE (GOT_DTPREL16_HA, REL) +RELOC_TYPE (EMB_NADDR32, REL) /* note 3 */ +RELOC_TYPE (EMB_NADDR16, REL) /* note 3 */ +RELOC_TYPE (EMB_NADDR16_LO, REL) /* note 3 */ +RELOC_TYPE (EMB_NADDR16_HI, REL) /* note 3 */ +RELOC_TYPE (EMB_NADDR16_HA, REL) /* note 3 */ +RELOC_TYPE (EMB_SDAI16, REL) /* note 3 */ +RELOC_TYPE (EMB_SDA2I16, REL) /* note 3 */ +RELOC_TYPE (EMB_SDA2REL, REL) /* note 3 */ +RELOC_TYPE (EMB_SDA21, REL) /* note 3 */ +RELOC_TYPE (EMB_MRKREF, REL) /* note 3 */ +RELOC_TYPE (EMB_RELSEC16, REL) /* note 3 */ +RELOC_TYPE (EMB_RELST_LO, REL) /* note 3 */ +RELOC_TYPE (EMB_RELST_HI, REL) /* note 3 */ +RELOC_TYPE (EMB_RELST_HA, REL) /* note 3 */ +RELOC_TYPE (EMB_BIT_FLD, REL) /* note 3 */ +RELOC_TYPE (EMB_RELSDA, REL) /* note 3 */ +RELOC_TYPE (DIAB_SDA21_LO, REL) /* note 3 */ +RELOC_TYPE (DIAB_SDA21_HI, REL) /* note 3 */ +RELOC_TYPE (DIAB_SDA21_HA, REL) /* note 3 */ +RELOC_TYPE (DIAB_RELSDA_LO, REL) /* note 3 */ +RELOC_TYPE (DIAB_RELSDA_HI, REL) /* note 3 */ +RELOC_TYPE (DIAB_RELSDA_HA, REL) /* note 3 */ +RELOC_TYPE (REL16, REL) /* note 2 */ +RELOC_TYPE (REL16_LO, REL) /* note 2 */ +RELOC_TYPE (REL16_HI, REL) /* note 2 */ +RELOC_TYPE (REL16_HA, REL) /* note 2 */ +RELOC_TYPE (TOC16, REL) /* note 2 */ + +/* Notes from Alan Modra: + + 1) These relocs should not really appear in EXEC or DYN, but they do, + primarily due to improper assembly or non-pic shared objects. They + will cause TEXTREL to be set. I marked them in the table, because + numerous people seem to think non-pic shared libs are a good idea. + + 2) As for (1), these relocs can appear anywhere with improper + assembler. I should probably make ld reject anything other than the + cases allowed in this table. Not seen in the wild, so I haven't + added the other cases. + + 3) Not used in SYSV4 +*/ diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c new file mode 100644 index 00000000..39b42da1 --- /dev/null +++ b/backends/ppc_retval.c @@ -0,0 +1,191 @@ +/* Function return value location for Linux/PPC ABI. + Copyright (C) 2005, 2006, 2007, 2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND ppc_ +#include "libebl_CPU.h" + + +/* This is the SVR4 ELF ABI convention, but AIX and Linux do not use it. */ +#define SVR4_STRUCT_RETURN 0 + + +/* r3, or pair r3, r4, or quad r3-r6. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg4 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg5 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg6 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 +#define nloc_intregquad 8 + +/* f1. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_regx, .number = 33 } + }; +#define nloc_fpreg 1 + +/* vr2. */ +static const Dwarf_Op loc_vmxreg[] = + { + { .atom = DW_OP_regx, .number = 1124 + 2 } + }; +#define nloc_vmxreg 1 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in r3. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg3, .number = 0 } + }; +#define nloc_aggregate 1 + + +/* XXX We should check the SHT_GNU_ATTRIBUTES bits here (or in ppc_init). */ +static bool +ppc_altivec_abi (void) +{ + return true; +} + +int +ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 4; + else + return -1; + } + } + + if (size <= 8) + { + if (tag == DW_TAG_base_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, + DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + if (encoding == DW_ATE_float) + { + *locp = loc_fpreg; + return nloc_fpreg; + } + } + intreg: + *locp = loc_intreg; + return size <= 4 ? nloc_intreg : nloc_intregpair; + } + + aggregate: + *locp = loc_aggregate; + return nloc_aggregate; + + case DW_TAG_array_type: + { + Dwarf_Attribute attr_mem; + bool is_vector; + if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector, + &attr_mem), &is_vector) == 0 + && is_vector + && dwarf_aggregate_size (typedie, &size) == 0) + switch (size) + { + case 16: + if (ppc_altivec_abi ()) + { + *locp = loc_vmxreg; + return nloc_vmxreg; + } + *locp = loc_intreg; + return nloc_intregquad; + } + } + FALLTHROUGH; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + if (SVR4_STRUCT_RETURN + && dwarf_aggregate_size (typedie, &size) == 0 + && size > 0 && size <= 8) + goto intreg; + goto aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/ppc_symbol.c b/backends/ppc_symbol.c new file mode 100644 index 00000000..5a169d54 --- /dev/null +++ b/backends/ppc_symbol.c @@ -0,0 +1,188 @@ +/* PPC specific symbolic name handling. + Copyright (C) 2004, 2005, 2007, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND ppc_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_PPC_ADDR32: + case R_PPC_UADDR32: + return ELF_T_WORD; + case R_PPC_UADDR16: + return ELF_T_HALF; + default: + return ELF_T_NUM; + } +} + + +/* Check whether machine flags are valid. */ +bool +ppc_machine_flag_check (GElf_Word flags) +{ + return ((flags &~ (EF_PPC_EMB + | EF_PPC_RELOCATABLE + | EF_PPC_RELOCATABLE_LIB)) == 0); +} + + +const char * +ppc_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_PPC_GOT: + return "PPC_GOT"; + case DT_PPC_OPT: + return "PPC_OPT"; + default: + break; + } + return NULL; +} + + +bool +ppc_dynamic_tag_check (int64_t tag) +{ + return (tag == DT_PPC_GOT + || tag == DT_PPC_OPT); +} + + +/* Look for DT_PPC_GOT. */ +static bool +find_dyn_got (Elf *elf, GElf_Addr *addr) +{ + size_t phnum; + if (elf_getphdrnum (elf, &phnum) != 0) + return false; + + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (phdr == NULL || phdr->p_type != PT_DYNAMIC) + continue; + + Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + Elf_Data *data = elf_getdata (scn, NULL); + if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL + && shdr->sh_entsize != 0) + for (unsigned int j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); + if (dyn != NULL && dyn->d_tag == DT_PPC_GOT) + { + *addr = dyn->d_un.d_ptr; + return true; + } + } + + /* There is only one PT_DYNAMIC entry. */ + break; + } + + return false; +} + + +/* Check whether given symbol's st_value and st_size are OK despite failing + normal checks. */ +bool +ppc_check_special_symbol (Elf *elf, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) +{ + if (name == NULL) + return false; + + if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + { + /* In -msecure-plt mode, DT_PPC_GOT is present and must match. */ + GElf_Addr gotaddr; + if (find_dyn_got (elf, &gotaddr)) + return sym->st_value == gotaddr; + + /* In -mbss-plt mode, any place in the section is valid. */ + return true; + } + + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); + if (sname == NULL) + return false; + + /* Small data area. Normally points to .sdata, in which case we + check it is at an offset of 0x8000. It might however fall in the + .data section, in which case we cannot check the offset. The + size always should be zero. */ + if (strcmp (name, "_SDA_BASE_") == 0) + return (((strcmp (sname, ".sdata") == 0 + && sym->st_value == destshdr->sh_addr + 0x8000) + || strcmp (sname, ".data") == 0) + && sym->st_size == 0); + + if (strcmp (name, "_SDA2_BASE_") == 0) + return (strcmp (sname, ".sdata2") == 0 + && sym->st_value == destshdr->sh_addr + 0x8000 + && sym->st_size == 0); + + return false; +} + + +/* Check if backend uses a bss PLT in this file. */ +bool +ppc_bss_plt_p (Elf *elf) +{ + GElf_Addr addr; + return ! find_dyn_got (elf, &addr); +} diff --git a/backends/riscv64_corenote.c b/backends/riscv64_corenote.c new file mode 100644 index 00000000..dbcb89d9 --- /dev/null +++ b/backends/riscv64_corenote.c @@ -0,0 +1,2 @@ +#define BITS 64 +#include "riscv_corenote.c" diff --git a/backends/riscv_cfi.c b/backends/riscv_cfi.c new file mode 100644 index 00000000..1c52ea8d --- /dev/null +++ b/backends/riscv_cfi.c @@ -0,0 +1,75 @@ +/* RISC-V ABI-specified defaults for DWARF CFI. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND riscv64_ +#include "libebl_CPU.h" + + +int +riscv_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* The initial Canonical Frame Address is the value of the + Stack Pointer (r2) as setup in the previous frame. */ + DW_CFA_def_cfa, ULEB128_7 (2), ULEB128_7 (0), + + /* The Stack Pointer (r2) is restored from CFA address by default. */ + DW_CFA_val_offset, ULEB128_7 (2), ULEB128_7 (0), + +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + /* The return address register contains the return address setup by + caller. */ + SV (1), + + /* Callee-saved registers s0-s11, fs0-fs11. */ + SV(8), SV (9), SV (18), SV (19), SV (20), SV (21), + SV (22), SV (23), SV (24), SV (25), SV (26), SV (27), + + SV (40), SV (41), SV (50), SV (51), SV (52), SV (53), + SV (54), SV (55), SV (56), SV (57), SV (58), SV (59), +#undef SV + + /* XXX Note: registers intentionally unused by the program, + for example as a consequence of the procedure call standard + should be initialized as if by DW_CFA_same_value. */ + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = -4; + + abi_info->return_address_register = 1; /* ra. */ + + return 0; +} diff --git a/backends/riscv_corenote.c b/backends/riscv_corenote.c new file mode 100644 index 00000000..416dffc3 --- /dev/null +++ b/backends/riscv_corenote.c @@ -0,0 +1,88 @@ +/* RISC-V specific core note handling. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef BITS +# define BITS 32 +# define BACKEND riscv_ +#else +# define BITS 64 +# define BACKEND riscv64_ +#endif + +#include "libebl_CPU.h" + +#if BITS == 32 +# define ULONG uint32_t +# define UID_T uint16_t +# define GID_T uint16_t +# define ALIGN_ULONG 4 +# define ALIGN_UID_T 2 +# define ALIGN_GID_T 2 +# define TYPE_ULONG ELF_T_WORD +# define TYPE_UID_T ELF_T_HALF +# define TYPE_GID_T ELF_T_HALF +#else +# define ULONG uint64_t +# define UID_T uint32_t +# define GID_T uint32_t +# define ALIGN_ULONG 8 +# define ALIGN_UID_T 4 +# define ALIGN_GID_T 4 +# define TYPE_ULONG ELF_T_XWORD +# define TYPE_UID_T ELF_T_WORD +# define TYPE_GID_T ELF_T_WORD +#endif + +#define PID_T int32_t +#define ALIGN_PID_T 4 +#define TYPE_PID_T ELF_T_SWORD + + +static const Ebl_Register_Location prstatus_regs[] = + { + { .offset = BITS/8, .regno = 1, .count = 31, .bits = BITS } /* x1..x31 */ + }; +#define PRSTATUS_REGS_SIZE (32 * (BITS/8)) + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "pc", .type = ELF_T_ADDR, .format = 'x', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[0]), \ + .group = "register", .pc_register = true \ + } + +#include "linux-core-note.c" diff --git a/backends/riscv_init.c b/backends/riscv_init.c new file mode 100644 index 00000000..551e7bb6 --- /dev/null +++ b/backends/riscv_init.c @@ -0,0 +1,72 @@ +/* Initialization of RISC-V specific backend library. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND riscv_ +#define RELOC_PREFIX R_RISCV_ +#include "libebl_CPU.h" + +#include "libelfP.h" + +/* This defines the common reloc hooks based on riscv_reloc.def. */ +#include "common-reloc.c" + +extern __typeof (EBLHOOK (return_value_location)) + riscv_return_value_location_lp64d attribute_hidden; + +extern __typeof (EBLHOOK (core_note)) riscv64_core_note attribute_hidden; + +Ebl * +riscv_init (Elf *elf, + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + riscv_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, register_info); + HOOK (eh, abi_cfi); + HOOK (eh, disasm); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = 66; + HOOK (eh, check_special_symbol); + HOOK (eh, machine_flag_check); + HOOK (eh, set_initial_registers_tid); + if (eh->class == ELFCLASS64) + eh->core_note = riscv64_core_note; + else + HOOK (eh, core_note); + if (eh->class == ELFCLASS64 + && ((elf->state.elf64.ehdr->e_flags & EF_RISCV_FLOAT_ABI) + == EF_RISCV_FLOAT_ABI_DOUBLE)) + eh->return_value_location = riscv_return_value_location_lp64d; + + return eh; +} diff --git a/backends/riscv_initreg.c b/backends/riscv_initreg.c new file mode 100644 index 00000000..e31a4dfd --- /dev/null +++ b/backends/riscv_initreg.c @@ -0,0 +1,77 @@ +/* Fetch live process registers from TID. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "system.h" +#include +#if defined __riscv && defined __linux__ +# include +# include +# include +#endif + +#define BACKEND riscv_ +#include "libebl_CPU.h" + +bool +riscv_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined __riscv || !defined __linux__ + return false; +#else /* __riscv */ + + /* General registers. */ + elf_gregset_t gregs; + struct iovec iovec; + iovec.iov_base = &gregs; + iovec.iov_len = sizeof (gregs); + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0) + return false; + + /* X0 is constant 0. */ + Dwarf_Word zero = 0; + if (! setfunc (0, 1, &zero, arg)) + return false; + + /* X1..X31. */ + if (! setfunc (1, 32, (Dwarf_Word *) &gregs[1], arg)) + return false; + + /* PC. */ + if (! setfunc (-1, 1, (Dwarf_Word *) &gregs[0], arg)) + return false; + + /* FP registers not yet supported. */ + + return true; +#endif /* __riscv */ +} diff --git a/backends/riscv_regs.c b/backends/riscv_regs.c new file mode 100644 index 00000000..d5961ad5 --- /dev/null +++ b/backends/riscv_regs.c @@ -0,0 +1,177 @@ +/* Register names and numbers for RISC-V DWARF. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND riscv_ +#include "libebl_CPU.h" + +ssize_t +riscv_register_info (Ebl *ebl, int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 64; + + *prefix = ""; + + if (regno < 32) + { + *setname = "integer"; + *type = DW_ATE_signed; + *bits = ebl->class == ELFCLASS64 ? 64 : 32; + } + else + { + *setname = "FPU"; + *type = DW_ATE_float; + *bits = 64; + } + + switch (regno) + { + case 0: + return stpcpy (name, "zero") + 1 - name; + + case 1: + *type = DW_ATE_address; + return stpcpy (name, "ra") + 1 - name; + + case 2: + *type = DW_ATE_address; + return stpcpy (name, "sp") + 1 - name; + + case 3: + *type = DW_ATE_address; + return stpcpy (name, "gp") + 1 - name; + + case 4: + *type = DW_ATE_address; + return stpcpy (name, "tp") + 1 - name; + + case 5 ... 7: + name[0] = 't'; + name[1] = regno - 5 + '0'; + namelen = 2; + break; + + case 8 ... 9: + name[0] = 's'; + name[1] = regno - 8 + '0'; + namelen = 2; + break; + + case 10 ... 17: + name[0] = 'a'; + name[1] = regno - 10 + '0'; + namelen = 2; + break; + + case 18 ... 25: + name[0] = 's'; + name[1] = regno - 18 + '2'; + namelen = 2; + break; + + case 26 ... 27: + name[0] = 's'; + name[1] = '1'; + name[2] = regno - 26 + '0'; + namelen = 3; + break; + + case 28 ... 31: + name[0] = 't'; + name[1] = regno - 28 + '3'; + namelen = 2; + break; + + case 32 ... 39: + name[0] = 'f'; + name[1] = 't'; + name[2] = regno - 32 + '0'; + namelen = 3; + break; + + case 40 ... 41: + name[0] = 'f'; + name[1] = 's'; + name[2] = regno - 40 + '0'; + namelen = 3; + break; + + case 42 ... 49: + name[0] = 'f'; + name[1] = 'a'; + name[2] = regno - 42 + '0'; + namelen = 3; + break; + + case 50 ... 57: + name[0] = 'f'; + name[1] = 's'; + name[2] = regno - 50 + '2'; + namelen = 3; + break; + + case 58 ... 59: + name[0] = 'f'; + name[1] = 's'; + name[2] = '1'; + name[3] = regno - 58 + '0'; + namelen = 4; + break; + + case 60 ... 61: + name[0] = 'f'; + name[1] = 't'; + name[2] = regno - 60 + '8'; + namelen = 3; + break; + + case 62 ... 63: + name[0] = 'f'; + name[1] = 't'; + name[2] = '1'; + name[3] = regno - 62 + '0'; + namelen = 4; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/riscv_reloc.def b/backends/riscv_reloc.def new file mode 100644 index 00000000..2bd3513e --- /dev/null +++ b/backends/riscv_reloc.def @@ -0,0 +1,83 @@ +/* List the relocation types for RISC-V. -*- C -*- + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, EXEC|DYN) +RELOC_TYPE (32, REL|EXEC|DYN) +RELOC_TYPE (64, REL|EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (JUMP_SLOT, EXEC|DYN) +RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN) +RELOC_TYPE (TLS_DTPMOD64, EXEC|DYN) +RELOC_TYPE (TLS_DTPREL32, EXEC|DYN) +RELOC_TYPE (TLS_DTPREL64, EXEC|DYN) +RELOC_TYPE (TLS_TPREL32, EXEC|DYN) +RELOC_TYPE (TLS_TPREL64, EXEC|DYN) +RELOC_TYPE (BRANCH, REL) +RELOC_TYPE (JAL, REL) +RELOC_TYPE (CALL, REL) +RELOC_TYPE (CALL_PLT, REL) +RELOC_TYPE (GOT_HI20, REL) +RELOC_TYPE (TLS_GOT_HI20, REL) +RELOC_TYPE (TLS_GD_HI20, REL) +RELOC_TYPE (PCREL_HI20, REL) +RELOC_TYPE (PCREL_LO12_I, REL) +RELOC_TYPE (PCREL_LO12_S, REL) +RELOC_TYPE (HI20, REL) +RELOC_TYPE (LO12_I, REL) +RELOC_TYPE (LO12_S, REL) +RELOC_TYPE (TPREL_HI20, REL) +RELOC_TYPE (TPREL_LO12_I, REL) +RELOC_TYPE (TPREL_LO12_S, REL) +RELOC_TYPE (TPREL_ADD, REL) +RELOC_TYPE (ADD8, REL) +RELOC_TYPE (ADD16, REL) +RELOC_TYPE (ADD32, REL) +RELOC_TYPE (ADD64, REL) +RELOC_TYPE (SUB8, REL) +RELOC_TYPE (SUB16, REL) +RELOC_TYPE (SUB32, REL) +RELOC_TYPE (SUB64, REL) +RELOC_TYPE (GNU_VTINHERIT, REL) +RELOC_TYPE (GNU_VTENTRY, REL) +RELOC_TYPE (ALIGN, REL) +RELOC_TYPE (RVC_BRANCH, REL) +RELOC_TYPE (RVC_JUMP, REL) +RELOC_TYPE (RVC_LUI, REL) +RELOC_TYPE (GPREL_I, REL) +RELOC_TYPE (GPREL_S, REL) +RELOC_TYPE (TPREL_I, REL) +RELOC_TYPE (TPREL_S, REL) +RELOC_TYPE (RELAX, REL) +RELOC_TYPE (SUB6, REL) +RELOC_TYPE (SET6, REL) +RELOC_TYPE (SET8, REL) +RELOC_TYPE (SET16, REL) +RELOC_TYPE (SET32, REL) +RELOC_TYPE (32_PCREL, REL) diff --git a/backends/riscv_retval.c b/backends/riscv_retval.c new file mode 100644 index 00000000..35b6010b --- /dev/null +++ b/backends/riscv_retval.c @@ -0,0 +1,251 @@ +/* Function return value location for Linux/RISC-V ABI. + Copyright (C) 2018 Sifive, Inc. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include + +#define BACKEND riscv_ +#include "libebl_CPU.h" + +static int +dwarf_bytesize_aux (Dwarf_Die *die, Dwarf_Word *sizep) +{ + int bits; + if (((bits = 8 * dwarf_bytesize (die)) < 0 + && (bits = dwarf_bitsize (die)) < 0) + || bits % 8 != 0) + return -1; + + *sizep = bits / 8; + return 0; +} + +static int +pass_in_gpr_lp64 (const Dwarf_Op **locp, Dwarf_Word size) +{ + static const Dwarf_Op loc[] = + { + { .atom = DW_OP_reg10 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg11 }, { .atom = DW_OP_piece, .number = 8 } + }; + + *locp = loc; + return size <= 8 ? 1 : 4; +} + +static int +pass_by_ref (const Dwarf_Op **locp) +{ + static const Dwarf_Op loc[] = { { .atom = DW_OP_breg10 } }; + + *locp = loc; + return 1; +} + +static int +pass_in_fpr_lp64f (const Dwarf_Op **locp, Dwarf_Word size) +{ + static const Dwarf_Op loc[] = + { + { .atom = DW_OP_regx, .number = 42 }, + { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_regx, .number = 43 }, + { .atom = DW_OP_piece, .number = 4 } + }; + + *locp = loc; + return size <= 4 ? 1 : 4; +} + +static int +pass_in_fpr_lp64d (const Dwarf_Op **locp, Dwarf_Word size) +{ + static const Dwarf_Op loc[] = + { + { .atom = DW_OP_regx, .number = 42 }, + { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_regx, .number = 43 }, + { .atom = DW_OP_piece, .number = 8 } + }; + + *locp = loc; + return size <= 8 ? 1 : 4; +} + +static int +flatten_aggregate_arg (Dwarf_Die *typedie __attribute__ ((unused)), + Dwarf_Die *arg0 __attribute__ ((unused)), + Dwarf_Die *arg1 __attribute__ ((unused))) +{ + /* ??? */ + return 1; +} + +static int +pass_by_flattened_arg (const Dwarf_Op **locp __attribute__ ((unused)), + Dwarf_Word size __attribute__ ((unused)), + Dwarf_Die *arg0 __attribute__ ((unused)), + Dwarf_Die *arg1 __attribute__ ((unused))) +{ + /* ??? */ + return -2; +} + +int +riscv_return_value_location_lp64d (Dwarf_Die *functypedie, + const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die typedie; + int tag = dwarf_peeled_die_type (functypedie, &typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size = (Dwarf_Word)-1; + + /* If the argument type is a Composite Type that is larger than 16 + bytes, then the argument is copied to memory allocated by the + caller and the argument is replaced by a pointer to the copy. */ + if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type + || tag == DW_TAG_class_type || tag == DW_TAG_array_type) + { + Dwarf_Die arg0, arg1; + + if (dwarf_aggregate_size (&typedie, &size) < 0) + return -1; + /* A struct containing just one floating-point real is passed as though + it were a standalone floating-point real. A struct containing two + floating-point reals is passed in two floating-point registers, if + neither is more than FLEN bits wide. A struct containing just one + complex floating-point number is passed as though it were a struct + containing two floating-point reals. A struct containing one + floating-point real and one integer (or bitfield), in either order, + is passed in a floating-point register and an integer register, + provided the floating-point real is no more than FLEN bits wide and + the integer is no more than XLEN bits wide. */ + if (tag == DW_TAG_structure_type + && flatten_aggregate_arg (&typedie, &arg0, &arg1)) + return pass_by_flattened_arg (locp, size, &arg0, &arg1); + /* Aggregates larger than 2*XLEN bits are passed by reference. */ + else if (size > 16) + return pass_by_ref (locp); + /* Aggregates whose total size is no more than XLEN bits are passed in + a register. Aggregates whose total size is no more than 2*XLEN bits + are passed in a pair of registers. */ + else + return pass_in_gpr_lp64 (locp, size); + } + + if (tag == DW_TAG_base_type + || tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + { + if (dwarf_bytesize_aux (&typedie, &size) < 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 8; + else + return -1; + } + + Dwarf_Attribute attr_mem; + if (tag == DW_TAG_base_type) + { + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (&typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + + switch (encoding) + { + case DW_ATE_boolean: + case DW_ATE_signed: + case DW_ATE_unsigned: + case DW_ATE_unsigned_char: + case DW_ATE_signed_char: + /* Scalars that are at most XLEN bits wide are passed in a single + argument register. Scalars that are 2*XLEN bits wide are + passed in a pair of argument registers. Scalars wider than + 2*XLEN are passed by reference; there are none for LP64D. */ + return pass_in_gpr_lp64 (locp, size); + + case DW_ATE_float: + /* A real floating-point argument is passed in a floating-point + argument register if it is no more than FLEN bits wide, + otherwise it is passed according to the integer calling + convention. */ + switch (size) + { + case 4: /* single */ + case 8: /* double */ + return pass_in_fpr_lp64d (locp, size); + + case 16: /* quad */ + return pass_in_gpr_lp64 (locp, size); + + default: + return -2; + } + + case DW_ATE_complex_float: + /* A complex floating-point number is passed as though it were a + struct containing two floating-point reals. */ + switch (size) + { + case 8: /* float _Complex */ + return pass_in_fpr_lp64f (locp, size); + + case 16: /* double _Complex */ + return pass_in_fpr_lp64d (locp, size); + + case 32: /* long double _Complex */ + return pass_by_ref (locp); + + default: + return -2; + } + } + + return -2; + } + else + return pass_in_gpr_lp64 (locp, size); + } + + *locp = NULL; + return 0; +} diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c new file mode 100644 index 00000000..c34b7702 --- /dev/null +++ b/backends/riscv_symbol.c @@ -0,0 +1,121 @@ +/* RISC-V specific symbolic name handling. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#define BACKEND riscv_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub) +{ + switch (type) + { + case R_RISCV_SET8: + return ELF_T_BYTE; + case R_RISCV_SET16: + return ELF_T_HALF; + case R_RISCV_32: + case R_RISCV_SET32: + return ELF_T_WORD; + case R_RISCV_64: + return ELF_T_XWORD; + case R_RISCV_ADD16: + *addsub = 1; + return ELF_T_HALF; + case R_RISCV_SUB16: + *addsub = -1; + return ELF_T_HALF; + case R_RISCV_ADD32: + *addsub = 1; + return ELF_T_WORD; + case R_RISCV_SUB32: + *addsub = -1; + return ELF_T_WORD; + case R_RISCV_ADD64: + *addsub = 1; + return ELF_T_XWORD; + case R_RISCV_SUB64: + *addsub = -1; + return ELF_T_XWORD; + default: + return ELF_T_NUM; + } +} + +/* Check whether machine flags are valid. */ +bool +riscv_machine_flag_check (GElf_Word flags) +{ + return ((flags &~ (EF_RISCV_RVC + | EF_RISCV_FLOAT_ABI)) == 0); +} + +/* Check whether given symbol's st_value and st_size are OK despite failing + normal checks. */ +bool +riscv_check_special_symbol (Elf *elf, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) +{ + if (name == NULL) + return false; + + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); + if (sname == NULL) + return false; + + /* _GLOBAL_OFFSET_TABLE_ points to the start of the .got section, but it + is preceded by the .got.plt section in the output .got section. */ + if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + return (strcmp (sname, ".got") == 0 + && sym->st_value >= destshdr->sh_addr + && sym->st_value < destshdr->sh_addr + destshdr->sh_size); + + /* __global_pointer$ points to the .sdata section with an offset of + 0x800. It might however fall in the .got section, in which case we + cannot check the offset. The size always should be zero. */ + if (strcmp (name, "__global_pointer$") == 0) + return (((strcmp (sname, ".sdata") == 0 + && sym->st_value == destshdr->sh_addr + 0x800) + || strcmp (sname, ".got") == 0) + && sym->st_size == 0); + + return false; +} diff --git a/backends/s390_cfi.c b/backends/s390_cfi.c new file mode 100644 index 00000000..cb494861 --- /dev/null +++ b/backends/s390_cfi.c @@ -0,0 +1,65 @@ +/* s390 ABI-specified defaults for DWARF CFI. + Copyright (C) 2012, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND s390_ +#include "libebl_CPU.h" + +int +s390_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* This instruction is provided in every CIE. It is not repeated here: + DW_CFA_def_cfa, ULEB128_7 (15), ULEB128_7 (96) */ + /* r14 is not callee-saved but it needs to be preserved as it is pre-set + by the caller. */ + DW_CFA_same_value, ULEB128_7 (14), /* r14 */ + + /* Callee-saved regs. */ +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + SV (6), SV (7), SV (8), SV (9), SV (10), /* r6-r13, r15 */ + SV (11), SV (12), SV (13), SV (15), + SV (16 + 8), SV (16 + 9), SV (16 + 10), SV (16 + 11), /* f8-f15 */ + SV (16 + 12), SV (16 + 13), SV (16 + 14), SV (16 + 15) +#undef SV + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = ebl->class == ELFCLASS64 ? 8 : 4; + + abi_info->return_address_register = 14; + + return 0; +} diff --git a/backends/s390_corenote.c b/backends/s390_corenote.c new file mode 100644 index 00000000..7ca35168 --- /dev/null +++ b/backends/s390_corenote.c @@ -0,0 +1,189 @@ +/* S390-specific core note handling. + Copyright (C) 2012 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef BITS +# define BITS 32 +# define BACKEND s390_ +#else +# define BITS 64 +# define BACKEND s390x_ +#endif +#include "libebl_CPU.h" + +static const Ebl_Register_Location prstatus_regs[] = + { +#define GR(at, n, dwreg, b...) \ + { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = b } + + GR ( 0, 1, 64, BITS), /* pswm */ + GR ( 1, 1, 65, BITS, .pc_register = true ), /* pswa */ + GR ( 2, 16, 0, BITS), /* r0-r15 */ + GR (18, 16, 48, 32), /* ar0-ar15 */ + +#undef GR + }; + + /* orig_r2 is at offset (BITS == 32 ? 34 * 4 : 26 * 8). */ +#define PRSTATUS_REGS_SIZE (BITS / 8 * (BITS == 32 ? 35 : 27)) + +static const Ebl_Register_Location fpregset_regs[] = + { +#define FPR(at, n, dwreg) \ + { .offset = at * 64/8, .regno = dwreg, .count = n, .bits = 64 } + + /* fpc is at offset 0, see fpregset_items, it has no assigned DWARF regno. + Bytes at offsets 4 to 7 are unused. */ + FPR (1 + 0, 1, 16), /* f0 */ + FPR (1 + 1, 1, 20), /* f1 */ + FPR (1 + 2, 1, 17), /* f2 */ + FPR (1 + 3, 1, 21), /* f3 */ + FPR (1 + 4, 1, 18), /* f4 */ + FPR (1 + 5, 1, 22), /* f5 */ + FPR (1 + 6, 1, 19), /* f6 */ + FPR (1 + 7, 1, 23), /* f7 */ + FPR (1 + 8, 1, 24), /* f8 */ + FPR (1 + 9, 1, 28), /* f9 */ + FPR (1 + 10, 1, 25), /* f10 */ + FPR (1 + 11, 1, 29), /* f11 */ + FPR (1 + 12, 1, 26), /* f12 */ + FPR (1 + 13, 1, 30), /* f13 */ + FPR (1 + 14, 1, 27), /* f14 */ + FPR (1 + 15, 1, 31), /* f15 */ + +#undef FPR + }; + +static const Ebl_Core_Item fpregset_items[] = + { + { + .name = "fpc", .group = "register", .offset = 0, .type = ELF_T_WORD, + .format = 'x', + }, + }; + +/* Do not set FPREGSET_SIZE so that we can supply fpregset_items. */ +#define EXTRA_NOTES_FPREGSET \ + EXTRA_REGSET_ITEMS (NT_FPREGSET, 17 * 8, fpregset_regs, fpregset_items) + +#if BITS == 32 +# define ULONG uint32_t +# define ALIGN_ULONG 4 +# define TYPE_ULONG ELF_T_WORD +# define TYPE_LONG ELF_T_SWORD +# define UID_T uint16_t +# define GID_T uint16_t +# define ALIGN_UID_T 2 +# define ALIGN_GID_T 2 +# define TYPE_UID_T ELF_T_HALF +# define TYPE_GID_T ELF_T_HALF +#else +# define ULONG uint64_t +# define ALIGN_ULONG 8 +# define TYPE_ULONG ELF_T_XWORD +# define TYPE_LONG ELF_T_SXWORD +# define UID_T uint32_t +# define GID_T uint32_t +# define ALIGN_UID_T 4 +# define ALIGN_GID_T 4 +# define TYPE_UID_T ELF_T_WORD +# define TYPE_GID_T ELF_T_WORD +#endif +#define PID_T int32_t +#define ALIGN_PID_T 4 +#define TYPE_PID_T ELF_T_SWORD +/* s390 psw_compat_t has alignment 8 bytes where it is inherited from. */ +#define ALIGN_PR_REG 8 + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "orig_r2", .type = TYPE_LONG, .format = 'd', \ + .offset = offsetof (struct EBLHOOK(prstatus), \ + pr_reg[BITS == 32 ? 34 : 26]), \ + .group = "register" \ + } + +#if BITS == 32 + +static const Ebl_Core_Item high_regs_items[] = + { +#define HR(n) \ + { \ + .name = "high_r" #n , .group = "register", .offset = (n) * 4, \ + .type = ELF_T_WORD, .format = 'x', \ + } + + /* Upper halves of r0-r15 are stored here. + FIXME: They are currently not combined with the r0-r15 lower halves. */ + HR (0), HR (1), HR (2), HR (3), HR (4), HR (5), HR (6), HR (7), + HR (8), HR (9), HR (10), HR (11), HR (12), HR (13), HR (14), HR (15) + +#undef HR + }; + +#define EXTRA_NOTES_HIGH_GPRS \ + EXTRA_ITEMS (NT_S390_HIGH_GPRS, 16 * 4, high_regs_items) + +#else /* BITS == 64 */ + +#define EXTRA_NOTES_HIGH_GPRS + +#endif /* BITS == 64 */ + +static const Ebl_Core_Item last_break_items[] = + { + { + .name = "last_break", .group = "system", .offset = BITS == 32 ? 4 : 0, + .type = BITS == 32 ? ELF_T_WORD : ELF_T_XWORD, .format = 'x', + }, + }; + +static const Ebl_Core_Item system_call_items[] = + { + { + .name = "system_call", .group = "system", .offset = 0, .type = ELF_T_WORD, + .format = 'd', + }, + }; + +#define EXTRA_NOTES \ + EXTRA_NOTES_FPREGSET \ + EXTRA_NOTES_HIGH_GPRS \ + EXTRA_ITEMS (NT_S390_LAST_BREAK, 8, last_break_items) \ + EXTRA_ITEMS (NT_S390_SYSTEM_CALL, 4, system_call_items) + +#include "linux-core-note.c" diff --git a/backends/s390_init.c b/backends/s390_init.c new file mode 100644 index 00000000..fd79502d --- /dev/null +++ b/backends/s390_init.c @@ -0,0 +1,74 @@ +/* Initialization of S/390 specific backend library. + Copyright (C) 2005, 2006, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND s390_ +#define RELOC_PREFIX R_390_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on arm_reloc.def. */ +#include "common-reloc.c" + +extern __typeof (s390_core_note) s390x_core_note; + + +Ebl * +s390_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + s390_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, check_special_symbol); + HOOK (eh, register_info); + HOOK (eh, return_value_location); + if (eh->class == ELFCLASS64) + eh->core_note = s390x_core_note; + else + HOOK (eh, core_note); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS 34. + But from the gcc/config/s390/s390.h "Register usage." comment it looks as + if #32 (Argument pointer) and #33 (Condition code) are not used for + unwinding. */ + eh->frame_nregs = 32; + HOOK (eh, set_initial_registers_tid); + if (eh->class == ELFCLASS32) + HOOK (eh, normalize_pc); + HOOK (eh, unwind); + + /* Only the 64-bit format uses the incorrect hash table entry size. */ + if (eh->class == ELFCLASS64) + eh->sysvhash_entrysize = sizeof (Elf64_Xword); + + return eh; +} diff --git a/backends/s390_initreg.c b/backends/s390_initreg.c new file mode 100644 index 00000000..23bf8edc --- /dev/null +++ b/backends/s390_initreg.c @@ -0,0 +1,95 @@ +/* Fetch live process registers from TID. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "system.h" +#include +#if defined(__s390__) && defined(__linux__) +# include +# include +# include +#endif + +#define BACKEND s390_ +#include "libebl_CPU.h" + +bool +s390_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined(__s390__) || !defined(__linux__) + return false; +#else /* __s390__ */ + struct user user_regs; + ptrace_area parea; + parea.process_addr = (uintptr_t) &user_regs; + parea.kernel_addr = 0; + parea.len = sizeof (user_regs); + if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea, NULL) != 0) + return false; + /* If we run as s390x we get the 64-bit registers of tid. + But -m31 executable seems to use only the 32-bit parts of its + registers so we ignore the upper half. */ + Dwarf_Word dwarf_regs[16]; + for (unsigned u = 0; u < 16; u++) + dwarf_regs[u] = user_regs.regs.gprs[u]; + if (! setfunc (0, 16, dwarf_regs, arg)) + return false; + /* Avoid conversion double -> integer. */ + eu_static_assert (sizeof user_regs.regs.fp_regs.fprs[0] + == sizeof dwarf_regs[0]); + for (unsigned u = 0; u < 16; u++) + { + // Store the double bits as is in the Dwarf_Word without conversion. + union + { + double d; + Dwarf_Word w; + } fpr = { .d = user_regs.regs.fp_regs.fprs[u] }; + dwarf_regs[u] = fpr.w; + } + + if (! setfunc (16, 16, dwarf_regs, arg)) + return false; + dwarf_regs[0] = user_regs.regs.psw.addr; + return setfunc (-1, 1, dwarf_regs, arg); +#endif /* __s390__ */ +} + +void +s390_normalize_pc (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr *pc) +{ + assert (ebl->class == ELFCLASS32); + + /* Clear S390 bit 31. */ + *pc &= (1U << 31) - 1; +} diff --git a/backends/s390_regs.c b/backends/s390_regs.c new file mode 100644 index 00000000..ba6178a3 --- /dev/null +++ b/backends/s390_regs.c @@ -0,0 +1,146 @@ +/* Register names and numbers for S/390 DWARF. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND s390_ +#include "libebl_CPU.h" + + +/* +zseries (64) + +0-15 gpr0-gpr15 x +16-19 fpr[0246] +20-24 fpr[13578] +25-27 fpr1[024] +28 fpr9 +29-31 fpr1[135] +32-47 cr0-cr15 x +48-63 ar0-ar15 x +64 psw_mask +65 psw_address +*/ + + +ssize_t +s390_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 66; + + if (regno < 0 || regno > 65 || namelen < 7) + return -1; + + *prefix = "%"; + + *bits = ebl->class == ELFCLASS64 ? 64 : 32; + *type = DW_ATE_unsigned; + if (regno < 16) + { + *setname = "integer"; + *type = DW_ATE_signed; + } + else if (regno < 32) + { + *setname = "FPU"; + *type = DW_ATE_float; + *bits = 64; + } + else if (regno < 48 || regno > 63) + *setname = "control"; + else + { + *setname = "access"; + *bits = 32; + } + + switch (regno) + { + case 0 ... 9: + name[0] = 'r'; + name[1] = regno + '0'; + namelen = 2; + break; + + case 10 ... 15: + name[0] = 'r'; + name[1] = '1'; + name[2] = regno - 10 + '0'; + namelen = 3; + break; + + case 16 ... 31: + name[0] = 'f'; + regno = (regno & 8) | ((regno & 4) >> 2) | ((regno & 3) << 1); + namelen = 1; + if (regno >= 10) + { + regno -= 10; + name[namelen++] = '1'; + } + name[namelen++] = regno + '0'; + break; + + case 32 + 0 ... 32 + 9: + case 48 + 0 ... 48 + 9: + name[0] = regno < 48 ? 'c' : 'a'; + name[1] = (regno & 15) + '0'; + namelen = 2; + break; + + case 32 + 10 ... 32 + 15: + case 48 + 10 ... 48 + 15: + name[0] = regno < 48 ? 'c' : 'a'; + name[1] = '1'; + name[2] = (regno & 15) - 10 + '0'; + namelen = 3; + break; + + case 64: + return stpcpy (name, "pswm") + 1 - name; + case 65: + *type = DW_ATE_address; + return stpcpy (name, "pswa") + 1 - name; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/s390_reloc.def b/backends/s390_reloc.def new file mode 100644 index 00000000..cdef9ebf --- /dev/null +++ b/backends/s390_reloc.def @@ -0,0 +1,91 @@ +/* List the relocation types for s390. -*- C -*- + Copyright (C) 2005, 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (8, REL|EXEC|DYN) +RELOC_TYPE (12, REL|EXEC|DYN) +RELOC_TYPE (16, REL|EXEC|DYN) +RELOC_TYPE (32, REL|EXEC|DYN) +RELOC_TYPE (PC32, REL|EXEC|DYN) +RELOC_TYPE (GOT12, REL) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (GOTOFF32, REL) +RELOC_TYPE (GOTPC, REL) +RELOC_TYPE (GOT16, REL) +RELOC_TYPE (PC16, REL|EXEC|DYN) +RELOC_TYPE (PC16DBL, REL|EXEC|DYN) +RELOC_TYPE (PLT16DBL, REL) +RELOC_TYPE (PC32DBL, REL|EXEC|DYN) +RELOC_TYPE (PLT32DBL, REL) +RELOC_TYPE (GOTPCDBL, REL) +RELOC_TYPE (64, REL|EXEC|DYN) +RELOC_TYPE (PC64, REL|EXEC|DYN) +RELOC_TYPE (GOT64, REL) +RELOC_TYPE (PLT64, REL) +RELOC_TYPE (GOTENT, REL) +RELOC_TYPE (GOTOFF16, REL) +RELOC_TYPE (GOTOFF64, REL) +RELOC_TYPE (GOTPLT12, REL) +RELOC_TYPE (GOTPLT16, REL) +RELOC_TYPE (GOTPLT32, REL) +RELOC_TYPE (GOTPLT64, REL) +RELOC_TYPE (GOTPLTENT, REL) +RELOC_TYPE (PLTOFF16, REL) +RELOC_TYPE (PLTOFF32, REL) +RELOC_TYPE (PLTOFF64, REL) +RELOC_TYPE (TLS_LOAD, REL) +RELOC_TYPE (TLS_GDCALL, REL) +RELOC_TYPE (TLS_LDCALL, REL) +RELOC_TYPE (TLS_GD32, REL) +RELOC_TYPE (TLS_GD64, REL) +RELOC_TYPE (TLS_GOTIE12, REL) +RELOC_TYPE (TLS_GOTIE32, REL) +RELOC_TYPE (TLS_GOTIE64, REL) +RELOC_TYPE (TLS_LDM32, REL) +RELOC_TYPE (TLS_LDM64, REL) +RELOC_TYPE (TLS_IE32, REL) +RELOC_TYPE (TLS_IE64, REL) +RELOC_TYPE (TLS_IEENT, REL) +RELOC_TYPE (TLS_LE32, REL) +RELOC_TYPE (TLS_LE64, REL) +RELOC_TYPE (TLS_LDO32, REL) +RELOC_TYPE (TLS_LDO64, REL) +RELOC_TYPE (TLS_DTPMOD, DYN) +RELOC_TYPE (TLS_DTPOFF, DYN) +RELOC_TYPE (TLS_TPOFF, DYN) +RELOC_TYPE (20, REL|EXEC|DYN) +RELOC_TYPE (GOT20, REL) +RELOC_TYPE (GOTPLT20, REL) +RELOC_TYPE (TLS_GOTIE20, REL) diff --git a/backends/s390_retval.c b/backends/s390_retval.c new file mode 100644 index 00000000..2043f985 --- /dev/null +++ b/backends/s390_retval.c @@ -0,0 +1,144 @@ +/* Function return value location for S/390 ABI. + Copyright (C) 2006, 2007, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND s390_ +#include "libebl_CPU.h" + + +/* %r2, or pair %r2, %r3. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %f0. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_reg16 }, + }; +#define nloc_fpreg 1 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in %r2. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg2, .number = 0 } + }; +#define nloc_aggregate 1 + + +int +s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Die cudie; + uint8_t asize; + if (dwarf_diecu (typedie, &cudie, &asize, NULL) == NULL) + return -1; + + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = asize; + else + return -1; + } + if (tag == DW_TAG_base_type) + { + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + if (encoding == DW_ATE_float && size <= 8) + { + *locp = loc_fpreg; + return nloc_fpreg; + } + } + if (size <= 8) + { + *locp = loc_intreg; + return size <= asize ? nloc_intreg : nloc_intregpair; + } + } + FALLTHROUGH; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + *locp = loc_aggregate; + return nloc_aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/s390_symbol.c b/backends/s390_symbol.c new file mode 100644 index 00000000..9e80ecaa --- /dev/null +++ b/backends/s390_symbol.c @@ -0,0 +1,95 @@ +/* S/390-specific symbolic name handling. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND s390_ +#include "libebl_CPU.h" + +/* Check for the simple reloc types. */ +Elf_Type +s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_390_64: + return ELF_T_SXWORD; + case R_390_32: + return ELF_T_SWORD; + case R_390_16: + return ELF_T_HALF; + case R_390_8: + return ELF_T_BYTE; + default: + return ELF_T_NUM; + } +} + +/* The _GLOBAL_OFFSET_TABLE_ symbol might point to the DT_PLTGOT, + which is in the .got section, even if the symbol itself is + associated with the is a .got.plt section. + https://sourceware.org/ml/binutils/2018-07/msg00200.html */ +bool +s390_check_special_symbol (Elf *elf, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) +{ + if (name != NULL + && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + { + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); + if (sname != NULL + && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0)) + { + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + { + sname = elf_strptr (elf, shstrndx, shdr->sh_name); + if (sname != NULL && strcmp (sname, ".got") == 0) + return (sym->st_value >= shdr->sh_addr + && sym->st_value < shdr->sh_addr + shdr->sh_size); + } + } + } + } + + return false; +} diff --git a/backends/s390_unwind.c b/backends/s390_unwind.c new file mode 100644 index 00000000..752bc287 --- /dev/null +++ b/backends/s390_unwind.c @@ -0,0 +1,139 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND s390_ +#include "libebl_CPU.h" + +/* s390/s390x do not annotate signal handler frame by CFI. It would be also + difficult as PC points into a stub built on stack. Function below is called + only if unwinder could not find CFI. Function then verifies the register + state for this frame really belongs to a signal frame. In such case it + fetches original registers saved by the signal frame. */ + +bool +s390_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, ebl_pid_memory_read_t *readfunc, + void *arg, bool *signal_framep) +{ + /* Caller already assumed caller adjustment but S390 instructions are 4 bytes + long. Undo it. */ + if ((pc & 0x3) != 0x3) + return false; + pc++; + /* We can assume big-endian read here. */ + Dwarf_Word instr; + if (! readfunc (pc, &instr, arg)) + return false; + /* Fetch only the very first two bytes. */ + instr = (instr >> (ebl->class == ELFCLASS64 ? 48 : 16)) & 0xffff; + /* See GDB s390_sigtramp_frame_sniffer. */ + /* Check for 'svc' as the first instruction. */ + if (((instr >> 8) & 0xff) != 0x0a) + return false; + /* Check for 'sigreturn' or 'rt_sigreturn' as the second instruction. */ + if ((instr & 0xff) != 119 && (instr & 0xff) != 173) + return false; + /* See GDB s390_sigtramp_frame_unwind_cache. */ + Dwarf_Word this_sp; + if (! getfunc (0 + 15, 1, &this_sp, arg)) + return false; + unsigned word_size = ebl->class == ELFCLASS64 ? 8 : 4; + Dwarf_Addr next_cfa = this_sp + 16 * word_size + 32; + /* "New-style RT frame" is not supported, + assuming "Old-style RT frame and all non-RT frames". + Pointer to the array of saved registers is at NEXT_CFA + 8. */ + Dwarf_Word sigreg_ptr; + if (! readfunc (next_cfa + 8, &sigreg_ptr, arg)) + return false; + /* Skip PSW mask. */ + sigreg_ptr += word_size; + /* Read PSW address. */ + Dwarf_Word val; + if (! readfunc (sigreg_ptr, &val, arg)) + return false; + if (! setfunc (-1, 1, &val, arg)) + return false; + sigreg_ptr += word_size; + /* Then the GPRs. */ + Dwarf_Word gprs[16]; + for (int i = 0; i < 16; i++) + { + if (! readfunc (sigreg_ptr, &gprs[i], arg)) + return false; + sigreg_ptr += word_size; + } + /* Then the ACRs. Skip them, they are not used in CFI. */ + for (int i = 0; i < 16; i++) + sigreg_ptr += 4; + /* The floating-point control word. */ + sigreg_ptr += 8; + /* And finally the FPRs. */ + Dwarf_Word fprs[16]; + for (int i = 0; i < 16; i++) + { + if (! readfunc (sigreg_ptr, &val, arg)) + return false; + if (ebl->class == ELFCLASS32) + { + Dwarf_Addr val_low; + if (! readfunc (sigreg_ptr + 4, &val_low, arg)) + return false; + val = (val << 32) | val_low; + } + fprs[i] = val; + sigreg_ptr += 8; + } + /* If we have them, the GPR upper halves are appended at the end. */ + if (ebl->class == ELFCLASS32) + { + /* Skip signal number. */ + sigreg_ptr += 4; + for (int i = 0; i < 16; i++) + { + if (! readfunc (sigreg_ptr, &val, arg)) + return false; + Dwarf_Word val_low = gprs[i]; + val = (val << 32) | val_low; + gprs[i] = val; + sigreg_ptr += 4; + } + } + if (! setfunc (0, 16, gprs, arg)) + return false; + if (! setfunc (16, 16, fprs, arg)) + return false; + *signal_framep = true; + return true; +} diff --git a/backends/s390x_corenote.c b/backends/s390x_corenote.c new file mode 100644 index 00000000..427bf7de --- /dev/null +++ b/backends/s390x_corenote.c @@ -0,0 +1,2 @@ +#define BITS 64 +#include "s390_corenote.c" diff --git a/backends/sh_corenote.c b/backends/sh_corenote.c new file mode 100644 index 00000000..9268f568 --- /dev/null +++ b/backends/sh_corenote.c @@ -0,0 +1,88 @@ +/* SH specific core note handling. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + Contributed Matt Fleming . + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#define BACKEND sh_ +#include "libebl_CPU.h" + +static const Ebl_Register_Location prstatus_regs[] = + { +#define GR(at, n, dwreg) \ + { .offset = at * 4, .regno = dwreg, .count = n, .bits = 32 } + GR (0, 16, 0), /* r0-r15 */ + GR (16, 1, 16), /* pc */ + GR (17, 1, 17), /* pr */ + GR (18, 1, 22), /* sr */ + GR (19, 1, 18), /* gbr */ + GR (20, 1, 20), /* mach */ + GR (21, 1, 21), /* macl */ + /* 22, 1, tra */ +#undef GR + }; +#define PRSTATUS_REGS_SIZE (23 * 4) + +#define ULONG uint32_t +#define PID_T int32_t +#define UID_T uint16_t +#define GID_T uint16_t +#define ALIGN_ULONG 4 +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 2 +#define ALIGN_GID_T 2 +#define TYPE_ULONG ELF_T_WORD +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_HALF +#define TYPE_GID_T ELF_T_HALF + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "tra", .type = ELF_T_ADDR, .format = 'x', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[22]), \ + .group = "register" \ + } + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 25, .count = 16, .bits = 32 }, /* fr0-fr15 */ + { .offset = 16, .regno = 87, .count = 16, .bits = 32 }, /* xf0-xf15 */ + { .offset = 32, .regno = 24, .count = 1, .bits = 32 }, /* fpscr */ + { .offset = 33, .regno = 23, .count = 1, .bits = 32 } /* fpul */ + }; +#define FPREGSET_SIZE (50 * 4) + +#include "linux-core-note.c" diff --git a/backends/sh_init.c b/backends/sh_init.c new file mode 100644 index 00000000..05cf8b18 --- /dev/null +++ b/backends/sh_init.c @@ -0,0 +1,57 @@ +/* Initialization of SH specific backend library. + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND sh_ +#define RELOC_PREFIX R_SH_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on sh_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +sh_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + sh_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, gotpc_reloc_check); + HOOK (eh, machine_flag_check); + HOOK (eh, core_note); + HOOK (eh, register_info); + HOOK (eh, return_value_location); + + return eh; +} diff --git a/backends/sh_regs.c b/backends/sh_regs.c new file mode 100644 index 00000000..d4332364 --- /dev/null +++ b/backends/sh_regs.c @@ -0,0 +1,191 @@ +/* Register names and numbers for SH DWARF. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + Contributed by Matt Fleming . + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND sh_ +#include "libebl_CPU.h" + +ssize_t +sh_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 104; + + if (regno < 0 || regno > 103 || namelen < 6) + return -1; + + *prefix = ""; + *bits = 32; + *type = DW_ATE_signed; + + switch (regno) + { + case 0 ... 9: + *setname = "integer"; + name[0] = 'r'; + name[1] = regno + '0'; + namelen = 2; + break; + + case 10 ... 15: + *setname = "integer"; + name[0] = 'r'; + name[1] = '1'; + name[2] = regno - 10 + '0'; + namelen = 3; + break; + + case 16: + *setname = "system"; + *type = DW_ATE_address; + name[0] = 'p'; + name[1] = 'c'; + namelen = 2; + break; + + case 17: + *setname = "system"; + *type = DW_ATE_address; + name[0] = 'p'; + name[1] = 'r'; + namelen = 2; + break; + + case 18: + *setname = "control"; + *type = DW_ATE_unsigned; + name[0] = 's'; + name[1] = 'r'; + namelen = 2; + break; + + case 19: + *setname = "control"; + *type = DW_ATE_unsigned; + name[0] = 'g'; + name[1] = 'b'; + name[2] = 'r'; + namelen = 3; + break; + + case 20: + *setname = "system"; + name[0] = 'm'; + name[1] = 'a'; + name[2] = 'c'; + name[3] = 'h'; + namelen = 4; + break; + + case 21: + *setname = "system"; + name[0] = 'm'; + name[1] = 'a'; + name[2] = 'c'; + name[3] = 'l'; + namelen = 4; + + break; + + case 23: + *setname = "system"; + *type = DW_ATE_unsigned; + name[0] = 'f'; + name[1] = 'p'; + name[2] = 'u'; + name[3] = 'l'; + namelen = 4; + break; + + case 24: + *setname = "system"; + *type = DW_ATE_unsigned; + name[0] = 'f'; + name[1] = 'p'; + name[2] = 's'; + name[3] = 'c'; + name[4] = 'r'; + namelen = 5; + break; + + case 25 ... 34: + *setname = "fpu"; + *type = DW_ATE_float; + name[0] = 'f'; + name[1] = 'r'; + name[2] = regno - 25 + '0'; + namelen = 3; + break; + + case 35 ... 40: + *setname = "fpu"; + *type = DW_ATE_float; + name[0] = 'f'; + name[1] = 'r'; + name[2] = '1'; + name[3] = regno - 35 + '0'; + namelen = 4; + break; + + case 87 ... 96: + *type = DW_ATE_float; + *setname = "fpu"; + name[0] = 'x'; + name[1] = 'f'; + name[2] = regno - 87 + '0'; + namelen = 3; + break; + + case 97 ... 103: + *type = DW_ATE_float; + *setname = "fpu"; + name[0] = 'x'; + name[1] = 'f'; + name[2] = '1'; + name[3] = regno - 97 + '0'; + namelen = 4; + break; + + default: + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/sh_reloc.def b/backends/sh_reloc.def new file mode 100644 index 00000000..aded3612 --- /dev/null +++ b/backends/sh_reloc.def @@ -0,0 +1,67 @@ +/* List the relocation types for SH. -*- C -*- + Copyright (C) 2005, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (DIR32, REL|DYN) +RELOC_TYPE (REL32, REL|DYN) +RELOC_TYPE (DIR8WPN, REL) +RELOC_TYPE (IND12W, REL) +RELOC_TYPE (DIR8WPL, REL) +RELOC_TYPE (DIR8WPZ, REL) +RELOC_TYPE (DIR8BP, REL) +RELOC_TYPE (DIR8W, REL) +RELOC_TYPE (DIR8L, REL) +RELOC_TYPE (SWITCH16, REL) +RELOC_TYPE (SWITCH32, REL) +RELOC_TYPE (USES, REL) +RELOC_TYPE (COUNT, REL) +RELOC_TYPE (ALIGN, REL) +RELOC_TYPE (CODE, REL) +RELOC_TYPE (DATA, REL) +RELOC_TYPE (LABEL, REL) +RELOC_TYPE (SWITCH8, REL) +RELOC_TYPE (GNU_VTINHERIT, REL) +RELOC_TYPE (GNU_VTENTRY, REL) +RELOC_TYPE (TLS_GD_32, REL) +RELOC_TYPE (TLS_LD_32, REL) +RELOC_TYPE (TLS_LDO_32, REL) +RELOC_TYPE (TLS_IE_32, REL) +RELOC_TYPE (TLS_LE_32, REL) +RELOC_TYPE (TLS_DTPMOD32, DYN) +RELOC_TYPE (TLS_DTPOFF32, DYN) +RELOC_TYPE (TLS_TPOFF32, DYN) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (GOTOFF, REL) +RELOC_TYPE (GOTPC, REL) diff --git a/backends/sh_retval.c b/backends/sh_retval.c new file mode 100644 index 00000000..33d7d964 --- /dev/null +++ b/backends/sh_retval.c @@ -0,0 +1,131 @@ +/* Function return value location for Linux/SH ABI. + Copyright (C) 2010, 2014 Red Hat, Inc. + This file is part of elfutils. + Contributed by Matt Fleming . + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND sh_ +#include "libebl_CPU.h" + + +/* This is the SVR4 ELF ABI convention, but AIX and Linux do not use it. */ +#define SVR4_STRUCT_RETURN 0 + + +/* r0, or pair r0, r1. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* fr0 or fr1. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_reg25 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg26 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_fpreg 1 +#define nloc_fpregpair 2 + +int +sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 4; + else + return -1; + } + } + + if (size <= 8) + { + if (tag == DW_TAG_base_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, + DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + if (encoding == DW_ATE_float) + { + *locp = loc_fpreg; + return size <= 4 ? nloc_fpreg : nloc_fpregpair; + } + } + *locp = loc_intreg; + return size <= 4 ? nloc_intreg : nloc_intregpair; + } + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/sh_symbol.c b/backends/sh_symbol.c new file mode 100644 index 00000000..2761d92c --- /dev/null +++ b/backends/sh_symbol.c @@ -0,0 +1,95 @@ +/* SH specific relocation handling. + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND sh_ +#include "libebl_CPU.h" + + +/* Return true if the symbol type is that referencing the GOT. */ +bool +sh_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type) +{ + return type == R_SH_GOTPC; +} + +/* Check for the simple reloc types. */ +Elf_Type +sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_SH_DIR32: + return ELF_T_WORD; + default: + return ELF_T_NUM; + } +} + +/* Check whether machine flags are valid. */ +bool +sh_machine_flag_check (GElf_Word flags) +{ + switch (flags & EF_SH_MACH_MASK) + { + case EF_SH_UNKNOWN: + case EF_SH1: + case EF_SH2: + case EF_SH3: + case EF_SH_DSP: + case EF_SH3_DSP: + case EF_SH4AL_DSP: + case EF_SH3E: + case EF_SH4: + case EF_SH2E: + case EF_SH4A: + case EF_SH2A: + case EF_SH4_NOFPU: + case EF_SH4A_NOFPU: + case EF_SH4_NOMMU_NOFPU: + case EF_SH2A_NOFPU: + case EF_SH3_NOMMU: + case EF_SH2A_SH4_NOFPU: + case EF_SH2A_SH3_NOFPU: + case EF_SH2A_SH4: + case EF_SH2A_SH3E: + break; + default: + return false; + } + + return ((flags &~ (EF_SH_MACH_MASK)) == 0); +} diff --git a/backends/sparc64_corenote.c b/backends/sparc64_corenote.c new file mode 100644 index 00000000..cef6431e --- /dev/null +++ b/backends/sparc64_corenote.c @@ -0,0 +1,2 @@ +#define BITS 64 +#include "sparc_corenote.c" diff --git a/backends/sparc_attrs.c b/backends/sparc_attrs.c new file mode 100644 index 00000000..974e8fb0 --- /dev/null +++ b/backends/sparc_attrs.c @@ -0,0 +1,105 @@ +/* Object attribute tags for SPARC. + Copyright (C) 2015 Oracle, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +bool +sparc_check_object_attribute (Ebl *ebl __attribute__ ((unused)), + const char *vendor, int tag, uint64_t value, + const char **tag_name, const char **value_name) +{ + static const char *hwcaps[32] = + { + "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", + "asi_blk_init", "fmaf", "vis3", "hpc", "random", "trans", + "fjfmau", "ima", "asi_cache_sparing", "aes", "des", "kasumi", + "camellia", "md5", "sha1", "sha256", "sha512", "mpmul", "mont", + "pause", "cbcond", "crc32c", "resv30", "resv31" + }; + + + static const char *hwcaps2[32] = + { + "fjathplus", "vis3b", "adp", "sparc5", "mwait", "xmpmul", "xmont", + "nsec", "resv8", "resv9" , "resv10", "resv11", "fjathhpc", "fjdes", + "fjaes", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20", + "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27", + "resv28", "resv29", "resv30", "resv31", + }; + + /* NAME should be big enough to hold any possible comma-separated + list (no repetitions allowed) of attribute names from one of the + arrays above. */ + static char name[32*17+32+1]; + name[0] = '\0'; + + if (!strcmp (vendor, "gnu")) + switch (tag) + { + case 4: + case 8: + { + const char **caps; + int cap; + + if (tag == 4) + { + *tag_name = "GNU_Sparc_HWCAPS"; + caps = hwcaps; + } + else + { + *tag_name = "GNU_Sparc_HWCAPS2"; + caps = hwcaps2; + } + + char *s = name; + for (cap = 0; cap < 32; cap++) + if (value & (1U << cap)) + { + if (*s != '\0') + s = strcat (s, ","); + s = strcat (s, caps[cap]); + } + + *value_name = s; + return true; + } + } + + return false; +} + diff --git a/backends/sparc_auxv.c b/backends/sparc_auxv.c new file mode 100644 index 00000000..2da349ca --- /dev/null +++ b/backends/sparc_auxv.c @@ -0,0 +1,46 @@ +/* SPARC-specific auxv handling. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +int +EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format) +{ + if (a_type != AT_HWCAP) + return 0; + + *name = "HWCAP"; + *format = "b" + "flush\0" "stbar\0" "swap\0" "muldiv\0" "v9\0" "ultra3\0" "v9v\0" "\0"; + return 1; +} diff --git a/backends/sparc_cfi.c b/backends/sparc_cfi.c new file mode 100644 index 00000000..dcc17bd6 --- /dev/null +++ b/backends/sparc_cfi.c @@ -0,0 +1,83 @@ +/* SPARC defaults for DWARF CFI. + Copyright (C) 2015 Oracle Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +int +sparc_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { +#define SV(n) DW_CFA_same_value, ULEB128_7 (n) + /* %g0 .. %g7 */ + SV (0), SV (1), SV (2), SV (3), SV (4), SV (5), SV (6), SV (7), + /* %o0 .. %o7 */ + SV (8), SV (9), SV (10), SV (11), SV (12), SV (13), SV (14), SV (15), + /* %l0 .. %l7 */ + SV (16), SV (17), SV (18), SV (19), SV (20), SV (21), SV (22), SV (23), + /* %i0 .. %i7 */ + SV (24), SV (25), SV (26), SV (27), SV (28), SV (29), SV (30), SV (31), + /* %f0 .. %f32 */ + SV (32), SV (33), SV (34), SV (35), SV (36), SV (37), SV (38), SV (39), + SV (40), SV (41), SV (42), SV (43), SV (44), SV (45), SV (46), SV (47), + SV (48), SV (49), SV (50), SV (51), SV (52), SV (53), SV (54), SV (55), + SV (56), SV (57), SV (58), SV (59), SV (60), SV (61), SV (52), SV (63), + /* %f33 .. %63 + Note that there are DWARF columns for the odd registers, even + if they don't exist in hardware) */ + SV (64), SV (65), SV (66), SV (67), SV (68), SV (69), SV (70), SV (71), + SV (72), SV (73), SV (74), SV (75), SV (76), SV (77), SV (78), SV (79), + SV (80), SV (81), SV (82), SV (83), SV (84), SV (85), SV (86), SV (87), + SV (88), SV (89), SV (90), SV (91), SV (92), SV (93), SV (94), SV (95), + /* %fcc[0123] */ + SV (96), SV (97), SV (98), SV (99), + /* %icc/%xcc */ + SV (100), + /* Soft frame-pointer */ + SV (101), + /* %gsr */ + SV (102) +#undef SV + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = 4; + + abi_info->return_address_register = 31; /* %i7 */ + + return 0; +} + diff --git a/backends/sparc_corenote.c b/backends/sparc_corenote.c new file mode 100644 index 00000000..c9b6ff3d --- /dev/null +++ b/backends/sparc_corenote.c @@ -0,0 +1,120 @@ +/* SPARC specific core note handling. + Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2015 Oracle, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef BITS +# define BITS 32 +# define BACKEND sparc_ +#else +# define BITS 64 +# define BACKEND sparc64_ +#endif +#include "libebl_CPU.h" + +#define GR(at, n, dwreg) \ + { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = BITS } + +static const Ebl_Register_Location prstatus_regs[] = + { + GR (0, 32, 0), /* %g0-%g7, %o0-%o7, %i0-%i7 */ +#if BITS == 32 + GR (32, 1, 65), /* %psr */ + GR (33, 2, 68), /* %pc, %npc */ + GR (35, 1, 64), /* %y */ + GR (36, 1, 66), /* %wim, %tbr */ +#else + GR (32, 1, 82), /* %state */ + GR (33, 2, 80), /* %pc, %npc */ + GR (35, 1, 85), /* %y */ +#endif + }; +#define PRSTATUS_REGS_SIZE (BITS / 8 * (32 + (BITS == 32 ? 6 : 4))) + +static const Ebl_Register_Location fpregset_regs[] = + { +#if BITS == 32 + GR (0, 32, 32), /* %f0-%f31 */ + /* padding word */ + GR (33, 1, 70), /* %fsr */ + /* qcnt, q_entrysize, en, q, padding */ +# define FPREGSET_SIZE (34 * 4 + 4 + 64 * 4 + 4) +#else + GR (0, 32, 32), /* %f0-%f31 */ + GR (32, 1, 83), /* %fsr */ + /* 33, 1, %gsr */ + GR (34, 1, 84), /* %fprs */ +# define FPREGSET_SIZE (35 * 8) +#endif + }; + +#if BITS == 32 +# define ULONG uint32_t +# define ALIGN_ULONG 4 +# define TYPE_ULONG ELF_T_WORD +# define TYPE_LONG ELF_T_SWORD +# define UID_T uint16_t +# define GID_T uint16_t +# define ALIGN_UID_T 2 +# define ALIGN_GID_T 2 +# define TYPE_UID_T ELF_T_HALF +# define TYPE_GID_T ELF_T_HALF +#else +# define ULONG uint64_t +# define ALIGN_ULONG 8 +# define TYPE_ULONG ELF_T_XWORD +# define TYPE_LONG ELF_T_SXWORD +# define UID_T uint32_t +# define GID_T uint32_t +# define ALIGN_UID_T 4 +# define ALIGN_GID_T 4 +# define TYPE_UID_T ELF_T_WORD +# define TYPE_GID_T ELF_T_WORD +# define SUSECONDS_HALF 1 +#endif +#define PID_T int32_t +#define ALIGN_PID_T 4 +#define TYPE_PID_T ELF_T_SWORD + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "pc", .type = ELF_T_ADDR, .format = 'x', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[33]), \ + .group = "register", .pc_register = true \ + } + +#include "linux-core-note.c" diff --git a/backends/sparc_init.c b/backends/sparc_init.c new file mode 100644 index 00000000..647a7897 --- /dev/null +++ b/backends/sparc_init.c @@ -0,0 +1,78 @@ +/* Initialization of SPARC specific backend library. + Copyright (C) 2002, 2005, 2006, 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND sparc_ +#define RELOC_PREFIX R_SPARC_ +#include "libebl_CPU.h" + +/* In SPARC some relocations use the most significative 24 bits of the + r_type field to encode a secondary addend. Make sure the routines + in common-reloc.c acknowledge this. */ +#define RELOC_TYPE_ID(type) ((type) & 0xff) + +/* This defines the common reloc hooks based on sparc_reloc.def. */ +#include "common-reloc.c" + +extern __typeof (EBLHOOK (core_note)) sparc64_core_note attribute_hidden; + +Ebl * +sparc_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + sparc_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, machine_flag_check); + HOOK (eh, check_special_section); + HOOK (eh, symbol_type_name); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); + if (eh->class == ELFCLASS64) + eh->core_note = sparc64_core_note; + else + HOOK (eh, core_note); + HOOK (eh, auxv_info); + HOOK (eh, register_info); + HOOK (eh, return_value_location); + HOOK (eh, check_object_attribute); + HOOK (eh, abi_cfi); + /* gcc/config/sparc.h define FIRST_PSEUDO_REGISTER */ + eh->frame_nregs = 103; + /* The CFI Dwarf register with the "return address" in sparc + actually contains the call address. The return address is + located 8 bytes after it. */ + eh->ra_offset = 8; + HOOK (eh, set_initial_registers_tid); + + return eh; +} diff --git a/backends/sparc_initreg.c b/backends/sparc_initreg.c new file mode 100644 index 00000000..c4b321c6 --- /dev/null +++ b/backends/sparc_initreg.c @@ -0,0 +1,129 @@ +/* Fetch live process registers from TID. + Copyright (C) 2015 Oracle, In + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "system.h" +#include +#ifdef __sparc__ +# include +# include +#endif + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +bool +EBLHOOK (set_initial_registers_tid) (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined(__sparc__) || !defined( __arch64__) + return false; +#else /* __sparc__ */ + + + /* The pt_regs structure filled in by PTRACE_GETREGS provides the + PC, the global registers and the output registers. Note how the + %g0 register is not explicitly provided in the structure (it's + value is always 0) and the resulting weird packing in the u_regs + array: the last element is not used. */ + + struct pt_regs regs; + if (ptrace (PTRACE_GETREGS, tid, ®s, 0) == -1) + return false; + + /* PC: no DWARF number */ + if (!setfunc (-1, 1, (Dwarf_Word *) ®s.tpc, arg)) + return false; + + /* Global registers: DWARF 0 .. 7 */ + Dwarf_Word zero = 0; + if (!setfunc (0, 1, &zero, arg)) + return false; + if (!setfunc (1, 7, (Dwarf_Word *) ®s.u_regs[0], arg)) + return false; + + /* Output registers: DWARF 8 .. 15 */ + if (!setfunc (8, 8, (Dwarf_Word *) ®s.u_regs[7], arg)) + return false; + + /* Local and input registers must be read from the stack. They are + saved in the previous stack frame. The stack pointer is %o6, + read above. */ + + Dwarf_Word locals_outs[16]; + Dwarf_Word sp = regs.u_regs[13]; + + if (sp & 1) + { + /* Registers are 64 bits, and we need to apply the 2047 stack + bias in order to get the real stack pointer. */ + + sp += 2047; + + for (unsigned i = 0; i < 16; i++) + { + locals_outs[i] = ptrace (PTRACE_PEEKDATA, tid, + (void *) (uintptr_t) (sp + (i * 8)), + NULL); + if (errno != 0) + return false; + } + } + else + { + /* Registers are 32 bits. */ + + for (unsigned i = 0; i < 8; i++) + { + Dwarf_Word tuple = ptrace (PTRACE_PEEKDATA, tid, + (void *) (uintptr_t) (sp + (i * 8)), + NULL); + if (errno != 0) + return false; + + locals_outs[2*i] = (tuple >> 32) & 0xffffffff; + locals_outs[2*i+1] = tuple & 0xffffffff; + } + } + + + /* Local registers: DWARF 16 .. 23 */ + if (!setfunc (16, 8, &locals_outs[0], arg)) + return false; + + /* Input registers: DWARF 24 .. 31 */ + if (!setfunc (24, 8, &locals_outs[8], arg)) + return false; + + return true; +#endif +} diff --git a/backends/sparc_regs.c b/backends/sparc_regs.c new file mode 100644 index 00000000..2bddcf43 --- /dev/null +++ b/backends/sparc_regs.c @@ -0,0 +1,111 @@ +/* Register names and numbers for SPARC DWARF. + Copyright (C) 2005, 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +ssize_t +sparc_register_info (Ebl *ebl, + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + const int nfp = 32 + (ebl->class == ELFCLASS32 ? 0 : 16); + const int nspec = ebl->class == ELFCLASS32 ? 8 : 6; + + if (name == NULL) + return 32 + nfp + nspec; + + if (regno < 0 || regno >= 32 + nfp + nspec || namelen < 6) + return -1; + + *bits = ebl->class == ELFCLASS32 ? 32 : 64; + *type = DW_ATE_signed; + + *prefix = "%"; + + if (regno >= 32 + nfp) + { + regno -= 32 + nfp; + static const char names[2][8][6] = + { + { "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" }, /* v8 */ + { "pc", "npc", "state", "fsr", "fprs", "y" } /* v9 */ + }; + *setname = "control"; + *type = DW_ATE_unsigned; + if ((ebl->class == ELFCLASS64 ? 0 : 4) + 1 - (unsigned int) regno <= 1) + *type = DW_ATE_address; + return stpncpy (name, names[ebl->class == ELFCLASS64][regno], + namelen) + 1 - name; + } + + if (regno < 32) + { + *setname = "integer"; + name[0] = "goli"[regno >> 3]; + name[1] = (regno & 7) + '0'; + namelen = 2; + if ((regno & 8) && (regno & 7) == 6) + *type = DW_ATE_address; + } + else + { + *setname = "FPU"; + *type = DW_ATE_float; + + regno -= 32; + if (regno >= 32) + regno = 32 + 2 * (regno - 32); + else + *bits = 32; + + name[0] = 'f'; + if (regno < 10) + { + name[1] = regno + '0'; + namelen = 2; + } + else + { + name[1] = regno / 10 + '0'; + name[2] = regno % 10 + '0'; + namelen = 3; + } + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/sparc_reloc.def b/backends/sparc_reloc.def new file mode 100644 index 00000000..7cd5ce96 --- /dev/null +++ b/backends/sparc_reloc.def @@ -0,0 +1,124 @@ +/* List the relocation types for sparc. -*- C -*- + Copyright (C) 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, REL) +RELOC_TYPE (8, REL) +RELOC_TYPE (16, REL) +RELOC_TYPE (32, REL|DYN) +RELOC_TYPE (DISP8, REL) +RELOC_TYPE (DISP16, REL) +RELOC_TYPE (DISP32, REL) +RELOC_TYPE (WDISP30, REL) +RELOC_TYPE (WDISP22, REL) +RELOC_TYPE (HI22, REL) +RELOC_TYPE (22, REL) +RELOC_TYPE (13, REL) +RELOC_TYPE (LO10, REL) +RELOC_TYPE (GOT10, REL) +RELOC_TYPE (GOT13, REL) +RELOC_TYPE (GOT22, REL) +RELOC_TYPE (PC10, REL) +RELOC_TYPE (PC22, REL) +RELOC_TYPE (WPLT30, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (UA32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (HIPLT22, REL) +RELOC_TYPE (LOPLT10, REL) +RELOC_TYPE (PCPLT32, REL) +RELOC_TYPE (PCPLT22, REL) +RELOC_TYPE (PCPLT10, REL) +RELOC_TYPE (10, REL) +RELOC_TYPE (11, REL) +RELOC_TYPE (64, REL|DYN) +RELOC_TYPE (OLO10, REL) +RELOC_TYPE (HH22, REL) +RELOC_TYPE (HM10, REL) +RELOC_TYPE (LM22, REL) +RELOC_TYPE (PC_HH22, REL) +RELOC_TYPE (PC_HM10, REL) +RELOC_TYPE (PC_LM22, REL) +RELOC_TYPE (WDISP16, REL) +RELOC_TYPE (WDISP19, REL) +RELOC_TYPE (GLOB_JMP, EXEC|DYN) +RELOC_TYPE (7, REL) +RELOC_TYPE (5, REL) +RELOC_TYPE (6, REL) +RELOC_TYPE (DISP64, REL) +RELOC_TYPE (PLT64, REL) +RELOC_TYPE (HIX22, REL) +RELOC_TYPE (LOX10, REL) +RELOC_TYPE (H44, REL) +RELOC_TYPE (M44, REL) +RELOC_TYPE (L44, REL) +RELOC_TYPE (REGISTER, REL) +RELOC_TYPE (UA64, REL) +RELOC_TYPE (UA16, REL) +RELOC_TYPE (TLS_GD_HI22, REL) +RELOC_TYPE (TLS_GD_LO10, REL) +RELOC_TYPE (TLS_GD_ADD, REL) +RELOC_TYPE (TLS_GD_CALL, REL) +RELOC_TYPE (TLS_LDM_HI22, REL) +RELOC_TYPE (TLS_LDM_LO10, REL) +RELOC_TYPE (TLS_LDM_ADD, REL) +RELOC_TYPE (TLS_LDM_CALL, REL) +RELOC_TYPE (TLS_LDO_HIX22, REL) +RELOC_TYPE (TLS_LDO_LOX10, REL) +RELOC_TYPE (TLS_LDO_ADD, REL) +RELOC_TYPE (TLS_IE_HI22, REL) +RELOC_TYPE (TLS_IE_LO10, REL) +RELOC_TYPE (TLS_IE_LD, REL) +RELOC_TYPE (TLS_IE_LDX, REL) +RELOC_TYPE (TLS_IE_ADD, REL) +RELOC_TYPE (TLS_LE_HIX22, REL) +RELOC_TYPE (TLS_LE_LOX10, REL) +RELOC_TYPE (TLS_DTPMOD32, DYN) +RELOC_TYPE (TLS_DTPMOD64, DYN) +RELOC_TYPE (TLS_DTPOFF32, DYN) +RELOC_TYPE (TLS_DTPOFF64, DYN) +RELOC_TYPE (TLS_TPOFF32, DYN) +RELOC_TYPE (TLS_TPOFF64, DYN) +RELOC_TYPE (GOTDATA_HIX22, REL) +RELOC_TYPE (GOTDATA_LOX10, REL) +RELOC_TYPE (GOTDATA_OP_HIX22, REL|DYN) +RELOC_TYPE (GOTDATA_OP_LOX10, REL|DYN) +RELOC_TYPE (GOTDATA_OP, REL|DYN) +RELOC_TYPE (H34, REL) +RELOC_TYPE (SIZE32, REL) +RELOC_TYPE (SIZE64, REL) +RELOC_TYPE (WDISP10, REL) +RELOC_TYPE (JMP_IREL, REL) +RELOC_TYPE (IRELATIVE, REL) +RELOC_TYPE (GNU_VTINHERIT, REL) +RELOC_TYPE (GNU_VTENTRY, REL) +RELOC_TYPE (REV32, REL) diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c new file mode 100644 index 00000000..fb81cdce --- /dev/null +++ b/backends/sparc_retval.c @@ -0,0 +1,159 @@ +/* Function return value location for SPARC. + Copyright (C) 2006-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND sparc_ +#include "libebl_CPU.h" + + +/* %o0, or pair %o0, %o1. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg8 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg9 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %f0 or pair %f0, %f1, or quad %f0..%f3. */ +static const Dwarf_Op loc_fpreg[] = + { + { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 4 }, + }; +#define nloc_fpreg 1 +#define nloc_fpregpair 4 +#define nloc_fpregquad 8 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in %o0. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg8, .number = 0 } + }; +#define nloc_aggregate 1 + +int +sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + uint8_t asize; + Dwarf_Die cudie; + if ((tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + && dwarf_diecu (typedie, &cudie, &asize, NULL) != NULL) + size = asize; + else + return -1; + } + } + + if (tag == DW_TAG_base_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + if (encoding == DW_ATE_float) + { + *locp = loc_fpreg; + if (size <= 4) + return nloc_fpreg; + if (size <= 8) + return nloc_fpregpair; + if (size <= 16) + return nloc_fpregquad; + } + } + if (size <= 8) + { + intreg: + *locp = loc_intreg; + return size <= 4 ? nloc_intreg : nloc_intregpair; + } + + aggregate: + *locp = loc_aggregate; + return nloc_aggregate; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + if (dwarf_aggregate_size (typedie, &size) == 0 + && size > 0 && size <= 8) + goto intreg; + goto aggregate; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/sparc_symbol.c b/backends/sparc_symbol.c new file mode 100644 index 00000000..e8ee3911 --- /dev/null +++ b/backends/sparc_symbol.c @@ -0,0 +1,149 @@ +/* SPARC specific symbolic name handling. + Copyright (C) 2002, 2003, 2005, 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Jakub Jelinek , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND sparc_ +#include "libebl_CPU.h" + +/* Check for the simple reloc types. */ +Elf_Type +sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_SPARC_8: + return ELF_T_BYTE; + case R_SPARC_16: + case R_SPARC_UA16: + return ELF_T_HALF; + case R_SPARC_32: + case R_SPARC_UA32: + return ELF_T_WORD; + case R_SPARC_64: + case R_SPARC_UA64: + return ELF_T_XWORD; + default: + return ELF_T_NUM; + } +} + +/* Check whether machine flags are valid. */ +bool +sparc_machine_flag_check (GElf_Word flags) +{ + return ((flags &~ (EF_SPARCV9_MM + | EF_SPARC_LEDATA + | EF_SPARC_32PLUS + | EF_SPARC_SUN_US1 + | EF_SPARC_SUN_US3)) == 0); +} + +bool +sparc_check_special_section (Ebl *ebl, + int ndx __attribute__ ((unused)), + const GElf_Shdr *shdr, + const char *sname __attribute__ ((unused))) +{ + if ((shdr->sh_flags & (SHF_WRITE | SHF_EXECINSTR)) + == (SHF_WRITE | SHF_EXECINSTR)) + { + /* This is ordinarily flagged, but is valid for a PLT on SPARC. + + Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it. + Its d_ptr should match the .plt section's sh_addr. */ + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr scn_shdr; + if (likely (gelf_getshdr (scn, &scn_shdr) != NULL) + && scn_shdr.sh_type == SHT_DYNAMIC + && scn_shdr.sh_entsize != 0) + { + Elf_Data *data = elf_getdata (scn, NULL); + if (data != NULL) + for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i) + { + GElf_Dyn dyn; + if (unlikely (gelf_getdyn (data, i, &dyn) == NULL)) + break; + if (dyn.d_tag == DT_PLTGOT) + return dyn.d_un.d_ptr == shdr->sh_addr; + } + break; + } + } + } + + return false; +} + +const char * +sparc_symbol_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (type) + { + case STT_SPARC_REGISTER: + return "SPARC_REGISTER"; + } + return NULL; +} + +const char * +sparc_dynamic_tag_name (int64_t tag, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_SPARC_REGISTER: + return "SPARC_REGISTER"; + } + return NULL; +} + +bool +sparc_dynamic_tag_check (int64_t tag) +{ + switch (tag) + { + case DT_SPARC_REGISTER: + return true; + } + return false; +} diff --git a/backends/x32_corenote.c b/backends/x32_corenote.c new file mode 100644 index 00000000..bd6560de --- /dev/null +++ b/backends/x32_corenote.c @@ -0,0 +1,2 @@ +#define BITS 32 +#include "x86_64_corenote.c" diff --git a/backends/x86_64_cfi.c b/backends/x86_64_cfi.c new file mode 100644 index 00000000..6db8ac44 --- /dev/null +++ b/backends/x86_64_cfi.c @@ -0,0 +1,63 @@ +/* x86-64 ABI-specified defaults for DWARF CFI. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND x86_64_ +#include "libebl_CPU.h" + +int +x86_64_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) +{ + static const uint8_t abi_cfi[] = + { + /* Call-saved regs. */ + DW_CFA_same_value, ULEB128_7 (0), /* %rbx */ + DW_CFA_same_value, ULEB128_7 (6), /* %rbp */ + DW_CFA_same_value, ULEB128_7 (12), /* %r12 */ + DW_CFA_same_value, ULEB128_7 (13), /* %r13 */ + DW_CFA_same_value, ULEB128_7 (14), /* %r14 */ + DW_CFA_same_value, ULEB128_7 (15), /* %r15 */ + DW_CFA_same_value, ULEB128_7 (16), /* %r16 */ + + /* The CFA is the SP. */ + DW_CFA_val_offset, ULEB128_7 (7), ULEB128_7 (0), + }; + + abi_info->initial_instructions = abi_cfi; + abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi]; + abi_info->data_alignment_factor = 8; + + abi_info->return_address_register = 16; /* %rip */ + + return 0; +} diff --git a/backends/x86_64_corenote.c b/backends/x86_64_corenote.c new file mode 100644 index 00000000..1bacc60f --- /dev/null +++ b/backends/x86_64_corenote.c @@ -0,0 +1,139 @@ +/* x86-64 specific core note handling. + Copyright (C) 2005, 2007, 2008 Red Hat, Inc. + Copyright (C) H.J. Lu , 2015. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef BITS +# define BITS 64 +# define BACKEND x86_64_ +#else +# define BITS 32 +# define BACKEND x32_ +#endif +#include "libebl_CPU.h" + + +static const Ebl_Register_Location prstatus_regs[] = + { +#define GR(at, n, dwreg) \ + { .offset = at * 8, .regno = dwreg, .count = n, .bits = 64 } +#define SR(at, n, dwreg) \ + { .offset = at * 8, .regno = dwreg, .count = n, .bits = 16, .pad = 6 } + + GR (0, 1, 15), /* %r15 */ + GR (1, 1, 14), /* %r14 */ + GR (2, 1, 13), /* %r13 */ + GR (3, 1, 12), /* %r12 */ + GR (4, 1, 6), /* %rbp */ + GR (5, 1, 3), /* %rbx */ + GR (6, 1, 11), /* %r11 */ + GR (7, 1, 10), /* %r10 */ + GR (8, 1, 9), /* %r9 */ + GR (9, 1, 8), /* %r8 */ + GR (10,1, 0), /* %rax */ + GR (11,1, 2), /* %rcx */ + GR (12,1, 1), /* %rdx */ + GR (13,2, 4), /* %rsi-%rdi */ + /* 15,1, orig_rax */ + GR (16,1, 16), /* %rip */ + SR (17,1, 51), /* %cs */ + GR (18,1, 49), /* %rFLAGS */ + GR (19,1, 7), /* %rsp */ + SR (20,1, 52), /* %ss */ + GR (21,2, 58), /* %fs.base-%gs.base */ + SR (23,1, 53), /* %ds */ + SR (24,1, 50), /* %es */ + SR (25,2, 54), /* %fs-%gs */ + +#undef GR +#undef SR + }; +#define PRSTATUS_REGS_SIZE (27 * 8) + +#if BITS == 32 +# define ULONG uint32_t +# define ALIGN_ULONG 4 +# define TYPE_ULONG ELF_T_WORD +# define PRPSINFO_UID_T uint16_t +# define ALIGN_PRPSINFO_UID_T 2 +# define TYPE_PRPSINFO_UID_T ELF_T_HALF +# define PRPSINFO_GID_T uint16_t +# define ALIGN_PRPSINFO_GID_T 2 +# define TYPE_PRPSINFO_GID_T ELF_T_HALF +#else +# define ULONG uint64_t +# define ALIGN_ULONG 8 +# define TYPE_ULONG ELF_T_XWORD +# define PRPSINFO_UID_T uint32_t +# define ALIGN_PRPSINFO_UID_T 4 +# define TYPE_PRPSINFO_UID_T TYPE_UID_T +# define PRPSINFO_GID_T uint32_t +# define ALIGN_PRPSINFO_GID_T 4 +# define TYPE_PRPSINFO_GID_T TYPE_GID_T +#endif +#define PR_REG uint64_t +#define ALIGN_PR_REG 8 +#define PID_T int32_t +#define UID_T uint32_t +#define GID_T uint32_t +#define ALIGN_PID_T 4 +#define ALIGN_UID_T 4 +#define ALIGN_GID_T 4 +#define TYPE_PID_T ELF_T_SWORD +#define TYPE_UID_T ELF_T_SWORD +#define TYPE_GID_T ELF_T_SWORD + +#define PRSTATUS_REGSET_ITEMS \ + { \ + .name = "orig_rax", .type = ELF_T_SXWORD, .format = 'd', \ + .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (8 * 15), \ + .group = "register" \ + } + +static const Ebl_Register_Location fpregset_regs[] = + { + { .offset = 0, .regno = 65, .count = 2, .bits = 16 }, /* fcw-fsw */ + { .offset = 24, .regno = 64, .count = 1, .bits = 32 }, /* mxcsr */ + { .offset = 32, .regno = 33, .count = 8, .bits = 80, .pad = 6 }, /* stN */ + { .offset = 32 + 128, .regno = 17, .count = 16, .bits = 128 }, /* xmm */ + }; +#define FPREGSET_SIZE 512 + +#define EXTRA_NOTES EXTRA_NOTES_IOPERM + +#include "x86_corenote.c" +#include "linux-core-note.c" diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c new file mode 100644 index 00000000..be965fa6 --- /dev/null +++ b/backends/x86_64_init.c @@ -0,0 +1,69 @@ +/* Initialization of x86-64 specific backend library. + Copyright (C) 2002-2009, 2013, 2018 Red Hat, Inc. + Copyright (C) H.J. Lu , 2015. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND x86_64_ +#define RELOC_PREFIX R_X86_64_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on x86_64_reloc.def. */ +#include "common-reloc.c" + +extern __typeof (EBLHOOK (core_note)) x32_core_note attribute_hidden; + +Ebl * +x86_64_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + /* We handle it. */ + x86_64_init_reloc (eh); + HOOK (eh, reloc_simple_type); + HOOK (eh, section_type_name); + if (eh->class == ELFCLASS32) + eh->core_note = x32_core_note; + else + HOOK (eh, core_note); + HOOK (eh, return_value_location); + HOOK (eh, register_info); + HOOK (eh, auxv_info); + HOOK (eh, disasm); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = 17; + HOOK (eh, set_initial_registers_tid); + HOOK (eh, unwind); + HOOK (eh, check_reloc_target_type); + + return eh; +} diff --git a/backends/x86_64_initreg.c b/backends/x86_64_initreg.c new file mode 100644 index 00000000..50e90020 --- /dev/null +++ b/backends/x86_64_initreg.c @@ -0,0 +1,73 @@ +/* Fetch live process registers from TID. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if defined(__x86_64__) && defined(__linux__) +# include +# include +#endif + +#define BACKEND x86_64_ +#include "libebl_CPU.h" + +bool +x86_64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#if !defined(__x86_64__) || !defined(__linux__) + return false; +#else /* __x86_64__ */ + struct user_regs_struct user_regs; + if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0) + return false; + Dwarf_Word dwarf_regs[17]; + dwarf_regs[0] = user_regs.rax; + dwarf_regs[1] = user_regs.rdx; + dwarf_regs[2] = user_regs.rcx; + dwarf_regs[3] = user_regs.rbx; + dwarf_regs[4] = user_regs.rsi; + dwarf_regs[5] = user_regs.rdi; + dwarf_regs[6] = user_regs.rbp; + dwarf_regs[7] = user_regs.rsp; + dwarf_regs[8] = user_regs.r8; + dwarf_regs[9] = user_regs.r9; + dwarf_regs[10] = user_regs.r10; + dwarf_regs[11] = user_regs.r11; + dwarf_regs[12] = user_regs.r12; + dwarf_regs[13] = user_regs.r13; + dwarf_regs[14] = user_regs.r14; + dwarf_regs[15] = user_regs.r15; + dwarf_regs[16] = user_regs.rip; + return setfunc (0, 17, dwarf_regs, arg); +#endif /* __x86_64__ */ +} diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c new file mode 100644 index 00000000..ef987daf --- /dev/null +++ b/backends/x86_64_regs.c @@ -0,0 +1,186 @@ +/* Register names and numbers for x86-64 DWARF. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND x86_64_ +#include "libebl_CPU.h" + +ssize_t +x86_64_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 67; + + if (regno < 0 || regno > 66 || namelen < 7) + return -1; + + *prefix = "%"; + *bits = 64; + *type = DW_ATE_unsigned; + if (regno < 17) + { + *setname = "integer"; + *type = DW_ATE_signed; + } + else if (regno < 33) + { + *setname = "SSE"; + *bits = 128; + } + else if (regno < 41) + { + *setname = "x87"; + *type = DW_ATE_float; + *bits = 80; + } + else if (regno < 49) + *setname = "MMX"; + else if (regno > 49 && regno < 60) + { + *setname = "segment"; + *bits = 16; + } + else + *setname = "control"; + + switch (regno) + { + static const char baseregs[][2] = + { + "ax", "dx", "cx", "bx", "si", "di", "bp", "sp" + }; + + case 6 ... 7: + *type = DW_ATE_address; + FALLTHROUGH; + case 0 ... 5: + name[0] = 'r'; + name[1] = baseregs[regno][0]; + name[2] = baseregs[regno][1]; + namelen = 3; + break; + + case 8 ... 9: + name[0] = 'r'; + name[1] = regno - 8 + '8'; + namelen = 2; + break; + + case 10 ... 15: + name[0] = 'r'; + name[1] = '1'; + name[2] = regno - 10 + '0'; + namelen = 3; + break; + + case 16: + *type = DW_ATE_address; + name[0] = 'r'; + name[1] = 'i'; + name[2] = 'p'; + namelen = 3; + break; + + case 17 ... 26: + name[0] = 'x'; + name[1] = 'm'; + name[2] = 'm'; + name[3] = regno - 17 + '0'; + namelen = 4; + break; + + case 27 ... 32: + name[0] = 'x'; + name[1] = 'm'; + name[2] = 'm'; + name[3] = '1'; + name[4] = regno - 27 + '0'; + namelen = 5; + break; + + case 33 ... 40: + name[0] = 's'; + name[1] = 't'; + name[2] = regno - 33 + '0'; + namelen = 3; + break; + + case 41 ... 48: + name[0] = 'm'; + name[1] = 'm'; + name[2] = regno - 41 + '0'; + namelen = 3; + break; + + case 50 ... 55: + name[0] = "ecsdfg"[regno - 50]; + name[1] = 's'; + namelen = 2; + break; + + case 58 ... 59: + *type = DW_ATE_address; + *bits = 64; + name[0] = regno - 58 + 'f'; + return stpcpy (&name[1], "s.base") + 1 - name; + + case 49: + *setname = "integer"; + return stpcpy (name, "rflags") + 1 - name; + case 62: + return stpcpy (name, "tr") + 1 - name; + case 63: + return stpcpy (name, "ldtr") + 1 - name; + case 64: + return stpcpy (name, "mxcsr") + 1 - name; + + case 65 ... 66: + *bits = 16; + name[0] = 'f'; + name[1] = "cs"[regno - 65]; + name[2] = 'w'; + namelen = 3; + break; + + default: + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} diff --git a/backends/x86_64_reloc.def b/backends/x86_64_reloc.def new file mode 100644 index 00000000..07a7c3d7 --- /dev/null +++ b/backends/x86_64_reloc.def @@ -0,0 +1,65 @@ +/* List the relocation types for x86-64. -*- C -*- + Copyright (C) 2000, 2001, 2002, 2003, 2005, 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, 0) +RELOC_TYPE (64, REL|EXEC|DYN) +RELOC_TYPE (PC32, REL|EXEC|DYN) +RELOC_TYPE (GOT32, REL) +RELOC_TYPE (PLT32, REL) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (GLOB_DAT, EXEC|DYN) +RELOC_TYPE (JUMP_SLOT, EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (GOTPCREL, REL) +RELOC_TYPE (32, REL|EXEC|DYN) +RELOC_TYPE (32S, REL) +RELOC_TYPE (16, REL) +RELOC_TYPE (PC16, REL) +RELOC_TYPE (8, REL) +RELOC_TYPE (PC8, REL) +RELOC_TYPE (DTPMOD64, EXEC|DYN) +RELOC_TYPE (DTPOFF64, EXEC|DYN) +RELOC_TYPE (TPOFF64, EXEC|DYN) +RELOC_TYPE (TLSGD, REL) +RELOC_TYPE (TLSLD, REL) +RELOC_TYPE (DTPOFF32, REL) +RELOC_TYPE (GOTTPOFF, REL) +RELOC_TYPE (TPOFF32, REL) +RELOC_TYPE (PC64, REL|EXEC|DYN) +RELOC_TYPE (GOTOFF64, REL) +RELOC_TYPE (GOTPC32, REL) +RELOC_TYPE (SIZE32, REL|EXEC|DYN) +RELOC_TYPE (SIZE64, REL|EXEC|DYN) +RELOC_TYPE (GOTPC32_TLSDESC, REL) +RELOC_TYPE (TLSDESC_CALL, REL) +RELOC_TYPE (TLSDESC, REL|EXEC|DYN) +RELOC_TYPE (IRELATIVE, EXEC|DYN) +RELOC_TYPE (GOTPCRELX, REL) +RELOC_TYPE (REX_GOTPCRELX, REL) diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c new file mode 100644 index 00000000..f9114cb1 --- /dev/null +++ b/backends/x86_64_retval.c @@ -0,0 +1,194 @@ +/* Function return value location for Linux/x86-64 ABI. + Copyright (C) 2005-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND x86_64_ +#include "libebl_CPU.h" + + +/* %rax, or pair %rax, %rdx. */ +static const Dwarf_Op loc_intreg[] = + { + { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 8 }, + { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 8 }, + }; +#define nloc_intreg 1 +#define nloc_intregpair 4 + +/* %st(0), or pair %st(0), %st(1). */ +static const Dwarf_Op loc_x87reg[] = + { + { .atom = DW_OP_regx, .number = 33 }, + { .atom = DW_OP_piece, .number = 10 }, + { .atom = DW_OP_regx, .number = 34 }, + { .atom = DW_OP_piece, .number = 10 }, + }; +#define nloc_x87reg 1 +#define nloc_x87regpair 4 + +/* %xmm0, or pair %xmm0, %xmm1. */ +static const Dwarf_Op loc_ssereg[] = + { + { .atom = DW_OP_reg17 }, { .atom = DW_OP_piece, .number = 16 }, + { .atom = DW_OP_reg18 }, { .atom = DW_OP_piece, .number = 16 }, + }; +#define nloc_ssereg 1 +#define nloc_sseregpair 4 + +/* The return value is a structure and is actually stored in stack space + passed in a hidden argument by the caller. But, the compiler + helpfully returns the address of that space in %rax. */ +static const Dwarf_Op loc_aggregate[] = + { + { .atom = DW_OP_breg0, .number = 0 } + }; +#define nloc_aggregate 1 + + +int +x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) +{ + /* Start with the function's type, and get the DW_AT_type attribute, + which is the type of the return value. */ + Dwarf_Die die_mem, *typedie = &die_mem; + int tag = dwarf_peeled_die_type (functypedie, typedie); + if (tag <= 0) + return tag; + + Dwarf_Word size; + switch (tag) + { + case -1: + return -1; + + case DW_TAG_subrange_type: + if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size)) + { + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem); + typedie = dwarf_formref_die (attr, &die_mem); + tag = DWARF_TAG_OR_RETURN (typedie); + } + FALLTHROUGH; + + case DW_TAG_base_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + { + Dwarf_Attribute attr_mem; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, + &attr_mem), &size) != 0) + { + if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type) + size = 8; + else + return -1; + } + } + + if (tag == DW_TAG_base_type) + { + Dwarf_Attribute attr_mem; + Dwarf_Word encoding; + if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, + &attr_mem), + &encoding) != 0) + return -1; + + switch (encoding) + { + case DW_ATE_complex_float: + switch (size) + { + case 4 * 2: /* complex float */ + case 8 * 2: /* complex double */ + *locp = loc_ssereg; + return nloc_sseregpair; + case 16 * 2: /* complex long double */ + *locp = loc_x87reg; + return nloc_x87regpair; + } + return -2; + + case DW_ATE_float: + switch (size) + { + case 4: /* float */ + case 8: /* double */ + *locp = loc_ssereg; + return nloc_ssereg; + case 16: /* long double */ + /* XXX distinguish __float128, which is sseregpair?? */ + *locp = loc_x87reg; + return nloc_x87reg; + } + return -2; + } + } + + intreg: + *locp = loc_intreg; + if (size <= 8) + return nloc_intreg; + if (size <= 16) + return nloc_intregpair; + + large: + *locp = loc_aggregate; + return nloc_aggregate; + + case DW_TAG_structure_type: + case DW_TAG_class_type: + case DW_TAG_union_type: + case DW_TAG_array_type: + if (dwarf_aggregate_size (typedie, &size) != 0) + goto large; + if (size > 16) + goto large; + + /* XXX + Must examine the fields in picayune ways to determine the + actual answer. This will be right for small C structs + containing integer types and similarly simple cases. + */ + + goto intreg; + } + + /* XXX We don't have a good way to return specific errors from ebl calls. + This value means we do not understand the type, but it is well-formed + DWARF and might be valid. */ + return -2; +} diff --git a/backends/x86_64_symbol.c b/backends/x86_64_symbol.c new file mode 100644 index 00000000..d5f62e8f --- /dev/null +++ b/backends/x86_64_symbol.c @@ -0,0 +1,81 @@ +/* x86_64 specific symbolic name handling. + Copyright (C) 2002, 2005, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define BACKEND x86_64_ +#include "libebl_CPU.h" + +/* Check for the simple reloc types. */ +Elf_Type +x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, + int *addsub __attribute__ ((unused))) +{ + switch (type) + { + case R_X86_64_64: + return ELF_T_XWORD; + case R_X86_64_32: + return ELF_T_WORD; + case R_X86_64_32S: + return ELF_T_SWORD; + case R_X86_64_16: + return ELF_T_HALF; + case R_X86_64_8: + return ELF_T_BYTE; + default: + return ELF_T_NUM; + } +} + +/* Return symbolic representation of section type. */ +const char * +x86_64_section_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + if (type == SHT_X86_64_UNWIND) + return "X86_64_UNWIND"; + + return NULL; +} + +/* The SHT_X86_64_UNWIND section type is a valid target for relocation. */ +bool +x86_64_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), + Elf64_Word sh_type) +{ + return sh_type == SHT_X86_64_UNWIND; +} diff --git a/backends/x86_64_unwind.c b/backends/x86_64_unwind.c new file mode 100644 index 00000000..ade64c01 --- /dev/null +++ b/backends/x86_64_unwind.c @@ -0,0 +1,86 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2016 The Qt Company Ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND x86_64_ +#include "libebl_CPU.h" + +/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that? */ + +bool +x86_64_unwind (Ebl *ebl __attribute__ ((unused)), + Dwarf_Addr pc __attribute__ ((unused)), + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep __attribute__ ((unused))) +{ + // Register 6 is supposed to be rbp, thus the conventional frame pointer + const int fpReg = 6; + const int spReg = 7; + + Dwarf_Word fp; + if (!getfunc(fpReg, 1, &fp, arg) || fp == 0) + return false; + + // Try to read old sp, so that we can avoid infinite loops below + Dwarf_Word sp; + if (!getfunc(spReg, 1, &sp, arg)) + sp = 0; + + Dwarf_Word prev_fp; + if (!readfunc(fp, &prev_fp, arg)) + prev_fp = 0; + + Dwarf_Word ret; + if (!readfunc(fp + 8, &ret, arg)) + return false; + + if (!setfunc(fpReg, 1, &prev_fp, arg)) + return false; + + fp += 16; // Pop fp and return address and write result to sp + if (!setfunc(spReg, 1, &fp, arg)) + return false; + + if (!setfunc(-1, 1, &ret, arg)) + return false; + + // If the sp didn't move up we don't actually have a new stack + // frame but rather some random data that doesn't include frame + // pointers. Break the unwinding then. + if (sp >= fp) + return false; + + return true; +} diff --git a/backends/x86_corenote.c b/backends/x86_corenote.c new file mode 100644 index 00000000..629462c3 --- /dev/null +++ b/backends/x86_corenote.c @@ -0,0 +1,51 @@ +/* x86-specific core note handling, pieces common to x86-64 and i386. + Copyright (C) 2005-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define EXTRA_NOTES_IOPERM \ + case NT_386_IOPERM: \ + return ioperm_info (nhdr->n_descsz, \ + regs_offset, nregloc, reglocs, nitems, items); + +static int +ioperm_info (GElf_Word descsz, GElf_Word *regs_offset, + size_t *nregloc, const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **items) +{ + static const Ebl_Core_Item ioperm_item = + { .type = ELF_T_WORD, .format = 'b', .name = "ioperm" }; + + if (descsz % 4 != 0) + return 0; + + *regs_offset = 0; + *nregloc = 0; + *reglocs = NULL; + *nitems = 1; + *items = &ioperm_item; + return 1; +} diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..5891a0c5 --- /dev/null +++ b/config.h.in @@ -0,0 +1,180 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Building with -fsanitize=undefined or not */ +#undef CHECK_UNDEFINED + +/* Should ar and ranlib use -D behavior by default? */ +#undef DEFAULT_AR_DETERMINISTIC + +/* Build dummy libdebuginfod */ +#undef DUMMY_LIBDEBUGINFOD + +/* Build debuginfod */ +#undef ENABLE_DEBUGINFOD + +/* Enable libdebuginfod */ +#undef ENABLE_LIBDEBUGINFOD + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to 1 if you have the Mac OS X function + CFLocaleCopyPreferredLanguages in the CoreFoundation framework. */ +#undef HAVE_CFLOCALECOPYPREFERREDLANGUAGES + +/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +#undef HAVE_CFPREFERENCESCOPYAPPVALUE + +/* define if the compiler supports basic C++11 syntax */ +#undef HAVE_CXX11 + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the declaration of `mempcpy', and to 0 if you + don't. */ +#undef HAVE_DECL_MEMPCPY + +/* Define to 1 if you have the declaration of `memrchr', and to 0 if you + don't. */ +#undef HAVE_DECL_MEMRCHR + +/* Define to 1 if you have the declaration of `powerof2', and to 0 if you + don't. */ +#undef HAVE_DECL_POWEROF2 + +/* Define to 1 if you have the declaration of `rawmemchr', and to 0 if you + don't. */ +#undef HAVE_DECL_RAWMEMCHR + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#undef HAVE_DECL_STRERROR_R + +/* Defined if __attribute__((fallthrough)) is supported */ +#undef HAVE_FALLTHROUGH + +/* Defined if __attribute__((gcc_struct)) is supported */ +#undef HAVE_GCC_STRUCT + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define if you have the iconv() function and it works. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `process_vm_readv' function. */ +#undef HAVE_PROCESS_VM_READV + +/* Enable pthread_setname_np */ +#undef HAVE_PTHREAD_SETNAME_NP + +/* Define to 1 if `stdatomic.h` is provided by the system, 0 otherwise. */ +#undef HAVE_STDATOMIC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror_r' function. */ +#undef HAVE_STRERROR_R + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if defines struct user_regs_struct */ +#undef HAVE_SYS_USER_REGS + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Defined if __attribute__((visibility())) is supported */ +#undef HAVE_VISIBILITY + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if strerror_r returns char *. */ +#undef STRERROR_R_CHAR_P + +/* Support bzip2 decompression via -lbz2. */ +#undef USE_BZLIB + +/* Defined if demangling is enabled */ +#undef USE_DEMANGLE + +/* Defined if libraries should be thread-safe. */ +#undef USE_LOCKS + +/* Support LZMA (xz) decompression via -llzma. */ +#undef USE_LZMA + +/* Support gzip decompression via -lz. */ +#undef USE_ZLIB + +/* Support ZSTD (zst) decompression via -lzstd. */ +#undef USE_ZSTD + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +#include diff --git a/config/10-default-yama-scope.conf b/config/10-default-yama-scope.conf new file mode 100644 index 00000000..4df20903 --- /dev/null +++ b/config/10-default-yama-scope.conf @@ -0,0 +1,35 @@ +# When yama is enabled in the kernel it might be used to filter any user +# space access which requires PTRACE_MODE_ATTACH like ptrace attach, access +# to /proc/PID/{mem,personality,stack,syscall}, and the syscalls +# process_vm_readv and process_vm_writev which are used for interprocess +# services, communication and introspection (like synchronisation, signaling, +# debugging, tracing and profiling) of processes. +# +# Usage of ptrace attach is restricted by normal user permissions. Normal +# unprivileged processes cannot interact through ptrace with processes +# that they cannot send signals to or processes that are running set-uid +# or set-gid. +# +# yama ptrace scope can be used to reduce these permissions even more. +# This should normally not be done because it will break various programs +# relying on the default ptrace security restrictions. But can be used +# if you don't have any other way to separate processes in their own +# domains. A different way to restrict ptrace is to set the selinux +# deny_ptrace boolean. Both mechanisms will break some programs relying +# on the ptrace system call and might force users to elevate their +# privileges to root to do their work. +# +# For more information see Documentation/security/Yama.txt in the kernel +# sources. Which also describes the defaults when CONFIG_SECURITY_YAMA +# is enabled in a kernel build (currently 1 for ptrace_scope). +# +# This runtime kernel parameter can be set to the following options: +# (Note that setting this to anything except zero will break programs!) +# +# 0 - Default attach security permissions. +# 1 - Restricted attach. Only child processes plus normal permissions. +# 2 - Admin-only attach. Only executables with CAP_SYS_PTRACE. +# 3 - No attach. No process may call ptrace at all. Irrevocable. +# +kernel.yama.ptrace_scope = 0 + diff --git a/config/ChangeLog b/config/ChangeLog new file mode 100644 index 00000000..2cdcfa72 --- /dev/null +++ b/config/ChangeLog @@ -0,0 +1,564 @@ +2021-05-10 Mark Wielaard + + * elfutils.spec.in: Update for 0.185. + +2021-05-11 Frank Ch. Eigler + + * elfutils.spec.in: Add procps to BuildRequires: for %check. + +2021-05-10 Mark Wielaard + + * elfutils.spec.in: Update for 0.184. + +2021-02-17 Timm Bäder + + * eu.am (NO_PACKED_NOT_ALIGNED_WARNING): New variable. + (AM_CFLAGS): Use NO_PACKED_NOT_ALIGNED_WARNING. + (AM_CXXFLAGS): Likewise. + +2021-02-17 Timm Bäder + + * eu.am (TRAMPOLINES_WARNING): New variable. + (AM_CFLAGS): Use TRAMPOLINES_WARNING. + (AM_CXXFLAGS): Likewise. + +2021-02-12 Mark Wielaard + + * elfutils.spec.in: Escape %%check in comment. + +2021-02-05 Mark Wielaard + + * elfutils.spec.in: Update for 0.183. + +2020-12-20 Dmitry V. Levin + + * .gitignore: New file. + +2020-12-12 Dmitry V. Levin + + * 10-default-yama-scope.conf: Fix spelling typo in comment. + * upload-release.sh: Likewise. + * elfutils.spec.in: Fix spelling typos in %changelog. + +2020-11-04 Dmitry V. Levin + + * profile.sh.in, profile.csh.in: Do not define $DEBUGINFOD_URLS unless + configured using --enable-debuginfod-urls. + +2020-11-02 Dmitry V. Levin + + * Makefile.am (pkgconfig_DATA, install-data-local, uninstall-local): + Conditionalize on LIBDEBUGINFOD instead of DEBUGINFOD. + +2020-10-31 Dmitry V. Levin + + * Makefile.am (install-data-local, uninstall-local): Conditionalize + on DEBUGINFOD. + +2020-10-30 Mark Wielaard + + * elfutils.spec.in: Update for 0.182. + +2020-10-31 Frank Ch. Eigler + + * debuginfod.service: Bump up TimeoutStopSec. + +2020-10-30 Frank Ch. Eigler + + * elfutils.spec.in: Fix debuginfod config/state file attributes + for non-lossy updates. + +2020-10-08 Frank Ch. Eigler + + * Makefile.am (uninstall-local): Uninstall the new profile.d files. + +2020-10-01 Frank Ch. Eigler + + PR25461 + * profile.sh.in, profile.csh.in: New files for /etc/profile.d + to define $DEBUGINFOD_URLS. + * elfutils.spec.in: Configure with --enable-debuginfod-urls. + * Makefile.am: Install them. + +2020-09-18 Mark Wielaard + + * elfutils.spec.in: Add BuildRequires for libzstd-devel and zstd. + * libdw.pc.in: Requires.private libzstd. + +2020-09-08 Mark Wielaard + + * elfutils.spec.in: Update for 0.181. + +2020-06-16 Mark Wielaard + + * upload-release.sh: Use /usr/bin/env bash. + +2020-06-11 Mark Wielaard + + * elfutils.spec.in: Update for 0.189. + +2020-04-21 Frank Ch. Eigler + + * debuginfod.sysconfig (DEBUGINFOD_PATHS): Add /var/lib/pulp. + +2020-03-30 Mark Wielaard + + * upload-release.sh: chmod uploaded dir and files to make them + readable. + +2020-03-30 Mark Wielaard + + * elfutils.spec.in: Update for 0.179. + +2020-03-25 Frank Ch. Eigler + + * elfutils.spec.in: *Require: bsdtar instead of dpkg. + +2020-03-04 Mark Wielaard + + * elfutils.spec.in (package debuginfod): Remove Requires: rpm. + Add Requires: dpkg. + +2020-01-12 Frank Ch. Eigler + + * elfutils.spec.in: Typo fix for "Requires: debuginfod-client". + +2020-01-11 Frank Ch. Eigler + + * debuginfod.service: Set PrivateTmp=yes. + +2020-01-01 Dmitry V. Levin + + * Makefile.am (pkgconfig_DATA): Conditionalize libdebuginfod.pc + on DEBUGINFOD. + +2019-12-22 Frank Ch. Eigler + + * elfutils.spec.in (debuginfod): Add BuildRequire dpkg + for deb testing. (Available on Fedora & EPEL, not base RHEL.) + +2019-12-05 Mark Wielaard + + * elfutils.spec.in: Add explicit version-release requires for all + packages. + +2019-11-28 Mark Wielaard + + * elfutils.spec.in (debuginfod): Add an explicit Requires + elfutils-debuginfod-client. + +2019-11-27 Mark Wielaard + + * elfutils.spec.in: Move all versioned libdebuginfod libraries + from debuginfod-client-devel to debuginfod-client. + +2019-11-26 Mark Wielaard + + * elfutils.spec.in: Remove Group tags, remove fedora and rhel + specifics, introduce elfutils-libs subpackage, move Requires + and BuildRequires around for new subpackage, remove dot at end + of Summary tags, add post/postun ldconfig for libs and + debuginfod-client, remove default defattr(-,root,root) for file + lists, order binaries by name. + +2019-11-25 Mark Wielaard + + * elfutils.spec.in: Add BuildRequires curl. + +2019-10-28 Frank Ch. Eigler + + * eu.am (AM_CXXFLAGS): Clone & amend AM_CFLAGS for c++11 code. + * debuginfod.service, debuginfod.sysconfig: New files: systemd. + * Makefile.am: Install them. + * elfutils.spec.in: Add debuginfod and debuginfod-client subrpms. + +2019-08-29 Mark Wielaard + + * elfutils.spec.in (%description devel): Remove libebl text. + (%install): Don't touch backend lib.*.so* files. + (%files): Remove backends dir and so files. + (%files devel): Remove libebl.h and libebl.a + +2019-08-28 Mark Wielaard + + * elfutils.spec.in (License): Add GFDL. + (%install): Correct sub-shell syntax, use (), not {}. + (%files): Add man1/eu-*.1*. + Add eu-stack. Add COPYING-GFDL. + (%files libelf-devel): Add man3/elf_*.3*. + +2019-08-14 Dmitry V. Levin + + * elfutils.spec.in (%files): Add %{_bindir}/eu-elfclassify. + +2019-08-13 Mark Wielaard + + * Makefile.am (elfutils.spec.in): Use git --get user.name and + user.email. + +2019-04-15 Mark Wielaard + + * upload-release.sh: Add git tag --verify. + +2019-02-14 Mark Wielaard + + * elfutils.spec.in: Update for 0.176. + +2018-11-19 Mark Wielaard + + * eu.am (AM_CFLAGS): Add -Wtrampolines. + +2018-07-04 Mark Wielaard + + * upload-release.sh: New file. + +2018-06-11 Mark Wielaard + + * elfutils.spec.in: Update for 0.172. + +2018-06-01 Mark Wielaard + + * elfutils.spec.in: Update for 0.171. + +2018-02-09 Joshua Watt + + * eu.am (IMPLICIT_FALLTHROUGH_WARNING): Set to 5. + +2017-11-02 Mark Wielaard + + * elfutils.spec.in: Config files under /usr/lib/sysctl.d (_sysctldir) + aren't %config. + +2017-10-24 Mark Wielaard + + * eu.am (AM_CFLAGS): Handle -Wno-packed-not-aligned. + +2017-04-27 Ulf Hermann + + * eu.am: Use fpic_CFLAGS. + +2016-08-02 Mark Wielaard + + * elfutils.spec.in: Update for 0.170. + +2017-05-05 Mark Wielaard + + * elfutils.spec.in: Update for 0.169. + +2016-12-27 Mark Wielaard + + * elfutils.spec.in: Update for 0.168 and new project location. + +2016-12-24 Mark Wielaard + + * libdw.pc.in: Set URL to http://elfutils.org/ + * libelf.pc.in: Likewise. + +2016-11-02 Mark Wielaard + + * eu.am: Check HAVE_IMPLICIT_FALLTHROUGH_WARNING. + (AM_CFLAGS): Add IMPLICIT_FALLTHROUGH_WARNING. + +2016-08-04 Mark Wielaard + + * elfutils.spec.in: Update for 0.167. + +2016-07-06 Mark Wielaard + + * elfutils.spec.in: Remove eu-ld. + +2016-03-31 Mark Wielaard + + * elfutils.spec.in: Update for 0.166. + +2016-02-13 Mark Wielaard + + * eu.am: Check HAVE_NULL_DEREFERENCE_WARNING. + (AM_CFLAGS): Add NULL_DEREFERENCE_WARNING. + +2016-02-09 Mark Wielaard + + * eu.am: Check SANE_LOGICAL_OP_WARNING and + HAVE_DUPLICATED_COND_WARNING. + (AM_CFLAGS): Add LOGICAL_OP_WARNING and DUPLICATED_COND_WARNING. + +2016-01-08 Mark Wielaard + + * elfutils.spec.in: Add elfcompress. Update for 0.165. + +2016-01-04 Mark Wielaard + + * libelf.pc.in: New file. + * libdw.pc.in: Likewise. + * Makefile.am (EXTRA_DIST): Add libelf.pc.in and libdw.pc.in. + (pkgconfigdir): New variable. + (pkgconfigdir_DATA): Likewise. + * elfutils.spec.in (files devel): Add libdw.pc. + (files libelf-devel): Add libelf.pc. + +2015-10-15 Mark Wielaard + + * elfutils.spec.in: Update for 0.164. + +2015-10-07 Mark Wielaard + + * eu.am (ARFLAGS): Set to "cr". + +2015-10-09 Josh Stone + + * eu.am (print-%): New target to print any variable. + +2015-10-05 Josh Stone + + * eu.am (%.os): Add AM_V_CC silencers. + +2015-09-24 Jose E. Marchesi + + * eu.am (%.os): Use -fPIC instead of -fpic to avoid relocation + overflows in some platforms. + +2015-09-22 Mark Wielaard + + * eu.am (AM_CFLAGS): Add -Wold-style-definition -Wstrict-prototypes. + +2015-08-04 Mark Wielaard + + * 10-default-yama-scope.conf: New file. + * Makefile.am (EXTRA_DIST): Add 10-default-yama-scope.conf. + * elfutils.spec.in (Requires): default-yama-scope. + (default-yama-scope): New package. + +2015-06-19 Mark Wielaard + + * elfutils.spec.in: Update for 0.163. + +2015-06-11 Mark Wielaard + + * elfutils.spec.in (devel): Include elfutils/known-dwarf.h and + elfutils/version.h. + +2015-06-10 Mark Wielaard + + * elfutils.spec.in: Update for 0.162. + +2015-05-23 Mark Wielaard + + * eu.am (STACK_USAGE_WARNING): New variable set based on + ADD_STACK_USAGE_WARNING conditional. + (AM_CFLAGS): Use STACK_USAGE_WARNING variable. + +2015-05-23 Mark Wielaard + + * eu.am (AM_CFLAGS): Add -Wstack-usage=262144. + +2015-04-23 Max Filippov + + * eu.am (DEFS.os): New variable. + +2015-03-18 Petr Machata + + * known-dwarf.awk (comment): Drop all uses of this variable. + (END): Always emit the non-_DESC variant. Emit + DWARF_ALL_KNOWN_DW_ instead of ALL_KNOWN_DW_*, and + DWARF_ONE_KNOWN_DW_ instead of ONE_KNOWN_DW_*. + +2015-02-20 Petr Machata + + * known-dwarf.awk (END): Drop useless variables lo, hi. Merge two + continue-checks in one. + +2014-12-18 Mark Wielaard + + * elfutils.spec.in: Update for 0.161. + +2014-11-27 Mark Wielaard + + * eu.am: Define textrel_msg, textrel_found and textrel_check based + on FATAL_TEXTREL. + +2014-08-25 Mark Wielaard + + * elfutils.spec.in: Update for 0.160. + +2014-05-17 Mark Wielaard + + * elfutils.spec.in: Update for 0.159. + (%files devel): Add libdwelf.h. + +2014-04-13 Mark Wielaard + + * eu.am (AM_CFLAGS): Don't add -fmudflap. + (COMPILE.os): Don't remove no_mudflap.os. + +2014-01-22 Mark Wielaard + + * eu.am (AM_CFLAGS): Unconditionally add -Wformat=2. + +2014-01-03 Mark Wielaard + + * elfutils.spec.in: Update for 0.158. + +2013-11-01 Michael Forney + + * eu.am: Use READELF. + +2013-09-30 Mark Wielaard + + * elfutils.spec.in: Update for readelf NT_SIGINFO and NT_FILE + core notes. + +2013-09-27 Mark Wielaard + + * config/elfutils.spec.in: Update for 0.157. + +2013-07-25 Jan Kratochvil + + * config/elfutils.spec.in: Update for 0.156. + +2013-04-24 Mark Wielaard + + * eu.am: Use AM_CPPFLAGS instead of INCLUDES. + +2012-08-27 Mark Wielaard + + * config/elfutils.spec.in: Update for 0.155. + +2012-07-19 Mark Wielaard + + * known-dwarf.awk: "Generated by" header had wrong file names, + mention config/known-dwarf.awk and libdw/dwarf.h contents. + +2012-06-22 Mark Wielaard + + * config/elfutils.spec.in: Update for 0.154. + +2012-02-23 Mark Wielaard + + * config/elfutils.spec.in: Update for 0.153. + +2011-10-31 Mark Wielaard + + * known-dwarf.awk: Use gawk. + +2010-07-02 Ulrich Drepper + + * elfutils.spec.in: Add more BuildRequires. + Ship the .mo files with the libelf subpackage. + +2010-04-15 Roland McGrath + + * eu.am (DEFS): Add -DLOCALEDIR=... here. + +2010-02-15 Roland McGrath + + * eu.am: New file. + +2009-04-19 Roland McGrath + + * version.h.in: Revert last change. + +2009-04-17 Roland McGrath + + * version.h.in (_ELFUTILS_PREREQ): Multiple major by 1000000 and minor + by 1000; now _ELFUTILS_VERSION is 789000 for version 0.789. + +2009-01-22 Ulrich Drepper + + * elfutils.spec.in: Distribute in + elfutils-libelf-devel. + +2009-01-22 Roland McGrath + + * known-dwarf.awk: Handle DW_FOO_BAR_* sets better. + +2009-01-11 Roland McGrath + + * known-dwarf.awk: New file. + * Makefile.am (EXTRA_DIST): Add it. + +2008-12-24 Roland McGrath + + * Makefile.am ($(srcdir)/elfutils.spec.in): Rewrite awk magic. + Put the target inside [if MAINTAINER_MODE]. + +2008-12-16 Roland McGrath + + * version.h.in: New file. + +2008-01-12 Ulrich Drepper + + * elfutils.spec.in: Add m4 to build requirements. + +2008-01-02 Ulrich Drepper + + * elfutils.spec.in: Changes for disasm branch merge. + +2007-08-08 Roland McGrath + + * elfutils.spec.in (License): Canonicalize. + +2007-04-23 Roland McGrath + + * elfutils.spec.in: Distribute eu-unstrip. + +2005-08-13 Roland McGrath + + * Makefile.am ($(srcdir)/elfutils.spec.in): Add missing $. + +2005-07-28 Roland McGrath + + * elfutils.spec.in: Remove libdwfl.so from package. + +2005-07-21 Ulrich Drepper + + * elfutils.spec.in: Distribute eu-elfcmp. + +2005-04-01 Ulrich Drepper + + * elfutils.spec.in: Distribute eu-addr2line. + +2005-03-17 Ulrich Drepper + + * elfutils.spec.in: Distribute libdw.{a,so,h}. + +2005-02-22 Ulrich Drepper + + * Makefile.am: Ignore result of cvs run. + + * elfutils.spec.in: Simplify build process by not using a subdir. + This means we can use %configure. + +2005-02-18 Ulrich Drepper + + * Makefile.am: Automatically added changelog from NEWS file on dist. + +2005-02-15 Ulrich Drepper + + * elfutils.spec.in: Make sure RPM_OPT_FLAGS is used. During + %build, really do build the binaries. + Remove --enable-shared configure parameters. + +2005-02-07 Ulrich Drepper + + * elfutils.spec.in (BuildRequires): Up gcc requirement to 3.4. + +2004-11-23 Ulrich Drepper + + * elfutils.spec.in: Some more changes for the RPM with the fake + binaries. + +2004-01-29 Ulrich Drepper + + * elfutils.spec.in: Update BuildRequires. + +2004-01-17 Ulrich Drepper + + * Makefile.am: New file. + * config.guess: Moved to here from toplevel. + * config.rpath: Likewise. + * config.sub: Likewise. + * depcomp: Likewise. + * install-sh: Likewise. + * missing: Likewise. + * mkinstalldirs: Likewise. + * elfutils.spec.in: New file. diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 00000000..a66f5490 --- /dev/null +++ b/config/Makefile.am @@ -0,0 +1,66 @@ +## Process this file with automake to produce Makefile.in -*-Makefile-*- +## Configure input file for elfutils. +## +## Copyright (C) 2004, 2005, 2008, 2009, 2011, 2015, 2016 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +EXTRA_DIST = elfutils.spec.in known-dwarf.awk 10-default-yama-scope.conf \ + libelf.pc.in libdw.pc.in libdebuginfod.pc.in \ + debuginfod.service debuginfod.sysconfig profile.sh.in profile.csh.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libelf.pc libdw.pc +if LIBDEBUGINFOD +pkgconfig_DATA += libdebuginfod.pc + +install-data-local: + $(INSTALL_DATA) profile.sh -D $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.sh + $(INSTALL_DATA) profile.csh -D $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.csh + +uninstall-local: + rm -f $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.sh $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.csh +endif + +if MAINTAINER_MODE +$(srcdir)/elfutils.spec.in: $(top_srcdir)/NEWS + @tmpname=$$(mktemp $${TMPDIR:-/tmp}/elfutils.XXXXXX); \ + date +'* %a %b %e %Y' | tr '[\n]' '[ ]' > $$tmpname; \ + username=$$(git config --get user.name); \ + useremail=$$(git config --get user.email); \ + echo -n "$$username <$$useremail> " >> $$tmpname; \ + awk '\ + $$1 == "Version" && started { exit } \ + $$1 == "Version" { started=1; line=""; sub(/:/,"",$$2); \ + print $$2 "-1"; next } \ + NF > 0 { line = (line != "") ? (line " " $$0) : ("- " $$0) } \ + NF == 0 && line != "" { print line; line="" } \ + END { if (line != "") print line; print "" }' $< \ + | fold -s -w 70 | sed '1!s/^[^-]/ &/' >> $$tmpname; \ + sed "/^%changelog/r $$tmpname" $@ > $@.new; \ + rm -f $$tmpname; \ + mv -f $@.new $@ +endif diff --git a/config/Makefile.in b/config/Makefile.in new file mode 100644 index 00000000..3cf3702c --- /dev/null +++ b/config/Makefile.in @@ -0,0 +1,588 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@LIBDEBUGINFOD_TRUE@am__append_1 = libdebuginfod.pc +subdir = config +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = libelf.pc libdw.pc libdebuginfod.pc profile.sh \ + profile.csh +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libdebuginfod.pc.in \ + $(srcdir)/libdw.pc.in $(srcdir)/libelf.pc.in \ + $(srcdir)/profile.csh.in $(srcdir)/profile.sh.in ChangeLog \ + ar-lib compile config.guess config.rpath config.sub depcomp \ + install-sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +EXTRA_DIST = elfutils.spec.in known-dwarf.awk 10-default-yama-scope.conf \ + libelf.pc.in libdw.pc.in libdebuginfod.pc.in \ + debuginfod.service debuginfod.sysconfig profile.sh.in profile.csh.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libelf.pc libdw.pc $(am__append_1) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits config/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits config/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +libelf.pc: $(top_builddir)/config.status $(srcdir)/libelf.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +libdw.pc: $(top_builddir)/config.status $(srcdir)/libdw.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +libdebuginfod.pc: $(top_builddir)/config.status $(srcdir)/libdebuginfod.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +profile.sh: $(top_builddir)/config.status $(srcdir)/profile.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +profile.csh: $(top_builddir)/config.status $(srcdir)/profile.csh.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@LIBDEBUGINFOD_FALSE@install-data-local: +@LIBDEBUGINFOD_FALSE@uninstall-local: +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-data-local install-pkgconfigDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-local uninstall-pkgconfigDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-data-local install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-local uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +@LIBDEBUGINFOD_TRUE@install-data-local: +@LIBDEBUGINFOD_TRUE@ $(INSTALL_DATA) profile.sh -D $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.sh +@LIBDEBUGINFOD_TRUE@ $(INSTALL_DATA) profile.csh -D $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.csh + +@LIBDEBUGINFOD_TRUE@uninstall-local: +@LIBDEBUGINFOD_TRUE@ rm -f $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.sh $(DESTDIR)$(sysconfdir)/profile.d/debuginfod.csh + +@MAINTAINER_MODE_TRUE@$(srcdir)/elfutils.spec.in: $(top_srcdir)/NEWS +@MAINTAINER_MODE_TRUE@ @tmpname=$$(mktemp $${TMPDIR:-/tmp}/elfutils.XXXXXX); \ +@MAINTAINER_MODE_TRUE@ date +'* %a %b %e %Y' | tr '[\n]' '[ ]' > $$tmpname; \ +@MAINTAINER_MODE_TRUE@ username=$$(git config --get user.name); \ +@MAINTAINER_MODE_TRUE@ useremail=$$(git config --get user.email); \ +@MAINTAINER_MODE_TRUE@ echo -n "$$username <$$useremail> " >> $$tmpname; \ +@MAINTAINER_MODE_TRUE@ awk '\ +@MAINTAINER_MODE_TRUE@ $$1 == "Version" && started { exit } \ +@MAINTAINER_MODE_TRUE@ $$1 == "Version" { started=1; line=""; sub(/:/,"",$$2); \ +@MAINTAINER_MODE_TRUE@ print $$2 "-1"; next } \ +@MAINTAINER_MODE_TRUE@ NF > 0 { line = (line != "") ? (line " " $$0) : ("- " $$0) } \ +@MAINTAINER_MODE_TRUE@ NF == 0 && line != "" { print line; line="" } \ +@MAINTAINER_MODE_TRUE@ END { if (line != "") print line; print "" }' $< \ +@MAINTAINER_MODE_TRUE@ | fold -s -w 70 | sed '1!s/^[^-]/ &/' >> $$tmpname; \ +@MAINTAINER_MODE_TRUE@ sed "/^%changelog/r $$tmpname" $@ > $@.new; \ +@MAINTAINER_MODE_TRUE@ rm -f $$tmpname; \ +@MAINTAINER_MODE_TRUE@ mv -f $@.new $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/config/ar-lib b/config/ar-lib new file mode 100755 index 00000000..1e9388e2 --- /dev/null +++ b/config/ar-lib @@ -0,0 +1,271 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2019-07-04.01; # UTC + +# Copyright (C) 2010-2020 Free Software Foundation, Inc. +# Written by Peter Rosin . +# +# 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, 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, see . + +# 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. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin | msys) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <. +# +# 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, 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, see . + +# 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. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/config.guess b/config/config.guess new file mode 100755 index 00000000..f50dcdb6 --- /dev/null +++ b/config/config.guess @@ -0,0 +1,1480 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-24' + +# 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 3 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, see . +# +# 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. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -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 1992-2018 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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > "$dummy.c" ; + for c in cc gcc c89 c99 ; do + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + 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 ; set_cc_for_build= ;' + +# 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 + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# 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 tuples: *-*-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=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-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) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + 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 + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # 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. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + 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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval "$set_cc_for_build" + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + 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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # 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 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + 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 -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + 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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + 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 ;; + *: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 + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[4567]) + 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/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 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 -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + eval "$set_cc_for_build" + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 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 -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + i*86:Minix:*:*) + echo "$UNAME_MACHINE"-pc-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + 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 -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + eval "$set_cc_for_build" + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + 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-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + if objdump -f /bin/sh | grep -q elf32-x86-64; then + echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 + else + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + fi + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + 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 ;; + 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 ;; + 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 ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*: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 ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + 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 ;; + 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|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + 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 i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + 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 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval "$set_cc_for_build" + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *: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 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *: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 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&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-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/config.rpath b/config/config.rpath new file mode 100755 index 00000000..24be79cf --- /dev/null +++ b/config/config.rpath @@ -0,0 +1,684 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2020 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + xl* | bgxl* | bgf* | mpixl*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + newsos6) + ;; + *nto* | *qnx*) + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd2.[01]*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + *nto* | *qnx*) + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' + ;; + freebsd* | dragonfly*) + library_names_spec='$libname$shrext' + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + *nto* | *qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. +# +# 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. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# 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. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# 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 or ALIAS + +Canonicalize a configuration name. + +Options: + -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 1992-2018 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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 ;; + + * ) + 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* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + 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 | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -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 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + ;; + -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 \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | wasm32 \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # 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-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | wasm32-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # 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-pc + 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 + ;; + abacus) + basic_machine=abacus-unknown + ;; + 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 + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + 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 + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + 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 + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + 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 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2*) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + 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 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + 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 + ;; + 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 + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + 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 + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + 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 + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + 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 + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-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-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + 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) + 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 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + 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 + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + 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 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + 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 + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + 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 + ;; + x64) + basic_machine=x86_64-pc + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + 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 + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + 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 + ;; + *-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. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now 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* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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 + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -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 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4*) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; + -nacl*) + ;; + -ios) + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # 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 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + 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 + ;; + pru-*) + os=-elf + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-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 + ;; + *-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 + ;; + -cnk*|-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 + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + 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 + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/debuginfod.service b/config/debuginfod.service new file mode 100644 index 00000000..b64d8cb9 --- /dev/null +++ b/config/debuginfod.service @@ -0,0 +1,17 @@ +[Unit] +Description=elfutils debuginfo-over-http server +Documentation=http://elfutils.org/ +After=network.target + +[Service] +EnvironmentFile=/etc/sysconfig/debuginfod +User=debuginfod +Group=debuginfod +#CacheDirectory=debuginfod +ExecStart=/usr/bin/debuginfod -d /var/cache/debuginfod/debuginfod.sqlite -p $DEBUGINFOD_PORT $DEBUGINFOD_VERBOSE $DEBUGINFOD_PRAGMAS $DEBUGINFOD_PATHS +# Stopping can take a long time if scanning of large archives is in progress +TimeoutStopSec=60 +PrivateTmp=yes + +[Install] +WantedBy=multi-user.target diff --git a/config/debuginfod.sysconfig b/config/debuginfod.sysconfig new file mode 100644 index 00000000..44603874 --- /dev/null +++ b/config/debuginfod.sysconfig @@ -0,0 +1,14 @@ +# +DEBUGINFOD_PORT="8002" +#DEBUGINFOD_VERBOSE="-v" + +# some common places to find trustworthy ELF/DWARF files and RPMs +DEBUGINFOD_PATHS="-t43200 -F -R /usr/lib/debug /usr/bin /usr/libexec /usr/sbin /usr/lib /usr/lib64 /var/cache/yum /var/cache/dnf /var/lib/pulp" + +# prefer reliability/durability over performance +#DEBUGINFOD_PRAGMAS="-D 'pragma synchronous=full;'" + +# upstream debuginfods +#DEBUGINFOD_URLS="http://secondhost:8002 http://thirdhost:8002" +#DEBUGINFOD_TIMEOUT="5" +#DEBUGINFOD_CACHE_DIR="" diff --git a/config/depcomp b/config/depcomp new file mode 100755 index 00000000..6b391623 --- /dev/null +++ b/config/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. + +# 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, 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, see . + +# 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 Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in new file mode 100644 index 00000000..5552352b --- /dev/null +++ b/config/elfutils.spec.in @@ -0,0 +1,1209 @@ +# -*- rpm-spec-*- +Name: elfutils +Version: @PACKAGE_VERSION@ +Release: 1 +URL: http://elfutils.org/ +License: GPLv3+ and (GPLv2+ or LGPLv3+) and GFDL +Source: ftp://sourceware.org/pub/elfutils/%{version}/elfutils-%{version}.tar.bz2 +Summary: A collection of utilities and DSOs to handle ELF files and DWARF data + +Requires: elfutils-libelf = %{version}-%{release} +Requires: elfutils-libs = %{version}-%{release} +# Can be a Recommends if rpm supports that +Requires: elfutils-debuginfod-client = %{version}-%{release} + +BuildRequires: gcc +# For libstdc++ demangle support +BuildRequires: gcc-c++ + +BuildRequires: gettext +BuildRequires: bison +BuildRequires: flex + +# Compression support +BuildRequires: zlib-devel +BuildRequires: bzip2-devel +BuildRequires: xz-devel +BuildRequires: libzstd-devel + +# For debuginfod +BuildRequires: pkgconfig(libmicrohttpd) >= 0.9.33 +BuildRequires: pkgconfig(libcurl) >= 7.29.0 +BuildRequires: pkgconfig(sqlite3) >= 3.7.17 +BuildRequires: pkgconfig(libarchive) >= 3.1.2 + +# For tests need to bunzip2 test files. +BuildRequires: bzip2 +BuildRequires: zstd +# For the run-debuginfod-find.sh test case in %%check for /usr/sbin/ss etc. +BuildRequires: iproute +BuildRequires: procps +BuildRequires: bsdtar +BuildRequires: curl + +%define _gnu %{nil} +%define _programprefix eu- + +%description +Elfutils is a collection of utilities, including stack (to show +backtraces), nm (for listing symbols from object files), size +(for listing the section sizes of an object or archive file), +strip (for discarding symbols), readelf (to see the raw ELF file +structures), elflint (to check for well-formed ELF files) and +elfcompress (to compress or decompress ELF sections). + +%package libs +Summary: Libraries to handle compiled objects +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libelf = %{version}-%{release} +Requires: default-yama-scope +# Can be a Recommends if rpm supports that +Requires: elfutils-debuginfod-client = %{version}-%{release} + +%description libs +The elfutils-libs package contains libraries which implement DWARF, ELF, +and machine-specific ELF handling and process introspection. These +libraries are used by the programs in the elfutils package. The +elfutils-devel package enables building other programs using these +libraries. + +%package devel +Summary: Development libraries to handle compiled objects +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libs = %{version}-%{release} +Requires: elfutils-libelf-devel = %{version}-%{release} +# Can be a Recommends if rpm supports that +Requires: elfutils-debuginfod-client-devel = %{version}-%{release} + +%description devel +The elfutils-devel package contains the libraries to create +applications for handling compiled objects. libdw provides access +to the DWARF debugging information. libasm provides a programmable +assembler interface. + +%package devel-static +Summary: Static archives to handle compiled objects +License: GPLv2+ or LGPLv3+ +Requires: elfutils-devel = %{version}-%{release} +Requires: elfutils-libelf-devel-static = %{version}-%{release} + +%description devel-static +The elfutils-devel-static package contains the static archives +with the code to handle compiled objects. + +%package libelf +Summary: Library to read and write ELF files +License: GPLv2+ or LGPLv3+ + +%description libelf +The elfutils-libelf package provides a DSO which allows reading and +writing ELF files on a high level. Third party programs depend on +this package to read internals of ELF files. The programs of the +elfutils package use it also to generate new ELF files. + +%package libelf-devel +Summary: Development support for libelf +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libelf = %{version}-%{release} +Conflicts: libelf-devel + +%description libelf-devel +The elfutils-libelf-devel package contains the libraries to create +applications for handling compiled objects. libelf allows you to +access the internals of the ELF object file format, so you can see the +different sections of an ELF file. + +%package libelf-devel-static +Summary: Static archive of libelf +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libelf-devel = %{version}-%{release} +Conflicts: libelf-devel + +%description libelf-devel-static +The elfutils-libelf-static package contains the static archive +for libelf. + +%package default-yama-scope +Summary: Default yama attach scope sysctl setting +License: GPLv2+ or LGPLv3+ +Provides: default-yama-scope +BuildArch: noarch + +%description default-yama-scope +Yama sysctl setting to enable default attach scope settings +enabling programs to use ptrace attach, access to +/proc/PID/{mem,personality,stack,syscall}, and the syscalls +process_vm_readv and process_vm_writev which are used for +interprocess services, communication and introspection +(like synchronisation, signaling, debugging, tracing and +profiling) of processes. + +%package debuginfod-client +Summary: Library and command line client for build-id HTTP ELF/DWARF server +License: GPLv3+ and (GPLv2+ or LGPLv3+) + +%package debuginfod-client-devel +Summary: Libraries and headers to build debuginfod client applications +License: GPLv2+ or LGPLv3+ +Requires: elfutils-debuginfod-client = %{version}-%{release} + +%package debuginfod +Summary: HTTP ELF/DWARF file server addressed by build-id +License: GPLv3+ +Requires: elfutils-libs = %{version}-%{release} +Requires: elfutils-libelf = %{version}-%{release} +Requires: elfutils-debuginfod-client = %{version}-%{release} +BuildRequires: systemd +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires(pre): shadow-utils +# To extract .deb files with a bsdtar (= libarchive) subshell +Requires: bsdtar + +%description debuginfod-client +The elfutils-debuginfod-client package contains shared libraries +dynamically loaded from -ldw, which use a debuginfod service +to look up debuginfo and associated data. Also includes a +command-line frontend. + +%description debuginfod-client-devel +The elfutils-debuginfod-client-devel package contains the libraries +to create applications to use the debuginfod service. + +%description debuginfod +The elfutils-debuginfod package contains the debuginfod binary +and control files for a service that can provide ELF/DWARF +files to remote clients, based on build-id identification. +The ELF/DWARF file searching functions in libdwfl can query +such servers to download those files on demand. + +%prep +%setup -q + +%build +%configure --program-prefix=%{_programprefix} --enable-debuginfod --enable-debuginfod-urls +make -s %{?_smp_mflags} + +%install +rm -rf ${RPM_BUILD_ROOT} +mkdir -p ${RPM_BUILD_ROOT}%{_prefix} + +%make_install + +chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/lib*.so* +mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod +touch ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod/debuginfod.sqlite + +# XXX Nuke unpackaged files +( cd ${RPM_BUILD_ROOT} + rm -f .%{_includedir}/elfutils/libasm.h + rm -f .%{_libdir}/libasm.so + rm -f .%{_libdir}/libasm.a +) + +install -Dm0644 config/10-default-yama-scope.conf ${RPM_BUILD_ROOT}%{_sysctldir}/10-default-yama-scope.conf + +install -Dm0644 config/debuginfod.service ${RPM_BUILD_ROOT}%{_unitdir}/debuginfod.service +install -Dm0644 config/debuginfod.sysconfig ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/debuginfod +mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod +touch ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod/debuginfod.sqlite + +%check +make -s %{?_smp_mflags} check + +%post libs -p /sbin/ldconfig +%postun libs -p /sbin/ldconfig +%post libelf -p /sbin/ldconfig +%postun libelf -p /sbin/ldconfig +%post debuginfod-client -p /sbin/ldconfig +%postun debuginfod-client -p /sbin/ldconfig + +%post default-yama-scope +# Due to circular dependencies might not be installed yet, so double check. +# (systemd -> elfutils-libs -> default-yama-scope -> systemd) +if [ -x /usr/lib/systemd/systemd-sysctl ] ; then +%sysctl_apply 10-default-yama-scope.conf +fi + +%files +%license COPYING COPYING-GPLV2 COPYING-LGPLV3 doc/COPYING-GFDL +%doc README TODO CONTRIBUTING +%{_bindir}/eu-addr2line +%{_bindir}/eu-ar +%{_bindir}/eu-elfclassify +%{_bindir}/eu-elfcmp +%{_bindir}/eu-elfcompress +%{_bindir}/eu-elflint +%{_bindir}/eu-findtextrel +%{_bindir}/eu-make-debug-archive +%{_bindir}/eu-nm +%{_bindir}/eu-objdump +%{_bindir}/eu-ranlib +%{_bindir}/eu-readelf +%{_bindir}/eu-size +%{_bindir}/eu-stack +%{_bindir}/eu-strings +%{_bindir}/eu-strip +%{_bindir}/eu-unstrip +%{_mandir}/man1/eu-*.1* + +%files libs +%license COPYING-GPLV2 COPYING-LGPLV3 +%{_libdir}/libasm-%{version}.so +%{_libdir}/libdw-%{version}.so +%{_libdir}/libasm.so.* +%{_libdir}/libdw.so.* + +%files devel +%{_includedir}/dwarf.h +%dir %{_includedir}/elfutils +%{_includedir}/elfutils/elf-knowledge.h +%{_includedir}/elfutils/known-dwarf.h +#%{_includedir}/elfutils/libasm.h +%{_includedir}/elfutils/libdw.h +%{_includedir}/elfutils/libdwfl.h +%{_includedir}/elfutils/libdwelf.h +%{_includedir}/elfutils/version.h +#%{_libdir}/libasm.so +%{_libdir}/libdw.so +%{_libdir}/pkgconfig/libdw.pc + +%files devel-static +%{_libdir}/libdw.a +#%{_libdir}/libasm.a + +%files libelf +%license COPYING-GPLV2 COPYING-LGPLV3 +%{_libdir}/libelf-%{version}.so +%{_libdir}/libelf.so.* +%{_datadir}/locale/*/LC_MESSAGES/elfutils.mo + +%files libelf-devel +%{_includedir}/libelf.h +%{_includedir}/gelf.h +%{_includedir}/nlist.h +%{_libdir}/libelf.so +%{_libdir}/pkgconfig/libelf.pc +%{_mandir}/man3/elf_*.3* + +%files libelf-devel-static +%{_libdir}/libelf.a + +%files default-yama-scope +%{_sysctldir}/10-default-yama-scope.conf + +%files debuginfod-client +%defattr(-,root,root) +%{_libdir}/libdebuginfod-%{version}.so +%{_libdir}/libdebuginfod.so.* +%{_bindir}/debuginfod-find +%{_mandir}/man1/debuginfod-find.1* +%config(noreplace) %{_sysconfdir}/profile.d/* + +%files debuginfod-client-devel +%defattr(-,root,root) +%{_libdir}/pkgconfig/libdebuginfod.pc +%{_mandir}/man3/debuginfod_*.3* +%{_includedir}/elfutils/debuginfod.h +%{_libdir}/libdebuginfod.so + +%files debuginfod +%defattr(-,root,root) +%{_bindir}/debuginfod +%config(noreplace) %{_sysconfdir}/sysconfig/debuginfod +%{_unitdir}/debuginfod.service +%{_sysconfdir}/sysconfig/debuginfod +%{_mandir}/man8/debuginfod.8* + +%dir %attr(0700,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod +%ghost %attr(0600,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod/debuginfod.sqlite + +%pre debuginfod +getent group debuginfod >/dev/null || groupadd -r debuginfod +getent passwd debuginfod >/dev/null || \ + useradd -r -g debuginfod -d /var/cache/debuginfod -s /sbin/nologin \ + -c "elfutils debuginfo server" debuginfod +exit 0 + +%post debuginfod +%systemd_post debuginfod.service + +%postun debuginfod +%systemd_postun_with_restart debuginfod.service + +%changelog +* Sat May 22 2021 Mark Wielaard 0.185-1 +- debuginfod-client: Simplify curl handle reuse so downloads which + return an error are retried. +- elfcompress: Always exit with code 0 when the operation succeeds + (even when nothing was done). On error the exit code is + now always 1. + +* Mon May 10 2021 Mark Wielaard 0.184-1 +- debuginfod: Use libarchive's bsdtar as the .deb-family file unpacker. +- debuginfod-client: Client caches negative results. If a query for a + file failed with 404, an empty 000 permission + file is created in the cache. This will prevent + requesting the same file for the next 10 minutes. +- Client objects now carry long-lived curl handles + for outgoing connections. This makes it more + efficient for multiple sequential queries, because + the TCP connections and/or TLS state info are kept + around awhile, avoiding O(100ms) setup latencies. +- libdw: handle DW_FORM_indirect when reading attributes +- translations: Update Polish translation. + +* Fri Feb 5 2021 Mark Wielaard 0.183-1 +- debuginfod: New thread-busy metric and more detailed error metrics. + New --fdcache-mintmp and tracking of filesystem freespace. +- debigonfod-client: DEBUGINFOD_SONAME macro added to debuginfod.h can + be used to dlopen the libdebuginfod.so library. + New function debuginfod_set_verbose_fd and DEBUGINFOD_VERBOSE + environment variable. +- config: profile.sh and profile.csh won't export DEBUGINFOD_URLS + unless configured --enable-debuginfod-urls[=URLS] +- elflint, readelf: Recognize SHF_GNU_RETAIN. + Handle SHT_X86_64_UNWIND as valid relocation target type. + +* Sat Oct 31 2020 Mark Wielaard 0.182-1 +- backends: Support for tilegx has been removed. +- config: New /etc/profile.d files to provide default $DEBUGINFOD_URLS. +- debuginfod: More efficient package traversal, tolerate various + errors during scanning, grooming progress is more visible and + interruptible, more prometheus metrics. +- debuginfod-client: Now supports compressed (kernel) ELF images. +- libdwfl: Add ZSTD compression support. + +* Tue Sep 8 2020 Mark Wielaard 0.181-1 +- libelf: elf_update now compensates (fixes up) a bad sh_addralign + for SHF_COMPRESSED sections. +- libdebuginfod: configure now takes --enable-libdebuginfod=dummy or + --disable-libdebuginfod for bootstrapping. + DEBUGINFOD_URLS now accepts "scheme-free" urls + (guessing at what the user meant, either http:// or file://) +- readelf, elflint: Handle aarch64 bti, pac bits in dynamic table and + gnu property notes. +- libdw, readelf: Recognize DW_CFA_AARCH64_negate_ra_state. Allows + unwinding on arm64 for code that is compiled for PAC + (Pointer Authentication Code) as long as it isn't enabled. + +* Thu Jun 11 2020 Mark Wielaard 0.180-1 +- elflint: Allow SHF_EXCLUDE as generic section flag when --gnu is given. +- libdw, readelf: Handle GCC LTO .gnu.debuglto_ prefix. +- libdw: Use correct CU to resolve file names in dwarf_decl_file. +- libdwfl: Handle debugaltlink in dwfl_standard_find_debuginfo. +- size: Also obey radix printing for bsd format. +- nm: Explicitly print weak 'V' or 'T' and common 'C' symbols. + +* Mon Mar 30 2020 Mark Wielaard 0.179-1 +- debuginfod-client: When DEBUGINFOD_PROGRESS is set and the program + doesn't install its own debuginfod_progressfn_t show download + progress on stderr. + DEBUGINFOD_TIMEOUT is now defined as seconds to get at least 100K, + defaults to 90 seconds. + Default to $XDG_CACHE_HOME/debuginfod_client. + New functions debuginfod_set_user_data, debuginfod_get_user_data, + debuginfod_get_url and debuginfod_add_http_header. + Support for file:// URLs. +- debuginfod: Uses libarchive directly for reading rpm archives. + Support for indexing .deb/.ddeb archives through dpkg-deb or bsdtar. + Generic archive support through -Z EXT[=CMD]. Which can be used for + example for arch-linux pacman files by using -Z '.tar.zst=zstdcat'. + Better logging using User-Agent and X-Forwarded-For headers. + More prometheus metrics. + Support for eliding dots or extraneous slashes in path names. +- debuginfod-find: Accept /path/names in place of buildid hex. +- libelf: Handle PN_XNUM in elf_getphdrnum before shdr 0 is cached. + Ensure zlib resource cleanup on failure. +- libdwfl: dwfl_linux_kernel_find_elf and dwfl_linux_kernel_report_offline + now find and handle a compressed vmlinuz image. +- readelf, elflint: Handle PT_GNU_PROPERTY. +- translations: Updated Ukrainian translation. + +* Tue Nov 26 2019 Mark Wielaard 0.178-1 +- debuginfod: New server, client tool and library to index and fetch + ELF/DWARF files addressed by build-id through HTTP. +- doc: There are now some manual pages for functions and tools. +- backends: The libebl libraries are no longer dynamically loaded + through dlopen, but are now compiled into libdw.so directly. +- readelf: -n, --notes now takes an optional "SECTION" argument. + -p and -x now also handle section numbers. + New option --dyn-sym to show just the dynamic symbol table. +- libcpu: Add RISC-V disassembler. +- libdw: Abbrevs and DIEs can now be read concurrently by multiple + threads through the same Dwarf handle. +- libdwfl: Will try to use debuginfod when installed as fallback to + retrieve ELF and DWARF debug data files by build-id. + +* Tue Aug 13 2019 Mark Wielaard 0.177-1 +- elfclassify: New tool to analyze ELF objects. +- readelf: Print DW_AT_data_member_location as decimal offset. + Decode DW_AT_discr_list block attributes. +- libdw: Add DW_AT_GNU_numerator, DW_AT_GNU_denominator and DW_AT_GNU_bias. +- libdwelf: Add dwelf_elf_e_machine_string. + dwelf_elf_begin now only returns NULL when there is an error + reading or decompressing a file. If the file is not an ELF file + an ELF handle of type ELF_K_NONE is returned. +- backends: Add support for C-SKY. + +* Thu Feb 14 2019 Mark Wielaard 0.176-1 +- build: Add new --enable-install-elfh option. + Do NOT use this for system installs (it overrides glibc elf.h). +- backends: riscv improved core file and return value location support. +- Fixes CVE-2019-7146, CVE-2019-7148, CVE-2019-7149, CVE-2019-7150, + CVE-2019-7664, CVE-2019-7665. + +* Wed Nov 14 2018 Mark Wielaard 0.175-1 +- readelf: Handle multiple .debug_macro sections. + Recognize and parse GNU Property notes, NT_VERSION notes and + GNU Build Attribute ELF Notes. +- strip: Handle SHT_GROUP correctly. + Add strip --reloc-debug-sections-only option. + Handle relocations against GNU compressed sections. +- libdwelf: New function dwelf_elf_begin. +- libcpu: Recognize bpf jump variants BPF_JLT, BPF_JLE, BPF_JSLT + and BPF_JSLE. +- backends: RISCV handles ADD/SUB relocations. + Handle SHT_X86_64_UNWIND. +- Fixes CVE-2018-18310, CVE-2018-18520 and CVE-2018-18521. + +* Fri Sep 14 2018 Mark Wielaard 0.174-1 +- libelf, libdw and all tools now handle extended shnum and shstrndx + correctly. +- elfcompress: Don't rewrite input file if no section data needs + updating. Try harder to keep same file mode bits (suid) on rewrite. +- strip: Handle mixed (out of order) allocated/non-allocated sections. +- unstrip: Handle SHT_GROUP sections. +- backends: RISCV and M68K now have backend implementations to + generate CFI based backtraces. +- Fixes CVE-2018-16062, CVE-2018-16402 and CVE-2018-16403. + +* Fri Jun 29 2018 Mark Wielaard,,, 0.173-1 +- More fixes for crashes and hangs found by afl-fuzz. In particular + various functions now detect and break infinite loops caused by bad + DIE tree cycles. +- readelf: Will now lookup the size and signedness of constant value + types to display them correctly (and not just how they were encoded). +- libdw: New function dwarf_next_lines to read CU-less .debug_line data. + dwarf_begin_elf now accepts ELF files containing just .debug_line + or .debug_frame sections (which can be read without needing a DIE + tree from the .debug_info section). + Removed dwarf_getscn_info, which was never implemented. +- backends: Handle BPF simple relocations. + The RISCV backends now handles ABI specific CFI and knows about + RISCV register types and names. + +* Mon Jun 11 2018 Mark Wielaard 0.172-1 +- No functional changes compared to 0.171. +- Various bug fixes in libdw and eu-readelf dealing with bad DWARF5 + data. Thanks to running the afl fuzzer on eu-readelf and various + testcases. +- eu-readelf -N is ~15% faster. + +* Fri Jun 01 2018 Mark Wielaard 0.171-1 +- DWARF5 and split dwarf, including GNU DebugFission, support. +- readelf: Handle all new DWARF5 sections. + --debug-dump=info+ will show split unit DIEs when found. + --dwarf-skeleton can be used when inspecting a .dwo file. + Recognizes GNU locviews with --debug-dump=loc. +- libdw: New functions dwarf_die_addr_die, dwarf_get_units, + dwarf_getabbrevattr_data and dwarf_cu_info. + libdw will now try to resolve the alt file on first use + when not set yet with dwarf_set_alt. + dwarf_aggregate_size() now works with multi-dimensional arrays. +- libdwfl: Use process_vm_readv when available instead of ptrace. +- backends: Add a RISC-V backend. + +* Wed Aug 2 2017 Mark Wielaard 0.170-1 +- libdw: Added new DWARF5 attribute, tag, character encoding, + language code, calling convention, defaulted member function + and macro constants to dwarf.h. + New functions dwarf_default_lower_bound and dwarf_line_file. + dwarf_peel_type now handles DWARF5 immutable, packed and shared tags. + dwarf_getmacros now handles DWARF5 .debug_macro sections. +- strip: Add -R, --remove-section=SECTION and --keep-section=SECTION. +- backends: The bpf disassembler is now always build on all platforms. + +* Fri May 5 2017 Mark Wielaard 0.169-1 +- backends: Add support for EM_PPC64 GNU_ATTRIBUTES. + Frame pointer unwinding fallback support for i386, x86_64, aarch64. +- translations: Update Polish translation. + +* Tue Dec 27 2016 Mark Wielaard 0.168-1 +- http://elfutils.org/ is now hosted at http://sourceware.org/elfutils/ +- libelf: gelf_newehdr and gelf_newehdr now return void *. +- libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1). +- readelf: Add optional --symbols[=SECTION] argument to select section name. + +* Thu Aug 4 2016 Mark Wielaard 0.167-1 +- libasm: Add eBPF disassembler for EM_BPF files. +- backends: Add m68k and BPF backends. +- ld: Removed. +- dwelf: Add ELF/DWARF string table creation functions. + dwelf_strtab_init, dwelf_strtab_add, dwelf_strtab_add_len, + dwelf_strtab_finalize, dwelf_strent_off, dwelf_strent_str and + dwelf_strtab_free. + +* Thu Mar 31 2016 Mark Wielaard 0.166-1 +- config: The default program prefix for the installed tools is now + eu-. Use configure --program-prefix="" to not use a program prefix. + +* Fri Jan 8 2016 Mark Wielaard 0.165-1 +- elfcompress: New utility to compress or decompress ELF sections. +- readelf: Add -z,--decompress option. +- libelf: Add elf_compress, elf_compress_gnu, elf32_getchdr, + elf64_getchdr and gelf_getchdr. +- libdwelf: New function dwelf_scn_gnu_compressed_size. +- config: Add libelf and libdw pkg-config files. +- backends: sparc support for core and live backtraces. +- translations: Updated Polish translation. + +* Thu Oct 15 2015 Mark Wielaard 0.164-1 +- strip, unstrip: Handle ELF files with merged strtab/shstrtab + tables. Handle missing SHF_INFO_LINK section flags. +- libelf: Use int64_t for offsets in libelf.h instead of loff_t. +- libdw: dwarf.h Add preliminary DWARF5 DW_LANG_Haskell. +- libdwfl: dwfl_standard_find_debuginfo now searches any subdir of + the binary path under the debuginfo root when the separate + debug file couldn't be found by build-id. + dwfl_linux_proc_attach can now be called before any Dwfl_Modules + have been reported. +- backends: Better sparc and sparc64 support. +- translations: Updated Ukrainian translation. +- Provide default-yama-scope subpackage. + +* Fri Jun 19 2015 Mark Wielaard 0.163-1 +- Bug fixes only, no new features. + +* Wed Jun 10 2015 Mark Wielaard 0.162-1 +- libdw: Install new header elfutils/known-dwarf.h. + dwarf.h Add preliminary DWARF5 constants DW_TAG_atomic_type, + DW_LANG_Fortran03, DW_LANG_Fortran08. dwarf_peel_type now also + handles DW_TAG_atomic_type. +- addr2line: Input addresses are now always interpreted as + hexadecimal numbers, never as octal or decimal numbers. + New option -a, --addresses to print address before each entry. + New option -C, --demangle to show demangled symbols. + New option --pretty-print to print all information on one line. +- ar: CVE-2014-9447 Directory traversal vulnerability in ar + extraction. +- backends: x32 support. + +* Thu Dec 18 2014 Mark Wielaard 0.161-1 +- libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses + dwarf_peel_type to also provide the sizes of qualified types. + dwarf_getmacros will now serve either of .debug_macro and + .debug_macinfo transparently. New interfaces dwarf_getmacros_off, + dwarf_macro_getsrcfiles, dwarf_macro_getparamcnt, and + dwarf_macro_param are available for more generalized inspection of + macros and their parameters. + dwarf.h: Add DW_AT_GNU_deleted, DW_AT_noreturn, DW_LANG_C11, + DW_LANG_C_plus_plus_11 and DW_LANG_C_plus_plus_14. + +* Mon Aug 25 2014 Mark Wielaard 0.160-1 +- libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die. + dwarf.h remove non-existing DW_TAG_mutable_type. +- libdwfl: Handle LZMA .ko.xz compressed kernel modules. +- unstrip: New option -F, --force to combining files even if some ELF + headers don't seem to match. +- backends: Handle ARM THUMB functions. Add support for ppc64le ELFv2 abi. + +* Sat May 17 2014 Mark Wielaard 0.159-1 +- stack: New option -d, --debugname to lookup DWARF debuginfo name + for frame. New option -i, --inlines to show inlined frames + using DWARF debuginfo. +- libdwelf: New libdwelf.h header for libdw.so DWARF ELF Low-level + Functions. New function dwelf_elf_gnu_debuglink, + dwelf_dwarf_gnu_debugaltlink, and dwelf_elf_gnu_build_id. +- libdw: Support for DWZ multifile forms DW_FORM_GNU_ref_alt and + DW_FORM_GNU_strp_alt is now enabled by default and no longer + experimental. Added new functions dwarf_getalt and dwarf_setalt + to get or set the alternative debug file used for the alt FORMs. + The dwfl_linux_proc_find_elf callback will now find ELF from + process memory for (deleted) files if the Dwfl has process state + attached. +- libdwfl: The dwfl_build_id_find_debuginfo and + dwfl_standard_find_debuginfo functions will now try to + resolve and set the alternative debug file. +- backends: Add CFI unwinding for arm. Relies on .debug_frame. + Add arm process initial register state compatible mode to AARCH64. + Add aarch64 native and core unwind support. +- other: All separate elfutils-robustify patches have been merged. + CVE-2014-0172 Check overflow before calling malloc to uncompress + data. + +* Fri Jan 3 2014 Mark Wielaard 0.158-1 +- libdwfl: dwfl_core_file_report has new parameter executable. + New functions dwfl_module_getsymtab_first_global, + dwfl_module_getsym_info and dwfl_module_addrinfo. + Added unwinder with type Dwfl_Thread_Callbacks, opaque types + Dwfl_Thread and Dwfl_Frame and functions dwfl_attach_state, + dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread, + dwfl_thread_state_registers, dwfl_thread_state_register_pc, + dwfl_getthread_frames, dwfl_getthreads, dwfl_thread_getframes + and dwfl_frame_pc. +- addr2line: New option -x to show the section an address was found in. +- stack: New utility that uses the new unwinder for processes and cores. +- backends: Unwinder support for i386, x86_64, s390, s390x, ppc and ppc64. + aarch64 support. + +* Mon Sep 30 2013 Mark Wielaard 0.157-1 +- libdw: Add new functions dwarf_getlocations, dwarf_getlocation_attr + and dwarf_getlocation_die. +- readelf: Show contents of NT_SIGINFO and NT_FILE core notes. +- addr2line: Support -i, --inlines output option. +- backends: abi_cfi hook for arm, ppc and s390. + +* Thu Jul 25 2013 Jan Kratochvil 0.156-1 +- lib: New macro COMPAT_VERSION_NEWPROTO. +- libdw: Handle GNU extension opcodes in dwarf_getlocation. +- libdwfl: Fix STB_GLOBAL over STB_WEAK preference in + dwfl_module_addrsym. Add minisymtab support. Add + parameter add_p_vaddr to dwfl_report_elf. Use DT_DEBUG + library search first. +- libebl: Handle new core note types in EBL. +- backends: Interpret NT_ARM_VFP. Implement core file + registers parsing for s390/s390x. +- readelf: Add --elf-section input option to inspect an embedded ELF + file. Add -U, --unresolved-address-offsets output control. + Add --debug-dump=decodedline support. Accept version + 8 .gdb_index section format. Adjust output formatting width. + When highpc is in constant form print it also as address. + Display raw .debug_aranges. Use libdw only for decodedaranges. +- elflint: Add __bss_start__ to the list of allowed symbols. +- tests: Add configure --enable-valgrind option to run all tests + under valgrind. Enable automake parallel-tests for make check. +- translations: Updated Polish translation. +- Updates for Automake 1.13. + +* Fri Aug 24 2012 Mark Wielaard 0.155-1 +- libelf: elf*_xlatetomd now works for cross-endian ELF note data. + elf_getshdr now works consistently on non-mmaped ELF files after + calling elf_cntl(ELF_C_FDREAD). Implement support for + ar archives with 64-bit symbol table. +- libdw: dwarf.h corrected the DW_LANG_ObjC constant name (was + DW_LANG_Objc). Any existing sources using the old name will + have to be updated. Add DW_MACRO_GNU .debug_macro type + encodings constants, DW_ATE_UTF and DW_OP_GNU_parameter_ref to + dwarf.h. Experimental support for DWZ multifile forms + DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. Disabled by + default. Use configure --enable-dwz to test it. +- readelf: Add .debug_macro parsing support. Add .gdb_index + version 7 parsing support. Recognize DW_OP_GNU_parameter_ref. +- backends: Add support for Tilera TILE-Gx processor. +- translations: Updated Ukrainian translation. + +* Fri Jun 22 2012 Mark Wielaard 0.154-1 +- libelf: [g]elf[32|64]_offscn() do not match SHT_NOBITS sections at + OFFSET. +- libdw: dwarf_highpc function now handles DWARF 4 DW_AT_high_pc + constant form. Fix bug using dwarf_next_unit to iterate over + .debug_types. +- elflint: Now accepts gold linker produced executables. +- The license is now GPLv2/LGPLv3+ for the libraries and GPLv3+ for + stand-alone programs. There is now also a formal CONTRIBUTING + document describing how to submit patches. + +* Thu Feb 23 2012 Mark Wielaard 0.153-1 +- libdw: Support reading .zdebug_* DWARF sections compressed via zlib. +- libdwfl: Speed up dwfl_module_addrsym. +- nm: Support C++ demangling. +- ar: Support D modifier for "deterministic output" with no + uid/gid/mtime info. The U modifier is the inverse. elfutils + can be configured with the --enable-deterministic-archives option + to make the D behavior the default when U is not specified. +- ranlib: Support -D and -U flags with same meaning. +- readelf: Improve output of -wline. Add support for printing SDT elf + notes. Add printing of .gdb_index section. Support for + typed DWARF stack, call_site and entry_value. +- strip: Add --reloc-debug-sections option. Improved SHT_GROUP + sections handling. + +* Tue Feb 15 2011 0.152-1 +- Various build and warning nits fixed for newest GCC and Autoconf. +- libdwfl: Yet another prelink-related fix for another regression. + Look for Linux kernel images in files named with compression + suffixes. +- elfcmp: New flag --ignore-build-id to ignore differing build ID + bits. New flag -l/--verbose to print all differences. + +* Wed Jan 12 2011 0.151-1 +- libdwfl: Fix for more prelink cases with separate debug file. +- strip: New flag --strip-sections to remove section headers entirely. + +* Mon Nov 22 2010 0.150-1 +- libdw: Fix for handling huge .debug_aranges section. +- libdwfl: Fix for handling prelinked DSO with separate debug file. +- findtextrel: Fix diagnostics to work with usual section ordering. +- libebl: i386 backend fix for multi-register integer return value + location. + +* Mon Sep 13 2010 0.149-1 +- libdw: Decode new DW_OP_GNU_implicit_pointer operation; new + function dwarf_getlocation_implicit_pointer. +- libdwfl: New function dwfl_dwarf_line. +- addr2line: New flag -F/--flags to print more DWARF line information + details. +- strip: -g recognizes .gdb_index as a debugging section. + +* Mon Jun 28 2010 0.148-1 +- libdw: Accept DWARF 4 format: new functions dwarf_next_unit, + dwarf_offdie_types. New functions dwarf_lineisa, + dwarf_linediscriminator, dwarf_lineop_index. +- libdwfl: Fixes in core-file handling, support cores from PIEs. + When working from build IDs, don't open a named file that + mismatches. +- readelf: Handle DWARF 4 formats. + +* Mon May 3 2010 Ulrich Drepper 0.147-1 +- libdw: Fixes in CFI handling, best possible handling of bogus CFA + ops. +- libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r + bugs. + +* Wed Apr 21 2010 0.146-1 +- libdwfl: New function dwfl_core_file_report. + +* Tue Feb 23 2010 Ulrich Drepper 0.145-1 +- Fix build with --disable-dependency-tracking. +- Fix build with most recent glibc headers. +- libelf: More robust to bogus section headers. +- libdw: Fix CFI decoding. +- libdwfl: Fix address bias returned by CFI accessors. Fix core + file module layout identification. +- readelf: Fix CFI decoding. + +* Thu Jan 14 2010 0.144-1 +- libelf: New function elf_getphdrnum. Now support using more than + 65536 program headers in a file. +- libdw: New function dwarf_aggregate_size for computing (constant) + type sizes, including array_type cases with nontrivial + calculation. +- readelf: Don't give errors for missing info under -a. + Handle Linux "VMCOREINFO" notes under -n. + +* Mon Sep 21 2009 0.143-1 +- libdw: Various convenience functions for individual attributes now + use dwarf_attr_integrate to look up indirect inherited + attributes. Location expression handling now supports + DW_OP_implicit_value. +- libdwfl: Support automatic decompression of files in XZ format, + and of Linux kernel images made with bzip2 or LZMA (as well + as gzip). + +* Mon Jun 29 2009 0.142-1 +- libelf: Add elf_getshdrnum alias for elf_getshnum and elf_getshdrstrndx alias + for elf_getshstrndx and deprecate original names. Sun screwed up + their implementation and asked for a solution. +- libebl: Add support for STB_GNU_UNIQUE. +- elflint: Add support for STB_GNU_UNIQUE. +- readelf: Add -N option, speeds up DWARF printing without address->name lookups. +- libdw: Add support for decoding DWARF CFI into location description form. + Handle some new DWARF 3 expression operations previously omitted. + Basic handling of some new encodings slated for DWARF + +* Thu Apr 23 2009 Ulrich Drepper 0.141-1 +- libebl: sparc backend fixes; some more arm backend support +- libdwfl: fix dwfl_module_build_id for prelinked DSO case; + fixes in core file support; dwfl_module_getsym interface + improved for non-address symbols +- strip: fix infinite loop on strange inputs with -f +- addr2line: take -j/--section=NAME option for binutils compatibility + (same effect as '(NAME)0x123' syntax already supported) + +* Mon Feb 16 2009 Ulrich Drepper 0.140-1 +- libelf: Fix regression in creation of section header +- libdwfl: Less strict behavior if DWARF reader is just used to + display data + +* Thu Jan 22 2009 Ulrich Drepper 0.139-1 +- libcpu: Add Intel SSE4 disassembler support +- readelf: Implement call frame information and exception handling + dumping. Add -e option. Enable it implicitly for -a. +- elflint: Check PT_GNU_EH_FRAME program header entry. +- libdwfl: Support automatic gzip/bzip2 decompression of ELF files. + +* Wed Dec 31 2008 Roland McGrath 0.138-1 +- Install header file for applications to use in + source version compatibility checks. +- libebl: backend fixes for i386 TLS relocs; backend support for + NT_386_IOPERM +- libcpu: disassembler fixes +- libdwfl: bug fixes +- libelf: bug fixes +- nm: bug fixes for handling corrupt input files + +* Tue Aug 26 2008 Ulrich Drepper 0.137-1 +- Minor fixes for unreleased 0.136 release. + +* Mon Aug 25 2008 Ulrich Drepper 0.136-1 +- libdwfl: bug fixes; new segment interfaces; all the libdwfl-based + tools now support --core=COREFILE option + +* Mon May 12 2008 Ulrich Drepper 0.135-1 +- libdwfl: bug fixes +- strip: changed handling of ET_REL files wrt symbol tables and relocs + +* Tue Apr 8 2008 Ulrich Drepper 0.134-1 +- elflint: backend improvements for sparc, alpha +- libdwfl, libelf: bug fixes + +* Sat Mar 1 2008 Ulrich Drepper 0.133-1 +- readelf, elflint, libebl: SHT_GNU_ATTRIBUTE section handling (readelf -A) +- readelf: core note handling for NT_386_TLS, NT_PPC_SPE, Alpha NT_AUXV +- libdwfl: bug fixes and optimization in relocation handling +- elfcmp: bug fix for non-allocated section handling +- ld: implement newer features of binutils linker. + +* Mon Jan 21 2008 Ulrich Drepper 0.132-1 +- libcpu: Implement x86 and x86-64 disassembler. +- libasm: Add interface for disassembler. +- all programs: add debugging of branch prediction. +- libelf: new function elf_scnshndx. + +* Sun Nov 11 2007 Ulrich Drepper 0.131-1 +- libdw: DW_FORM_ref_addr support; dwarf_formref entry point now depreca +ted; bug fixes for oddly-formatted DWARF +- libdwfl: bug fixes in offline archive support, symbol table handling; + apply partial relocations for dwfl_module_address_section on +ET_REL +- libebl: powerpc backend support for Altivec registers + +* Mon Oct 15 2007 Ulrich Drepper 0.130-1 +- readelf: -p option can take an argument like -x for one section, + or no argument (as before) for all SHF_STRINGS sections; + new option --archive-index (or -c); improved -n output for +core files, on many machines +- libelf: new function elf_getdata_rawchunk, replaces gelf_rawchunk; + new functions gelf_getnote, gelf_getauxv, gelf_update_auxv +- readelf, elflint: handle SHT_NOTE sections without requiring phdrs +- elflint: stricter checks on debug sections +- libdwfl: new functions dwfl_build_id_find_elf, dwfl_build_id_find_debu +ginfo, dwfl_module_build_id, dwfl_module_report_build_id; suppo +rt dynamic symbol tables found via phdrs; dwfl_standard_find_de +buginfo now uses build IDs when available +- unstrip: new option --list (or -n) +- libebl: backend improvements for sparc, alpha, powerpc + +* Tue Aug 14 2007 Ulrich Drepper 0.129-1 +- readelf: new options --hex-dump (or -x), --strings (or -p) +- addr2line: new option --symbols (or -S) + +* Wed Apr 18 2007 Ulrich Drepper 0.127-1 +- libdw: new function dwarf_getsrcdirs +- libdwfl: new functions dwfl_module_addrsym, dwfl_report_begin_add, + dwfl_module_address_section + +* Mon Feb 5 2007 Ulrich Drepper 0.126-1 +- new program: ar + +* Mon Dec 18 2006 Ulrich Drepper 0.125-1 +- elflint: Compare DT_GNU_HASH tests. +- move archives into -static RPMs +- libelf, elflint: better support for core file handling + +* Tue Oct 10 2006 Ulrich Drepper 0.124-1 +- libebl: sparc backend support for return value location +- libebl, libdwfl: backend register name support extended with more info +- libelf, libdw: bug fixes for unaligned accesses on machines that care +- readelf, elflint: trivial bugs fixed + +* Mon Aug 14 2006 Roland McGrath 0.123-1 +- libebl: Backend build fixes, thanks to Stepan Kasal. +- libebl: ia64 backend support for register names, return value location +- libdwfl: Handle truncated linux kernel module section names. +- libdwfl: Look for linux kernel vmlinux files with .debug suffix. +- elflint: Fix checks to permit --hash-style=gnu format. + +* Wed Jul 12 2006 Ulrich Drepper 0.122-1 +- libebl: add function to test for relative relocation +- elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks +- elflint, readelf: add support for DT_GNU_HASHlibelf: add elf_gnu_hash +- elflint, readelf: add support for 64-bit SysV-style hash tables +- libdwfl: new functions dwfl_module_getsymtab, dwfl_module_getsym. + +* Wed Jun 14 2006 0.121-1 +- libelf: bug fixes for rewriting existing files when using mmap. +- make all installed headers usable in C++ code. +- readelf: better output format. +- elflint: fix tests of dynamic section content. +- ld: Implement --as-needed, --execstack, PT_GNU_STACK. Many small patc +hes. +- libdw, libdwfl: handle files without aranges info. + +* Tue Apr 4 2006 Ulrich Drepper 0.120-1 +- Bug fixes. +- dwarf.h updated for DWARF 3.0 final specification. +- libdwfl: New function dwfl_version. +- The license is now GPL for most files. The libelf, libebl, libdw,and +libdwfl libraries have additional exceptions. Add reference toOIN. + +* Thu Jan 12 2006 Roland McGrath 0.119-1 +- elflint: more tests. +- libdwfl: New function dwfl_module_register_names. +- libebl: New backend hook for register names. + +* Tue Dec 6 2005 Ulrich Drepper 0.118-1 +- elflint: more tests. +- libdwfl: New function dwfl_module_register_names. +- libebl: New backend hook for register names. + +* Thu Nov 17 2005 Ulrich Drepper 0.117-1 +- libdwfl: New function dwfl_module_return_value_location. +- libebl: Backend improvements for several CPUs. + +* Mon Oct 31 2005 Ulrich Drepper 0.116-1 +- libdw: New functions dwarf_ranges, dwarf_entrypc, dwarf_diecu, d +warf_entry_breakpoints. Removed Dwarf_Func type and functions d +warf_func_name, dwarf_func_lowpc, dwarf_func_highpc, dwarf_func_ +entrypc, dwarf_func_die; dwarf_getfuncs callback now uses Dwarf_ +Die, and dwarf_func_file, dwarf_func_line, dwarf_func_col replac +ed by dwarf_decl_file, dwarf_decl_line, dwarf_decl_column; dwarf +_func_inline, dwarf_func_inline_instances now take Dwarf_Die. Ty +pe Dwarf_Loc renamed to Dwarf_Op; dwarf_getloclist, dwarf_addrlo +clists renamed dwarf_getlocation, dwarf_getlocation_addr. + +* Fri Sep 2 2005 Ulrich Drepper 0.115-1 +- libelf: speed-ups of non-mmap reading. +- strings: New program. +- Implement --enable-gcov option for configure. +- libdw: New function dwarf_getscopes_die. + +* Wed Aug 24 2005 Ulrich Drepper 0.114-1 +- libelf: new function elf_getaroff +- libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_inst +ances. +- libdwfl: New functions dwfl_report_offline, dwfl_offline_section_addre +ss, dwfl_linux_kernel_report_offline. +- ranlib: new program + +* Mon Aug 15 2005 Ulrich Drepper 0.114-1 +- libelf: new function elf_getaroff +- ranlib: new program + +* Wed Aug 10 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. Allow .rodata +sectionto have STRINGS and MERGE flag set. +- strip: add some more compatibility with binutils. + +* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. Allow .rodata +sectionto have STRINGS and MERGE flag set. + +* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. + +* Fri Aug 5 2005 Ulrich Drepper <@redhat.com> 0.112-1 +- elfcmp: some more relaxation. +- elflint: many more tests, especially regarding to symbol versioning. +- libelf: Add elfXX_offscn and gelf_offscn. +- libasm: asm_begin interface changes. +- libebl: Add three new interfaces to directly access machine, class, an +ddata encoding information. +- objdump: New program. Just the beginning. + +* Thu Jul 28 2005 Ulrich Drepper <@redhat.com> 0.111-1 +- libdw: now contains all of libdwfl. The latter is not installed anymore. +- elfcmp: little usability tweak, name and index of differing section is + printed. + +* Sun Jul 24 2005 Ulrich Drepper <@redhat.com> 0.110-1 +- libelf: fix a numbe rof problems with elf_update +- elfcmp: fix a few bugs. Compare gaps. +- Fix a few PLT problems and mudflap build issues. +- libebl: Don't expose Ebl structure definition in libebl.h. It's now p +rivate. + +* Thu Jul 21 2005 Ulrich Drepper <@redhat.com> 0.109-1 +- libebl: Check for matching modules. +- elflint: Check that copy relocations only happen for OBJECT or NOTYPE +symbols. +- elfcmp: New program. +- libdwfl: New library. + +* Mon May 9 2005 Ulrich Drepper <@redhat.com> 0.108-1 +- strip: fix bug introduced in last change +- libdw: records returned by dwarf_getsrclines are now sorted by address + +* Sun May 8 2005 Ulrich Drepper <@redhat.com> 0.108-1 +- strip: fix bug introduced in last change + +* Sun May 8 2005 Ulrich Drepper <@redhat.com> 0.107-1 +- readelf: improve DWARF output format +- strip: support Linux kernel modules + +* Fri Apr 29 2005 Ulrich Drepper 0.107-1 +- readelf: improve DWARF output format + +* Mon Apr 4 2005 Ulrich Drepper 0.106-1 +- libdw: Updated dwarf.h from DWARF3 speclibdw: add new functions dwarf_f +unc_entrypc, dwarf_func_file, dwarf_func_line,dwarf_func_col, dwarf_ge +tsrc_file + +* Fri Apr 1 2005 Ulrich Drepper 0.105-1 +- addr2line: New program +- libdw: add new functions: dwarf_addrdie, dwarf_macro_*, dwarf_getfuncs +,dwarf_func_*. +- findtextrel: use dwarf_addrdie + +* Mon Mar 28 2005 Ulrich Drepper 0.104-1 +- findtextrel: New program. + +* Mon Mar 21 2005 Ulrich Drepper 0.103-1 +- libdw: Fix using libdw.h with gcc < 4 and C++ code. Compiler bug. + +* Tue Feb 22 2005 Ulrich Drepper 0.102-1 +- More Makefile and spec file cleanups. + +* Fri Jan 16 2004 Jakub Jelinek 0.94-1 +- upgrade to 0.94 + +* Fri Jan 16 2004 Jakub Jelinek 0.93-1 +- upgrade to 0.93 + +* Thu Jan 8 2004 Jakub Jelinek 0.92-1 +- full version +- macroized spec file for GPL or OSL builds +- include only libelf under GPL plus wrapper scripts + +* Wed Jan 7 2004 Jakub Jelinek 0.91-2 +- macroized spec file for GPL or OSL builds + +* Wed Jan 7 2004 Ulrich Drepper +- split elfutils-devel into two packages. + +* Wed Jan 7 2004 Jakub Jelinek 0.91-1 +- include only libelf under GPL plus wrapper scripts + +* Tue Dec 23 2003 Jeff Johnson 0.89-3 +- readelf, not readline, in %%description (#111214). + +* Fri Sep 26 2003 Bill Nottingham 0.89-1 +- update to 0.89 (fix eu-strip) + +* Tue Sep 23 2003 Jakub Jelinek 0.86-3 +- update to 0.86 (fix eu-strip on s390x/alpha) +- libebl is an archive now; remove references to DSO + +* Mon Jul 14 2003 Jeff Johnson 0.84-3 +- upgrade to 0.84 (readelf/elflint improvements, rawhide bugs fixed). + +* Fri Jul 11 2003 Jeff Johnson 0.83-3 +- upgrade to 0.83 (fix invalid ELf handle on *.so strip, more). + +* Wed Jul 9 2003 Jeff Johnson 0.82-3 +- upgrade to 0.82 (strip tests fixed on big-endian). + +* Tue Jul 8 2003 Jeff Johnson 0.81-3 +- upgrade to 0.81 (strip excludes unused symtable entries, test borked). + +* Thu Jun 26 2003 Jeff Johnson 0.80-3 +- upgrade to 0.80 (debugedit changes for kernel in progress). + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Wed May 21 2003 Jeff Johnson 0.79-2 +- upgrade to 0.79 (correct formats for size_t, more of libdw "works"). + +* Mon May 19 2003 Jeff Johnson 0.78-2 +- upgrade to 0.78 (libdwarf bugfix, libdw additions). + +* Mon Feb 24 2003 Elliot Lee +- debuginfo rebuild + +* Thu Feb 20 2003 Jeff Johnson 0.76-2 +- use the correct way of identifying the section via the sh_info link. + +* Sat Feb 15 2003 Jakub Jelinek 0.75-2 +- update to 0.75 (eu-strip -g fix) + +* Tue Feb 11 2003 Jakub Jelinek 0.74-2 +- update to 0.74 (fix for writing with some non-dirty sections) + +* Thu Feb 6 2003 Jeff Johnson 0.73-3 +- another -0.73 update (with sparc fixes). +- do "make check" in %%check, not %%install, section. + +* Mon Jan 27 2003 Jeff Johnson 0.73-2 +- update to 0.73 (with s390 fixes). + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Wed Jan 22 2003 Jakub Jelinek 0.72-4 +- fix arguments to gelf_getsymshndx and elf_getshstrndx +- fix other warnings +- re-enable checks on s390x + +* Sat Jan 11 2003 Karsten Hopp 0.72-3 +- temporarily disable checks on s390x, until someone has + time to look at it + +* Thu Dec 12 2002 Jakub Jelinek 0.72-2 +- update to 0.72 + +* Wed Dec 11 2002 Jakub Jelinek 0.71-2 +- update to 0.71 + +* Wed Dec 11 2002 Jeff Johnson 0.69-4 +- update to 0.69. +- add "make check" and segfault avoidance patch. +- elfutils-libelf needs to run ldconfig. + +* Tue Dec 10 2002 Jeff Johnson 0.68-2 +- update to 0.68. + +* Fri Dec 6 2002 Jeff Johnson 0.67-2 +- update to 0.67. + +* Tue Dec 3 2002 Jeff Johnson 0.65-2 +- update to 0.65. + +* Mon Dec 2 2002 Jeff Johnson 0.64-2 +- update to 0.64. + +* Sun Dec 1 2002 Ulrich Drepper 0.64 +- split packages further into elfutils-libelf + +* Sat Nov 30 2002 Jeff Johnson 0.63-2 +- update to 0.63. + +* Fri Nov 29 2002 Ulrich Drepper 0.62 +- Adjust for dropping libtool + +* Sun Nov 24 2002 Jeff Johnson 0.59-2 +- update to 0.59 + +* Thu Nov 14 2002 Jeff Johnson 0.56-2 +- update to 0.56 + +* Thu Nov 7 2002 Jeff Johnson 0.54-2 +- update to 0.54 + +* Sun Oct 27 2002 Jeff Johnson 0.53-2 +- update to 0.53 +- drop x86_64 hack, ICE fixed in gcc-3.2-11. + +* Sat Oct 26 2002 Jeff Johnson 0.52-3 +- get beehive to punch a rhpkg generated package. + +* Wed Oct 23 2002 Jeff Johnson 0.52-2 +- build in 8.0.1. +- x86_64: avoid gcc-3.2 ICE on x86_64 for now. + +* Tue Oct 22 2002 Ulrich Drepper 0.52 +- Add libelf-devel to conflicts for elfutils-devel + +* Mon Oct 21 2002 Ulrich Drepper 0.50 +- Split into runtime and devel package + +* Fri Oct 18 2002 Ulrich Drepper 0.49 +- integrate into official sources + +* Wed Oct 16 2002 Jeff Johnson 0.46-1 +- Swaddle. diff --git a/config/eu.am b/config/eu.am new file mode 100644 index 00000000..2c3e4571 --- /dev/null +++ b/config/eu.am @@ -0,0 +1,139 @@ +## Common automake fragments for elfutils subdirectory makefiles. +## +## Copyright (C) 2010, 2014, 2016 Red Hat, Inc. +## +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## + +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr + +# Warn about stack usage of more than 256K = 262144 bytes. +if ADD_STACK_USAGE_WARNING +STACK_USAGE_WARNING=-Wstack-usage=262144 +else +STACK_USAGE_WARNING= +endif + +if SANE_LOGICAL_OP_WARNING +LOGICAL_OP_WARNING=-Wlogical-op +else +LOGICAL_OP_WARNING= +endif + +if HAVE_DUPLICATED_COND_WARNING +DUPLICATED_COND_WARNING=-Wduplicated-cond +else +DUPLICATED_COND_WARNING= +endif + +if HAVE_NULL_DEREFERENCE_WARNING +NULL_DEREFERENCE_WARNING=-Wnull-dereference +else +NULL_DEREFERENCE_WARNING= +endif + +if HAVE_IMPLICIT_FALLTHROUGH_WARNING +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +if HAVE_IMPLICIT_FALLTHROUGH_5_WARNING +IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough=5 +else +IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough +endif +else +IMPLICIT_FALLTHROUGH_WARNING= +endif + +if HAVE_TRAMPOLINES_WARNING +TRAMPOLINES_WARNING=-Wtrampolines +else +TRAMPOLINES_WARNING= +endif + +if HAVE_NO_PACKED_NOT_ALIGNED_WARNING +NO_PACKED_NOT_ALIGNED_WARNING=-Wno-packed-not-aligned +else +NO_PACKED_NOT_ALIGNED_WARNING= +endif + +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) + +DEFS.os = -DPIC -DSHARED +if SYMBOL_VERSIONING +DEFS.os += -DSYMBOL_VERSIONING +else +endif + +%.os: %.c %.o +if AMDEP + $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ + -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ + then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ + rm -f "$(DEPDIR)/$*.Tpo"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ + fi +else + $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< +endif + +CLEANFILES = *.gcno *.gcda + +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +if FATAL_TEXTREL +textrel_found = $(textrel_msg); exit 1 +else +textrel_found = $(textrel_msg) +endif +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi + +print-%: + @echo $*=$($*) diff --git a/config/install-sh b/config/install-sh new file mode 100755 index 00000000..ec298b53 --- /dev/null +++ b/config/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2020-11-14.01; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/known-dwarf.awk b/config/known-dwarf.awk new file mode 100755 index 00000000..bc9b02db --- /dev/null +++ b/config/known-dwarf.awk @@ -0,0 +1,56 @@ +#!/bin/gawk -f + +## Copyright (C) 2012, 2015 Red Hat, Inc. +## +## This file is part of elfutils. +## +## 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 3 of the License, or +## (at your option) any later version. +## +## elfutils 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, see . + +$1 == "enum" { set = ""; next } + +set == "" && $1 ~ /DW_([A-Z_]+)_([^ ]+)/ { + set = $1; + sub(/^DW_/, "", set); + sub(/_[^[:upper:]_].*$/, "", set); + if (set ~ /LANG_.+/) set = "LANG"; +} + +$1 ~ /DW([_A-Z]+)_([^ ]+)/ { + match($1, ("DW_" set "_([^ ]+)"), fields); + elt = fields[1]; + if (set in DW) + DW[set] = DW[set] "," elt; + else + DW[set] = elt; +} + +END { + print "/* Generated by config/known-dwarf.awk from libdw/dwarf.h contents. */"; + n = asorti(DW, sets); + for (i = 1; i <= n; ++i) { + set = sets[i]; + if (what && what != set) continue; + split(DW[set], elts, ","); + m = asort(elts); + if (m == 0) continue; + print "\n#define DWARF_ALL_KNOWN_DW_" set " \\"; + for (j = 1; j <= m; ++j) { + elt = elts[j]; + if (elt ~ /(low?|hi|high)_user$/) + continue; + print " DWARF_ONE_KNOWN_DW_" set " (" elt ", DW_" set "_" elt ") \\"; + } + print " /* End of DW_" set "_*. */"; + } +} diff --git a/config/libdebuginfod.pc.in b/config/libdebuginfod.pc.in new file mode 100644 index 00000000..46722a76 --- /dev/null +++ b/config/libdebuginfod.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: debuginfod +Description: elfutils library to query debuginfo files from debuginfod servers +Version: @VERSION@ +URL: http://elfutils.org/ + +Libs: -L${libdir} -ldebuginfod +Cflags: -I${includedir} diff --git a/config/libdw.pc.in b/config/libdw.pc.in new file mode 100644 index 00000000..2e83a432 --- /dev/null +++ b/config/libdw.pc.in @@ -0,0 +1,22 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libdw +Description: elfutils library for DWARF data and ELF file or process inspection +Version: @VERSION@ +URL: http://elfutils.org/ + +Libs: -L${libdir} -ldw +Cflags: -I${includedir} + +# We need the exact matching elfutils libelf version since internal data +# structures are used. +Requires: libelf = @VERSION@ + +# We support various compressed ELF images, but don't export any of the +# data structures or functions. zlib (gz) is always required, bzip2 (bz2) +# lzma (xz) and zstd () are optional. But bzip2 doesn't have a pkg-config file. +Requires.private: zlib @LIBLZMA@ @LIBZSTD@ +Libs.private: @BZ2_LIB@ diff --git a/config/libelf.pc.in b/config/libelf.pc.in new file mode 100644 index 00000000..48f3f021 --- /dev/null +++ b/config/libelf.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libelf +Description: elfutils libelf library to read and write ELF files +Version: @VERSION@ +URL: http://elfutils.org/ + +Libs: -L${libdir} -lelf +Cflags: -I${includedir} + +Requires.private: zlib diff --git a/config/missing b/config/missing new file mode 100755 index 00000000..8d0eaad2 --- /dev/null +++ b/config/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 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, 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, see . + +# 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. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/profile.csh.in b/config/profile.csh.in new file mode 100644 index 00000000..0a2d6d16 --- /dev/null +++ b/config/profile.csh.in @@ -0,0 +1,11 @@ +if ("@DEBUGINFOD_URLS@" != "") then + if ($?DEBUGINFOD_URLS) then + if ($%DEBUGINFOD_URLS) then + setenv DEBUGINFOD_URLS "$DEBUGINFOD_URLS @DEBUGINFOD_URLS@" + else + setenv DEBUGINFOD_URLS "@DEBUGINFOD_URLS@" + endif + else + setenv DEBUGINFOD_URLS "@DEBUGINFOD_URLS@" + endif +endif diff --git a/config/profile.sh.in b/config/profile.sh.in new file mode 100644 index 00000000..aa228a0d --- /dev/null +++ b/config/profile.sh.in @@ -0,0 +1,4 @@ +if [ -n "@DEBUGINFOD_URLS@" ]; then + DEBUGINFOD_URLS="${DEBUGINFOD_URLS-}${DEBUGINFOD_URLS:+ }@DEBUGINFOD_URLS@" + export DEBUGINFOD_URLS +fi diff --git a/config/test-driver b/config/test-driver new file mode 100755 index 00000000..9759384a --- /dev/null +++ b/config/test-driver @@ -0,0 +1,150 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 2011-2020 Free Software Foundation, Inc. +# +# 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, 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, see . + +# 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. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/version.h.in b/config/version.h.in new file mode 100644 index 00000000..34e62c3b --- /dev/null +++ b/config/version.h.in @@ -0,0 +1,38 @@ +/* Version information about elfutils development libraries. + Copyright (C) 2008 Red Hat, Inc. + + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _ELFUTILS_VERSION_H +#define _ELFUTILS_VERSION_H 1 + +#define _ELFUTILS_VERSION @eu_version@ + +#define _ELFUTILS_PREREQ(major, minor) \ + (_ELFUTILS_VERSION >= ((major) * 1000 + (minor))) + +#endif /* elfutils/version.h */ diff --git a/config/ylwrap b/config/ylwrap new file mode 100755 index 00000000..d1533360 --- /dev/null +++ b/config/ylwrap @@ -0,0 +1,247 @@ +#! /bin/sh +# ylwrap - wrapper for lex/yacc invocations. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# +# Written by Tom Tromey . +# +# 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, 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, see . + +# 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. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +get_dirname () +{ + case $1 in + */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; + # Otherwise, we want the empty string (not "."). + esac +} + +# guard FILE +# ---------- +# The CPP macro used to guard inclusion of FILE. +guard () +{ + printf '%s\n' "$1" \ + | sed \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ + -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ + -e 's/__*/_/g' +} + +# quote_for_sed [STRING] +# ---------------------- +# Return STRING (or stdin) quoted to be used as a sed pattern. +quote_for_sed () +{ + case $# in + 0) cat;; + 1) printf '%s\n' "$1";; + esac \ + | sed -e 's|[][\\.*]|\\&|g' +} + +case "$1" in + '') + echo "$0: No files given. Try '$0 --help' for more information." 1>&2 + exit 1 + ;; + --basedir) + basedir=$2 + shift 2 + ;; + -h|--h*) + cat <<\EOF +Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... + +Wrapper for lex/yacc invocations, renaming files as desired. + + INPUT is the input file + OUTPUT is one file PROG generates + DESIRED is the file we actually want instead of OUTPUT + PROGRAM is program to run + ARGS are passed to PROG + +Any number of OUTPUT,DESIRED pairs may be used. + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "ylwrap $scriptversion" + exit $? + ;; +esac + + +# The input. +input=$1 +shift +# We'll later need for a correct munging of "#line" directives. +input_sub_rx=`get_dirname "$input" | quote_for_sed` +case $input in + [\\/]* | ?:[\\/]*) + # Absolute path; do nothing. + ;; + *) + # Relative path. Make it absolute. + input=`pwd`/$input + ;; +esac +input_rx=`get_dirname "$input" | quote_for_sed` + +# Since DOS filename conventions don't allow two dots, +# the DOS version of Bison writes out y_tab.c instead of y.tab.c +# and y_tab.h instead of y.tab.h. Test to see if this is the case. +y_tab_nodot=false +if test -f y_tab.c || test -f y_tab.h; then + y_tab_nodot=true +fi + +# The parser itself, the first file, is the destination of the .y.c +# rule in the Makefile. +parser=$1 + +# A sed program to s/FROM/TO/g for all the FROM/TO so that, for +# instance, we rename #include "y.tab.h" into #include "parse.h" +# during the conversion from y.tab.c to parse.c. +sed_fix_filenames= + +# Also rename header guards, as Bison 2.7 for instance uses its header +# guard in its implementation file. +sed_fix_header_guards= + +while test $# -ne 0; do + if test x"$1" = x"--"; then + shift + break + fi + from=$1 + # Handle y_tab.c and y_tab.h output by DOS + if $y_tab_nodot; then + case $from in + "y.tab.c") from=y_tab.c;; + "y.tab.h") from=y_tab.h;; + esac + fi + shift + to=$1 + shift + sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" + sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" +done + +# The program to run. +prog=$1 +shift +# Make any relative path in $prog absolute. +case $prog in + [\\/]* | ?:[\\/]*) ;; + *[\\/]*) prog=`pwd`/$prog ;; +esac + +dirname=ylwrap$$ +do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' +trap "ret=129; $do_exit" 1 +trap "ret=130; $do_exit" 2 +trap "ret=141; $do_exit" 13 +trap "ret=143; $do_exit" 15 +mkdir $dirname || exit 1 + +cd $dirname + +case $# in + 0) "$prog" "$input" ;; + *) "$prog" "$@" "$input" ;; +esac +ret=$? + +if test $ret -eq 0; then + for from in * + do + to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` + if test -f "$from"; then + # If $2 is an absolute path name, then just use that, + # otherwise prepend '../'. + case $to in + [\\/]* | ?:[\\/]*) target=$to;; + *) target=../$to;; + esac + + # Do not overwrite unchanged header files to avoid useless + # recompilations. Always update the parser itself: it is the + # destination of the .y.c rule in the Makefile. Divert the + # output of all other files to a temporary file so we can + # compare them to existing versions. + if test $from != $parser; then + realtarget=$target + target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` + fi + + # Munge "#line" or "#" directives. Don't let the resulting + # debug information point at an absolute srcdir. Use the real + # output file name, not yy.lex.c for instance. Adjust the + # include guards too. + sed -e "/^#/!b" \ + -e "s|$input_rx|$input_sub_rx|" \ + -e "$sed_fix_filenames" \ + -e "$sed_fix_header_guards" \ + "$from" >"$target" || ret=$? + + # Check whether files must be updated. + if test "$from" != "$parser"; then + if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then + echo "$to is unchanged" + rm -f "$target" + else + echo "updating $to" + mv -f "$target" "$realtarget" + fi + fi + else + # A missing file is only an error for the parser. This is a + # blatant hack to let us support using "yacc -d". If -d is not + # specified, don't fail when the header file is "missing". + if test "$from" = "$parser"; then + ret=1 + fi + fi + done +fi + +# Remove the directory. +cd .. +rm -rf $dirname + +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/configure b/configure new file mode 100755 index 00000000..4ea75ee6 --- /dev/null +++ b/configure @@ -0,0 +1,14284 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for elfutils 0.185. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +# +# Copyright (C) 1996-2021 The elfutils developers. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: https://sourceware.org/bugzilla about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='elfutils' +PACKAGE_TARNAME='elfutils' +PACKAGE_VERSION='0.185' +PACKAGE_STRING='elfutils 0.185' +PACKAGE_BUGREPORT='https://sourceware.org/bugzilla' +PACKAGE_URL='http://elfutils.org/' + +ac_unique_file="libelf/libelf.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +gt_needs= +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +DEBUGINFOD_URLS +DEBUGINFOD_FALSE +DEBUGINFOD_TRUE +libarchive_LIBS +libarchive_CFLAGS +sqlite3_LIBS +sqlite3_CFLAGS +libmicrohttpd_LIBS +libmicrohttpd_CFLAGS +HAVE_CXX11 +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +DUMMY_LIBDEBUGINFOD_FALSE +DUMMY_LIBDEBUGINFOD_TRUE +LIBDEBUGINFOD_FALSE +LIBDEBUGINFOD_TRUE +libcurl_LIBS +libcurl_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +HAVE_ZSTD_FALSE +HAVE_ZSTD_TRUE +HAVE_ZSTD +HAVE_BUNZIP2 +HAVE_GAWK +HAVE_BISON +HAVE_FLEX +CC_BIARCH +BIARCH_FALSE +BIARCH_TRUE +eu_version +POSUB +LTLIBINTL +LIBINTL +INTLLIBS +LTLIBICONV +LIBICONV +INTL_MACOSX_LIBS +XGETTEXT_EXTRA_OPTIONS +MSGMERGE_FOR_MSGFMT_OPTION +MSGMERGE +XGETTEXT_015 +XGETTEXT +GMSGFMT_015 +GMSGFMT +MSGFMT +GETTEXT_MACRO_VERSION +USE_NLS +SED +obstack_LIBS +fts_LIBS +argp_LDADD +HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE +HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE +HAVE_TRAMPOLINES_WARNING_FALSE +HAVE_TRAMPOLINES_WARNING_TRUE +HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE +HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE +HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE +HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE +HAVE_NULL_DEREFERENCE_WARNING_FALSE +HAVE_NULL_DEREFERENCE_WARNING_TRUE +HAVE_DUPLICATED_COND_WARNING_FALSE +HAVE_DUPLICATED_COND_WARNING_TRUE +SANE_LOGICAL_OP_WARNING_FALSE +SANE_LOGICAL_OP_WARNING_TRUE +ADD_STACK_USAGE_WARNING_FALSE +ADD_STACK_USAGE_WARNING_TRUE +SYMBOL_VERSIONING_FALSE +SYMBOL_VERSIONING_TRUE +FATAL_TEXTREL_FALSE +FATAL_TEXTREL_TRUE +DEMANGLE_FALSE +DEMANGLE_TRUE +EGREP +GREP +CPP +zip_LIBS +LIBZSTD +ZSTD_FALSE +ZSTD_TRUE +LIBLZMA +LZMA_FALSE +LZMA_TRUE +BZ2_LIB +BZLIB_FALSE +BZLIB_TRUE +ZLIB_FALSE +ZLIB_TRUE +TESTS_RPATH_FALSE +TESTS_RPATH_TRUE +BUILD_STATIC_FALSE +BUILD_STATIC_TRUE +INSTALL_ELFH_FALSE +INSTALL_ELFH_TRUE +USE_VG_ANNOTATIONS_FALSE +USE_VG_ANNOTATIONS_TRUE +USE_VALGRIND_FALSE +USE_VALGRIND_TRUE +HAVE_VALGRIND +GCOV_FALSE +GCOV_TRUE +GENHTML +LCOV +GCOV +GPROF_FALSE +GPROF_TRUE +DEBUGPRED +HAVE_STDATOMIC_H_FALSE +HAVE_STDATOMIC_H_TRUE +dso_LDFLAGS +fpie_CFLAGS +fpic_CFLAGS +NM +READELF +ac_ct_AR +AR +LEXLIB +LEX_OUTPUT_ROOT +LEX +YFLAGS +YACC +RANLIB +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +USE_LOCKS_FALSE +USE_LOCKS_TRUE +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +LIBDEBUGINFOD_SONAME +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_maintainer_mode +enable_deterministic_archives +enable_thread_safety +enable_dependency_tracking +enable_largefile +enable_debugpred +enable_gprof +enable_gcov +enable_sanitize_undefined +enable_valgrind +with_valgrind +enable_valgrind_annotations +enable_install_elfh +enable_tests_rpath +with_zlib +with_bzlib +with_lzma +with_zstd +enable_textrelcheck +enable_symbol_versioning +enable_nls +with_gnu_ld +enable_rpath +with_libiconv_prefix +with_libintl_prefix +with_biarch +enable_libdebuginfod +enable_debuginfod +enable_debuginfod_urls +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +YACC +YFLAGS +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +libcurl_CFLAGS +libcurl_LIBS +CXX +CXXFLAGS +CCC +libmicrohttpd_CFLAGS +libmicrohttpd_LIBS +sqlite3_CFLAGS +sqlite3_LIBS +libarchive_CFLAGS +libarchive_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures elfutils 0.185 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/elfutils] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of elfutils 0.185:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-deterministic-archives + ar and ranlib default to -D behavior + --enable-thread-safety enable thread safety of libraries EXPERIMENTAL + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --disable-largefile omit support for large files + --enable-debugpred build binaries with support to debug branch + prediction + --enable-gprof build binaries with gprof support + --enable-gcov build binaries with gcov support + --enable-sanitize-undefined + Use gcc undefined behaviour sanitizer + --enable-valgrind run all tests under valgrind + --enable-valgrind-annotations + insert extra annotations for better valgrind support + --enable-install-elfh install elf.h in include dir + --enable-tests-rpath build $ORIGIN-using rpath into tests + --disable-textrelcheck Disable textrelcheck being a fatal error + --disable-symbol-versioning + Disable symbol versioning in shared objects + --disable-nls do not use Native Language Support + --disable-rpath do not hardcode runtime library paths + --enable-libdebuginfod Build debuginfod client library (can be =dummy) + --enable-debuginfod Build debuginfod server + --enable-debuginfod-urls[=URLS] + add URLS to profile.d DEBUGINFOD_URLS + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-valgrind include directory for Valgrind headers + --with-zlib support [zlib] compression in libdwfl + --with-bzlib support [bzlib] compression in libdwfl + --with-lzma support [lzma] compression in libdwfl + --with-zstd support [zstd] compression in libdwfl + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib + --without-libintl-prefix don't search for libintl in includedir and libdir + --with-biarch enable biarch tests despite build problems + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + YACC The `Yet Another Compiler Compiler' implementation to use. + Defaults to the first program found out of: `bison -y', `byacc', + `yacc'. + YFLAGS The list of arguments that will be passed by default to $YACC. + This script will default YFLAGS to the empty string to avoid a + default value of `-d' given by some make applications. + CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + libcurl_CFLAGS + C compiler flags for libcurl, overriding pkg-config + libcurl_LIBS + linker flags for libcurl, overriding pkg-config + CXX C++ compiler command + CXXFLAGS C++ compiler flags + libmicrohttpd_CFLAGS + C compiler flags for libmicrohttpd, overriding pkg-config + libmicrohttpd_LIBS + linker flags for libmicrohttpd, overriding pkg-config + sqlite3_CFLAGS + C compiler flags for sqlite3, overriding pkg-config + sqlite3_LIBS + linker flags for sqlite3, overriding pkg-config + libarchive_CFLAGS + C compiler flags for libarchive, overriding pkg-config + libarchive_LIBS + linker flags for libarchive, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +elfutils home page: . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +elfutils configure 0.185 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. + +Copyright (C) 1996-2021 The elfutils developers. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by elfutils $as_me 0.185, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +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 || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +gt_needs="$gt_needs need-formatstring-macros" +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + +LIBDEBUGINFOD_SONAME=libdebuginfod.so.1 + + +# We want eu- as default program prefix if none was given by the user. +# But if the user explicitly provided --program-prefix="" then pretend +# it wasn't set at all (NONE). We want to test this really early before +# configure has a chance to use the value. + +if test "x$program_prefix" = "xNONE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: No --program-prefix given, using \"eu-\"" >&5 +$as_echo "$as_me: No --program-prefix given, using \"eu-\"" >&6;} + program_prefix="eu-" +elif test "x$program_prefix" = "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Using no program-prefix" >&5 +$as_echo "$as_me: Using no program-prefix" >&6;} + program_prefix=NONE +fi + +ac_aux_dir= +for ac_dir in config "$srcdir"/config; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +ac_config_files="$ac_config_files config/Makefile" + + + + +am__api_version='1.16' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='elfutils' + VERSION='0.185' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + + +ac_config_files="$ac_config_files Makefile" + +ac_config_headers="$ac_config_headers config.h" + + +ac_config_files="$ac_config_files elfutils.spec:config/elfutils.spec.in" + + +ac_config_files="$ac_config_files debuginfod/Makefile debuginfod/debuginfod.h" + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +# Check whether --enable-deterministic-archives was given. +if test "${enable_deterministic_archives+set}" = set; then : + enableval=$enable_deterministic_archives; +if test "${enableval}" = no; then + default_ar_deterministic=false +else + default_ar_deterministic=true +fi +else + default_ar_deterministic=false +fi + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_AR_DETERMINISTIC $default_ar_deterministic +_ACEOF + + +# Check whether --enable-thread-safety was given. +if test "${enable_thread_safety+set}" = set; then : + enableval=$enable_thread_safety; use_locks=$enableval +else + use_locks=no +fi + + if test "$use_locks" = yes; then + USE_LOCKS_TRUE= + USE_LOCKS_FALSE='#' +else + USE_LOCKS_TRUE='#' + USE_LOCKS_FALSE= +fi + +if test "$use_locks" = yes; then : + $as_echo "#define USE_LOCKS 1" >>confdefs.h + +fi +if test "$use_locks" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: thread-safety is EXPERIMENTAL tests might fail." >&5 +$as_echo "$as_me: WARNING: thread-safety is EXPERIMENTAL tests might fail." >&2;} +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +for ac_prog in 'bison -y' byacc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_YACC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_YACC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +YACC=$ac_cv_prog_YACC +if test -n "$YACC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 +$as_echo "$YACC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + + +for ac_prog in flex lex +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LEX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LEX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LEX=$ac_cv_prog_LEX +if test -n "$LEX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 +$as_echo "$LEX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LEX" && break +done +test -n "$LEX" || LEX=":" + +if test "x$LEX" != "x:"; then + cat >conftest.l <<_ACEOF +%% +a { ECHO; } +b { REJECT; } +c { yymore (); } +d { yyless (1); } +e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ + yyless ((input () != 0)); } +f { unput (yytext[0]); } +. { BEGIN INITIAL; } +%% +#ifdef YYTEXT_POINTER +extern char *yytext; +#endif +int +main (void) +{ + return ! yylex () + ! yywrap (); +} +_ACEOF +{ { ac_try="$LEX conftest.l" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$LEX conftest.l") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 +$as_echo_n "checking lex output file root... " >&6; } +if ${ac_cv_prog_lex_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 +$as_echo "$ac_cv_prog_lex_root" >&6; } +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +if test -z "${LEXLIB+set}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 +$as_echo_n "checking lex library... " >&6; } +if ${ac_cv_lib_lex+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS=$LIBS + ac_cv_lib_lex='none needed' + for ac_lib in '' -lfl -ll; do + LIBS="$ac_lib $ac_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_lex=$ac_lib +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + test "$ac_cv_lib_lex" != 'none needed' && break + done + LIBS=$ac_save_LIBS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 +$as_echo "$ac_cv_lib_lex" >&6; } + test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 +$as_echo_n "checking whether yytext is a pointer... " >&6; } +if ${ac_cv_prog_lex_yytext_pointer+:} false; then : + $as_echo_n "(cached) " >&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +ac_save_LIBS=$LIBS +LIBS="$LEXLIB $ac_save_LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define YYTEXT_POINTER 1 +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_prog_lex_yytext_pointer=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_save_LIBS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 +$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } +if test $ac_cv_prog_lex_yytext_pointer = yes; then + +$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h + +fi +rm -f conftest.l $LEX_OUTPUT_ROOT.c + +fi +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi +# Only available since automake 1.12 +if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +$as_echo_n "checking the archiver ($AR) interface... " >&6; } +if ${am_cv_ar_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +$as_echo "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. +set dummy ${ac_tool_prefix}readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$READELF"; then + ac_cv_prog_READELF="$READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_READELF="${ac_tool_prefix}readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +READELF=$ac_cv_prog_READELF +if test -n "$READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 +$as_echo "$READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_READELF"; then + ac_ct_READELF=$READELF + # Extract the first word of "readelf", so it can be a program name with args. +set dummy readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_READELF"; then + ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_READELF="readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_READELF=$ac_cv_prog_ac_ct_READELF +if test -n "$ac_ct_READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 +$as_echo "$ac_ct_READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_READELF" = x; then + READELF="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + READELF=$ac_ct_READELF + fi +else + READELF="$ac_cv_prog_READELF" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +$as_echo "$NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NM="nm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5 +$as_echo "$ac_ct_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +else + NM="$ac_cv_prog_NM" +fi + + +# We use -std=gnu99 but have explicit checks for some language constructs +# and GNU extensions since some compilers claim GNU99 support, but don't +# really support all language extensions. In particular we need +# Mixed Declarations and Code +# https://gcc.gnu.org/onlinedocs/gcc/Mixed-Declarations.html +# Nested Functions +# https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html +# Arrays of Variable Length +# https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc with GNU99 support" >&5 +$as_echo_n "checking for gcc with GNU99 support... " >&6; } +if ${ac_cv_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -std=gnu99" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (int a) +{ + for (int i = 0; i < a; ++i) if (i % 4) break; int s = a; return s; +} + +double bar (double a, double b) +{ + double square (double z) { return z * z; } + return square (a) + square (b); +} + +void baz (int n) +{ + struct S { int x[n]; }; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c99=yes +else + ac_cv_c99=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c99" >&5 +$as_echo "$ac_cv_c99" >&6; } +if test "x$ac_cv_c99" != xyes; then : + as_fn_error $? "gcc with GNU99 support required" "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports __attribute__((visibility()))" >&5 +$as_echo_n "checking whether gcc supports __attribute__((visibility()))... " >&6; } +if ${ac_cv_visibility+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int __attribute__((visibility("hidden"))) +foo (int a) +{ + return a; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_visibility=yes +else + ac_cv_visibility=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$save_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_visibility" >&5 +$as_echo "$ac_cv_visibility" >&6; } +if test "$ac_cv_visibility" = "yes"; then + +$as_echo "#define HAVE_VISIBILITY 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports __attribute__((gcc_struct))" >&5 +$as_echo_n "checking whether gcc supports __attribute__((gcc_struct))... " >&6; } +if ${ac_cv_gcc_struct+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +struct test { int x; } __attribute__((gcc_struct)); + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_gcc_struct=yes +else + ac_cv_gcc_struct=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$save_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_struct" >&5 +$as_echo "$ac_cv_gcc_struct" >&6; } +if test "$ac_cv_gcc_struct" = "yes"; then + +$as_echo "#define HAVE_GCC_STRUCT 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports -fPIC" >&5 +$as_echo_n "checking whether gcc supports -fPIC... " >&6; } +if ${ac_cv_fpic+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -fPIC -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_fpic=yes +else + ac_cv_fpic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$save_CFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fpic" >&5 +$as_echo "$ac_cv_fpic" >&6; } +if test "$ac_cv_fpic" = "yes"; then + fpic_CFLAGS="-fPIC" +else + fpic_CFLAGS="" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports -fPIE" >&5 +$as_echo_n "checking whether gcc supports -fPIE... " >&6; } +if ${ac_cv_fpie+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -fPIE -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_fpie=yes +else + ac_cv_fpie=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$save_CFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fpie" >&5 +$as_echo "$ac_cv_fpie" >&6; } +if test "$ac_cv_fpie" = "yes"; then + fpie_CFLAGS="-fPIE" +else + fpie_CFLAGS="" +fi + + +dso_LDFLAGS="-shared" + +ZDEFS_LDFLAGS="-Wl,-z,defs" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports $ZDEFS_LDFLAGS" >&5 +$as_echo_n "checking whether gcc supports $ZDEFS_LDFLAGS... " >&6; } +if ${ac_cv_zdefs+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" +LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_zdefs=yes +else + ac_cv_zdefs=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_zdefs" >&5 +$as_echo "$ac_cv_zdefs" >&6; } +if test "$ac_cv_zdefs" = "yes"; then + dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS" +fi + +# We really want build-ids. Warn and force generating them if gcc was +# configure without --enable-linker-build-id +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler generates build-ids" >&5 +$as_echo_n "checking whether the compiler generates build-ids... " >&6; } +if ${ac_cv_buildid+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_buildid=yes; $READELF -n conftest$EXEEXT | grep -q NT_GNU_BUILD_ID || ac_cv_buildid=no +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "unexpected compile failure +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_buildid" >&5 +$as_echo "$ac_cv_buildid" >&6; } +if test "$ac_cv_buildid" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compiler doesn't generate build-id by default" >&5 +$as_echo "$as_me: WARNING: compiler doesn't generate build-id by default" >&2;} + LDFLAGS="$LDFLAGS -Wl,--build-id" +fi + +ZRELRO_LDFLAGS="-Wl,-z,relro" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports $ZRELRO_LDFLAGS" >&5 +$as_echo_n "checking whether gcc supports $ZRELRO_LDFLAGS... " >&6; } +if ${ac_cv_zrelro+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" +LDFLAGS="$ZRELRO_LDFLAGS $save_LDFLAGS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_zrelro=yes +else + ac_cv_zrelro=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_zrelro" >&5 +$as_echo "$ac_cv_zrelro" >&6; } +if test "$ac_cv_zrelro" = "yes"; then + dso_LDFLAGS="$dso_LDFLAGS $ZRELRO_LDFLAGS" +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __thread support" >&5 +$as_echo_n "checking for __thread support... " >&6; } +if ${ac_cv_tls+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Use the same flags that we use for our DSOs, so the test is representative. +# Some old compiler/linker/libc combinations fail some ways and not others. +save_CFLAGS="$CFLAGS" +save_LDFLAGS="$LDFLAGS" +CFLAGS="$fpic_CFLAGS $CFLAGS" +LDFLAGS="$dso_LDFLAGS $LDFLAGS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#undef __thread +static __thread int a; int foo (int b) { return a + b; } +int +main () +{ +exit (foo (0)); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_tls=yes +else + ac_cv_tls=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS="$save_CFLAGS" +LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tls" >&5 +$as_echo "$ac_cv_tls" >&6; } +if test "x$ac_cv_tls" != xyes; then : + as_fn_error $? "__thread support required" "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc provides stdatomic.h" >&5 +$as_echo_n "checking whether gcc provides stdatomic.h... " >&6; } +if ${ac_cv_has_stdatomic+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_has_stdatomic=yes +else + ac_cv_has_stdatomic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_has_stdatomic" >&5 +$as_echo "$ac_cv_has_stdatomic" >&6; } + if test "x$ac_cv_has_stdatomic" = xyes; then + HAVE_STDATOMIC_H_TRUE= + HAVE_STDATOMIC_H_FALSE='#' +else + HAVE_STDATOMIC_H_TRUE='#' + HAVE_STDATOMIC_H_FALSE= +fi + +if test "x$ac_cv_has_stdatomic" = xyes; then : + $as_echo "#define HAVE_STDATOMIC_H 1" >>confdefs.h + +fi + + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fts.h is bad when included (with LFS)" >&5 +$as_echo_n "checking whether fts.h is bad when included (with LFS)... " >&6; } +if ${ac_cv_bad_fts+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_bad_fts=no +else + ac_cv_bad_fts=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_bad_fts" >&5 +$as_echo "$ac_cv_bad_fts" >&6; } +if test "x$ac_cv_bad_fts" = "xyes"; then : + CFLAGS="$CFLAGS -DBAD_FTS=1" CXXFLAGS="$CXXFLAGS -DBAD_FTS=1" +fi + +# See if we can add -D_FORTIFY_SOURCE=2. Don't do it if it is already +# (differently) defined or if it generates warnings/errors because we +# don't use the right optimisation level (string.h will warn about that). +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to add -D_FORTIFY_SOURCE=2 to CFLAGS" >&5 +$as_echo_n "checking whether to add -D_FORTIFY_SOURCE=2 to CFLAGS... " >&6; } +case "$CFLAGS" in + *-D_FORTIFY_SOURCE=2*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, already there" >&5 +$as_echo "no, already there" >&6; } + ;; + *) + save_CFLAGS="$CFLAGS" + CFLAGS="-D_FORTIFY_SOURCE=2 $CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() { return 0; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="-D_FORTIFY_SOURCE=2 $save_CFLAGS" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$save_CFLAGS" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; +esac + +# Check whether --enable-debugpred was given. +if test "${enable_debugpred+set}" = set; then : + enableval=$enable_debugpred; use_debugpred=$enableval +else + use_debugpred=no +fi + +case $use_debugpred in + yes) use_debugpred_val=1 ;; + *) use_debugpred_val=0 ;; +esac +DEBUGPRED=$use_debugpred_val + + +# Check whether --enable-gprof was given. +if test "${enable_gprof+set}" = set; then : + enableval=$enable_gprof; use_gprof=$enableval +else + use_gprof=no +fi + +if test "$use_gprof" = yes; then + CFLAGS="$CFLAGS -pg" + LDFLAGS="$LDFLAGS -pg" +fi + if test "$use_gprof" = yes; then + GPROF_TRUE= + GPROF_FALSE='#' +else + GPROF_TRUE='#' + GPROF_FALSE= +fi + + +# Enable gcov support. +# Check whether --enable-gcov was given. +if test "${enable_gcov+set}" = set; then : + enableval=$enable_gcov; use_gcov=$enableval +else + use_gcov=no +fi + +if test "$use_gcov" = yes; then + CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" + CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage" + LDFLAGS="$LDFLAGS -fprofile-arcs" + # Extract the first word of "gcov", so it can be a program name with args. +set dummy gcov; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GCOV"; then + ac_cv_prog_GCOV="$GCOV" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GCOV="gcov" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GCOV=$ac_cv_prog_GCOV +if test -n "$GCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCOV" >&5 +$as_echo "$GCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "lcov", so it can be a program name with args. +set dummy lcov; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LCOV"; then + ac_cv_prog_LCOV="$LCOV" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LCOV="lcov" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LCOV=$ac_cv_prog_LCOV +if test -n "$LCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 +$as_echo "$LCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "genhtml", so it can be a program name with args. +set dummy genhtml; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GENHTML+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GENHTML"; then + ac_cv_prog_GENHTML="$GENHTML" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GENHTML="genhtml" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GENHTML=$ac_cv_prog_GENHTML +if test -n "$GENHTML"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 +$as_echo "$GENHTML" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi + if test "$use_gcov" = yes; then + GCOV_TRUE= + GCOV_FALSE='#' +else + GCOV_TRUE='#' + GCOV_FALSE= +fi + + +# Check whether --enable-sanitize-undefined was given. +if test "${enable_sanitize_undefined+set}" = set; then : + enableval=$enable_sanitize_undefined; use_undefined=$enableval +else + use_undefined=no +fi + +if test "$use_undefined" = yes; then + old_CFLAGS="$CFLAGS" + old_CXXFLAGS="$CXXFLAGS" + # We explicitly use unaligned access when possible (see ALLOW_UNALIGNED) + # We want to fail immediately on first error, don't try to recover. + CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize-recover" + CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main (int argc, char **argv) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + use_undefined=yes +else + use_undefined=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "x$use_undefined" != xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gcc undefined behaviour sanitizer not available" >&5 +$as_echo "$as_me: WARNING: gcc undefined behaviour sanitizer not available" >&2;} + CFLAGS="$old_CFLAGS" CXXFLAGS="$old_CXXFLAGS" +fi +fi +case $use_undefined in + yes) check_undefined_val=1 ;; + *) check_undefined_val=0 ;; +esac + +cat >>confdefs.h <<_ACEOF +#define CHECK_UNDEFINED $check_undefined_val +_ACEOF + + +# Check whether --enable-valgrind was given. +if test "${enable_valgrind+set}" = set; then : + enableval=$enable_valgrind; use_valgrind=$enableval +else + use_valgrind=no +fi + +if test "$use_valgrind" = yes; then + # Extract the first word of "valgrind", so it can be a program name with args. +set dummy valgrind; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_VALGRIND+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_VALGRIND"; then + ac_cv_prog_HAVE_VALGRIND="$HAVE_VALGRIND" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_VALGRIND="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_VALGRIND" && ac_cv_prog_HAVE_VALGRIND="no" +fi +fi +HAVE_VALGRIND=$ac_cv_prog_HAVE_VALGRIND +if test -n "$HAVE_VALGRIND"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_VALGRIND" >&5 +$as_echo "$HAVE_VALGRIND" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$HAVE_VALGRIND" = "no"; then + as_fn_error $? "valgrind not found" "$LINENO" 5 + fi +fi + if test "$use_valgrind" = yes; then + USE_VALGRIND_TRUE= + USE_VALGRIND_FALSE='#' +else + USE_VALGRIND_TRUE='#' + USE_VALGRIND_FALSE= +fi + + + +# Check whether --with-valgrind was given. +if test "${with_valgrind+set}" = set; then : + withval=$with_valgrind; with_valgrind_headers=$withval +else + with_valgrind_headers=no +fi + +if test "x$with_valgrind_headers" != xno; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I$with_valgrind_headers" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() { return 0; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + HAVE_VALGRIND_HEADERS="yes" + CFLAGS="$save_CFLAGS -I$with_valgrind_headers" +else + as_fn_error $? "invalid valgrind include directory: $with_valgrind_headers" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# Check whether --enable-valgrind-annotations was given. +if test "${enable_valgrind_annotations+set}" = set; then : + enableval=$enable_valgrind_annotations; use_vg_annotations=$enableval +else + use_vg_annotations=no +fi + +if test "$use_vg_annotations" = yes; then + if test "x$HAVE_VALGRIND_HEADERS" != "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Valgrind headers are available" >&5 +$as_echo_n "checking whether Valgrind headers are available... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() { return 0; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + as_fn_error $? "valgrind annotations requested but no headers are available" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi + if test "$use_vg_annotations" = yes; then + USE_VG_ANNOTATIONS_TRUE= + USE_VG_ANNOTATIONS_FALSE='#' +else + USE_VG_ANNOTATIONS_TRUE='#' + USE_VG_ANNOTATIONS_FALSE= +fi + + +# Check whether --enable-install-elfh was given. +if test "${enable_install_elfh+set}" = set; then : + enableval=$enable_install_elfh; install_elfh=$enableval +else + install_elfh=no +fi + + if test "$install_elfh" = yes; then + INSTALL_ELFH_TRUE= + INSTALL_ELFH_FALSE='#' +else + INSTALL_ELFH_TRUE='#' + INSTALL_ELFH_FALSE= +fi + + + if test "$use_gprof" = yes -o "$use_gcov" = yes; then + BUILD_STATIC_TRUE= + BUILD_STATIC_FALSE='#' +else + BUILD_STATIC_TRUE='#' + BUILD_STATIC_FALSE= +fi + + +# Check whether --enable-tests-rpath was given. +if test "${enable_tests_rpath+set}" = set; then : + enableval=$enable_tests_rpath; tests_use_rpath=$enableval +else + tests_use_rpath=no +fi + + if test "$tests_use_rpath" = yes; then + TESTS_RPATH_TRUE= + TESTS_RPATH_FALSE='#' +else + TESTS_RPATH_TRUE='#' + TESTS_RPATH_FALSE= +fi + + +save_LIBS="$LIBS" +LIBS= + +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then : + withval=$with_zlib; +else + with_zlib=default +fi + +if test $with_zlib != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gzdirect" >&5 +$as_echo_n "checking for library containing gzdirect... " >&6; } +if ${ac_cv_search_gzdirect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzdirect (); +int +main () +{ +return gzdirect (); + ; + return 0; +} +_ACEOF +for ac_lib in '' z; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_gzdirect=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_gzdirect+:} false; then : + break +fi +done +if ${ac_cv_search_gzdirect+:} false; then : + +else + ac_cv_search_gzdirect=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gzdirect" >&5 +$as_echo "$ac_cv_search_gzdirect" >&6; } +ac_res=$ac_cv_search_gzdirect +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + with_zlib=yes +else + test $with_zlib = default || + as_fn_error $? "missing -lz for --with-zlib" "$LINENO" 5 +fi + +fi + if test $with_zlib = yes; then + ZLIB_TRUE= + ZLIB_FALSE='#' +else + ZLIB_TRUE='#' + ZLIB_FALSE= +fi + +if test $with_zlib = yes; then + $as_echo "#define USE_ZLIB 1" >>confdefs.h + +else + with_zlib=no +fi + +if test "x$with_zlib" = xno; then : + as_fn_error $? "zlib not found but is required" "$LINENO" 5 +fi +LIBS="$save_LIBS" + +save_LIBS="$LIBS" +LIBS= + +# Check whether --with-bzlib was given. +if test "${with_bzlib+set}" = set; then : + withval=$with_bzlib; +else + with_bzlib=default +fi + +if test $with_bzlib != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing BZ2_bzdopen" >&5 +$as_echo_n "checking for library containing BZ2_bzdopen... " >&6; } +if ${ac_cv_search_BZ2_bzdopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char BZ2_bzdopen (); +int +main () +{ +return BZ2_bzdopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' bz2; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_BZ2_bzdopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_BZ2_bzdopen+:} false; then : + break +fi +done +if ${ac_cv_search_BZ2_bzdopen+:} false; then : + +else + ac_cv_search_BZ2_bzdopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_BZ2_bzdopen" >&5 +$as_echo "$ac_cv_search_BZ2_bzdopen" >&6; } +ac_res=$ac_cv_search_BZ2_bzdopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + with_bzlib=yes +else + test $with_bzlib = default || + as_fn_error $? "missing -lbz2 for --with-bzlib" "$LINENO" 5 +fi + +fi + if test $with_bzlib = yes; then + BZLIB_TRUE= + BZLIB_FALSE='#' +else + BZLIB_TRUE='#' + BZLIB_FALSE= +fi + +if test $with_bzlib = yes; then + $as_echo "#define USE_BZLIB 1" >>confdefs.h + +else + with_bzlib=no +fi + +# We need this since bzip2 doesn't have a pkgconfig file. +BZ2_LIB="$LIBS" + + +# Check whether --with-lzma was given. +if test "${with_lzma+set}" = set; then : + withval=$with_lzma; +else + with_lzma=default +fi + +if test $with_lzma != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing lzma_auto_decoder" >&5 +$as_echo_n "checking for library containing lzma_auto_decoder... " >&6; } +if ${ac_cv_search_lzma_auto_decoder+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char lzma_auto_decoder (); +int +main () +{ +return lzma_auto_decoder (); + ; + return 0; +} +_ACEOF +for ac_lib in '' lzma; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_lzma_auto_decoder=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_lzma_auto_decoder+:} false; then : + break +fi +done +if ${ac_cv_search_lzma_auto_decoder+:} false; then : + +else + ac_cv_search_lzma_auto_decoder=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_lzma_auto_decoder" >&5 +$as_echo "$ac_cv_search_lzma_auto_decoder" >&6; } +ac_res=$ac_cv_search_lzma_auto_decoder +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + with_lzma=yes +else + test $with_lzma = default || + as_fn_error $? "missing -llzma for --with-lzma" "$LINENO" 5 +fi + +fi + if test $with_lzma = yes; then + LZMA_TRUE= + LZMA_FALSE='#' +else + LZMA_TRUE='#' + LZMA_FALSE= +fi + +if test $with_lzma = yes; then + $as_echo "#define USE_LZMA 1" >>confdefs.h + +else + with_lzma=no +fi + +if test "x$with_lzma" = xyes; then : + LIBLZMA="liblzma" +else + LIBLZMA="" +fi + + +# Check whether --with-zstd was given. +if test "${with_zstd+set}" = set; then : + withval=$with_zstd; +else + with_zstd=default +fi + +if test $with_zstd != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ZSTD_decompress" >&5 +$as_echo_n "checking for library containing ZSTD_decompress... " >&6; } +if ${ac_cv_search_ZSTD_decompress+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ZSTD_decompress (); +int +main () +{ +return ZSTD_decompress (); + ; + return 0; +} +_ACEOF +for ac_lib in '' zstd; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ZSTD_decompress=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_ZSTD_decompress+:} false; then : + break +fi +done +if ${ac_cv_search_ZSTD_decompress+:} false; then : + +else + ac_cv_search_ZSTD_decompress=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ZSTD_decompress" >&5 +$as_echo "$ac_cv_search_ZSTD_decompress" >&6; } +ac_res=$ac_cv_search_ZSTD_decompress +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + with_zstd=yes +else + test $with_zstd = default || + as_fn_error $? "missing -lzstd for --with-zstd" "$LINENO" 5 +fi + +fi + if test $with_zstd = yes; then + ZSTD_TRUE= + ZSTD_FALSE='#' +else + ZSTD_TRUE='#' + ZSTD_FALSE= +fi + +if test $with_zstd = yes; then + $as_echo "#define USE_ZSTD 1" >>confdefs.h + +else + with_zstd=no +fi + +if test "x$with_zstd" = xyes; then : + LIBZSTD="libzstd" +else + LIBLZSTD="" +fi + +zip_LIBS="$LIBS" +LIBS="$save_LIBS" + + +ac_fn_c_check_decl "$LINENO" "memrchr" "ac_cv_have_decl_memrchr" "#define _GNU_SOURCE + #include +" +if test "x$ac_cv_have_decl_memrchr" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_MEMRCHR $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "rawmemchr" "ac_cv_have_decl_rawmemchr" "#define _GNU_SOURCE + #include +" +if test "x$ac_cv_have_decl_rawmemchr" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_RAWMEMCHR $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "powerof2" "ac_cv_have_decl_powerof2" "#include +" +if test "x$ac_cv_have_decl_powerof2" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_POWEROF2 $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "mempcpy" "ac_cv_have_decl_mempcpy" "#define _GNU_SOURCE + #include +" +if test "x$ac_cv_have_decl_mempcpy" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_MEMPCPY $ac_have_decl +_ACEOF + + +for ac_func in process_vm_readv +do : + ac_fn_c_check_func "$LINENO" "process_vm_readv" "ac_cv_func_process_vm_readv" +if test "x$ac_cv_func_process_vm_readv" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PROCESS_VM_READV 1 +_ACEOF + +fi +done + + +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -D_GNU_SOURCE" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_c_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" +if test "x$ac_cv_have_decl_strerror_r" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRERROR_R $ac_have_decl +_ACEOF + +for ac_func in strerror_r +do : + ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r" +if test "x$ac_cv_func_strerror_r" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRERROR_R 1 +_ACEOF + +fi +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5 +$as_echo_n "checking whether strerror_r returns char *... " >&6; } +if ${ac_cv_func_strerror_r_char_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_cv_func_strerror_r_char_p=no + if test $ac_cv_have_decl_strerror_r = yes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + char *p = strerror_r (0, buf, sizeof buf); + return !p || x; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_strerror_r_char_p=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + else + # strerror_r is not declared. Choose between + # systems that have relatively inaccessible declarations for the + # function. BeOS and DEC UNIX 4.0 fall in this category, but the + # former has a strerror_r that returns char*, while the latter + # has a strerror_r that returns `int'. + # This test should segfault on the DEC system. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + extern char *strerror_r (); +int +main () +{ +char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + return ! isalpha (x); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_strerror_r_char_p=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5 +$as_echo "$ac_cv_func_strerror_r_char_p" >&6; } +if test $ac_cv_func_strerror_r_char_p = yes; then + +$as_echo "#define STRERROR_R_CHAR_P 1" >>confdefs.h + +fi + +CFLAGS="$old_CFLAGS" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cxa_demangle in -lstdc++" >&5 +$as_echo_n "checking for __cxa_demangle in -lstdc++... " >&6; } +if ${ac_cv_lib_stdcpp___cxa_demangle+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lstdc++ $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __cxa_demangle (); +int +main () +{ +return __cxa_demangle (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_stdcpp___cxa_demangle=yes +else + ac_cv_lib_stdcpp___cxa_demangle=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_stdcpp___cxa_demangle" >&5 +$as_echo "$ac_cv_lib_stdcpp___cxa_demangle" >&6; } +if test "x$ac_cv_lib_stdcpp___cxa_demangle" = xyes; then : + +$as_echo "#define USE_DEMANGLE 1" >>confdefs.h + +fi + + if test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes"; then + DEMANGLE_TRUE= + DEMANGLE_FALSE='#' +else + DEMANGLE_TRUE='#' + DEMANGLE_FALSE= +fi + +if test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes"; then : + enable_demangler=yes +else + enable_demangler=no +fi + +# Check whether --enable-textrelcheck was given. +if test "${enable_textrelcheck+set}" = set; then : + enableval=$enable_textrelcheck; +fi + + if test "x$enable_textrelcheck" != "xno"; then + FATAL_TEXTREL_TRUE= + FATAL_TEXTREL_FALSE='#' +else + FATAL_TEXTREL_TRUE='#' + FATAL_TEXTREL_FALSE= +fi + +if test "x$enable_textrelcheck" != "xno"; then : + enable_textrelcheck=yes +else + enable_textrelcheck=no +fi + +# Check whether --enable-symbol-versioning was given. +if test "${enable_symbol_versioning+set}" = set; then : + enableval=$enable_symbol_versioning; +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether symbol versioning is supported" >&5 +$as_echo_n "checking whether symbol versioning is supported... " >&6; } +if ${ac_cv_symbol_versioning+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define NEW_VERSION(name, version) \ + asm (".symver " #name "," #name "@@@" #version); +int foo(int x) { return x + 1; } +NEW_VERSION (foo, ELFUTILS_12.12) + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_symbol_versioning=yes +else + ac_cv_symbol_versioning=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_symbol_versioning" >&5 +$as_echo "$ac_cv_symbol_versioning" >&6; } +if test "$ac_cv_symbol_versioning" = "no"; then + if test "x$enable_symbol_versioning" != "xno"; then + as_fn_error $? "Symbol versioning is not supported. + Use --disable-symbol-versioning to build without." "$LINENO" 5 + fi +fi + + if test "x$enable_symbol_versioning" != "xno"; then + SYMBOL_VERSIONING_TRUE= + SYMBOL_VERSIONING_FALSE='#' +else + SYMBOL_VERSIONING_TRUE='#' + SYMBOL_VERSIONING_FALSE= +fi + +if test "x$enable_symbol_versioning" = "xno"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling symbol versioning breaks ABI compatibility." >&5 +$as_echo "$as_me: WARNING: Disabling symbol versioning breaks ABI compatibility." >&2;} + enable_symbol_versioning=no +else + enable_symbol_versioning=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wstack-usage" >&5 +$as_echo_n "checking whether gcc accepts -Wstack-usage... " >&6; } +if ${ac_cv_stack_usage+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wstack-usage=262144 -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_stack_usage=yes +else + ac_cv_stack_usage=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stack_usage" >&5 +$as_echo "$ac_cv_stack_usage" >&6; } + if test "x$ac_cv_stack_usage" != "xno"; then + ADD_STACK_USAGE_WARNING_TRUE= + ADD_STACK_USAGE_WARNING_FALSE='#' +else + ADD_STACK_USAGE_WARNING_TRUE='#' + ADD_STACK_USAGE_WARNING_FALSE= +fi + + +# -Wlogical-op was too fragile in the past, make sure we get a sane one. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc has a sane -Wlogical-op" >&5 +$as_echo_n "checking whether gcc has a sane -Wlogical-op... " >&6; } +if ${ac_cv_logical_op+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wlogical-op -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define FLAG 1 + int f (int r, int f) { return (r && (FLAG || (FLAG & f))); } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_logical_op=yes +else + ac_cv_logical_op=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_logical_op" >&5 +$as_echo "$ac_cv_logical_op" >&6; } + if test "x$ac_cv_logical_op" != "xno"; then + SANE_LOGICAL_OP_WARNING_TRUE= + SANE_LOGICAL_OP_WARNING_FALSE='#' +else + SANE_LOGICAL_OP_WARNING_TRUE='#' + SANE_LOGICAL_OP_WARNING_FALSE= +fi + + +# -Wduplicated-cond was added by GCC6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wduplicated-cond" >&5 +$as_echo_n "checking whether gcc accepts -Wduplicated-cond... " >&6; } +if ${ac_cv_duplicated_cond+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wduplicated-cond -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_duplicated_cond=yes +else + ac_cv_duplicated_cond=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_duplicated_cond" >&5 +$as_echo "$ac_cv_duplicated_cond" >&6; } + if test "x$ac_cv_duplicated_cond" != "xno"; then + HAVE_DUPLICATED_COND_WARNING_TRUE= + HAVE_DUPLICATED_COND_WARNING_FALSE='#' +else + HAVE_DUPLICATED_COND_WARNING_TRUE='#' + HAVE_DUPLICATED_COND_WARNING_FALSE= +fi + + +# -Wnull-dereference was added by GCC6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wnull-dereference" >&5 +$as_echo_n "checking whether gcc accepts -Wnull-dereference... " >&6; } +if ${ac_cv_null_dereference+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wnull-dereference -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_null_dereference=yes +else + ac_cv_null_dereference=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_null_dereference" >&5 +$as_echo "$ac_cv_null_dereference" >&6; } + if test "x$ac_cv_null_dereference" != "xno"; then + HAVE_NULL_DEREFERENCE_WARNING_TRUE= + HAVE_NULL_DEREFERENCE_WARNING_FALSE='#' +else + HAVE_NULL_DEREFERENCE_WARNING_TRUE='#' + HAVE_NULL_DEREFERENCE_WARNING_FALSE= +fi + + +# -Wimplicit-fallthrough was added by GCC7 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wimplicit-fallthrough" >&5 +$as_echo_n "checking whether gcc accepts -Wimplicit-fallthrough... " >&6; } +if ${ac_cv_implicit_fallthrough+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wimplicit-fallthrough -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_implicit_fallthrough=yes +else + ac_cv_implicit_fallthrough=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_implicit_fallthrough" >&5 +$as_echo "$ac_cv_implicit_fallthrough" >&6; } + if test "x$ac_cv_implicit_fallthrough" != "xno"; then + HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE= + HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE='#' +else + HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE='#' + HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE= +fi + + +# Check whether the compiler additionally accepts -Wimplicit-fallthrough=5 +# GCC accepts this and 5 means "don't parse any fallthrough comments and +# only accept the fallthrough attribute" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts -Wimplicit-fallthrough=5" >&5 +$as_echo_n "checking whether the compiler accepts -Wimplicit-fallthrough=5... " >&6; } +if ${ac_cv_implicit_fallthrough_5+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wimplicit-fallthrough=5 -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_implicit_fallthrough_5=yes +else + ac_cv_implicit_fallthrough_5=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_implicit_fallthrough_5" >&5 +$as_echo "$ac_cv_implicit_fallthrough_5" >&6; } + if test "x$ac_cv_implicit_fallthrough_5" != "xno"; then + HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE= + HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE='#' +else + HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE='#' + HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE= +fi + + +# Assume the fallthrough attribute is supported if -Wimplict-fallthrough is supported +if test "$ac_cv_implicit_fallthrough" = "yes"; then + +$as_echo "#define HAVE_FALLTHROUGH 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts -Wtrampolines" >&5 +$as_echo_n "checking whether the compiler accepts -Wtrampolines... " >&6; } +if ${ac_cv_trampolines+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wtrampolines -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_trampolines=yes +else + ac_cv_trampolines=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_trampolines" >&5 +$as_echo "$ac_cv_trampolines" >&6; } + if test "x$ac_cv_trampolines" != "xno"; then + HAVE_TRAMPOLINES_WARNING_TRUE= + HAVE_TRAMPOLINES_WARNING_FALSE='#' +else + HAVE_TRAMPOLINES_WARNING_TRUE='#' + HAVE_TRAMPOLINES_WARNING_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts -Wno-packed-not-aligned" >&5 +$as_echo_n "checking whether the compiler accepts -Wno-packed-not-aligned... " >&6; } +if ${ac_cv_no_packed_not_aligned+:} false; then : + $as_echo_n "(cached) " >&6 +else + old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wno-packed-not-aligned -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_no_packed_not_aligned=yes +else + ac_cv_no_packed_not_aligned=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_no_packed_not_aligned" >&5 +$as_echo "$ac_cv_no_packed_not_aligned" >&6; } + if test "x$ac_cv_no_packed_not_aligned" != "xno"; then + HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE= + HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE='#' +else + HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE='#' + HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE= +fi + + +saved_LIBS="$LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing argp_parse" >&5 +$as_echo_n "checking for library containing argp_parse... " >&6; } +if ${ac_cv_search_argp_parse+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char argp_parse (); +int +main () +{ +return argp_parse (); + ; + return 0; +} +_ACEOF +for ac_lib in '' argp; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_argp_parse=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_argp_parse+:} false; then : + break +fi +done +if ${ac_cv_search_argp_parse+:} false; then : + +else + ac_cv_search_argp_parse=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_argp_parse" >&5 +$as_echo "$ac_cv_search_argp_parse" >&6; } +ac_res=$ac_cv_search_argp_parse +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +LIBS="$saved_LIBS" +case "$ac_cv_search_argp_parse" in + no) { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to find argp_parse +See \`config.log' for more details" "$LINENO" 5; } ;; + -l*) argp_LDADD="$ac_cv_search_argp_parse" ;; + *) argp_LDADD= ;; +esac + + +saved_LIBS="$LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fts_close" >&5 +$as_echo_n "checking for library containing fts_close... " >&6; } +if ${ac_cv_search_fts_close+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char fts_close (); +int +main () +{ +return fts_close (); + ; + return 0; +} +_ACEOF +for ac_lib in '' fts; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_fts_close=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_fts_close+:} false; then : + break +fi +done +if ${ac_cv_search_fts_close+:} false; then : + +else + ac_cv_search_fts_close=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fts_close" >&5 +$as_echo "$ac_cv_search_fts_close" >&6; } +ac_res=$ac_cv_search_fts_close +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +LIBS="$saved_LIBS" +case "$ac_cv_search_fts_close" in + no) { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to find fts_close +See \`config.log' for more details" "$LINENO" 5; } ;; + -l*) fts_LIBS="$ac_cv_search_fts_close" ;; + *) fts_LIBS= ;; +esac + + +saved_LIBS="$LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing _obstack_free" >&5 +$as_echo_n "checking for library containing _obstack_free... " >&6; } +if ${ac_cv_search__obstack_free+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _obstack_free (); +int +main () +{ +return _obstack_free (); + ; + return 0; +} +_ACEOF +for ac_lib in '' obstack; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search__obstack_free=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search__obstack_free+:} false; then : + break +fi +done +if ${ac_cv_search__obstack_free+:} false; then : + +else + ac_cv_search__obstack_free=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search__obstack_free" >&5 +$as_echo "$ac_cv_search__obstack_free" >&6; } +ac_res=$ac_cv_search__obstack_free +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +LIBS="$saved_LIBS" +case "$ac_cv_search__obstack_free" in + no) { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to find _obstack_free +See \`config.log' for more details" "$LINENO" 5; } ;; + -l*) obstack_LIBS="$ac_cv_search__obstack_free" ;; + *) obstack_LIBS= ;; +esac + + + +ac_config_files="$ac_config_files doc/Makefile" + + +ac_config_files="$ac_config_files lib/Makefile" + + +ac_config_files="$ac_config_files libelf/Makefile" + + +ac_config_files="$ac_config_files libebl/Makefile" + + +ac_config_files="$ac_config_files libdwelf/Makefile" + + +ac_config_files="$ac_config_files libdw/Makefile" + + +ac_config_files="$ac_config_files libdwfl/Makefile" + + +ac_config_files="$ac_config_files libcpu/Makefile" + + +ac_config_files="$ac_config_files libasm/Makefile" + + +ac_config_files="$ac_config_files backends/Makefile" + + +ac_config_files="$ac_config_files src/Makefile po/Makefile.in" + + +ac_config_files="$ac_config_files tests/Makefile" + + +ac_config_files="$ac_config_files config/libelf.pc config/libdw.pc config/libdebuginfod.pc" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; USE_NLS=$enableval +else + USE_NLS=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + + + + + GETTEXT_MACRO_VERSION=0.20 + + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGFMT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test "$MSGFMT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 +$as_echo "$MSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GMSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT +if test -n "$GMSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 +$as_echo "$GMSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XGETTEXT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$XGETTEXT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test "$XGETTEXT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 +$as_echo "$XGETTEXT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + rm -f messages.po + + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGMERGE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGMERGE" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test "$MSGMERGE" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 +$as_echo "$MSGMERGE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' + else + if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' + else + MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' + fi + fi + + + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + + + ac_config_commands="$ac_config_commands po-directories" + + + + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld" >&5 +$as_echo_n "checking for ld... " >&6; } +elif test "$GCC" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + sparc64-*-netbsd*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + # The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + esac + +fi + + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking 32-bit host C ABI" >&5 +$as_echo_n "checking 32-bit host C ABI... " >&6; } +if ${gl_cv_host_cpu_c_abi_32bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$gl_cv_host_cpu_c_abi"; then + case "$gl_cv_host_cpu_c_abi" in + i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc) + gl_cv_host_cpu_c_abi_32bit=yes ;; + x86_64 | alpha | arm64 | hppa64 | ia64 | mips64 | powerpc64 | powerpc64-elfv2 | riscv*-lp64* | s390x | sparc64 ) + gl_cv_host_cpu_c_abi_32bit=no ;; + *) + gl_cv_host_cpu_c_abi_32bit=unknown ;; + esac + else + case "$host_cpu" in + + # CPUs that only support a 32-bit ABI. + arc \ + | bfin \ + | cris* \ + | csky \ + | epiphany \ + | ft32 \ + | h8300 \ + | m68k \ + | microblaze | microblazeel \ + | nds32 | nds32le | nds32be \ + | nios2 | nios2eb | nios2el \ + | or1k* \ + | or32 \ + | sh | sh1234 | sh1234elb \ + | tic6x \ + | xtensa* ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + # CPUs that only support a 64-bit ABI. + alpha | alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] \ + | mmix ) + gl_cv_host_cpu_c_abi_32bit=no + ;; + + i[34567]86 ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) \ + && !(defined __ILP32__ || defined _ILP32) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=yes +else + gl_cv_host_cpu_c_abi_32bit=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + riscv32 | riscv64 ) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + *) + gl_cv_host_cpu_c_abi_32bit=unknown + ;; + esac + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_host_cpu_c_abi_32bit" >&5 +$as_echo "$gl_cv_host_cpu_c_abi_32bit" >&6; } + + HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit" + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF binary format" >&5 +$as_echo_n "checking for ELF binary format... " >&6; } +if ${gl_cv_elf+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __ELF__ + Extensible Linking Format + #endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Extensible Linking Format" >/dev/null 2>&1; then : + gl_cv_elf=yes +else + gl_cv_elf=no +fi +rm -f conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_elf" >&5 +$as_echo "$gl_cv_elf" >&6; } + if test $gl_cv_elf; then + # Extract the ELF class of a file (5th byte) in decimal. + # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + if od -A x < /dev/null >/dev/null 2>/dev/null; then + # Use POSIX od. + func_elfclass () + { + od -A n -t d1 -j 4 -N 1 + } + else + # Use BSD hexdump. + func_elfclass () + { + dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "' + echo + } + fi + case $HOST_CPU_C_ABI_32BIT in + yes) + # 32-bit ABI. + acl_is_expected_elfclass () + { + test "`func_elfclass | sed -e 's/[ ]//g'`" = 1 + } + ;; + no) + # 64-bit ABI. + acl_is_expected_elfclass () + { + test "`func_elfclass | sed -e 's/[ ]//g'`" = 2 + } + ;; + *) + # Unknown. + acl_is_expected_elfclass () + { + : + } + ;; + esac + else + acl_is_expected_elfclass () + { + : + } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the common suffixes of directories in the library search path" >&5 +$as_echo_n "checking for the common suffixes of directories in the library search path... " >&6; } +if ${acl_cv_libdirstems+:} false; then : + $as_echo_n "(cached) " >&6 +else + acl_libdirstem=lib + acl_libdirstem2= + acl_libdirstem3= + case "$host_os" in + solaris*) + if test $HOST_CPU_C_ABI_32BIT = no; then + acl_libdirstem2=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem3=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem3=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test $HOST_CPU_C_ABI_32BIT != no; then + # 32-bit or unknown ABI. + if test -d /usr/lib32; then + acl_libdirstem2=lib32 + fi + fi + if test $HOST_CPU_C_ABI_32BIT != yes; then + # 64-bit or unknown ABI. + if test -d /usr/lib64; then + acl_libdirstem3=lib64 + fi + fi + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;; + */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib32 ) acl_libdirstem2=lib32 ;; + */lib64 ) acl_libdirstem3=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + if test $HOST_CPU_C_ABI_32BIT = yes; then + # 32-bit ABI. + acl_libdirstem3= + fi + if test $HOST_CPU_C_ABI_32BIT = no; then + # 64-bit ABI. + acl_libdirstem2= + fi + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_libdirstems" >&5 +$as_echo "$acl_cv_libdirstems" >&6; } + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'` + acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'` + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" + fi + fi + +fi + + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi + LIBICONV= + LTLIBICONV= + INCICONV= + LIBICONV_PREFIX= + HAVE_LIBICONV= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + fi + done + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then + haveit= + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$dependency_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$dependency_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 +$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } +if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFPreferencesCopyAppValue(NULL, NULL) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFPreferencesCopyAppValue=yes +else + gt_cv_func_CFPreferencesCopyAppValue=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 +$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + +$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyPreferredLanguages" >&5 +$as_echo_n "checking for CFLocaleCopyPreferredLanguages... " >&6; } +if ${gt_cv_func_CFLocaleCopyPreferredLanguages+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFLocaleCopyPreferredLanguages(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFLocaleCopyPreferredLanguages=yes +else + gt_cv_func_CFLocaleCopyPreferredLanguages=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyPreferredLanguages" >&5 +$as_echo "$gt_cv_func_CFLocaleCopyPreferredLanguages" >&6; } + if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + +$as_echo "#define HAVE_CFLOCALECOPYPREFERREDLANGUAGES 1" >>confdefs.h + + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes \ + || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + + + + + + + LIBINTL= + LTLIBINTL= + POSUB= + + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 +$as_echo_n "checking for GNU gettext in libc... " >&6; } +if eval \${$gt_func_gnugettext_libc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + +int +main () +{ + +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libc=yes" +else + eval "$gt_func_gnugettext_libc=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$gt_func_gnugettext_libc + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + +int +main () +{ +int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 16; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } + return result; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libintl-prefix was given. +if test "${with_libintl_prefix+set}" = set; then : + withval=$with_libintl_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" + fi + fi + +fi + + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi + LIBINTL= + LTLIBINTL= + INCINTL= + LIBINTL_PREFIX= + HAVE_LIBINTL= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='intl ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + fi + done + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then + haveit= + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$dependency_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$dependency_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" + ;; + esac + done + fi + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" + done + fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 +$as_echo_n "checking for GNU gettext in libintl... " >&6; } +if eval \${$gt_func_gnugettext_libintl+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + +int +main () +{ + +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libintl=yes" +else + eval "$gt_func_gnugettext_libintl=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + +int +main () +{ + +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS" +fi +eval ac_res=\$$gt_func_gnugettext_libintl + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + fi + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + else + USE_NLS=no + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 +$as_echo_n "checking whether to use NLS... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + if test "$USE_NLS" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 +$as_echo_n "checking where the gettext function comes from... " >&6; } + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 +$as_echo "$gt_source" >&6; } + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 +$as_echo_n "checking how to link with libintl... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 +$as_echo "$LIBINTL" >&6; } + + for element in $INCINTL; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + fi + + +$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h + + +$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h + + fi + + POSUB=po + fi + + + + INTLLIBS="$LIBINTL" + + + + + + + + + + + + +ac_config_files="$ac_config_files version.h:config/version.h.in" + + + +# 1.234 -> 1234 +case "$PACKAGE_VERSION" in +[0-9].*) eu_version=`echo "$PACKAGE_VERSION" | sed 's@\.@@'` ;; +*) as_fn_error $? "confused by version number '$PACKAGE_VERSION'" "$LINENO" 5 ;; +esac +case "$eu_version" in +*.*) + # 1234.567 -> "1234", "567" + eu_extra_version="${eu_version#*.}" + eu_version="${eu_version%%.*}" + case "$eu_extra_version" in + [0-9][0-9][0-9]) ;; + [0-9][0-9]) eu_extra_version="${eu_extra_version}0" ;; + [0-9]) eu_extra_version="${eu_extra_version}00" ;; + *) as_fn_error $? "confused by version number '$PACKAGE_VERSION'" "$LINENO" 5 ;; + esac + ;; +*) + eu_extra_version=000 + ;; +esac + +case "$eu_version" in + 0[0-9][0-9][0-9]) eu_version="${eu_version#0}$eu_extra_version" ;; +[0-9][0-9][0-9][0-9]) eu_version="${eu_version}$eu_extra_version" ;; +[0-9][0-9][0-9]) eu_version="${eu_version}0$eu_extra_version" ;; +[0-9][0-9]) eu_version="${eu_version}00$eu_extra_version";; +*) as_fn_error $? "confused by version number '$PACKAGE_VERSION'" "$LINENO" 5 ;; +esac + +# Round up to the next release API (x.y) version. +eu_version=$(( (eu_version + 999) / 1000 )) + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + +# On aarch64 before glibc 2.20 we would get the kernel user_pt_regs instead +# of the user_regs_struct from sys/user.h. They are structurally the same +# but we get either one or the other. +ac_fn_c_check_type "$LINENO" "struct user_regs_struct" "ac_cv_type_struct_user_regs_struct" "#include + #include + #include +" +if test "x$ac_cv_type_struct_user_regs_struct" = xyes; then : + sys_user_has_user_regs=yes +else + sys_user_has_user_regs=no +fi + +if test "$sys_user_has_user_regs" = "yes"; then + +$as_echo "#define HAVE_SYS_USER_REGS 1" >>confdefs.h + +fi + +# On a 64-bit host where can can use $CC -m32, we'll run two sets of tests. +# Likewise in a 32-bit build on a host where $CC -m64 works. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $CC option for 32-bit word size" >&5 +$as_echo_n "checking $CC option for 32-bit word size... " >&6; } +if ${utrace_cv_CC_m32+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CC="$CC" +utrace_cv_CC_m32=none +for ut_try in -m32 -m31; do + CC=`echo "$save_CC" | sed 's/ -m[36][241]//'`" $ut_try" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 1; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + utrace_cv_CC_m32=$ut_try +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test x$utrace_cv_CC_m32 = xnone || break +done +CC="$save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $utrace_cv_CC_m32" >&5 +$as_echo "$utrace_cv_CC_m32" >&6; } + +if test x$utrace_cv_CC_m32 != xnone; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 +$as_echo_n "checking for 64-bit host... " >&6; } +if ${utrace_cv_host64+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#if (UINTPTR_MAX > 0xffffffffUL) +@utrace_host64@ +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "@utrace_host64@" >/dev/null 2>&1; then : + utrace_cv_host64=yes +else + utrace_cv_host64=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $utrace_cv_host64" >&5 +$as_echo "$utrace_cv_host64" >&6; } +if test $utrace_cv_host64 = no; then : + utrace_biarch=-m64 utrace_thisarch=$utrace_cv_CC_m32 +else + utrace_biarch=$utrace_cv_CC_m32 utrace_thisarch=-m64 +fi + +biarch_CC=`echo "$CC" | sed "s/ *${utrace_thisarch}//"` +biarch_CC="$biarch_CC $utrace_biarch" +fi + +utrace_biarch_forced=no + +# Check whether --with-biarch was given. +if test "${with_biarch+set}" = set; then : + withval=$with_biarch; if test "x$with_biarch" != xno; then : + utrace_biarch_forced=yes +fi +fi + +if test $utrace_biarch_forced = yes; then : + utrace_cv_cc_biarch=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: enabling biarch tests regardless using $biarch_CC" >&5 +$as_echo "$as_me: enabling biarch tests regardless using $biarch_CC" >&6;} +else + if test x$utrace_cv_CC_m32 != xnone; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $biarch_CC makes executables we can run" >&5 +$as_echo_n "checking whether $biarch_CC makes executables we can run... " >&6; } +if ${utrace_cv_cc_biarch+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CC="$CC" +CC="$biarch_CC" +if test "$cross_compiling" = yes; then : + utrace_cv_cc_biarch=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + utrace_cv_cc_biarch=yes +else + utrace_cv_cc_biarch=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +CC="$save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $utrace_cv_cc_biarch" >&5 +$as_echo "$utrace_cv_cc_biarch" >&6; } +else + utrace_cv_cc_biarch=no +fi +if test $utrace_cv_cc_biarch != yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not running biarch tests, $biarch_CC does not work" >&5 +$as_echo "$as_me: WARNING: not running biarch tests, $biarch_CC does not work" >&2;} +fi +fi + if test $utrace_cv_cc_biarch = yes; then + BIARCH_TRUE= + BIARCH_FALSE='#' +else + BIARCH_TRUE='#' + BIARCH_FALSE= +fi + +# `$utrace_biarch' will be `-m64' even on an uniarch i386 machine. +CC_BIARCH="$CC $utrace_biarch" + + +# In maintainer mode we really need flex and bison. +# Otherwise we really need a release dir with maintainer files generated. +if test "x$enable_maintainer_mode" = xyes; then + # Extract the first word of "flex", so it can be a program name with args. +set dummy flex; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_FLEX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_FLEX"; then + ac_cv_prog_HAVE_FLEX="$HAVE_FLEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_FLEX="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_FLEX" && ac_cv_prog_HAVE_FLEX="no" +fi +fi +HAVE_FLEX=$ac_cv_prog_HAVE_FLEX +if test -n "$HAVE_FLEX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_FLEX" >&5 +$as_echo "$HAVE_FLEX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$HAVE_FLEX" = "no"; then + as_fn_error $? "flex needed in maintainer mode" "$LINENO" 5 + fi + # Extract the first word of "bison", so it can be a program name with args. +set dummy bison; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_BISON+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_BISON"; then + ac_cv_prog_HAVE_BISON="$HAVE_BISON" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_BISON="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_BISON" && ac_cv_prog_HAVE_BISON="no" +fi +fi +HAVE_BISON=$ac_cv_prog_HAVE_BISON +if test -n "$HAVE_BISON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_BISON" >&5 +$as_echo "$HAVE_BISON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$HAVE_BISON" = "no"; then + as_fn_error $? "bison needed in maintainer mode" "$LINENO" 5 + fi + # Extract the first word of "gawk", so it can be a program name with args. +set dummy gawk; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_GAWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_GAWK"; then + ac_cv_prog_HAVE_GAWK="$HAVE_GAWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_GAWK="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_GAWK" && ac_cv_prog_HAVE_GAWK="no" +fi +fi +HAVE_GAWK=$ac_cv_prog_HAVE_GAWK +if test -n "$HAVE_GAWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_GAWK" >&5 +$as_echo "$HAVE_GAWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$HAVE_GAWK" = "no"; then + as_fn_error $? "gawk needed in maintainer mode" "$LINENO" 5 + fi +else + if test ! -f ${srcdir}/libdw/known-dwarf.h; then + as_fn_error $? "No libdw/known-dwarf.h. configure --enable-maintainer-mode" "$LINENO" 5 + fi +fi + +# The testfiles are all compressed, we need bunzip2 when running make check +# Extract the first word of "bunzip2", so it can be a program name with args. +set dummy bunzip2; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_BUNZIP2+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_BUNZIP2"; then + ac_cv_prog_HAVE_BUNZIP2="$HAVE_BUNZIP2" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_BUNZIP2="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_BUNZIP2" && ac_cv_prog_HAVE_BUNZIP2="no" +fi +fi +HAVE_BUNZIP2=$ac_cv_prog_HAVE_BUNZIP2 +if test -n "$HAVE_BUNZIP2"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_BUNZIP2" >&5 +$as_echo "$HAVE_BUNZIP2" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "$HAVE_BUNZIP2" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No bunzip2, needed to run make check" >&5 +$as_echo "$as_me: WARNING: No bunzip2, needed to run make check" >&2;} +fi + +# For tests that need to use zstd compression +# Extract the first word of "zstd", so it can be a program name with args. +set dummy zstd; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_ZSTD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_ZSTD"; then + ac_cv_prog_HAVE_ZSTD="$HAVE_ZSTD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_ZSTD="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_ZSTD" && ac_cv_prog_HAVE_ZSTD="no" +fi +fi +HAVE_ZSTD=$ac_cv_prog_HAVE_ZSTD +if test -n "$HAVE_ZSTD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_ZSTD" >&5 +$as_echo "$HAVE_ZSTD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$HAVE_ZSTD" = "xyes"; then + HAVE_ZSTD_TRUE= + HAVE_ZSTD_FALSE='#' +else + HAVE_ZSTD_TRUE='#' + HAVE_ZSTD_FALSE= +fi + + +# Look for libcurl for libdebuginfod minimum version as per rhel7. +# Check whether --enable-libdebuginfod was given. +if test "${enable_libdebuginfod+set}" = set; then : + enableval=$enable_libdebuginfod; +fi + +if test "x$enable_libdebuginfod" != "xno"; then : + + if test "x$enable_libdebuginfod" != "xdummy"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking libdebuginfod dependencies, --disable-libdebuginfod or --enable-libdebuginfo=dummy to skip" >&5 +$as_echo "$as_me: checking libdebuginfod dependencies, --disable-libdebuginfod or --enable-libdebuginfo=dummy to skip" >&6;} + enable_libdebuginfod=yes # presume success + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcurl >= 7.29.0" >&5 +$as_echo_n "checking for libcurl >= 7.29.0... " >&6; } + +if test -n "$libcurl_CFLAGS"; then + pkg_cv_libcurl_CFLAGS="$libcurl_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcurl >= 7.29.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libcurl >= 7.29.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libcurl_CFLAGS=`$PKG_CONFIG --cflags "libcurl >= 7.29.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libcurl_LIBS"; then + pkg_cv_libcurl_LIBS="$libcurl_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcurl >= 7.29.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libcurl >= 7.29.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libcurl_LIBS=`$PKG_CONFIG --libs "libcurl >= 7.29.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libcurl_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcurl >= 7.29.0" 2>&1` + else + libcurl_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcurl >= 7.29.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libcurl_PKG_ERRORS" >&5 + + enable_libdebuginfod=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + enable_libdebuginfod=no +else + libcurl_CFLAGS=$pkg_cv_libcurl_CFLAGS + libcurl_LIBS=$pkg_cv_libcurl_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + if test "x$enable_libdebuginfod" = "xno"; then + as_fn_error $? "dependencies not found, use --disable-libdebuginfod to disable or --enable-libdebuginfod=dummy to build a (bootstrap) dummy library." "$LINENO" 5 + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: building (bootstrap) dummy libdebuginfo library" >&5 +$as_echo "$as_me: building (bootstrap) dummy libdebuginfo library" >&6;} + fi + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setname_np in -lpthread" >&5 +$as_echo_n "checking for pthread_setname_np in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_setname_np+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_setname_np (); +int +main () +{ +return pthread_setname_np (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_setname_np=yes +else + ac_cv_lib_pthread_pthread_setname_np=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_setname_np" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_setname_np" >&6; } +if test "x$ac_cv_lib_pthread_pthread_setname_np" = xyes; then : + + +$as_echo "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h + +fi + + +if test "x$enable_libdebuginfod" = "xyes" || test "x$enable_libdebuginfod" = "xdummy"; then : + +$as_echo "#define ENABLE_LIBDEBUGINFOD 1" >>confdefs.h + +fi +if test "x$enable_libdebuginfod" = "xdummy"; then : + +$as_echo "#define DUMMY_LIBDEBUGINFOD 1" >>confdefs.h + +fi + if test "x$enable_libdebuginfod" = "xyes" || test "x$enable_libdebuginfod" = "xdummy"; then + LIBDEBUGINFOD_TRUE= + LIBDEBUGINFOD_FALSE='#' +else + LIBDEBUGINFOD_TRUE='#' + LIBDEBUGINFOD_FALSE= +fi + + if test "x$enable_libdebuginfod" = "xdummy"; then + DUMMY_LIBDEBUGINFOD_TRUE= + DUMMY_LIBDEBUGINFOD_FALSE='#' +else + DUMMY_LIBDEBUGINFOD_TRUE='#' + DUMMY_LIBDEBUGINFOD_FALSE= +fi + + +# Look for libmicrohttpd, libarchive, sqlite for debuginfo server +# minimum versions as per rhel7. +# Check whether --enable-debuginfod was given. +if test "${enable_debuginfod+set}" = set; then : + enableval=$enable_debuginfod; +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + +if test "x$enable_debuginfod" != "xno"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking debuginfod C++11 support, --disable-debuginfod to skip" >&5 +$as_echo "$as_me: checking debuginfod C++11 support, --disable-debuginfod to skip" >&6;} + ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if ${ax_cv_cxx_compile_cxx11+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + + + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x +std=c++11 "-h std=c++11"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + ac_success=yes + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking debuginfod dependencies, --disable-debuginfod to skip" >&5 +$as_echo "$as_me: checking debuginfod dependencies, --disable-debuginfod to skip" >&6;} + if test "x$enable_libdebuginfod" = "xno"; then + as_fn_error $? "need libdebuginfod (or dummy), use --disable-debuginfod to disable." "$LINENO" 5 + fi + enable_debuginfod=yes # presume success + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd >= 0.9.33" >&5 +$as_echo_n "checking for libmicrohttpd >= 0.9.33... " >&6; } + +if test -n "$libmicrohttpd_CFLAGS"; then + pkg_cv_libmicrohttpd_CFLAGS="$libmicrohttpd_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.9.33\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.9.33") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libmicrohttpd_CFLAGS=`$PKG_CONFIG --cflags "libmicrohttpd >= 0.9.33" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libmicrohttpd_LIBS"; then + pkg_cv_libmicrohttpd_LIBS="$libmicrohttpd_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.9.33\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.9.33") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libmicrohttpd_LIBS=`$PKG_CONFIG --libs "libmicrohttpd >= 0.9.33" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libmicrohttpd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmicrohttpd >= 0.9.33" 2>&1` + else + libmicrohttpd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmicrohttpd >= 0.9.33" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libmicrohttpd_PKG_ERRORS" >&5 + + enable_debuginfod=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + enable_debuginfod=no +else + libmicrohttpd_CFLAGS=$pkg_cv_libmicrohttpd_CFLAGS + libmicrohttpd_LIBS=$pkg_cv_libmicrohttpd_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3 >= 3.7.17" >&5 +$as_echo_n "checking for sqlite3 >= 3.7.17... " >&6; } + +if test -n "$sqlite3_CFLAGS"; then + pkg_cv_sqlite3_CFLAGS="$sqlite3_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.7.17\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sqlite3 >= 3.7.17") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_sqlite3_CFLAGS=`$PKG_CONFIG --cflags "sqlite3 >= 3.7.17" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$sqlite3_LIBS"; then + pkg_cv_sqlite3_LIBS="$sqlite3_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.7.17\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sqlite3 >= 3.7.17") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_sqlite3_LIBS=`$PKG_CONFIG --libs "sqlite3 >= 3.7.17" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + sqlite3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sqlite3 >= 3.7.17" 2>&1` + else + sqlite3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sqlite3 >= 3.7.17" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$sqlite3_PKG_ERRORS" >&5 + + enable_debuginfod=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + enable_debuginfod=no +else + sqlite3_CFLAGS=$pkg_cv_sqlite3_CFLAGS + sqlite3_LIBS=$pkg_cv_sqlite3_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libarchive >= 3.1.2" >&5 +$as_echo_n "checking for libarchive >= 3.1.2... " >&6; } + +if test -n "$libarchive_CFLAGS"; then + pkg_cv_libarchive_CFLAGS="$libarchive_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libarchive >= 3.1.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libarchive >= 3.1.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libarchive_CFLAGS=`$PKG_CONFIG --cflags "libarchive >= 3.1.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libarchive_LIBS"; then + pkg_cv_libarchive_LIBS="$libarchive_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libarchive >= 3.1.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libarchive >= 3.1.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libarchive_LIBS=`$PKG_CONFIG --libs "libarchive >= 3.1.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libarchive_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libarchive >= 3.1.2" 2>&1` + else + libarchive_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libarchive >= 3.1.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libarchive_PKG_ERRORS" >&5 + + enable_debuginfod=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + enable_debuginfod=no +else + libarchive_CFLAGS=$pkg_cv_libarchive_CFLAGS + libarchive_LIBS=$pkg_cv_libarchive_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + if test "x$enable_debuginfod" = "xno"; then + as_fn_error $? "dependencies not found, use --disable-debuginfod to disable." "$LINENO" 5 + fi + +fi + +if test "x$enable_debuginfod" != "xno"; then : + +$as_echo "#define ENABLE_DEBUGINFOD 1" >>confdefs.h + +fi + if test "x$enable_debuginfod" = "xyes"; then + DEBUGINFOD_TRUE= + DEBUGINFOD_FALSE='#' +else + DEBUGINFOD_TRUE='#' + DEBUGINFOD_FALSE= +fi + + +default_debuginfod_urls="" +# Check whether --enable-debuginfod-urls was given. +if test "${enable_debuginfod_urls+set}" = set; then : + enableval=$enable_debuginfod_urls; if test "x${enableval}" = "xyes"; + then default_debuginfod_urls="https://debuginfod.elfutils.org/"; + elif test "x${enableval}" != "xno"; then + default_debuginfod_urls="${enableval}"; + fi +else + default_debuginfod_urls="" +fi + +DEBUGINFOD_URLS=$default_debuginfod_urls + +ac_config_files="$ac_config_files config/profile.sh config/profile.csh" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_LOCKS_TRUE}" && test -z "${USE_LOCKS_FALSE}"; then + as_fn_error $? "conditional \"USE_LOCKS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_STDATOMIC_H_TRUE}" && test -z "${HAVE_STDATOMIC_H_FALSE}"; then + as_fn_error $? "conditional \"HAVE_STDATOMIC_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GPROF_TRUE}" && test -z "${GPROF_FALSE}"; then + as_fn_error $? "conditional \"GPROF\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GCOV_TRUE}" && test -z "${GCOV_FALSE}"; then + as_fn_error $? "conditional \"GCOV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_VALGRIND_TRUE}" && test -z "${USE_VALGRIND_FALSE}"; then + as_fn_error $? "conditional \"USE_VALGRIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_VG_ANNOTATIONS_TRUE}" && test -z "${USE_VG_ANNOTATIONS_FALSE}"; then + as_fn_error $? "conditional \"USE_VG_ANNOTATIONS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${INSTALL_ELFH_TRUE}" && test -z "${INSTALL_ELFH_FALSE}"; then + as_fn_error $? "conditional \"INSTALL_ELFH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_STATIC_TRUE}" && test -z "${BUILD_STATIC_FALSE}"; then + as_fn_error $? "conditional \"BUILD_STATIC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TESTS_RPATH_TRUE}" && test -z "${TESTS_RPATH_FALSE}"; then + as_fn_error $? "conditional \"TESTS_RPATH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ZLIB_TRUE}" && test -z "${ZLIB_FALSE}"; then + as_fn_error $? "conditional \"ZLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BZLIB_TRUE}" && test -z "${BZLIB_FALSE}"; then + as_fn_error $? "conditional \"BZLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LZMA_TRUE}" && test -z "${LZMA_FALSE}"; then + as_fn_error $? "conditional \"LZMA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ZSTD_TRUE}" && test -z "${ZSTD_FALSE}"; then + as_fn_error $? "conditional \"ZSTD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DEMANGLE_TRUE}" && test -z "${DEMANGLE_FALSE}"; then + as_fn_error $? "conditional \"DEMANGLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FATAL_TEXTREL_TRUE}" && test -z "${FATAL_TEXTREL_FALSE}"; then + as_fn_error $? "conditional \"FATAL_TEXTREL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SYMBOL_VERSIONING_TRUE}" && test -z "${SYMBOL_VERSIONING_FALSE}"; then + as_fn_error $? "conditional \"SYMBOL_VERSIONING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ADD_STACK_USAGE_WARNING_TRUE}" && test -z "${ADD_STACK_USAGE_WARNING_FALSE}"; then + as_fn_error $? "conditional \"ADD_STACK_USAGE_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SANE_LOGICAL_OP_WARNING_TRUE}" && test -z "${SANE_LOGICAL_OP_WARNING_FALSE}"; then + as_fn_error $? "conditional \"SANE_LOGICAL_OP_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_DUPLICATED_COND_WARNING_TRUE}" && test -z "${HAVE_DUPLICATED_COND_WARNING_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DUPLICATED_COND_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_NULL_DEREFERENCE_WARNING_TRUE}" && test -z "${HAVE_NULL_DEREFERENCE_WARNING_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NULL_DEREFERENCE_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE}" && test -z "${HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE}"; then + as_fn_error $? "conditional \"HAVE_IMPLICIT_FALLTHROUGH_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE}" && test -z "${HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE}"; then + as_fn_error $? "conditional \"HAVE_IMPLICIT_FALLTHROUGH_5_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_TRAMPOLINES_WARNING_TRUE}" && test -z "${HAVE_TRAMPOLINES_WARNING_FALSE}"; then + as_fn_error $? "conditional \"HAVE_TRAMPOLINES_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE}" && test -z "${HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NO_PACKED_NOT_ALIGNED_WARNING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BIARCH_TRUE}" && test -z "${BIARCH_FALSE}"; then + as_fn_error $? "conditional \"BIARCH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_ZSTD_TRUE}" && test -z "${HAVE_ZSTD_FALSE}"; then + as_fn_error $? "conditional \"HAVE_ZSTD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBDEBUGINFOD_TRUE}" && test -z "${LIBDEBUGINFOD_FALSE}"; then + as_fn_error $? "conditional \"LIBDEBUGINFOD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DUMMY_LIBDEBUGINFOD_TRUE}" && test -z "${DUMMY_LIBDEBUGINFOD_FALSE}"; then + as_fn_error $? "conditional \"DUMMY_LIBDEBUGINFOD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DEBUGINFOD_TRUE}" && test -z "${DEBUGINFOD_FALSE}"; then + as_fn_error $? "conditional \"DEBUGINFOD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by elfutils $as_me 0.185, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to . +elfutils home page: ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +elfutils config.status 0.185 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" +# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. + OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config/Makefile") CONFIG_FILES="$CONFIG_FILES config/Makefile" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "elfutils.spec") CONFIG_FILES="$CONFIG_FILES elfutils.spec:config/elfutils.spec.in" ;; + "debuginfod/Makefile") CONFIG_FILES="$CONFIG_FILES debuginfod/Makefile" ;; + "debuginfod/debuginfod.h") CONFIG_FILES="$CONFIG_FILES debuginfod/debuginfod.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; + "libelf/Makefile") CONFIG_FILES="$CONFIG_FILES libelf/Makefile" ;; + "libebl/Makefile") CONFIG_FILES="$CONFIG_FILES libebl/Makefile" ;; + "libdwelf/Makefile") CONFIG_FILES="$CONFIG_FILES libdwelf/Makefile" ;; + "libdw/Makefile") CONFIG_FILES="$CONFIG_FILES libdw/Makefile" ;; + "libdwfl/Makefile") CONFIG_FILES="$CONFIG_FILES libdwfl/Makefile" ;; + "libcpu/Makefile") CONFIG_FILES="$CONFIG_FILES libcpu/Makefile" ;; + "libasm/Makefile") CONFIG_FILES="$CONFIG_FILES libasm/Makefile" ;; + "backends/Makefile") CONFIG_FILES="$CONFIG_FILES backends/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; + "config/libelf.pc") CONFIG_FILES="$CONFIG_FILES config/libelf.pc" ;; + "config/libdw.pc") CONFIG_FILES="$CONFIG_FILES config/libdw.pc" ;; + "config/libdebuginfod.pc") CONFIG_FILES="$CONFIG_FILES config/libdebuginfod.pc" ;; + "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; + "version.h") CONFIG_FILES="$CONFIG_FILES version.h:config/version.h.in" ;; + "config/profile.sh") CONFIG_FILES="$CONFIG_FILES config/profile.sh" ;; + "config/profile.csh") CONFIG_FILES="$CONFIG_FILES config/profile.csh" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "po-directories":C) + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + gt_tab=`printf '\t'` + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: +===================================================================== + elfutils: ${PACKAGE_VERSION} (eu_version: ${eu_version}) +===================================================================== + + Prefix : ${prefix} + Program prefix (\"eu-\" recommended) : ${program_prefix} + Source code location : ${srcdir} + Maintainer mode : ${enable_maintainer_mode} + build arch : ${ac_cv_build} + + RECOMMENDED FEATURES (should all be yes) + gzip support : ${with_zlib} + bzip2 support : ${with_bzlib} + lzma/xz support : ${with_lzma} + zstd support : ${with_zstd} + libstdc++ demangle support : ${enable_demangler} + File textrel check : ${enable_textrelcheck} + Symbol versioning : ${enable_symbol_versioning} + + NOT RECOMMENDED FEATURES (should all be no) + Experimental thread safety : ${use_locks} + install elf.h : ${install_elfh} + + OTHER FEATURES + Deterministic archives by default : ${default_ar_deterministic} + Native language support : ${USE_NLS} + Extra Valgrind annotations : ${use_vg_annotations} + libdebuginfod client support : ${enable_libdebuginfod} + Debuginfod server support : ${enable_debuginfod} + Default DEBUGINFOD_URLS : ${default_debuginfod_urls} + + EXTRA TEST FEATURES (used with make check) + have bunzip2 installed (required) : ${HAVE_BUNZIP2} + have zstd installed : ${HAVE_ZSTD} + debug branch prediction : ${use_debugpred} + gprof support : ${use_gprof} + gcov support : ${use_gcov} + run all tests under valgrind : ${use_valgrind} + gcc undefined behaviour sanitizer : ${use_undefined} + use rpath in tests : ${tests_use_rpath} + test biarch : ${utrace_cv_cc_biarch} +" >&5 +$as_echo "$as_me: +===================================================================== + elfutils: ${PACKAGE_VERSION} (eu_version: ${eu_version}) +===================================================================== + + Prefix : ${prefix} + Program prefix (\"eu-\" recommended) : ${program_prefix} + Source code location : ${srcdir} + Maintainer mode : ${enable_maintainer_mode} + build arch : ${ac_cv_build} + + RECOMMENDED FEATURES (should all be yes) + gzip support : ${with_zlib} + bzip2 support : ${with_bzlib} + lzma/xz support : ${with_lzma} + zstd support : ${with_zstd} + libstdc++ demangle support : ${enable_demangler} + File textrel check : ${enable_textrelcheck} + Symbol versioning : ${enable_symbol_versioning} + + NOT RECOMMENDED FEATURES (should all be no) + Experimental thread safety : ${use_locks} + install elf.h : ${install_elfh} + + OTHER FEATURES + Deterministic archives by default : ${default_ar_deterministic} + Native language support : ${USE_NLS} + Extra Valgrind annotations : ${use_vg_annotations} + libdebuginfod client support : ${enable_libdebuginfod} + Debuginfod server support : ${enable_debuginfod} + Default DEBUGINFOD_URLS : ${default_debuginfod_urls} + + EXTRA TEST FEATURES (used with make check) + have bunzip2 installed (required) : ${HAVE_BUNZIP2} + have zstd installed : ${HAVE_ZSTD} + debug branch prediction : ${use_debugpred} + gprof support : ${use_gprof} + gcov support : ${use_gcov} + run all tests under valgrind : ${use_valgrind} + gcc undefined behaviour sanitizer : ${use_undefined} + use rpath in tests : ${tests_use_rpath} + test biarch : ${utrace_cv_cc_biarch} +" >&6;} + +if test "$install_elfh" = yes; then + if test "${prefix}" = "/usr/local" -o "${prefix}" = "/usr"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: installing elf.h in ${includedir} might conflict with glibc/system elf.h" >&5 +$as_echo "$as_me: WARNING: installing elf.h in ${includedir} might conflict with glibc/system elf.h" >&2;} + fi +fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..b348a717 --- /dev/null +++ b/configure.ac @@ -0,0 +1,847 @@ +dnl Process this file with autoconf to produce a configure script. +dnl Configure input file for elfutils. -*-autoconf-*- +dnl +dnl Copyright (C) 1996-2019 Red Hat, Inc. +dnl +dnl This file is part of elfutils. +dnl +dnl This file is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl elfutils is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see . +AC_INIT([elfutils],[0.185],[https://sourceware.org/bugzilla],[elfutils],[http://elfutils.org/]) + +dnl Workaround for older autoconf < 2.64 +m4_ifndef([AC_PACKAGE_URL], + [AC_DEFINE([PACKAGE_URL], ["http://elfutils.org/"], + [Define to home page for this package]) + AC_SUBST([PACKAGE_URL], ["http://elfutils.org/"])]) + +LIBDEBUGINFOD_SONAME=libdebuginfod.so.1 +AC_SUBST([LIBDEBUGINFOD_SONAME]) + +# We want eu- as default program prefix if none was given by the user. +# But if the user explicitly provided --program-prefix="" then pretend +# it wasn't set at all (NONE). We want to test this really early before +# configure has a chance to use the value. + +if test "x$program_prefix" = "xNONE"; then + AC_MSG_NOTICE([No --program-prefix given, using "eu-"]) + program_prefix="eu-" +elif test "x$program_prefix" = "x"; then + AC_MSG_NOTICE([Using no program-prefix]) + program_prefix=NONE +fi + +AC_CONFIG_AUX_DIR([config]) +AC_CONFIG_FILES([config/Makefile]) + +AC_COPYRIGHT([Copyright (C) 1996-2021 The elfutils developers.]) +AC_PREREQ(2.63) dnl Minimum Autoconf version required. + +dnl We use GNU make extensions; automake 1.10 defaults to -Wportability. +AM_INIT_AUTOMAKE([gnits 1.11 -Wno-portability dist-bzip2 no-dist-gzip parallel-tests]) +AM_MAINTAINER_MODE + +AM_SILENT_RULES([yes]) + +AC_CONFIG_SRCDIR([libelf/libelf.h]) +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_HEADERS([config.h]) + +dnl The RPM spec file. We substitute a few values in the file. +AC_CONFIG_FILES([elfutils.spec:config/elfutils.spec.in]) + +dnl debuginfo-server client & server parts. +AC_CONFIG_FILES([debuginfod/Makefile debuginfod/debuginfod.h]) + +AC_CANONICAL_HOST + +AC_ARG_ENABLE(deterministic-archives, +[AS_HELP_STRING([--enable-deterministic-archives], + [ar and ranlib default to -D behavior])], [ +if test "${enableval}" = no; then + default_ar_deterministic=false +else + default_ar_deterministic=true +fi], [default_ar_deterministic=false]) +AC_DEFINE_UNQUOTED(DEFAULT_AR_DETERMINISTIC, $default_ar_deterministic, + [Should ar and ranlib use -D behavior by default?]) + +AC_ARG_ENABLE([thread-safety], +AS_HELP_STRING([--enable-thread-safety], + [enable thread safety of libraries EXPERIMENTAL]), + use_locks=$enableval, use_locks=no) +AM_CONDITIONAL(USE_LOCKS, test "$use_locks" = yes) +AS_IF([test "$use_locks" = yes], [AC_DEFINE(USE_LOCKS)]) +AS_IF([test "$use_locks" = yes], + [AC_MSG_WARN([thread-safety is EXPERIMENTAL tests might fail.])]) + +AH_TEMPLATE([USE_LOCKS], [Defined if libraries should be thread-safe.]) + +AC_PROG_CC +AC_PROG_RANLIB +AC_PROG_YACC +AM_PROG_LEX +# Only available since automake 1.12 +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +AC_CHECK_TOOL([READELF], [readelf]) +AC_CHECK_TOOL([NM], [nm]) + +# We use -std=gnu99 but have explicit checks for some language constructs +# and GNU extensions since some compilers claim GNU99 support, but don't +# really support all language extensions. In particular we need +# Mixed Declarations and Code +# https://gcc.gnu.org/onlinedocs/gcc/Mixed-Declarations.html +# Nested Functions +# https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html +# Arrays of Variable Length +# https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html +AC_CACHE_CHECK([for gcc with GNU99 support], ac_cv_c99, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -std=gnu99" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl +int foo (int a) +{ + for (int i = 0; i < a; ++i) if (i % 4) break; int s = a; return s; +} + +double bar (double a, double b) +{ + double square (double z) { return z * z; } + return square (a) + square (b); +} + +void baz (int n) +{ + struct S { int x[[n]]; }; +}])], + ac_cv_c99=yes, ac_cv_c99=no) +CFLAGS="$old_CFLAGS"]) +AS_IF([test "x$ac_cv_c99" != xyes], + AC_MSG_ERROR([gcc with GNU99 support required])) + +AC_CACHE_CHECK([whether gcc supports __attribute__((visibility()))], + ac_cv_visibility, [dnl +save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl +int __attribute__((visibility("hidden"))) +foo (int a) +{ + return a; +}])], ac_cv_visibility=yes, ac_cv_visibility=no) +CFLAGS="$save_CFLAGS"]) +if test "$ac_cv_visibility" = "yes"; then + AC_DEFINE([HAVE_VISIBILITY], [1], + [Defined if __attribute__((visibility())) is supported]) +fi + +AC_CACHE_CHECK([whether gcc supports __attribute__((gcc_struct))], + ac_cv_gcc_struct, [dnl +save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl +struct test { int x; } __attribute__((gcc_struct)); +])], ac_cv_gcc_struct=yes, ac_cv_gcc_struct=no) +CFLAGS="$save_CFLAGS"]) +if test "$ac_cv_gcc_struct" = "yes"; then + AC_DEFINE([HAVE_GCC_STRUCT], [1], + [Defined if __attribute__((gcc_struct)) is supported]) +fi + +AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl +save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -fPIC -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE()], ac_cv_fpic=yes, ac_cv_fpic=no) +CFLAGS="$save_CFLAGS" +]) +if test "$ac_cv_fpic" = "yes"; then + fpic_CFLAGS="-fPIC" +else + fpic_CFLAGS="" +fi +AC_SUBST([fpic_CFLAGS]) + +AC_CACHE_CHECK([whether gcc supports -fPIE], ac_cv_fpie, [dnl +save_CFLAGS="$CFLAGS" +CFLAGS="$save_CFLAGS -fPIE -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE()], ac_cv_fpie=yes, ac_cv_fpie=no) +CFLAGS="$save_CFLAGS" +]) +if test "$ac_cv_fpie" = "yes"; then + fpie_CFLAGS="-fPIE" +else + fpie_CFLAGS="" +fi +AC_SUBST([fpie_CFLAGS]) + +dso_LDFLAGS="-shared" + +ZDEFS_LDFLAGS="-Wl,-z,defs" +AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS" +AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no) +LDFLAGS="$save_LDFLAGS" +]) +if test "$ac_cv_zdefs" = "yes"; then + dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS" +fi + +# We really want build-ids. Warn and force generating them if gcc was +# configure without --enable-linker-build-id +AC_CACHE_CHECK([whether the compiler generates build-ids], ac_cv_buildid, [dnl +AC_LINK_IFELSE([AC_LANG_PROGRAM()],[ac_cv_buildid=yes; $READELF -n conftest$EXEEXT | grep -q NT_GNU_BUILD_ID || ac_cv_buildid=no],AC_MSG_FAILURE([unexpected compile failure]))]) +if test "$ac_cv_buildid" = "no"; then + AC_MSG_WARN([compiler doesn't generate build-id by default]) + LDFLAGS="$LDFLAGS -Wl,--build-id" +fi + +ZRELRO_LDFLAGS="-Wl,-z,relro" +AC_CACHE_CHECK([whether gcc supports $ZRELRO_LDFLAGS], ac_cv_zrelro, [dnl +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$ZRELRO_LDFLAGS $save_LDFLAGS" +AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zrelro=yes, ac_cv_zrelro=no) +LDFLAGS="$save_LDFLAGS" +]) +if test "$ac_cv_zrelro" = "yes"; then + dso_LDFLAGS="$dso_LDFLAGS $ZRELRO_LDFLAGS" +fi + +AC_SUBST([dso_LDFLAGS]) + +AC_CACHE_CHECK([for __thread support], ac_cv_tls, [dnl +# Use the same flags that we use for our DSOs, so the test is representative. +# Some old compiler/linker/libc combinations fail some ways and not others. +save_CFLAGS="$CFLAGS" +save_LDFLAGS="$LDFLAGS" +CFLAGS="$fpic_CFLAGS $CFLAGS" +LDFLAGS="$dso_LDFLAGS $LDFLAGS" +AC_LINK_IFELSE([dnl +AC_LANG_PROGRAM([[#include +#undef __thread +static __thread int a; int foo (int b) { return a + b; }]], + [[exit (foo (0));]])], + ac_cv_tls=yes, ac_cv_tls=no) +CFLAGS="$save_CFLAGS" +LDFLAGS="$save_LDFLAGS"]) +AS_IF([test "x$ac_cv_tls" != xyes], + AC_MSG_ERROR([__thread support required])) + +dnl Before 4.9 gcc doesn't ship stdatomic.h, but the necessary atomics are +dnl available by (at least) 4.7. So if the system doesn't have a stdatomic.h we +dnl fall back on one copied from FreeBSD that handles the difference. +AC_CACHE_CHECK([whether gcc provides stdatomic.h], ac_cv_has_stdatomic, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include ]])], + ac_cv_has_stdatomic=yes, ac_cv_has_stdatomic=no)]) +AM_CONDITIONAL(HAVE_STDATOMIC_H, test "x$ac_cv_has_stdatomic" = xyes) +AS_IF([test "x$ac_cv_has_stdatomic" = xyes], [AC_DEFINE(HAVE_STDATOMIC_H)]) + +AH_TEMPLATE([HAVE_STDATOMIC_H], [Define to 1 if `stdatomic.h` is provided by the + system, 0 otherwise.]) + +dnl This test must come as early as possible after the compiler configuration +dnl tests, because the choice of the file model can (in principle) affect +dnl whether functions and headers are available, whether they work, etc. +AC_SYS_LARGEFILE + +dnl Older glibc had a broken fts that didn't work with Large File Systems. +dnl We want the version that can handler LFS, but include workaround if we +dnl get a bad one. Add define to CFLAGS (not AC_DEFINE it) since we need to +dnl check it before including config.h (which might define _FILE_OFFSET_BITS). +AC_CACHE_CHECK([whether fts.h is bad when included (with LFS)], ac_cv_bad_fts, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include ]])], + ac_cv_bad_fts=no, ac_cv_bad_fts=yes)]) +AS_IF([test "x$ac_cv_bad_fts" = "xyes"], + [CFLAGS="$CFLAGS -DBAD_FTS=1" CXXFLAGS="$CXXFLAGS -DBAD_FTS=1"]) + +# See if we can add -D_FORTIFY_SOURCE=2. Don't do it if it is already +# (differently) defined or if it generates warnings/errors because we +# don't use the right optimisation level (string.h will warn about that). +AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CFLAGS]) +case "$CFLAGS" in + *-D_FORTIFY_SOURCE=2*) + AC_MSG_RESULT([no, already there]) + ;; + *) + save_CFLAGS="$CFLAGS" + CFLAGS="-D_FORTIFY_SOURCE=2 $CFLAGS -Werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #include + int main() { return 0; } + ]])], [ AC_MSG_RESULT([yes]) + CFLAGS="-D_FORTIFY_SOURCE=2 $save_CFLAGS" ], + [ AC_MSG_RESULT([no]) + CFLAGS="$save_CFLAGS"]) + ;; +esac + +dnl enable debugging of branch prediction. +AC_ARG_ENABLE([debugpred], +AS_HELP_STRING([--enable-debugpred],[build binaries with support to debug branch prediction]), +[use_debugpred=$enableval], [use_debugpred=no]) +case $use_debugpred in + yes) use_debugpred_val=1 ;; + *) use_debugpred_val=0 ;; +esac +AC_SUBST([DEBUGPRED], $use_debugpred_val) + +dnl Enable gprof support. +AC_ARG_ENABLE([gprof], +AS_HELP_STRING([--enable-gprof],[build binaries with gprof support]), [use_gprof=$enableval], [use_gprof=no]) +if test "$use_gprof" = yes; then + CFLAGS="$CFLAGS -pg" + LDFLAGS="$LDFLAGS -pg" +fi +AM_CONDITIONAL(GPROF, test "$use_gprof" = yes) + +# Enable gcov support. +AC_ARG_ENABLE([gcov], +AS_HELP_STRING([--enable-gcov],[build binaries with gcov support]), [use_gcov=$enableval], [use_gcov=no]) +if test "$use_gcov" = yes; then + CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" + CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage" + LDFLAGS="$LDFLAGS -fprofile-arcs" + AC_CHECK_PROG([GCOV], [gcov], [gcov]) + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) +fi +AM_CONDITIONAL(GCOV, test "$use_gcov" = yes) + +AC_ARG_ENABLE([sanitize-undefined], + AS_HELP_STRING([--enable-sanitize-undefined], + [Use gcc undefined behaviour sanitizer]), + [use_undefined=$enableval], [use_undefined=no]) +if test "$use_undefined" = yes; then + old_CFLAGS="$CFLAGS" + old_CXXFLAGS="$CXXFLAGS" + # We explicitly use unaligned access when possible (see ALLOW_UNALIGNED) + # We want to fail immediately on first error, don't try to recover. + CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize-recover" + CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover" + AC_LINK_IFELSE([AC_LANG_SOURCE([int main (int argc, char **argv) { return 0; }])], use_undefined=yes, use_undefined=no) + AS_IF([test "x$use_undefined" != xyes], + AC_MSG_WARN([gcc undefined behaviour sanitizer not available]) + CFLAGS="$old_CFLAGS" CXXFLAGS="$old_CXXFLAGS") +fi +case $use_undefined in + yes) check_undefined_val=1 ;; + *) check_undefined_val=0 ;; +esac +AC_DEFINE_UNQUOTED(CHECK_UNDEFINED, $check_undefined_val, + [Building with -fsanitize=undefined or not]) + +AC_ARG_ENABLE([valgrind], +AS_HELP_STRING([--enable-valgrind],[run all tests under valgrind]), +[use_valgrind=$enableval], [use_valgrind=no]) +if test "$use_valgrind" = yes; then + AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no) + if test "$HAVE_VALGRIND" = "no"; then + AC_MSG_ERROR([valgrind not found]) + fi +fi +AM_CONDITIONAL(USE_VALGRIND, test "$use_valgrind" = yes) + +AC_ARG_WITH([valgrind], +AS_HELP_STRING([--with-valgrind],[include directory for Valgrind headers]), +[with_valgrind_headers=$withval], [with_valgrind_headers=no]) +if test "x$with_valgrind_headers" != xno; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I$with_valgrind_headers" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #include + int main() { return 0; } + ]])], [ HAVE_VALGRIND_HEADERS="yes" + CFLAGS="$save_CFLAGS -I$with_valgrind_headers" ], + [ AC_MSG_ERROR([invalid valgrind include directory: $with_valgrind_headers]) ]) +fi + +AC_ARG_ENABLE([valgrind-annotations], +AS_HELP_STRING([--enable-valgrind-annotations],[insert extra annotations for better valgrind support]), +[use_vg_annotations=$enableval], [use_vg_annotations=no]) +if test "$use_vg_annotations" = yes; then + if test "x$HAVE_VALGRIND_HEADERS" != "xyes"; then + AC_MSG_CHECKING([whether Valgrind headers are available]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #include + int main() { return 0; } + ]])], [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_ERROR([valgrind annotations requested but no headers are available]) ]) + fi +fi +AM_CONDITIONAL(USE_VG_ANNOTATIONS, test "$use_vg_annotations" = yes) + +AC_ARG_ENABLE([install-elfh], +AS_HELP_STRING([--enable-install-elfh],[install elf.h in include dir]), + [install_elfh=$enableval], [install_elfh=no]) +AM_CONDITIONAL(INSTALL_ELFH, test "$install_elfh" = yes) + +AM_CONDITIONAL(BUILD_STATIC, [dnl +test "$use_gprof" = yes -o "$use_gcov" = yes]) + +AC_ARG_ENABLE([tests-rpath], +AS_HELP_STRING([--enable-tests-rpath],[build $ORIGIN-using rpath into tests]), + [tests_use_rpath=$enableval], [tests_use_rpath=no]) +AM_CONDITIONAL(TESTS_RPATH, test "$tests_use_rpath" = yes) + +dnl zlib is mandatory. +save_LIBS="$LIBS" +LIBS= +eu_ZIPLIB(zlib,ZLIB,z,gzdirect,gzip) +AS_IF([test "x$with_zlib" = xno], [AC_MSG_ERROR([zlib not found but is required])]) +LIBS="$save_LIBS" + +dnl Test for bzlib and xz/lzma/zstd, gives BZLIB/LZMALIB/ZSTD .am +dnl conditional and config.h USE_BZLIB/USE_LZMALIB/USE_ZSTD #define. +save_LIBS="$LIBS" +LIBS= +eu_ZIPLIB(bzlib,BZLIB,bz2,BZ2_bzdopen,bzip2) +# We need this since bzip2 doesn't have a pkgconfig file. +BZ2_LIB="$LIBS" +AC_SUBST([BZ2_LIB]) +eu_ZIPLIB(lzma,LZMA,lzma,lzma_auto_decoder,[LZMA (xz)]) +AS_IF([test "x$with_lzma" = xyes], [LIBLZMA="liblzma"], [LIBLZMA=""]) +AC_SUBST([LIBLZMA]) +eu_ZIPLIB(zstd,ZSTD,zstd,ZSTD_decompress,[ZSTD (zst)]) +AS_IF([test "x$with_zstd" = xyes], [LIBZSTD="libzstd"], [LIBLZSTD=""]) +AC_SUBST([LIBZSTD]) +zip_LIBS="$LIBS" +LIBS="$save_LIBS" +AC_SUBST([zip_LIBS]) + +AC_CHECK_DECLS([memrchr, rawmemchr],[],[], + [#define _GNU_SOURCE + #include ]) +AC_CHECK_DECLS([powerof2],[],[],[#include ]) +AC_CHECK_DECLS([mempcpy],[],[], + [#define _GNU_SOURCE + #include ]) + +AC_CHECK_FUNCS([process_vm_readv]) + +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -D_GNU_SOURCE" +AC_FUNC_STRERROR_R() +CFLAGS="$old_CFLAGS" + +AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl +AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])]) +AM_CONDITIONAL(DEMANGLE, test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes") +AS_IF([test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes"], + [enable_demangler=yes],[enable_demangler=no]) + +AC_ARG_ENABLE([textrelcheck], +AS_HELP_STRING([--disable-textrelcheck], + [Disable textrelcheck being a fatal error])) +AM_CONDITIONAL(FATAL_TEXTREL, [test "x$enable_textrelcheck" != "xno"]) +AS_IF([test "x$enable_textrelcheck" != "xno"], + [enable_textrelcheck=yes],[enable_textrelcheck=no]) + +AC_ARG_ENABLE([symbol-versioning], +AS_HELP_STRING([--disable-symbol-versioning], + [Disable symbol versioning in shared objects])) + +AC_CACHE_CHECK([whether symbol versioning is supported], ac_cv_symbol_versioning, [dnl +AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl +#define NEW_VERSION(name, version) \ + asm (".symver " #name "," #name "@@@" #version); +int foo(int x) { return x + 1; } +NEW_VERSION (foo, ELFUTILS_12.12) +])], ac_cv_symbol_versioning=yes, ac_cv_symbol_versioning=no)]) +if test "$ac_cv_symbol_versioning" = "no"; then + if test "x$enable_symbol_versioning" != "xno"; then + AC_MSG_ERROR([Symbol versioning is not supported. + Use --disable-symbol-versioning to build without.]) + fi +fi + +AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"]) +AS_IF([test "x$enable_symbol_versioning" = "xno"], + [AC_MSG_WARN([Disabling symbol versioning breaks ABI compatibility.]) + enable_symbol_versioning=no],[enable_symbol_versioning=yes]) + +AC_CACHE_CHECK([whether gcc accepts -Wstack-usage], ac_cv_stack_usage, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wstack-usage=262144 -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_stack_usage=yes, ac_cv_stack_usage=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(ADD_STACK_USAGE_WARNING, [test "x$ac_cv_stack_usage" != "xno"]) + +# -Wlogical-op was too fragile in the past, make sure we get a sane one. +AC_CACHE_CHECK([whether gcc has a sane -Wlogical-op], ac_cv_logical_op, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wlogical-op -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [#define FLAG 1 + int f (int r, int f) { return (r && (FLAG || (FLAG & f))); }])], + ac_cv_logical_op=yes, ac_cv_logical_op=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(SANE_LOGICAL_OP_WARNING, + [test "x$ac_cv_logical_op" != "xno"]) + +# -Wduplicated-cond was added by GCC6 +AC_CACHE_CHECK([whether gcc accepts -Wduplicated-cond], ac_cv_duplicated_cond, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wduplicated-cond -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_duplicated_cond=yes, ac_cv_duplicated_cond=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(HAVE_DUPLICATED_COND_WARNING, + [test "x$ac_cv_duplicated_cond" != "xno"]) + +# -Wnull-dereference was added by GCC6 +AC_CACHE_CHECK([whether gcc accepts -Wnull-dereference], ac_cv_null_dereference, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wnull-dereference -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_null_dereference=yes, ac_cv_null_dereference=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(HAVE_NULL_DEREFERENCE_WARNING, + [test "x$ac_cv_null_dereference" != "xno"]) + +# -Wimplicit-fallthrough was added by GCC7 +AC_CACHE_CHECK([whether gcc accepts -Wimplicit-fallthrough], ac_cv_implicit_fallthrough, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wimplicit-fallthrough -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_implicit_fallthrough=yes, ac_cv_implicit_fallthrough=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_WARNING, + [test "x$ac_cv_implicit_fallthrough" != "xno"]) + +# Check whether the compiler additionally accepts -Wimplicit-fallthrough=5 +# GCC accepts this and 5 means "don't parse any fallthrough comments and +# only accept the fallthrough attribute" +AC_CACHE_CHECK([whether the compiler accepts -Wimplicit-fallthrough=5], ac_cv_implicit_fallthrough_5, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wimplicit-fallthrough=5 -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_implicit_fallthrough_5=yes, ac_cv_implicit_fallthrough_5=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_5_WARNING, + [test "x$ac_cv_implicit_fallthrough_5" != "xno"]) + +# Assume the fallthrough attribute is supported if -Wimplict-fallthrough is supported +if test "$ac_cv_implicit_fallthrough" = "yes"; then + AC_DEFINE([HAVE_FALLTHROUGH], [1], + [Defined if __attribute__((fallthrough)) is supported]) +fi + +AC_CACHE_CHECK([whether the compiler accepts -Wtrampolines], ac_cv_trampolines, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wtrampolines -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_trampolines=yes, ac_cv_trampolines=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(HAVE_TRAMPOLINES_WARNING, + [test "x$ac_cv_trampolines" != "xno"]) + +AC_CACHE_CHECK([whether the compiler accepts -Wno-packed-not-aligned], ac_cv_no_packed_not_aligned, [dnl +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wno-packed-not-aligned -Werror" +AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], + ac_cv_no_packed_not_aligned=yes, ac_cv_no_packed_not_aligned=no) +CFLAGS="$old_CFLAGS"]) +AM_CONDITIONAL(HAVE_NO_PACKED_NOT_ALIGNED_WARNING, + [test "x$ac_cv_no_packed_not_aligned" != "xno"]) + +saved_LIBS="$LIBS" +AC_SEARCH_LIBS([argp_parse], [argp]) +LIBS="$saved_LIBS" +case "$ac_cv_search_argp_parse" in + no) AC_MSG_FAILURE([failed to find argp_parse]) ;; + -l*) argp_LDADD="$ac_cv_search_argp_parse" ;; + *) argp_LDADD= ;; +esac +AC_SUBST([argp_LDADD]) + +saved_LIBS="$LIBS" +AC_SEARCH_LIBS([fts_close], [fts]) +LIBS="$saved_LIBS" +case "$ac_cv_search_fts_close" in + no) AC_MSG_FAILURE([failed to find fts_close]) ;; + -l*) fts_LIBS="$ac_cv_search_fts_close" ;; + *) fts_LIBS= ;; +esac +AC_SUBST([fts_LIBS]) + +saved_LIBS="$LIBS" +AC_SEARCH_LIBS([_obstack_free], [obstack]) +LIBS="$saved_LIBS" +case "$ac_cv_search__obstack_free" in + no) AC_MSG_FAILURE([failed to find _obstack_free]) ;; + -l*) obstack_LIBS="$ac_cv_search__obstack_free" ;; + *) obstack_LIBS= ;; +esac +AC_SUBST([obstack_LIBS]) + +dnl The directories with content. + +dnl Documentation. +AC_CONFIG_FILES([doc/Makefile]) + +dnl Support library. +AC_CONFIG_FILES([lib/Makefile]) + +dnl ELF library. +AC_CONFIG_FILES([libelf/Makefile]) + +dnl Higher-level ELF support library. +AC_CONFIG_FILES([libebl/Makefile]) + +dnl DWARF-ELF Lower-level Functions support library. +AC_CONFIG_FILES([libdwelf/Makefile]) + +dnl DWARF library. +AC_CONFIG_FILES([libdw/Makefile]) + +dnl Higher-level DWARF support library. +AC_CONFIG_FILES([libdwfl/Makefile]) + +dnl CPU handling library. +AC_CONFIG_FILES([libcpu/Makefile]) + +dnl Assembler library. +AC_CONFIG_FILES([libasm/Makefile]) + +dnl CPU-specific backend libraries. +AC_CONFIG_FILES([backends/Makefile]) + +dnl Tools. +AC_CONFIG_FILES([src/Makefile po/Makefile.in]) + +dnl Test suite. +AC_CONFIG_FILES([tests/Makefile]) + +dnl pkgconfig files +AC_CONFIG_FILES([config/libelf.pc config/libdw.pc config/libdebuginfod.pc]) + +dnl As long as "git grep 'PRI[diouxX]' po" reports matches in +dnl translatable strings, we must use need-formatstring-macros here. +AM_GNU_GETTEXT([external], [need-formatstring-macros]) + +dnl AM_GNU_GETTEXT_VERSION is still needed for old versions +dnl of autoreconf that do not recognize AM_GNU_GETTEXT_REQUIRE_VERSION. +dnl 0.19.6 is the first version of gettext that provides +dnl AM_GNU_GETTEXT_REQUIRE_VERSION support. +AM_GNU_GETTEXT_VERSION([0.19.6]) +AM_GNU_GETTEXT_REQUIRE_VERSION([0.19.6]) + +dnl Appended to the config.h file. +dnl We hide all kinds of configuration magic in lib/eu-config.h. +AH_BOTTOM([#include ]) + +dnl Version compatibility header. +AC_CONFIG_FILES([version.h:config/version.h.in]) +AC_SUBST([eu_version]) + +# 1.234 -> 1234 +case "$PACKAGE_VERSION" in +[[0-9]].*) eu_version=`echo "$PACKAGE_VERSION" | sed 's@\.@@'` ;; +*) AC_MSG_ERROR([confused by version number '$PACKAGE_VERSION']) ;; +esac +case "$eu_version" in +*.*) + # 1234.567 -> "1234", "567" + eu_extra_version="${eu_version#*.}" + eu_version="${eu_version%%.*}" + case "$eu_extra_version" in + [[0-9]][[0-9]][[0-9]]) ;; + [[0-9]][[0-9]]) eu_extra_version="${eu_extra_version}0" ;; + [[0-9]]) eu_extra_version="${eu_extra_version}00" ;; + *) AC_MSG_ERROR([confused by version number '$PACKAGE_VERSION']) ;; + esac + ;; +*) + eu_extra_version=000 + ;; +esac + +case "$eu_version" in + 0[[0-9]][[0-9]][[0-9]]) eu_version="${eu_version#0}$eu_extra_version" ;; +[[0-9]][[0-9]][[0-9]][[0-9]]) eu_version="${eu_version}$eu_extra_version" ;; +[[0-9]][[0-9]][[0-9]]) eu_version="${eu_version}0$eu_extra_version" ;; +[[0-9]][[0-9]]) eu_version="${eu_version}00$eu_extra_version";; +*) AC_MSG_ERROR([confused by version number '$PACKAGE_VERSION']) ;; +esac + +# Round up to the next release API (x.y) version. +eu_version=$(( (eu_version + 999) / 1000 )) + +AC_CHECK_SIZEOF(long) + +# On aarch64 before glibc 2.20 we would get the kernel user_pt_regs instead +# of the user_regs_struct from sys/user.h. They are structurally the same +# but we get either one or the other. +AC_CHECK_TYPE([struct user_regs_struct], + [sys_user_has_user_regs=yes], [sys_user_has_user_regs=no], + [[#include ] + [#include ] + [#include ]]) +if test "$sys_user_has_user_regs" = "yes"; then + AC_DEFINE(HAVE_SYS_USER_REGS, 1, + [Define to 1 if defines struct user_regs_struct]) +fi + +# On a 64-bit host where can can use $CC -m32, we'll run two sets of tests. +# Likewise in a 32-bit build on a host where $CC -m64 works. +utrace_BIARCH +# `$utrace_biarch' will be `-m64' even on an uniarch i386 machine. +CC_BIARCH="$CC $utrace_biarch" +AC_SUBST([CC_BIARCH]) + +# In maintainer mode we really need flex and bison. +# Otherwise we really need a release dir with maintainer files generated. +if test "x$enable_maintainer_mode" = xyes; then + AC_CHECK_PROG(HAVE_FLEX, flex, yes, no) + if test "$HAVE_FLEX" = "no"; then + AC_MSG_ERROR([flex needed in maintainer mode]) + fi + AC_CHECK_PROG(HAVE_BISON, bison, yes, no) + if test "$HAVE_BISON" = "no"; then + AC_MSG_ERROR([bison needed in maintainer mode]) + fi + AC_CHECK_PROG(HAVE_GAWK, gawk, yes, no) + if test "$HAVE_GAWK" = "no"; then + AC_MSG_ERROR([gawk needed in maintainer mode]) + fi +else + if test ! -f ${srcdir}/libdw/known-dwarf.h; then + AC_MSG_ERROR([No libdw/known-dwarf.h. configure --enable-maintainer-mode]) + fi +fi + +# The testfiles are all compressed, we need bunzip2 when running make check +AC_CHECK_PROG(HAVE_BUNZIP2, bunzip2, yes, no) +if test "$HAVE_BUNZIP2" = "no"; then + AC_MSG_WARN([No bunzip2, needed to run make check]) +fi + +# For tests that need to use zstd compression +AC_CHECK_PROG(HAVE_ZSTD, zstd, yes, no) +AM_CONDITIONAL([HAVE_ZSTD],[test "x$HAVE_ZSTD" = "xyes"]) + +# Look for libcurl for libdebuginfod minimum version as per rhel7. +AC_ARG_ENABLE([libdebuginfod],AC_HELP_STRING([--enable-libdebuginfod], [Build debuginfod client library (can be =dummy)])) +AS_IF([test "x$enable_libdebuginfod" != "xno"], [ + if test "x$enable_libdebuginfod" != "xdummy"; then + AC_MSG_NOTICE([checking libdebuginfod dependencies, --disable-libdebuginfod or --enable-libdebuginfo=dummy to skip]) + enable_libdebuginfod=yes # presume success + PKG_PROG_PKG_CONFIG + PKG_CHECK_MODULES([libcurl],[libcurl >= 7.29.0],[],[enable_libdebuginfod=no]) + if test "x$enable_libdebuginfod" = "xno"; then + AC_MSG_ERROR([dependencies not found, use --disable-libdebuginfod to disable or --enable-libdebuginfod=dummy to build a (bootstrap) dummy library.]) + fi + else + AC_MSG_NOTICE([building (bootstrap) dummy libdebuginfo library]) + fi +]) + +AC_CHECK_LIB(pthread, pthread_setname_np, [ + AC_DEFINE([HAVE_PTHREAD_SETNAME_NP],[1],[Enable pthread_setname_np])]) + +AS_IF([test "x$enable_libdebuginfod" = "xyes" || test "x$enable_libdebuginfod" = "xdummy"], + [AC_DEFINE([ENABLE_LIBDEBUGINFOD], [1], [Enable libdebuginfod])]) +AS_IF([test "x$enable_libdebuginfod" = "xdummy"], + [AC_DEFINE([DUMMY_LIBDEBUGINFOD], [1], [Build dummy libdebuginfod])]) +AM_CONDITIONAL([LIBDEBUGINFOD],[test "x$enable_libdebuginfod" = "xyes" || test "x$enable_libdebuginfod" = "xdummy"]) +AM_CONDITIONAL([DUMMY_LIBDEBUGINFOD],[test "x$enable_libdebuginfod" = "xdummy"]) + +# Look for libmicrohttpd, libarchive, sqlite for debuginfo server +# minimum versions as per rhel7. +AC_ARG_ENABLE([debuginfod],AC_HELP_STRING([--enable-debuginfod], [Build debuginfod server])) +AC_PROG_CXX +AS_IF([test "x$enable_debuginfod" != "xno"], [ + AC_MSG_NOTICE([checking debuginfod C++11 support, --disable-debuginfod to skip]) + AX_CXX_COMPILE_STDCXX(11, noext, mandatory) + AC_MSG_NOTICE([checking debuginfod dependencies, --disable-debuginfod to skip]) + if test "x$enable_libdebuginfod" = "xno"; then + AC_MSG_ERROR([need libdebuginfod (or dummy), use --disable-debuginfod to disable.]) + fi + enable_debuginfod=yes # presume success + PKG_PROG_PKG_CONFIG + PKG_CHECK_MODULES([libmicrohttpd],[libmicrohttpd >= 0.9.33],[],[enable_debuginfod=no]) + PKG_CHECK_MODULES([sqlite3],[sqlite3 >= 3.7.17],[],[enable_debuginfod=no]) + PKG_CHECK_MODULES([libarchive],[libarchive >= 3.1.2],[],[enable_debuginfod=no]) + if test "x$enable_debuginfod" = "xno"; then + AC_MSG_ERROR([dependencies not found, use --disable-debuginfod to disable.]) + fi +]) + +AS_IF([test "x$enable_debuginfod" != "xno"],AC_DEFINE([ENABLE_DEBUGINFOD],[1],[Build debuginfod])) +AM_CONDITIONAL([DEBUGINFOD],[test "x$enable_debuginfod" = "xyes"]) + +dnl for /etc/profile.d/elfutils.{csh,sh} +default_debuginfod_urls="" +AC_ARG_ENABLE(debuginfod-urls, + [AS_HELP_STRING([--enable-debuginfod-urls@<:@=URLS@:>@],[add URLS to profile.d DEBUGINFOD_URLS])], + [if test "x${enableval}" = "xyes"; + then default_debuginfod_urls="https://debuginfod.elfutils.org/"; + elif test "x${enableval}" != "xno"; then + default_debuginfod_urls="${enableval}"; + fi], + [default_debuginfod_urls=""]) +AC_SUBST(DEBUGINFOD_URLS, $default_debuginfod_urls) +AC_CONFIG_FILES([config/profile.sh config/profile.csh]) + +AC_OUTPUT + +AC_MSG_NOTICE([ +===================================================================== + elfutils: ${PACKAGE_VERSION} (eu_version: ${eu_version}) +===================================================================== + + Prefix : ${prefix} + Program prefix ("eu-" recommended) : ${program_prefix} + Source code location : ${srcdir} + Maintainer mode : ${enable_maintainer_mode} + build arch : ${ac_cv_build} + + RECOMMENDED FEATURES (should all be yes) + gzip support : ${with_zlib} + bzip2 support : ${with_bzlib} + lzma/xz support : ${with_lzma} + zstd support : ${with_zstd} + libstdc++ demangle support : ${enable_demangler} + File textrel check : ${enable_textrelcheck} + Symbol versioning : ${enable_symbol_versioning} + + NOT RECOMMENDED FEATURES (should all be no) + Experimental thread safety : ${use_locks} + install elf.h : ${install_elfh} + + OTHER FEATURES + Deterministic archives by default : ${default_ar_deterministic} + Native language support : ${USE_NLS} + Extra Valgrind annotations : ${use_vg_annotations} + libdebuginfod client support : ${enable_libdebuginfod} + Debuginfod server support : ${enable_debuginfod} + Default DEBUGINFOD_URLS : ${default_debuginfod_urls} + + EXTRA TEST FEATURES (used with make check) + have bunzip2 installed (required) : ${HAVE_BUNZIP2} + have zstd installed : ${HAVE_ZSTD} + debug branch prediction : ${use_debugpred} + gprof support : ${use_gprof} + gcov support : ${use_gcov} + run all tests under valgrind : ${use_valgrind} + gcc undefined behaviour sanitizer : ${use_undefined} + use rpath in tests : ${tests_use_rpath} + test biarch : ${utrace_cv_cc_biarch} +]) + +if test "$install_elfh" = yes; then + if test "${prefix}" = "/usr/local" -o "${prefix}" = "/usr"; then + AC_MSG_WARN([installing elf.h in ${includedir} might conflict with glibc/system elf.h]) + fi +fi diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog new file mode 100644 index 00000000..21407dc2 --- /dev/null +++ b/debuginfod/ChangeLog @@ -0,0 +1,643 @@ +2021-05-14 Frank Ch. Eigler + + PR27859 + * debuginfod-client.c (debuginfod_client): Retain only + long-lived multi handle from PR27701 work. + (debuginfo_begin,debuginfod_end): ctor/dtor for surviving field only. + (debuginfod_query_server): Rework to reuse multi handle only. + +2021-04-19 Martin Liska + + * debuginfod-client.c (debuginfod_query_server): Use startswith. + (debuginfod_add_http_header): Likewise. + * debuginfod.cxx: Likewise. + +2021-05-04 Alice Zhang + + * debuginfod-client.c (cache_miss_default_s): New static time_t, + defaults to 600 (10 minutes). + (cache_miss_filename): New static char pointer. + (debuginfod_config_cache): New static function. + (debuginfod_clean_cache): Use debuginfod_config_cache for + interval_path and max_unused_path. + (debuginfod_query_server): Check whether target_cache_path exists + as negative cache file and create target_cache_path when the server + returns ENOENT. Check cache_miss_path fir cache miss time. + +2021-04-26 Frank Ch. Eigler + + PR27571 + * debuginfod-client.c (debuginfod_query_server): Chmod 0400 files + delivered into the cache to prevent accidental modification. + +2021-04-26 Frank Ch. Eigler + + PR26125 + * debuginfod-client.c (debuginfod_clean_cache): For directory + rmdir, check mtime first. + (debuginfod_query_server): Try mkdir / mkstemp up to twice, + in case of race. + +2021-04-23 Frank Ch. Eigler + + PR27701 + * debuginfod-client.c (struct debuginfod_client): Add long-lived + CURL easy and multi handles. + (debuginfo_begin,debuginfod_end): ctor/dtor for these. + (debuginfod_query_server): Rework to reuse easy & multi handles. + (*_envvar): Just use the DEBUGINFOD_*_ENV_VAR directly instead. + + * debuginfod.cxx (dc_pool): New pile of reusable debuginfod_client + objects for upstream federation connections. + (debuginfod_pool_{begin,end,groom}): New functions. + (handle_buildid): Use them. + (handler_cb): Fix keep-alive given libmicrohttpd convention of multiple + callbacks. + +2021-04-15 Frank Ch. Eigler + + * debuginfod.cxx (groom): Only update database stats once. + +2021-04-15 Frank Ch. Eigler + + * debuginfod.cxx (elf_classify): Recognize symtab-only stripped files + like fedora's libicudata as debuginfo files. + +2021-03-30 Frank Ch. Eigler + + * debuginfod.cxx (main): Set child thread names. + +2021-03-07 Timm Bäder + + * debuginfod-client.c (debuginfod_query_server): Tweak + double/long clamping arithmetic to avoid UB and warnings. + +2021-02-25 Frank Ch. Eigler + + * debuginfod.cxx (handler_cb): Filter webapi for bad + artifacttype keywords early for metric hygiene. + +2021-02-14 Frank Ch. Eigler + + * debuginfod.cxx (main -U): Use bsdtar unconditionally. Also map + the debian-compatible .ipk (openembedded distro family) to same. + +2021-02-04 Frank Ch. Eigler + + PR27092 low-memory handling + * debuginfod.cxx (fdcache_mintmp): New parameter, with cmd-line option. + (parse_opt): Parse it. + (main): Default it. + (statfs_free_enough_p): New function. + (libarchive_fdcache::*): Call it to trigger emergency fdcache flush. + (thread_main_scanner): Call it to report filesystem fullness metrics. + (groom): Ditto. + (set/add_metric): Take double rather than int64_t values. + (archive_exception): Propagate suberror to metric label. + (main): Detect pthread creation fatal errors properly. + +2021-02-02 Frank Ch. Eigler + + PR27323 + * debuginfod.cxx (dbq): New read-only database connection for queries + only. + (signal_handler): Interrupt it. + (main): Open / close it. + (handle_buildid): Use it for webapi queries only. + (database_stats_report): Make more interruptible. Report sqlite3 + operation times to the prometheus metrics. + (groom): Make more interruptible. + (thread_main_fts_source_paths, thread_main_groom): Ensure + state/progress metrics are fresh even in case of exceptions. + +2020-12-20 Dmitry V. Levin + + * .gitignore: New file. + +2020-12-12 Dmitry V. Levin + + * debuginfod-client.c (debuginfod_query_server): Fix spelling typos in + comments. + * debuginfod.cxx: Likewise. + (parse_opt): Fix spelling typos in error diagnostics. + +2020-12-08 Dmitry V. Levin + + * Makefile.am [LIBDEBUGINFOD]: Create libdebuginfod.so.1 first, turn + libdebuginfod.so into symlink. + +2020-11-30 Dmitry V. Levin + + * Makefile.am (libdebuginfod.so): Replace $@.$(VERSION) with + $(LIBDEBUGINFOD_SONAME). + (install, uninstall, MOSTLYCLEANFILES): Replace + libdebuginfod.so.$(VERSION) with $(LIBDEBUGINFOD_SONAME). + (VERSION): Remove. + * debuginfod.h: Rename to ... + * debuginfod.h.in ... this. + (DEBUGINFOD_SONAME): New macro. + +2020-11-30 Dmitry V. Levin + + * Makefile.am (libdebuginfod.so$(EXEEXT)): Drop $(EXEEXT) suffix. + +2020-11-25 Frank Ch. Eigler + + * debuginfod.cxx (step_ok_done): Correct typo in prom metric label. + +2020-11-25 Frank Ch. Eigler + + * debuginfod.cxx (tmp_ms_metric): Switch from gettimeofday to + clock_gettime(CLOCK_MONOTONIC) for time-interval measurements. + (handler_cb, scan_source_paths, groom): Ditto. + +2020-11-23 Frank Ch. Eigler + + * debuginfod.cxx (tmp_ms_metric): New class for RAII timing metrics. + (sqlite_ps::reset, step*): Call it to track sqlite3 performance. + (sqlite_exception ctor): Increment sqlite3 error_count. + +2020-11-23 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Initialize + struct handle_data errbuf to the empty string. + +2020-11-11 Mark Wielaard + + * debuginfod-client.c (debuginfod_set_verbose_fd): New function. + (struct debuginfod_client): Add verbose_fd. + (struct handle_data): Add errbuf. + (debuginfod_query_server): Produce verbose output when + debuginfod_client verbose_fd is set. Only clear old data and set + default_headers when any work is done. Always goto out when setting + rc to an error value. Use CURLOPT_ERRORBUFFER to get more error + output when verbose output is requested. + * debuginfod.h (DEBUGINFOD_VERBOSE_ENV_VAR): New. + (debuginfod_set_verbose_fd): Added. + * debuginfod-find.c (parse_opt): Set debuginfod_set_verbose_fd on -v. + * bdebuginfod.map (ELFUTILS_0.183): New section, add + debuginfod_set_verbose_fd. + +2020-11-21 Mark Wielaard + + * debuginfod.cxx (handle_root): New function. + (handler_cb): Handle "/" and report url1 in webapi error. + +2020-11-11 Mark Wielaard + + * debuginfod-find.c (progressfn): Use clock_gettime to print Progress + at most 5 times a second. + +2020-11-19 Frank Ch. Eigler + + * debuginfod.cxx (tmp_inc_metric): New class. + (handler_cb): Use it to track webapi operations. + +2020-11-01 Érico N. Rolim + + * debuginfod-client.c (debuginfod_init_cache): Use ACCESSPERMS for + mkdir, DEFFILEMODE for open with O_CREAT. + +2020-11-01 Érico N. Rolim + + * debuginfod.cxx: include libintl.h. + +2020-11-01 Érico N. Rolim + + * Makefile.am (debuginfod_LDADD): Add argp_LDADD and fts_LIBS. + (debuginfod_find_LDADD): Likewise. + (libdebuginfod_so_LDLIBS): Add fts_LIBS. + +2020-10-31 Frank Ch. Eigler + + * debuginfod.cxx (scan_source_file, scan_archive_file): Add new scanned_bytes_total, + scanned_files_total metrics. + (archive_classify): Exit early if interrupted. + (scan_source_paths): Perform realpath/regex checks only on FTS_F files. + Tweak metrics. + +2020-10-30 Frank Ch. Eigler + + PR26775 cont'd. + * debuginfod.cxx (thread_main_scanner): Ensure control doesn't + leave infinite loop until program exit, even if SIGUSR2. + (scan_source_paths): Have traverser clean scanq on + SIGUSR2. Emit additional traversed_total metrics. + (groom): Emit additional groomed_total metrics. + (thread_main_groom): Restore previous thread_work_total + metric. + +2020-10-29 Frank Ch. Eigler + + PR26775 + * debuginfod.cxx (forced_*_count): Make these global. + (runq::clear): New function. + (thread_main_scanner): Check for pending SIGUSR2; interrupt. + (scan_source_paths): Check for pending SIGUSR2; interrupt. + (groom): Report prometheus stats before groom also. Check for + pending SIGUSR1; interrupt. Increment thread_work_total for + each file scanned, not the entire cycle. + +2020-10-29 Frank Ch. Eigler + + PR26810 + * debuginfod.cxx (handle_buildid_*_match): Throw exceptions for + more lower level libc errors. + (handle_buildid_match): Catch & report exceptions but return 0 + for continued iteration in the caller. + +2020-10-25 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Translate + CURLE_PEER_FAILED_VERIFICATION to ECONNREFUSED. + +2020-10-20 Frank Ch. Eigler + + PR26756: more prometheus metrics + * debuginfod.cxx (*_exception): Add counters for error occurrences. + (fdcache::*): Add counters for fdcache operations and status. + (fdcache::set_metric): New fn for overall stat counts. + (fdcache::limit): ... allow metric-less use from dtors. + +2020-10-20 Frank Ch. Eigler + + * debuginfod.cxx (handle_buildid*): Add a parameter for detecting + internally-originated lookups for dwz resolution. + +2020-09-18 Frank Ch. Eigler + + * debuginfod.cxx (scan_source_file, archive_classify): Store only + canonicalized file names in sdef & sref records in the database. + +2020-09-08 Mark Wielaard + + * Makefile.am (BUILD_STATIC): Include libcurl_LIBS in libdebuginfod + when NOT DUMMY_LIBDEBUGINFOD. + +2020-09-16 Mark Wielaard + + * debuginfod-find.c: Fix license block comment. + +2020-09-15 Mark Wielaard + + * debuginfod-find.c (main): Use dwelf_elf_begin. + +2020-07-03 Alice Zhang + + * debuginfod-client.c (debuginfod_query_server): Use strncasecmp + to compare effective_url. Try CURLINFO_SCHEME as fallback. + +2020-06-19 Mark Wielaard + + * Makefile.am (bin_PROGRAMS): Guard with DEBUGINFOD and + LIBDEBUGINFOD. + (debuginfod_LDADD): Remove libcurl. + (libdebuginfod): When static and DUMMY_LIBDEBUGINFO remove libcurl. + (noinst_LIBRARIES): Guard with LIBDEBUGINFOD. + (AM_CPPFLAGS): Add -Wno-unused-parameter when DUMMY_LIBDEBUGINFOD. + (pkginclude_headers): Guard with LIBDEBUGINFOD + (libdebuginfod_so_LIBS): Likewise. + (+libdebuginfod_so_LDLIBS): Likewise. + (install): Likewise. + (uninstall): Likewise. + * debuginfod-client.c: Include dummy functions when + DUMMY_LIBDEBUGINFOD. + * debuginfod.cxx: Remove curl.h include. + +2020-06-16 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Check malloc. + Move curl_multi_init call before handle_data malloc call. + +2020-06-16 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Replace sizeof + build_id_bytes check with strlen build_id check. + +2020-06-16 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Increase suffix + array and prepare having to escape 1 character with 2. + +2020-06-16 Mark Wielaard + + * debuginfod-client.c (debuginfod_clean_cache): Handle failing + fopen (interval_path). + +2020-03-29 Mark Wielaard + + * debuginfod-client.c (debuginfod_add_http_header): Check header + contains precisely one colon that isn't the first or last char. + +2020-03-29 Frank Ch. Eigler + + * debuginfod-client.c (struct debuginfod_client): Add a flag field + for progressfn printing. + (default_progressfn): Set it if printing \rsomething. + (debuginfod_end): Terminate with \n if flag set, i.e., only if the + default_progressfn was actually called. + +2020-03-27 Mark Wielaard + + * debuginfod.cxx (parse_opt): Check port is not zero. + +2020-03-28 Frank Ch. Eigler + + * debuginfod.cxx (handle_buildid_r_match): During archive + extraction / fdcache prefetching, set the mtime of each + file in the cache. + +2020-03-27 Frank Ch. Eigler + + * debuginfod-find.c (main): Extract buildid from /binary/ if + given instead of hex string. + * Makefile.am: Add elfutils library prereqs for debuginfod-find. + +2020-03-24 Frank Ch. Eigler + + * debuginfod.h, libdebuginfod.map: New functions for _add_url_header. + * debuginfod-client.c (struct debuginfod_client): Add headers fields. + (debuginfod_add_http_header): New client api to add outgoing headers. + (add_default_headers): Renamed from add_extra_headers, skip if flag. + (debuginfod_query_server): Pass accumulated headers to libcurl. + (debuginfod_end): Clean accumulated headers. + (debuginfod_find_*): Add default headers at this point. + * debuginfod.cxx (handle_buildid): Add conn pointer. Use it to relay + incoming UA and XFF headers to federated upstream debuginfods. + +2020-03-26 Frank Ch. Eigler + + * debuginfod.cxx (handler_cb): Export two families of metrics for + prometheus traffic analysis: response times and data amounts. + +2020-03-26 Frank Ch. Eigler + + * debuginfod.cxx (parse_opt): For -U, prefer dpkg-deb + after all if access(3)-able, fallback to bsdtar. + +2020-03-25 Frank Ch. Eigler + + * debuginfod.cxx (parse_opt): Associate a bsdtar subshell with + the .deb & .ddeb extensions, instead of dpkg-deb. + +2020-03-26 Frank Ch. Eigler + + * debuginfod-client.c (debuginfod_query_server): Don't + set CURLOPT_PATH_AS_IS on old curl. Mostly harmless. + +2020-03-24 Frank Ch. Eigler + + * debuginfod-client.c (debuginfod_query_server): Set + CURLOPT_PATH_AS_IS, to propagate file names verbatim. + * debuginfod.cxx (canon_pathname): Implement RFC3986 + style pathname canonicalization. + (handle_buildid): Canonicalize incoming webapi source + paths, accept either one. + (scan_source_file, archive_classify): Store both + original and canonicalized dwarf-source file names. + +2020-03-24 Frank Ch. Eigler + + * debuginfod.cxx (handle_buildid): In case of federated fallback + queries, handle errors analogously to local ENOENT/404. + (handle_metrics): Return a size-of-response value. + (handler_cb): Add code to time entire application-side processing + stage + response sizes + http codes, so as to emit a complete + httpd-flavoured log line for each webapi request. + +2020-03-24 Frank Ch. Eigler + + * debuginfod-client.c (debuginfod_query_server): Print the + default_progressfn terminating \n message only if that progressfn + is actually set. + +2020-03-24 Frank Ch. Eigler + + * debuginfod-find.c (main): Correct /source full-pathness check for + "debuginfod-find -v source deadbeef /pathname" case. + +2020-03-22 Frank Ch. Eigler + + * debuginfod-client.c (struct debuginfod_client): Add url field. + (struct handle_data): Add client field as backpointer. + (debuginfod_write_callback): Compute & save URL. + (default_progressfn): Print front pieces of the URL. + (debuginfod_query_server): Clear URL and cleanup after progressfn. + * debuginfod-find.c (main): Print URL at transfer conclusion. + +2020-03-22 Frank Ch. Eigler + + * debuginfod.h, libdebuginfod.map: New functions for _get/set_user(). + * debuginfod-client.c: Implement them. + * debuginfod-find.c: Include a token call just for testing them. + +2020-03-03 Aaron Merey + + * debuginfod-client.c (debuginfod_query_server): Update + cache_path even when new default path already exists. + +2020-02-27 Aaron Merey + + * debuginfod-client.c (xalloc_str): New macro. Call + asprintf with error checking. + (debuginfod_query_server): Use XDG_CACHE_HOME as a default + cache location if it is set. Replace snprintf with xalloc_str. + +2020-02-26 Konrad Kleine + + * debuginfod-client.c (debuginfod_query_server): Handle curl's + response code correctly when DEBUGINFOD_URLS begin with file:// + +2020-02-25 Frank Ch. Eigler + + * debuginfod.cxx (parse_opt): Treat -R as if -Z.rpm . + +2020-02-25 Frank Ch. Eigler + + * debuginfod.cxx (fdcache_prefetch): New parameter. + (parse_opt): Parse it. + (main): Default it. + (fdcache::fd_size_mb): Change to double for accuracy. + (fdcache::probe): New function. + (fdcache::intern): New option to intern at end of LRU. + (fdcache::lookup): Clean fdcache. + (handle_buildid_r_match): Implement multi-stage archive + parsing, with optional prefetching of extracted contents + into the fdcache. + +2020-02-19 Aaron Merey + + * debuginfod-client.c (debuginfod_clean_cache): Restrict + cleanup to client-pattern files. + +2020-02-05 Frank Ch. Eigler + + * debuginfod.cxx (argp options): Add -Z option. + (canonicalized_archive_entry_pathname): New function for + distro-agnostic file name matching/storage. + +2020-01-22 Frank Ch. Eigler + + * debuginfod.cxx (dwarf_extract_source_paths): Don't print + "skipping hat" messages at verbosity <=3, too noisy. + +2020-01-19 Frank Ch. Eigler + + * debuginfod.cxx (scanq): Rework to let groomer/fts threads + synchronize with an empty workqueue, and lock out workqueue + consumers. + (thread_groom): Adopt new scanq idle APIs to lock out scanners. + (thread_main_fts_source_paths): Adopt new scanq idler API to + avoid being restarted while scanners haven't even finished yet. + (thread_main_*): Increment thread_work_total metric only after + a work cycle is completed, not when it begins. + +2020-01-18 Frank Ch. Eigler + + * debuginfod.cxx (thread_main_scanner): Handle empty source_paths[]. + +2020-01-11 Frank Ch. Eigler + + * debuginfod.cxx (libarchive_fdcache): New class/facility to own a + cache of temporary files that were previously extracted from an + archive. If only it could store just unlinked fd's instead of + filenames. + (handle_buildid_r_match): Use it to answer dwz/altdebug and webapi + requests. + (groom): Clean it. + (main): Initialize the cache control parameters from heuristics. + Use a consistent tmpdir for these and tmp files elsewhere. + +2020-01-11 Frank Ch. Eigler + + * debuginfod.cxx (conninfo): Print User-Agent and X-Forwarded-For + request headers, after mild safety-censorship (for easier machine + processing). + +2020-01-11 Frank Ch. Eigler + + * debuginfod.cxx: Rework threading model. + (workq): New class for concurrent work-queue. + (semaphore): Removed class, now unused. + (scan_source_file_path): Rework into ... + (scan_source_file): New function. + (thread_main_scan_source_file_path): Nuke. + (scan_source_archive_path): Rework into ... + (scan_archive_file): New function. + (thread_main_scanner): New function for scanner threads. + (thread_main_fts_source_paths): New function for traversal thread. + (scan_source_paths): ... doing this. + (thread_groom): Tweak metrics for consistency. + (main): Start 1 traversal and N scanner threads if needed. + +2019-01-02 Mark Wielaard + + * debuginfod.cxx (default_connect_timeout): Removed. + (default_transfer_timeout): Removed. + (default_timeout): New. Default to 90 seconds. + (debuginfod_query_server): Parse server_timeout_envvar as one number. + Set as CURLOPT_LOW_SPEED_TIME, with CURL_OPT_LOW_SPEED_LIMITE as 100K. + +2020-01-09 Frank Ch. Eigler + + * debuginfod-client.c (add_extra_headers): New function, + based on mjw's draft. + (debuginfod_query_server): Call it. + +2019-12-22 Frank Ch. Eigler + + * debuginfod.cxx (*_rpm_*): Rename to *_archive_* throughout. + (scan_archives): New read-mostly global to identify archive + file extensions and corresponding extractor commands. + (parse_opt): Handle new -U flag. + +2019-12-19 Frank Ch. Eigler + + * debuginfod-client.c (default_progressfn): New function. + (debuginfod_begin): Use it if $DEBUGINFOD_PROGRESS set. + (server_timeout): Bump to 30 seconds. + (debuginfod_query_server): Call progressfn -after- rather than + before curl ops, to make it likely that a successful transfer + results in final a=b call. Tweak cleanup sequence. + * debuginfod.h: Document $DEBUGINFOD_PROGRESS name. + +2019-12-09 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Check + server_urls_envvar early. + +2019-12-03 Mark Wielaard + + * debuginfod-client.c (debuginfod_query_server): Use separate + local variables for CURLcode curl_res and CURLMcode curlm_res. + +2019-11-26 Mark Wielaard + + * Makefile.am (BUILD_STATIC): Add needed libraries for libdw and + libdebuginfod. + +2019-11-25 Frank Ch. Eigler + + * debuginfod.cxx (groom): Add a sqlite3_db_release_memory() + at the end of periodic grooming to try to shrink the process. + +2019-11-24 Mark Wielaard + + * debuginfod.cxx (test_webapi_sleep): Removed. + (handler_cb): Don't check test_webapi_sleep and sleep. + (main): Don't set test_webapi_sleep. + +2019-11-24 Mark Wielaard + + * debuginfod.cxx (add_metric): New function. + (scan_source_file_path): Record metrics for + found_executable_total, found_debuginfo_total and + found_sourcerefs_total. + (scan_source_rpm_path): Likewise. + +2019-11-07 Frank Ch. Eigler + + * debuginfod.cxx: Add /metrics endpoint. Add numerous + calls to new functions inc_metric/set_metric to populate + threadsafe map containing stats. Add http content-type + response headers throughout. + (thread_main_*): Simplify counter/timer flow. + (main): Reorder web service shutdown to leave http running + as long as possible. + * debuginfod.8: Document it, add security caution. + +2019-11-06 Frank Ch. Eigler + + * debuginfod.cxx: Add new -L (symlink-following) mode. + * debuginfod.8: Document it. + +2019-11-04 Frank Ch. Eigler + + * debuginfo-client.c (debuginfod_set_progressfn): New function + for progress/interrupt callback. + (debuginfod_clean_cache, debuginfod_query_server): Call it. + * debuginfo.h: Declare it. + * debuginfod_set_progressfn.3, *_find_debuginfo.3: Document it. + * Makefile.am: Install it. + * libdebuginfod.map: Export it all under ELFUTILS_0.178 symversion. + + * debuginfod-find.c: Add -v option to activate progress cb. + * debuginfod-find.1: Document it. + * debuginfod.cxx: Add $DEBUGINFOD_TEST_WEBAPI_SLEEP env var + to insert sleep in webapi callbacks, to help manual testing. + +2019-10-28 Frank Ch. Eigler + + * debuginfod.cxx: New file: debuginfod server. + * debuginfod.8: New file: man page. + * Makefile.am: Build it. + +2019-10-28 Aaron Merey + + * debuginfod-client.c: New file: debuginfod client library. + * debuginfod.h: New file: header for same. + * libdebuginfod.map: New file: govern its solib exports. + * debuginfod-find.c: New file: command line frontend. + * debuginfod-find.1, debuginfod_find_source.3, + debuginfod_find_executable.3, debuginfod_find_debuginfo.3: + New man pages. diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am new file mode 100644 index 00000000..3adb2755 --- /dev/null +++ b/debuginfod/Makefile.am @@ -0,0 +1,146 @@ +## Makefile.am for libdebuginfod library subdirectory in elfutils. +## +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2019 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \ + $(libmicrohttpd_CFLAGS) $(libcurl_CFLAGS) $(sqlite3_CFLAGS) \ + $(libarchive_CFLAGS) + +# Disable eu- prefixing for artifacts (binaries & man pages) in this +# directory, since they do not conflict with binutils tools. +program_prefix= +program_transform_name = s,x,x, + +if BUILD_STATIC +libasm = ../libasm/libasm.a +libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread +libelf = ../libelf/libelf.a -lz +if DUMMY_LIBDEBUGINFOD +libdebuginfod = ./libdebuginfod.a +else +libdebuginfod = ./libdebuginfod.a $(libcurl_LIBS) +endif +else +libasm = ../libasm/libasm.so +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +libdebuginfod = ./libdebuginfod.so +endif +libebl = ../libebl/libebl.a +libeu = ../lib/libeu.a + +AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw:. + +bin_PROGRAMS = +if DEBUGINFOD +bin_PROGRAMS += debuginfod +endif + +if LIBDEBUGINFOD +bin_PROGRAMS += debuginfod-find +endif + +debuginfod_SOURCES = debuginfod.cxx +debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl + +debuginfod_find_SOURCES = debuginfod-find.c +debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) + +if LIBDEBUGINFOD +noinst_LIBRARIES = libdebuginfod.a +noinst_LIBRARIES += libdebuginfod_pic.a +endif + +libdebuginfod_a_SOURCES = debuginfod-client.c +libdebuginfod_pic_a_SOURCES = debuginfod-client.c +am_libdebuginfod_pic_a_OBJECTS = $(libdebuginfod_a_SOURCES:.c=.os) + +if DUMMY_LIBDEBUGINFOD +AM_CPPFLAGS += -Wno-unused-parameter +endif + +if LIBDEBUGINFOD +pkginclude_HEADERS = debuginfod.h +endif + +if LIBDEBUGINFOD +libdebuginfod_so_LIBS = libdebuginfod_pic.a +if DUMMY_LIBDEBUGINFOD +libdebuginfod_so_LDLIBS = +else +libdebuginfod_so_LDLIBS = $(libcurl_LIBS) $(fts_LIBS) +endif +$(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$(LIBDEBUGINFOD_SONAME) \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libdebuginfod_so_LIBS) -Wl,--no-whole-archive \ + $(libdebuginfod_so_LDLIBS) + @$(textrel_check) + +libdebuginfod.so: $(LIBDEBUGINFOD_SONAME) + ln -fs $< $@ + +install: install-am libdebuginfod.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) $(LIBDEBUGINFOD_SONAME) \ + $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so + ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME) + ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdebuginfod.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME) + rm -f $(DESTDIR)$(libdir)/libdebuginfod.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils +endif + +EXTRA_DIST = libdebuginfod.map +MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME) +CLEANFILES += $(am_libdebuginfod_pic_a_OBJECTS) libdebuginfod.so + +# automake std-options override: arrange to pass LD_LIBRARY_PATH +installcheck-binPROGRAMS: $(bin_PROGRAMS) + bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if LD_LIBRARY_PATH=$(DESTDIR)$(libdir) \ + $(DESTDIR)$(bindir)/$$f $$opt > c$${pid}_.out 2> c$${pid}_.err \ + && test -n "`cat c$${pid}_.out`" \ + && test -z "`cat c$${pid}_.err`"; then :; \ + else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad diff --git a/debuginfod/Makefile.in b/debuginfod/Makefile.in new file mode 100644 index 00000000..41da3bb4 --- /dev/null +++ b/debuginfod/Makefile.in @@ -0,0 +1,949 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +@DEBUGINFOD_TRUE@am__append_2 = debuginfod +@LIBDEBUGINFOD_TRUE@am__append_3 = debuginfod-find +@DUMMY_LIBDEBUGINFOD_TRUE@am__append_4 = -Wno-unused-parameter +subdir = debuginfod +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__pkginclude_HEADERS_DIST) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = debuginfod.h +CONFIG_CLEAN_VPATH_FILES = +@DEBUGINFOD_TRUE@am__EXEEXT_1 = debuginfod$(EXEEXT) +@LIBDEBUGINFOD_TRUE@am__EXEEXT_2 = debuginfod-find$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgincludedir)" +PROGRAMS = $(bin_PROGRAMS) +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libdebuginfod_a_AR = $(AR) $(ARFLAGS) +libdebuginfod_a_LIBADD = +am_libdebuginfod_a_OBJECTS = debuginfod-client.$(OBJEXT) +libdebuginfod_a_OBJECTS = $(am_libdebuginfod_a_OBJECTS) +libdebuginfod_pic_a_AR = $(AR) $(ARFLAGS) +libdebuginfod_pic_a_LIBADD = +libdebuginfod_pic_a_OBJECTS = $(am_libdebuginfod_pic_a_OBJECTS) +am_debuginfod_OBJECTS = debuginfod.$(OBJEXT) +debuginfod_OBJECTS = $(am_debuginfod_OBJECTS) +am__DEPENDENCIES_1 = +@BUILD_STATIC_FALSE@am__DEPENDENCIES_2 = ../libelf/libelf.so +@BUILD_STATIC_TRUE@am__DEPENDENCIES_2 = ../libelf/libelf.a +@BUILD_STATIC_FALSE@am__DEPENDENCIES_3 = ../libdw/libdw.so +@BUILD_STATIC_TRUE@am__DEPENDENCIES_3 = ../libdw/libdw.a \ +@BUILD_STATIC_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ +@BUILD_STATIC_TRUE@ $(libebl) +@BUILD_STATIC_FALSE@am__DEPENDENCIES_4 = ./libdebuginfod.so +@BUILD_STATIC_TRUE@@DUMMY_LIBDEBUGINFOD_FALSE@am__DEPENDENCIES_4 = ./libdebuginfod.a \ +@BUILD_STATIC_TRUE@@DUMMY_LIBDEBUGINFOD_FALSE@ $(am__DEPENDENCIES_1) +@BUILD_STATIC_TRUE@@DUMMY_LIBDEBUGINFOD_TRUE@am__DEPENDENCIES_4 = ./libdebuginfod.a +debuginfod_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(libeu) $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_debuginfod_find_OBJECTS = debuginfod-find.$(OBJEXT) +debuginfod_find_OBJECTS = $(am_debuginfod_find_OBJECTS) +debuginfod_find_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) $(libeu) $(am__DEPENDENCIES_4) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/debuginfod-client.Po \ + ./$(DEPDIR)/debuginfod-find.Po ./$(DEPDIR)/debuginfod.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libdebuginfod_a_SOURCES) $(libdebuginfod_pic_a_SOURCES) \ + $(debuginfod_SOURCES) $(debuginfod_find_SOURCES) +DIST_SOURCES = $(libdebuginfod_a_SOURCES) \ + $(libdebuginfod_pic_a_SOURCES) $(debuginfod_SOURCES) \ + $(debuginfod_find_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__pkginclude_HEADERS_DIST = debuginfod.h +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +HEADERS = $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/debuginfod.h.in \ + $(top_srcdir)/config/depcomp $(top_srcdir)/config/eu.am \ + ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = s,x,x, +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. -I$(srcdir) \ + -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \ + $(libmicrohttpd_CFLAGS) $(libcurl_CFLAGS) $(sqlite3_CFLAGS) \ + $(libarchive_CFLAGS) $(am__append_4) + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda $(am_libdebuginfod_pic_a_OBJECTS) \ + libdebuginfod.so +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi + +# Disable eu- prefixing for artifacts (binaries & man pages) in this +# directory, since they do not conflict with binutils tools. +program_prefix = +@BUILD_STATIC_FALSE@libasm = ../libasm/libasm.so +@BUILD_STATIC_TRUE@libasm = ../libasm/libasm.a +@BUILD_STATIC_FALSE@libdw = ../libdw/libdw.so +@BUILD_STATIC_TRUE@libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread +@BUILD_STATIC_FALSE@libelf = ../libelf/libelf.so +@BUILD_STATIC_TRUE@libelf = ../libelf/libelf.a -lz +@BUILD_STATIC_FALSE@libdebuginfod = ./libdebuginfod.so +@BUILD_STATIC_TRUE@@DUMMY_LIBDEBUGINFOD_FALSE@libdebuginfod = ./libdebuginfod.a $(libcurl_LIBS) +@BUILD_STATIC_TRUE@@DUMMY_LIBDEBUGINFOD_TRUE@libdebuginfod = ./libdebuginfod.a +libebl = ../libebl/libebl.a +libeu = ../lib/libeu.a +AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw:. +debuginfod_SOURCES = debuginfod.cxx +debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl +debuginfod_find_SOURCES = debuginfod-find.c +debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) +@LIBDEBUGINFOD_TRUE@noinst_LIBRARIES = libdebuginfod.a \ +@LIBDEBUGINFOD_TRUE@ libdebuginfod_pic.a +libdebuginfod_a_SOURCES = debuginfod-client.c +libdebuginfod_pic_a_SOURCES = debuginfod-client.c +am_libdebuginfod_pic_a_OBJECTS = $(libdebuginfod_a_SOURCES:.c=.os) +@LIBDEBUGINFOD_TRUE@pkginclude_HEADERS = debuginfod.h +@LIBDEBUGINFOD_TRUE@libdebuginfod_so_LIBS = libdebuginfod_pic.a +@DUMMY_LIBDEBUGINFOD_FALSE@@LIBDEBUGINFOD_TRUE@libdebuginfod_so_LDLIBS = $(libcurl_LIBS) $(fts_LIBS) +@DUMMY_LIBDEBUGINFOD_TRUE@@LIBDEBUGINFOD_TRUE@libdebuginfod_so_LDLIBS = +EXTRA_DIST = libdebuginfod.map +MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cxx .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits debuginfod/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits debuginfod/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +debuginfod.h: $(top_builddir)/config.status $(srcdir)/debuginfod.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libdebuginfod.a: $(libdebuginfod_a_OBJECTS) $(libdebuginfod_a_DEPENDENCIES) $(EXTRA_libdebuginfod_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdebuginfod.a + $(AM_V_AR)$(libdebuginfod_a_AR) libdebuginfod.a $(libdebuginfod_a_OBJECTS) $(libdebuginfod_a_LIBADD) + $(AM_V_at)$(RANLIB) libdebuginfod.a + +libdebuginfod_pic.a: $(libdebuginfod_pic_a_OBJECTS) $(libdebuginfod_pic_a_DEPENDENCIES) $(EXTRA_libdebuginfod_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdebuginfod_pic.a + $(AM_V_AR)$(libdebuginfod_pic_a_AR) libdebuginfod_pic.a $(libdebuginfod_pic_a_OBJECTS) $(libdebuginfod_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libdebuginfod_pic.a + +debuginfod$(EXEEXT): $(debuginfod_OBJECTS) $(debuginfod_DEPENDENCIES) $(EXTRA_debuginfod_DEPENDENCIES) + @rm -f debuginfod$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(debuginfod_OBJECTS) $(debuginfod_LDADD) $(LIBS) + +debuginfod-find$(EXEEXT): $(debuginfod_find_OBJECTS) $(debuginfod_find_DEPENDENCIES) $(EXTRA_debuginfod_find_DEPENDENCIES) + @rm -f debuginfod-find$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(debuginfod_find_OBJECTS) $(debuginfod_find_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debuginfod-client.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debuginfod-find.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debuginfod.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +@LIBDEBUGINFOD_FALSE@install: install-am +install-exec: install-exec-am +install-data: install-data-am +@LIBDEBUGINFOD_FALSE@uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/debuginfod-client.Po + -rm -f ./$(DEPDIR)/debuginfod-find.Po + -rm -f ./$(DEPDIR)/debuginfod.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: installcheck-binPROGRAMS + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/debuginfod-client.Po + -rm -f ./$(DEPDIR)/debuginfod-find.Po + -rm -f ./$(DEPDIR)/debuginfod.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgincludeHEADERS install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installcheck-binPROGRAMS installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) +@LIBDEBUGINFOD_TRUE@$(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS) +@LIBDEBUGINFOD_TRUE@ $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ +@LIBDEBUGINFOD_TRUE@ -Wl,--soname,$(LIBDEBUGINFOD_SONAME) \ +@LIBDEBUGINFOD_TRUE@ -Wl,--version-script,$<,--no-undefined \ +@LIBDEBUGINFOD_TRUE@ -Wl,--whole-archive $(libdebuginfod_so_LIBS) -Wl,--no-whole-archive \ +@LIBDEBUGINFOD_TRUE@ $(libdebuginfod_so_LDLIBS) +@LIBDEBUGINFOD_TRUE@ @$(textrel_check) + +@LIBDEBUGINFOD_TRUE@libdebuginfod.so: $(LIBDEBUGINFOD_SONAME) +@LIBDEBUGINFOD_TRUE@ ln -fs $< $@ + +@LIBDEBUGINFOD_TRUE@install: install-am libdebuginfod.so +@LIBDEBUGINFOD_TRUE@ $(mkinstalldirs) $(DESTDIR)$(libdir) +@LIBDEBUGINFOD_TRUE@ $(INSTALL_PROGRAM) $(LIBDEBUGINFOD_SONAME) \ +@LIBDEBUGINFOD_TRUE@ $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so +@LIBDEBUGINFOD_TRUE@ ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME) +@LIBDEBUGINFOD_TRUE@ ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdebuginfod.so + +@LIBDEBUGINFOD_TRUE@uninstall: uninstall-am +@LIBDEBUGINFOD_TRUE@ rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so +@LIBDEBUGINFOD_TRUE@ rm -f $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME) +@LIBDEBUGINFOD_TRUE@ rm -f $(DESTDIR)$(libdir)/libdebuginfod.so +@LIBDEBUGINFOD_TRUE@ rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils + +# automake std-options override: arrange to pass LD_LIBRARY_PATH +installcheck-binPROGRAMS: $(bin_PROGRAMS) + bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if LD_LIBRARY_PATH=$(DESTDIR)$(libdir) \ + $(DESTDIR)$(bindir)/$$f $$opt > c$${pid}_.out 2> c$${pid}_.err \ + && test -n "`cat c$${pid}_.out`" \ + && test -z "`cat c$${pid}_.err`"; then :; \ + else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c new file mode 100644 index 00000000..ee7eda24 --- /dev/null +++ b/debuginfod/debuginfod-client.c @@ -0,0 +1,1330 @@ +/* Retrieve ELF / DWARF / source files from the debuginfod. + Copyright (C) 2019-2020 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +/* cargo-cult from libdwfl linux-kernel-modules.c */ +/* In case we have a bad fts we include this before config.h because it + can't handle _FILE_OFFSET_BITS. + Everything we need here is fine if its declarations just come first. + Also, include sys/types.h before fts. On some systems fts.h is not self + contained. */ +#ifdef BAD_FTS + #include + #include +#endif + +#include "config.h" +#include "debuginfod.h" +#include "system.h" +#include +#include + +/* We might be building a bootstrap dummy library, which is really simple. */ +#ifdef DUMMY_LIBDEBUGINFOD + +debuginfod_client *debuginfod_begin (void) { errno = ENOSYS; return NULL; } +int debuginfod_find_debuginfo (debuginfod_client *c, const unsigned char *b, + int s, char **p) { return -ENOSYS; } +int debuginfod_find_executable (debuginfod_client *c, const unsigned char *b, + int s, char **p) { return -ENOSYS; } +int debuginfod_find_source (debuginfod_client *c, const unsigned char *b, + int s, const char *f, char **p) { return -ENOSYS; } +void debuginfod_set_progressfn(debuginfod_client *c, + debuginfod_progressfn_t fn) { } +void debuginfod_set_verbose_fd(debuginfod_client *c, int fd) { } +void debuginfod_set_user_data (debuginfod_client *c, void *d) { } +void* debuginfod_get_user_data (debuginfod_client *c) { return NULL; } +const char* debuginfod_get_url (debuginfod_client *c) { return NULL; } +int debuginfod_add_http_header (debuginfod_client *c, + const char *h) { return -ENOSYS; } +void debuginfod_end (debuginfod_client *c) { } + +#else /* DUMMY_LIBDEBUGINFOD */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* If fts.h is included before config.h, its indirect inclusions may not + give us the right LFS aliases of these functions, so map them manually. */ +#ifdef BAD_FTS + #ifdef _FILE_OFFSET_BITS + #define open open64 + #define fopen fopen64 + #endif +#else + #include + #include +#endif + +struct debuginfod_client +{ + /* Progress/interrupt callback function. */ + debuginfod_progressfn_t progressfn; + + /* Stores user data. */ + void* user_data; + + /* Stores current/last url, if any. */ + char* url; + + /* Accumulates outgoing http header names/values. */ + int user_agent_set_p; /* affects add_default_headers */ + struct curl_slist *headers; + + /* Flags the default_progressfn having printed something that + debuginfod_end needs to terminate. */ + int default_progressfn_printed_p; + + /* File descriptor to output any verbose messages if > 0. */ + int verbose_fd; + + /* Maintain a long-lived curl multi-handle, which keeps a + connection/tls/dns cache to recently seen servers. */ + CURLM *server_mhandle; + + /* Can contain all other context, like cache_path, server_urls, + timeout or other info gotten from environment variables, the + handle data, etc. So those don't have to be reparsed and + recreated on each request. */ +}; + +/* The cache_clean_interval_s file within the debuginfod cache specifies + how frequently the cache should be cleaned. The file's st_mtime represents + the time of last cleaning. */ +static const char *cache_clean_interval_filename = "cache_clean_interval_s"; +static const time_t cache_clean_default_interval_s = 86400; /* 1 day */ + +/* The cache_miss_default_s within the debuginfod cache specifies how + frequently the 000-permision file should be released.*/ +static const time_t cache_miss_default_s = 600; /* 10 min */ +static const char *cache_miss_filename = "cache_miss_s"; + +/* The cache_max_unused_age_s file within the debuginfod cache specifies the + the maximum time since last access that a file will remain in the cache. */ +static const char *cache_max_unused_age_filename = "max_unused_age_s"; +static const time_t cache_default_max_unused_age_s = 604800; /* 1 week */ + +/* Location of the cache of files downloaded from debuginfods. + The default parent directory is $HOME, or '/' if $HOME doesn't exist. */ +static const char *cache_default_name = ".debuginfod_client_cache"; +static const char *cache_xdg_name = "debuginfod_client"; + +/* URLs of debuginfods, separated by url_delim. */ +static const char *url_delim = " "; +static const char url_delim_char = ' '; + +/* Timeout for debuginfods, in seconds (to get at least 100K). */ +static const long default_timeout = 90; + + +/* Data associated with a particular CURL easy handle. Passed to + the write callback. */ +struct handle_data +{ + /* Cache file to be written to in case query is successful. */ + int fd; + + /* URL queried by this handle. */ + char url[PATH_MAX]; + + /* error buffer for this handle. */ + char errbuf[CURL_ERROR_SIZE]; + + /* This handle. */ + CURL *handle; + + /* The client object whom we're serving. */ + debuginfod_client *client; + + /* Pointer to handle that should write to fd. Initially points to NULL, + then points to the first handle that begins writing the target file + to the cache. Used to ensure that a file is not downloaded from + multiple servers unnecessarily. */ + CURL **target_handle; +}; + +static size_t +debuginfod_write_callback (char *ptr, size_t size, size_t nmemb, void *data) +{ + ssize_t count = size * nmemb; + + struct handle_data *d = (struct handle_data*)data; + + /* Indicate to other handles that they can abort their transfer. */ + if (*d->target_handle == NULL) + { + *d->target_handle = d->handle; + /* update the client object */ + const char *url = NULL; + (void) curl_easy_getinfo (d->handle, CURLINFO_EFFECTIVE_URL, &url); + if (url) + { + free (d->client->url); + d->client->url = strdup(url); /* ok if fails */ + } + } + + /* If this handle isn't the target handle, abort transfer. */ + if (*d->target_handle != d->handle) + return -1; + + return (size_t) write(d->fd, (void*)ptr, count); +} + +/* handle config file read and write */ +static int +debuginfod_config_cache(char *config_path, + long cache_config_default_s, + struct stat *st) +{ + int fd; + /* if the config file doesn't exist, create one with DEFFILEMODE*/ + if(stat(config_path, st) == -1) + { + fd = open(config_path, O_CREAT | O_RDWR, DEFFILEMODE); + if (fd < 0) + return -errno; + + if (dprintf(fd, "%ld", cache_config_default_s) < 0) + return -errno; + } + + long cache_config; + FILE *config_file = fopen(config_path, "r"); + if (config_file) + { + if (fscanf(config_file, "%ld", &cache_config) != 1) + cache_config = cache_config_default_s; + fclose(config_file); + } + else + cache_config = cache_config_default_s; + + return cache_config; +} + +/* Create the cache and interval file if they do not already exist. + Return 0 if cache and config file are initialized, otherwise return + the appropriate error code. */ +static int +debuginfod_init_cache (char *cache_path, char *interval_path, char *maxage_path) +{ + struct stat st; + + /* If the cache and config file already exist then we are done. */ + if (stat(cache_path, &st) == 0 && stat(interval_path, &st) == 0) + return 0; + + /* Create the cache and config files as necessary. */ + if (stat(cache_path, &st) != 0 && mkdir(cache_path, ACCESSPERMS) < 0) + return -errno; + + int fd = -1; + + /* init cleaning interval config file. */ + fd = open(interval_path, O_CREAT | O_RDWR, DEFFILEMODE); + if (fd < 0) + return -errno; + + if (dprintf(fd, "%ld", cache_clean_default_interval_s) < 0) + return -errno; + + /* init max age config file. */ + if (stat(maxage_path, &st) != 0 + && (fd = open(maxage_path, O_CREAT | O_RDWR, DEFFILEMODE)) < 0) + return -errno; + + if (dprintf(fd, "%ld", cache_default_max_unused_age_s) < 0) + return -errno; + + return 0; +} + + +/* Delete any files that have been unmodied for a period + longer than $DEBUGINFOD_CACHE_CLEAN_INTERVAL_S. */ +static int +debuginfod_clean_cache(debuginfod_client *c, + char *cache_path, char *interval_path, + char *max_unused_path) +{ + time_t clean_interval, max_unused_age; + int rc = -1; + struct stat st; + + /* Create new interval file. */ + rc = debuginfod_config_cache(interval_path, + cache_clean_default_interval_s, &st); + if (rc < 0) + return rc; + clean_interval = (time_t)rc; + + /* Check timestamp of interval file to see whether cleaning is necessary. */ + if (time(NULL) - st.st_mtime < clean_interval) + /* Interval has not passed, skip cleaning. */ + return 0; + + /* Read max unused age value from config file. */ + rc = debuginfod_config_cache(max_unused_path, + cache_default_max_unused_age_s, &st); + if (rc < 0) + return rc; + max_unused_age = (time_t)rc; + + char * const dirs[] = { cache_path, NULL, }; + + FTS *fts = fts_open(dirs, 0, NULL); + if (fts == NULL) + return -errno; + + regex_t re; + const char * pattern = ".*/[a-f0-9]+(/debuginfo|/executable|/source.*|)$"; /* include dirs */ + if (regcomp (&re, pattern, REG_EXTENDED | REG_NOSUB) != 0) + return -ENOMEM; + + FTSENT *f; + long files = 0; + time_t now = time(NULL); + while ((f = fts_read(fts)) != NULL) + { + /* ignore any files that do not match the pattern. */ + if (regexec (&re, f->fts_path, 0, NULL, 0) != 0) + continue; + + files++; + if (c->progressfn) /* inform/check progress callback */ + if ((c->progressfn) (c, files, 0)) + break; + + switch (f->fts_info) + { + case FTS_F: + /* delete file if max_unused_age has been met or exceeded w.r.t. atime. */ + if (now - f->fts_statp->st_atime >= max_unused_age) + (void) unlink (f->fts_path); + break; + + case FTS_DP: + /* Remove if old & empty. Weaken race against concurrent creation by + checking mtime. */ + if (now - f->fts_statp->st_mtime >= max_unused_age) + (void) rmdir (f->fts_path); + break; + + default: + ; + } + } + fts_close (fts); + regfree (&re); + + /* Update timestamp representing when the cache was last cleaned. */ + utime (interval_path, NULL); + return 0; +} + + +#define MAX_BUILD_ID_BYTES 64 + + +static void +add_default_headers(debuginfod_client *client) +{ + if (client->user_agent_set_p) + return; + + /* Compute a User-Agent: string to send. The more accurately this + describes this host, the likelier that the debuginfod servers + might be able to locate debuginfo for us. */ + + char* utspart = NULL; + struct utsname uts; + int rc = 0; + rc = uname (&uts); + if (rc == 0) + rc = asprintf(& utspart, "%s/%s", uts.sysname, uts.machine); + if (rc < 0) + utspart = NULL; + + FILE *f = fopen ("/etc/os-release", "r"); + if (f == NULL) + f = fopen ("/usr/lib/os-release", "r"); + char *id = NULL; + char *version = NULL; + if (f != NULL) + { + while (id == NULL || version == NULL) + { + char buf[128]; + char *s = &buf[0]; + if (fgets (s, sizeof(buf), f) == NULL) + break; + + int len = strlen (s); + if (len < 3) + continue; + if (s[len - 1] == '\n') + { + s[len - 1] = '\0'; + len--; + } + + char *v = strchr (s, '='); + if (v == NULL || strlen (v) < 2) + continue; + + /* Split var and value. */ + *v = '\0'; + v++; + + /* Remove optional quotes around value string. */ + if (*v == '"' || *v == '\'') + { + v++; + s[len - 1] = '\0'; + } + if (strcmp (s, "ID") == 0) + id = strdup (v); + if (strcmp (s, "VERSION_ID") == 0) + version = strdup (v); + } + fclose (f); + } + + char *ua = NULL; + rc = asprintf(& ua, "User-Agent: %s/%s,%s,%s/%s", + PACKAGE_NAME, PACKAGE_VERSION, + utspart ?: "", + id ?: "", + version ?: ""); + if (rc < 0) + ua = NULL; + + if (ua) + (void) debuginfod_add_http_header (client, ua); + + free (ua); + free (id); + free (version); + free (utspart); +} + + +#define xalloc_str(p, fmt, args...) \ + do \ + { \ + if (asprintf (&p, fmt, args) < 0) \ + { \ + p = NULL; \ + rc = -ENOMEM; \ + goto out; \ + } \ + } while (0) + + +/* Offer a basic form of progress tracing */ +static int +default_progressfn (debuginfod_client *c, long a, long b) +{ + const char* url = debuginfod_get_url (c); + int len = 0; + + /* We prefer to print the host part of the URL to keep the + message short. */ + if (url != NULL) + { + const char* buildid = strstr(url, "buildid/"); + if (buildid != NULL) + len = (buildid - url); + else + len = strlen(url); + } + + if (b == 0 || url==NULL) /* early stage */ + dprintf(STDERR_FILENO, + "\rDownloading %c", "-/|\\"[a % 4]); + else if (b < 0) /* download in progress but unknown total length */ + dprintf(STDERR_FILENO, + "\rDownloading from %.*s %ld", + len, url, a); + else /* download in progress, and known total length */ + dprintf(STDERR_FILENO, + "\rDownloading from %.*s %ld/%ld", + len, url, a, b); + c->default_progressfn_printed_p = 1; + + return 0; +} + + +/* Query each of the server URLs found in $DEBUGINFOD_URLS for the file + with the specified build-id, type (debuginfo, executable or source) + and filename. filename may be NULL. If found, return a file + descriptor for the target, otherwise return an error code. +*/ +static int +debuginfod_query_server (debuginfod_client *c, + const unsigned char *build_id, + int build_id_len, + const char *type, + const char *filename, + char **path) +{ + char *server_urls; + char *urls_envvar; + char *cache_path = NULL; + char *maxage_path = NULL; + char *interval_path = NULL; + char *cache_miss_path = NULL; + char *target_cache_dir = NULL; + char *target_cache_path = NULL; + char *target_cache_tmppath = NULL; + char suffix[PATH_MAX + 1]; /* +1 for zero terminator. */ + char build_id_bytes[MAX_BUILD_ID_BYTES * 2 + 1]; + int vfd = c->verbose_fd; + int rc; + + if (vfd >= 0) + { + dprintf (vfd, "debuginfod_find_%s ", type); + if (build_id_len == 0) /* expect clean hexadecimal */ + dprintf (vfd, "%s", (const char *) build_id); + else + for (int i = 0; i < build_id_len; i++) + dprintf (vfd, "%02x", build_id[i]); + if (filename != NULL) + dprintf (vfd, " %s\n", filename); + dprintf (vfd, "\n"); + } + + /* Is there any server we can query? If not, don't do any work, + just return with ENOSYS. Don't even access the cache. */ + urls_envvar = getenv(DEBUGINFOD_URLS_ENV_VAR); + if (vfd >= 0) + dprintf (vfd, "server urls \"%s\"\n", + urls_envvar != NULL ? urls_envvar : ""); + if (urls_envvar == NULL || urls_envvar[0] == '\0') + { + rc = -ENOSYS; + goto out; + } + + /* Clear the obsolete URL from a previous _find operation. */ + free (c->url); + c->url = NULL; + + add_default_headers(c); + + /* Copy lowercase hex representation of build_id into buf. */ + if (vfd >= 0) + dprintf (vfd, "checking build-id\n"); + if ((build_id_len >= MAX_BUILD_ID_BYTES) || + (build_id_len == 0 && + strlen ((const char *) build_id) > MAX_BUILD_ID_BYTES*2)) + { + rc = -EINVAL; + goto out; + } + + if (build_id_len == 0) /* expect clean hexadecimal */ + strcpy (build_id_bytes, (const char *) build_id); + else + for (int i = 0; i < build_id_len; i++) + sprintf(build_id_bytes + (i * 2), "%02x", build_id[i]); + + if (filename != NULL) + { + if (vfd >= 0) + dprintf (vfd, "checking filename\n"); + if (filename[0] != '/') // must start with / + { + rc = -EINVAL; + goto out; + } + + /* copy the filename to suffix, s,/,#,g */ + unsigned q = 0; + for (unsigned fi=0; q < PATH_MAX-2; fi++) /* -2, escape is 2 chars. */ + switch (filename[fi]) + { + case '\0': + suffix[q] = '\0'; + q = PATH_MAX-1; /* escape for loop too */ + break; + case '/': /* escape / to prevent dir escape */ + suffix[q++]='#'; + suffix[q++]='#'; + break; + case '#': /* escape # to prevent /# vs #/ collisions */ + suffix[q++]='#'; + suffix[q++]='_'; + break; + default: + suffix[q++]=filename[fi]; + } + suffix[q] = '\0'; + /* If the DWARF filenames are super long, this could exceed + PATH_MAX and truncate/collide. Oh well, that'll teach + them! */ + } + else + suffix[0] = '\0'; + + if (suffix[0] != '\0' && vfd >= 0) + dprintf (vfd, "suffix %s\n", suffix); + + /* set paths needed to perform the query + + example format + cache_path: $HOME/.cache + target_cache_dir: $HOME/.cache/0123abcd + target_cache_path: $HOME/.cache/0123abcd/debuginfo + target_cache_path: $HOME/.cache/0123abcd/source#PATH#TO#SOURCE ? + + $XDG_CACHE_HOME takes priority over $HOME/.cache. + $DEBUGINFOD_CACHE_PATH takes priority over $HOME/.cache and $XDG_CACHE_HOME. + */ + + /* Determine location of the cache. The path specified by the debuginfod + cache environment variable takes priority. */ + char *cache_var = getenv(DEBUGINFOD_CACHE_PATH_ENV_VAR); + if (cache_var != NULL && strlen (cache_var) > 0) + xalloc_str (cache_path, "%s", cache_var); + else + { + /* If a cache already exists in $HOME ('/' if $HOME isn't set), then use + that. Otherwise use the XDG cache directory naming format. */ + xalloc_str (cache_path, "%s/%s", getenv ("HOME") ?: "/", cache_default_name); + + struct stat st; + if (stat (cache_path, &st) < 0) + { + char cachedir[PATH_MAX]; + char *xdg = getenv ("XDG_CACHE_HOME"); + + if (xdg != NULL && strlen (xdg) > 0) + snprintf (cachedir, PATH_MAX, "%s", xdg); + else + snprintf (cachedir, PATH_MAX, "%s/.cache", getenv ("HOME") ?: "/"); + + /* Create XDG cache directory if it doesn't exist. */ + if (stat (cachedir, &st) == 0) + { + if (! S_ISDIR (st.st_mode)) + { + rc = -EEXIST; + goto out; + } + } + else + { + rc = mkdir (cachedir, 0700); + + /* Also check for EEXIST and S_ISDIR in case another client just + happened to create the cache. */ + if (rc < 0 + && (errno != EEXIST + || stat (cachedir, &st) != 0 + || ! S_ISDIR (st.st_mode))) + { + rc = -errno; + goto out; + } + } + + free (cache_path); + xalloc_str (cache_path, "%s/%s", cachedir, cache_xdg_name); + } + } + + xalloc_str (target_cache_dir, "%s/%s", cache_path, build_id_bytes); + xalloc_str (target_cache_path, "%s/%s%s", target_cache_dir, type, suffix); + xalloc_str (target_cache_tmppath, "%s.XXXXXX", target_cache_path); + + /* XXX combine these */ + xalloc_str (interval_path, "%s/%s", cache_path, cache_clean_interval_filename); + xalloc_str (cache_miss_path, "%s/%s", cache_path, cache_miss_filename); + xalloc_str (maxage_path, "%s/%s", cache_path, cache_max_unused_age_filename); + + if (vfd >= 0) + dprintf (vfd, "checking cache dir %s\n", cache_path); + + rc = debuginfod_init_cache(cache_path, interval_path, maxage_path); + if (rc != 0) + goto out; + rc = debuginfod_clean_cache(c, cache_path, interval_path, maxage_path); + if (rc != 0) + goto out; + + /* If the target is already in the cache then we are done. */ + int fd = open (target_cache_path, O_RDONLY); + if (fd >= 0) + { + /* Success!!!! */ + if (path != NULL) + *path = strdup(target_cache_path); + rc = fd; + goto out; + } + + struct stat st; + time_t cache_miss; + /* Check if the file exists and it's of permission 000*/ + if (errno == EACCES + && stat(target_cache_path, &st) == 0 + && (st.st_mode & 0777) == 0) + { + rc = debuginfod_config_cache(cache_miss_path, cache_miss_default_s, &st); + if (rc < 0) + goto out; + + cache_miss = (time_t)rc; + if (time(NULL) - st.st_mtime <= cache_miss) + { + rc = -ENOENT; + goto out; + } + else + unlink(target_cache_path); + } + + long timeout = default_timeout; + const char* timeout_envvar = getenv(DEBUGINFOD_TIMEOUT_ENV_VAR); + if (timeout_envvar != NULL) + timeout = atoi (timeout_envvar); + + if (vfd >= 0) + dprintf (vfd, "using timeout %ld\n", timeout); + + /* make a copy of the envvar so it can be safely modified. */ + server_urls = strdup(urls_envvar); + if (server_urls == NULL) + { + rc = -ENOMEM; + goto out; + } + /* thereafter, goto out0 on error*/ + + /* Because of a race with cache cleanup / rmdir, try to mkdir/mkstemp up to twice. */ + for(int i=0; i<2; i++) { + /* (re)create target directory in cache */ + (void) mkdir(target_cache_dir, 0700); /* files will be 0400 later */ + + /* NB: write to a temporary file first, to avoid race condition of + multiple clients checking the cache, while a partially-written or empty + file is in there, being written from libcurl. */ + fd = mkstemp (target_cache_tmppath); + if (fd >= 0) break; + } + if (fd < 0) /* Still failed after two iterations. */ + { + rc = -errno; + goto out0; + } + + /* Count number of URLs. */ + int num_urls = 0; + for (int i = 0; server_urls[i] != '\0'; i++) + if (server_urls[i] != url_delim_char + && (i == 0 || server_urls[i - 1] == url_delim_char)) + num_urls++; + + CURLM *curlm = c->server_mhandle; + assert (curlm != NULL); + + /* Tracks which handle should write to fd. Set to the first + handle that is ready to write the target file to the cache. */ + CURL *target_handle = NULL; + struct handle_data *data = malloc(sizeof(struct handle_data) * num_urls); + if (data == NULL) + { + rc = -ENOMEM; + goto out0; + } + + /* thereafter, goto out1 on error. */ + + /* Initialize handle_data with default values. */ + for (int i = 0; i < num_urls; i++) + { + data[i].handle = NULL; + data[i].fd = -1; + data[i].errbuf[0] = '\0'; + } + + char *strtok_saveptr; + char *server_url = strtok_r(server_urls, url_delim, &strtok_saveptr); + + /* Initialize each handle. */ + for (int i = 0; i < num_urls && server_url != NULL; i++) + { + if (vfd >= 0) + dprintf (vfd, "init server %d %s\n", i, server_url); + + data[i].fd = fd; + data[i].target_handle = &target_handle; + data[i].handle = curl_easy_init(); + if (data[i].handle == NULL) + { + rc = -ENETUNREACH; + goto out1; + } + data[i].client = c; + + /* Build handle url. Tolerate both http://foo:999 and + http://foo:999/ forms */ + char *slashbuildid; + if (strlen(server_url) > 1 && server_url[strlen(server_url)-1] == '/') + slashbuildid = "buildid"; + else + slashbuildid = "/buildid"; + + if (filename) /* must start with / */ + snprintf(data[i].url, PATH_MAX, "%s%s/%s/%s%s", server_url, + slashbuildid, build_id_bytes, type, filename); + else + snprintf(data[i].url, PATH_MAX, "%s%s/%s/%s", server_url, + slashbuildid, build_id_bytes, type); + + if (vfd >= 0) + dprintf (vfd, "url %d %s\n", i, data[i].url); + + curl_easy_setopt(data[i].handle, CURLOPT_URL, data[i].url); + if (vfd >= 0) + curl_easy_setopt(data[i].handle, CURLOPT_ERRORBUFFER, data[i].errbuf); + curl_easy_setopt(data[i].handle, + CURLOPT_WRITEFUNCTION, + debuginfod_write_callback); + curl_easy_setopt(data[i].handle, CURLOPT_WRITEDATA, (void*)&data[i]); + if (timeout > 0) + { + /* Make sure there is at least some progress, + try to get at least 100K per timeout seconds. */ + curl_easy_setopt (data[i].handle, CURLOPT_LOW_SPEED_TIME, + timeout); + curl_easy_setopt (data[i].handle, CURLOPT_LOW_SPEED_LIMIT, + 100 * 1024L); + } + curl_easy_setopt(data[i].handle, CURLOPT_FILETIME, (long) 1); + curl_easy_setopt(data[i].handle, CURLOPT_FOLLOWLOCATION, (long) 1); + curl_easy_setopt(data[i].handle, CURLOPT_FAILONERROR, (long) 1); + curl_easy_setopt(data[i].handle, CURLOPT_NOSIGNAL, (long) 1); +#if LIBCURL_VERSION_NUM >= 0x072a00 /* 7.42.0 */ + curl_easy_setopt(data[i].handle, CURLOPT_PATH_AS_IS, (long) 1); +#else + /* On old curl; no big deal, canonicalization here is almost the + same, except perhaps for ? # type decorations at the tail. */ +#endif + curl_easy_setopt(data[i].handle, CURLOPT_AUTOREFERER, (long) 1); + curl_easy_setopt(data[i].handle, CURLOPT_ACCEPT_ENCODING, ""); + curl_easy_setopt(data[i].handle, CURLOPT_HTTPHEADER, c->headers); + + curl_multi_add_handle(curlm, data[i].handle); + server_url = strtok_r(NULL, url_delim, &strtok_saveptr); + } + + /* Query servers in parallel. */ + if (vfd >= 0) + dprintf (vfd, "query %d urls in parallel\n", num_urls); + int still_running; + long loops = 0; + int committed_to = -1; + bool verbose_reported = false; + do + { + /* Wait 1 second, the minimum DEBUGINFOD_TIMEOUT. */ + curl_multi_wait(curlm, NULL, 0, 1000, NULL); + + /* If the target file has been found, abort the other queries. */ + if (target_handle != NULL) + { + for (int i = 0; i < num_urls; i++) + if (data[i].handle != target_handle) + curl_multi_remove_handle(curlm, data[i].handle); + else + committed_to = i; + } + + if (vfd >= 0 && !verbose_reported && committed_to >= 0) + { + bool pnl = (c->default_progressfn_printed_p && vfd == STDERR_FILENO); + dprintf (vfd, "%scommitted to url %d\n", pnl ? "\n" : "", + committed_to); + if (pnl) + c->default_progressfn_printed_p = 0; + verbose_reported = true; + } + + CURLMcode curlm_res = curl_multi_perform(curlm, &still_running); + if (curlm_res != CURLM_OK) + { + switch (curlm_res) + { + case CURLM_CALL_MULTI_PERFORM: continue; + case CURLM_OUT_OF_MEMORY: rc = -ENOMEM; break; + default: rc = -ENETUNREACH; break; + } + goto out1; + } + + if (c->progressfn) /* inform/check progress callback */ + { + loops ++; + long pa = loops; /* default params for progress callback */ + long pb = 0; /* transfer_timeout tempting, but loops != elapsed-time */ + if (target_handle) /* we've committed to a server; report its download progress */ + { + CURLcode curl_res; +#ifdef CURLINFO_SIZE_DOWNLOAD_T + curl_off_t dl; + curl_res = curl_easy_getinfo(target_handle, + CURLINFO_SIZE_DOWNLOAD_T, + &dl); + if (curl_res == 0 && dl >= 0) + pa = (dl > LONG_MAX ? LONG_MAX : (long)dl); +#else + double dl; + curl_res = curl_easy_getinfo(target_handle, + CURLINFO_SIZE_DOWNLOAD, + &dl); + if (curl_res == 0) + pa = (dl >= (double)(LONG_MAX+1UL) ? LONG_MAX : (long)dl); +#endif + + /* NB: If going through deflate-compressing proxies, this + number is likely to be unavailable, so -1 may show. */ +#ifdef CURLINFO_CONTENT_LENGTH_DOWNLOAD_T + curl_off_t cl; + curl_res = curl_easy_getinfo(target_handle, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, + &cl); + if (curl_res == 0 && cl >= 0) + pb = (cl > LONG_MAX ? LONG_MAX : (long)cl); +#else + double cl; + curl_res = curl_easy_getinfo(target_handle, + CURLINFO_CONTENT_LENGTH_DOWNLOAD, + &cl); + if (curl_res == 0) + pb = (cl >= (double)(LONG_MAX+1UL) ? LONG_MAX : (long)cl); +#endif + } + + if ((*c->progressfn) (c, pa, pb)) + break; + } + } while (still_running); + + /* Check whether a query was successful. If so, assign its handle + to verified_handle. */ + int num_msg; + rc = -ENOENT; + CURL *verified_handle = NULL; + do + { + CURLMsg *msg; + + msg = curl_multi_info_read(curlm, &num_msg); + if (msg != NULL && msg->msg == CURLMSG_DONE) + { + if (vfd >= 0) + { + bool pnl = (c->default_progressfn_printed_p + && vfd == STDERR_FILENO); + dprintf (vfd, "%sserver response %s\n", pnl ? "\n" : "", + curl_easy_strerror (msg->data.result)); + if (pnl) + c->default_progressfn_printed_p = 0; + for (int i = 0; i < num_urls; i++) + if (msg->easy_handle == data[i].handle) + { + if (strlen (data[i].errbuf) > 0) + dprintf (vfd, "url %d %s\n", i, data[i].errbuf); + break; + } + } + + if (msg->data.result != CURLE_OK) + { + /* Unsuccessful query, determine error code. */ + switch (msg->data.result) + { + case CURLE_COULDNT_RESOLVE_HOST: rc = -EHOSTUNREACH; break; // no NXDOMAIN + case CURLE_URL_MALFORMAT: rc = -EINVAL; break; + case CURLE_COULDNT_CONNECT: rc = -ECONNREFUSED; break; + case CURLE_PEER_FAILED_VERIFICATION: rc = -ECONNREFUSED; break; + case CURLE_REMOTE_ACCESS_DENIED: rc = -EACCES; break; + case CURLE_WRITE_ERROR: rc = -EIO; break; + case CURLE_OUT_OF_MEMORY: rc = -ENOMEM; break; + case CURLE_TOO_MANY_REDIRECTS: rc = -EMLINK; break; + case CURLE_SEND_ERROR: rc = -ECONNRESET; break; + case CURLE_RECV_ERROR: rc = -ECONNRESET; break; + case CURLE_OPERATION_TIMEDOUT: rc = -ETIME; break; + default: rc = -ENOENT; break; + } + } + else + { + /* Query completed without an error. Confirm that the + response code is 200 when using HTTP/HTTPS and 0 when + using file:// and set verified_handle. */ + + if (msg->easy_handle != NULL) + { + char *effective_url = NULL; + long resp_code = 500; + CURLcode ok1 = curl_easy_getinfo (target_handle, + CURLINFO_EFFECTIVE_URL, + &effective_url); + CURLcode ok2 = curl_easy_getinfo (target_handle, + CURLINFO_RESPONSE_CODE, + &resp_code); + if(ok1 == CURLE_OK && ok2 == CURLE_OK && effective_url) + { + if (strncasecmp (effective_url, "HTTP", 4) == 0) + if (resp_code == 200) + { + verified_handle = msg->easy_handle; + break; + } + if (strncasecmp (effective_url, "FILE", 4) == 0) + if (resp_code == 0) + { + verified_handle = msg->easy_handle; + break; + } + } + /* - libcurl since 7.52.0 version start to support + CURLINFO_SCHEME; + - before 7.61.0, effective_url would give us a + url with upper case SCHEME added in the front; + - effective_url between 7.61 and 7.69 can be lack + of scheme if the original url doesn't include one; + - since version 7.69 effective_url will be provide + a scheme in lower case. */ + #if LIBCURL_VERSION_NUM >= 0x073d00 /* 7.61.0 */ + #if LIBCURL_VERSION_NUM <= 0x074500 /* 7.69.0 */ + char *scheme = NULL; + CURLcode ok3 = curl_easy_getinfo (target_handle, + CURLINFO_SCHEME, + &scheme); + if(ok3 == CURLE_OK && scheme) + { + if (startswith (scheme, "HTTP")) + if (resp_code == 200) + { + verified_handle = msg->easy_handle; + break; + } + } + #endif + #endif + } + } + } + } while (num_msg > 0); + + /* Create a 000-permission file named as $HOME/.cache if the query + fails with ENOENT.*/ + if (rc == -ENOENT) + { + int efd = open (target_cache_path, O_CREAT|O_EXCL, 0000); + if (efd >= 0) + close(efd); + } + + if (verified_handle == NULL) + goto out1; + + if (vfd >= 0) + { + bool pnl = c->default_progressfn_printed_p && vfd == STDERR_FILENO; + dprintf (vfd, "%sgot file from server\n", pnl ? "\n" : ""); + if (pnl) + c->default_progressfn_printed_p = 0; + } + + /* we've got one!!!! */ + time_t mtime; + CURLcode curl_res = curl_easy_getinfo(verified_handle, CURLINFO_FILETIME, (void*) &mtime); + if (curl_res != CURLE_OK) + mtime = time(NULL); /* fall back to current time */ + + struct timeval tvs[2]; + tvs[0].tv_sec = tvs[1].tv_sec = mtime; + tvs[0].tv_usec = tvs[1].tv_usec = 0; + (void) futimes (fd, tvs); /* best effort */ + + /* PR27571: make cache files casually unwriteable; dirs are already 0700 */ + (void) fchmod(fd, 0400); + + /* rename tmp->real */ + rc = rename (target_cache_tmppath, target_cache_path); + if (rc < 0) + { + rc = -errno; + goto out1; + /* Perhaps we need not give up right away; could retry or something ... */ + } + + /* remove all handles from multi */ + for (int i = 0; i < num_urls; i++) + { + curl_multi_remove_handle(curlm, data[i].handle); /* ok to repeat */ + curl_easy_cleanup (data[i].handle); + } + + free (data); + free (server_urls); + + /* don't close fd - we're returning it */ + /* don't unlink the tmppath; it's already been renamed. */ + if (path != NULL) + *path = strdup(target_cache_path); + + rc = fd; + goto out; + +/* error exits */ + out1: + /* remove all handles from multi */ + for (int i = 0; i < num_urls; i++) + { + curl_multi_remove_handle(curlm, data[i].handle); /* ok to repeat */ + curl_easy_cleanup (data[i].handle); + } + + unlink (target_cache_tmppath); + close (fd); /* before the rmdir, otherwise it'll fail */ + (void) rmdir (target_cache_dir); /* nop if not empty */ + free(data); + + out0: + free (server_urls); + +/* general purpose exit */ + out: + /* Reset sent headers */ + curl_slist_free_all (c->headers); + c->headers = NULL; + c->user_agent_set_p = 0; + + /* Conclude the last \r status line */ + /* Another possibility is to use the ANSI CSI n K EL "Erase in Line" + code. That way, the previously printed messages would be erased, + and without a newline. */ + if (c->default_progressfn_printed_p) + dprintf(STDERR_FILENO, "\n"); + + if (vfd >= 0) + { + if (rc < 0) + dprintf (vfd, "not found %s (err=%d)\n", strerror (-rc), rc); + else + dprintf (vfd, "found %s (fd=%d)\n", target_cache_path, rc); + } + + free (cache_path); + free (maxage_path); + free (interval_path); + free (cache_miss_path); + free (target_cache_dir); + free (target_cache_path); + free (target_cache_tmppath); + return rc; +} + + + +/* See debuginfod.h */ +debuginfod_client * +debuginfod_begin (void) +{ + debuginfod_client *client; + size_t size = sizeof (struct debuginfod_client); + client = (debuginfod_client *) calloc (1, size); + + if (client != NULL) + { + if (getenv(DEBUGINFOD_PROGRESS_ENV_VAR)) + client->progressfn = default_progressfn; + if (getenv(DEBUGINFOD_VERBOSE_ENV_VAR)) + client->verbose_fd = STDERR_FILENO; + else + client->verbose_fd = -1; + } + + // allocate 1 curl multi handle + client->server_mhandle = curl_multi_init (); + if (client->server_mhandle == NULL) + goto out1; + + // extra future initialization + + goto out; + + out1: + free (client); + client = NULL; + + out: + return client; +} + +void +debuginfod_set_user_data(debuginfod_client *client, + void *data) +{ + client->user_data = data; +} + +void * +debuginfod_get_user_data(debuginfod_client *client) +{ + return client->user_data; +} + +const char * +debuginfod_get_url(debuginfod_client *client) +{ + return client->url; +} + +void +debuginfod_end (debuginfod_client *client) +{ + if (client == NULL) + return; + + curl_multi_cleanup (client->server_mhandle); + curl_slist_free_all (client->headers); + free (client->url); + free (client); +} + +int +debuginfod_find_debuginfo (debuginfod_client *client, + const unsigned char *build_id, int build_id_len, + char **path) +{ + return debuginfod_query_server(client, build_id, build_id_len, + "debuginfo", NULL, path); +} + + +/* See debuginfod.h */ +int +debuginfod_find_executable(debuginfod_client *client, + const unsigned char *build_id, int build_id_len, + char **path) +{ + return debuginfod_query_server(client, build_id, build_id_len, + "executable", NULL, path); +} + +/* See debuginfod.h */ +int debuginfod_find_source(debuginfod_client *client, + const unsigned char *build_id, int build_id_len, + const char *filename, char **path) +{ + return debuginfod_query_server(client, build_id, build_id_len, + "source", filename, path); +} + + +/* Add an outgoing HTTP header. */ +int debuginfod_add_http_header (debuginfod_client *client, const char* header) +{ + /* Sanity check header value is of the form Header: Value. + It should contain exactly one colon that isn't the first or + last character. */ + char *colon = strchr (header, ':'); + if (colon == NULL + || colon == header + || *(colon + 1) == '\0' + || strchr (colon + 1, ':') != NULL) + return -EINVAL; + + struct curl_slist *temp = curl_slist_append (client->headers, header); + if (temp == NULL) + return -ENOMEM; + + /* Track if User-Agent: is being set. If so, signal not to add the + default one. */ + if (startswith (header, "User-Agent:")) + client->user_agent_set_p = 1; + + client->headers = temp; + return 0; +} + + +void +debuginfod_set_progressfn(debuginfod_client *client, + debuginfod_progressfn_t fn) +{ + client->progressfn = fn; +} + +void +debuginfod_set_verbose_fd(debuginfod_client *client, int fd) +{ + client->verbose_fd = fd; +} + + +/* NB: these are thread-unsafe. */ +__attribute__((constructor)) attribute_hidden void libdebuginfod_ctor(void) +{ + curl_global_init(CURL_GLOBAL_DEFAULT); +} + +/* NB: this is very thread-unsafe: it breaks other threads that are still in libcurl */ +__attribute__((destructor)) attribute_hidden void libdebuginfod_dtor(void) +{ + /* ... so don't do this: */ + /* curl_global_cleanup(); */ +} + +#endif /* DUMMY_LIBDEBUGINFOD */ diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c new file mode 100644 index 00000000..3e8ab203 --- /dev/null +++ b/debuginfod/debuginfod-find.c @@ -0,0 +1,239 @@ +/* Command-line frontend for retrieving ELF / DWARF / source files + from the debuginfod. + Copyright (C) 2019-2020 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + + +#include "config.h" +#include "printversion.h" +#include "debuginfod.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Short description of program. */ +static const char doc[] = N_("Request debuginfo-related content " + "from debuginfods listed in $" DEBUGINFOD_URLS_ENV_VAR "."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("debuginfo BUILDID\n" + "debuginfo PATH\n" + "executable BUILDID\n" + "executable PATH\n" + "source BUILDID /FILENAME\n" + "source PATH /FILENAME\n"); + + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = + { + { "verbose", 'v', NULL, 0, "Increase verbosity.", 0 }, + { NULL, 0, NULL, 0, NULL, 0 } + }; + +/* debuginfod connection handle. */ +static debuginfod_client *client; +static int verbose; + +int progressfn(debuginfod_client *c __attribute__((__unused__)), + long a, long b) +{ + static bool first = true; + static struct timespec last; + struct timespec now; + uint64_t delta; + if (!first) + { + clock_gettime (CLOCK_MONOTONIC, &now); + delta = ((now.tv_sec - last.tv_sec) * 1000000 + + (now.tv_nsec - last.tv_nsec) / 1000); + } + else + { + first = false; + delta = 250000; + } + + /* Show progress the first time and then at most 5 times a second. */ + if (delta > 200000) + { + fprintf (stderr, "Progress %ld / %ld\n", a, b); + clock_gettime (CLOCK_MONOTONIC, &last); + } + return 0; +} + + +static error_t parse_opt (int key, char *arg, struct argp_state *state) +{ + (void) arg; + (void) state; + switch (key) + { + case 'v': verbose++; + debuginfod_set_progressfn (client, & progressfn); + debuginfod_set_verbose_fd (client, STDERR_FILENO); + break; + default: return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +/* Data structure to communicate with argp functions. */ +static struct argp argp = + { + options, parse_opt, args_doc, doc, NULL, NULL, NULL + }; + + + +int +main(int argc, char** argv) +{ + elf_version (EV_CURRENT); + + client = debuginfod_begin (); + if (client == NULL) + { + fprintf(stderr, "Couldn't create debuginfod client context\n"); + return 1; + } + + /* Exercise user data pointer, to support testing only. */ + debuginfod_set_user_data (client, (void *)"Progress"); + + int remaining; + (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_ARGS, &remaining, NULL); + + if (argc < 2 || remaining+1 == argc) /* no arguments or at least two non-option words */ + { + argp_help (&argp, stderr, ARGP_HELP_USAGE, argv[0]); + return 1; + } + + /* If we were passed an ELF file name in the BUILDID slot, look in there. */ + unsigned char* build_id = (unsigned char*) argv[remaining+1]; + int build_id_len = 0; /* assume text */ + + int any_non_hex = 0; + int i; + for (i = 0; build_id[i] != '\0'; i++) + if ((build_id[i] >= '0' && build_id[i] <= '9') || + (build_id[i] >= 'a' && build_id[i] <= 'f')) + ; + else + any_non_hex = 1; + + int fd = -1; + Elf* elf = NULL; + if (any_non_hex) /* raw build-id */ + { + fd = open ((char*) build_id, O_RDONLY); + if (fd < 0) + fprintf (stderr, "Cannot open %s: %s\n", build_id, strerror(errno)); + } + if (fd >= 0) + { + elf = dwelf_elf_begin (fd); + if (elf == NULL) + fprintf (stderr, "Cannot open as ELF file %s: %s\n", build_id, + elf_errmsg (-1)); + } + if (elf != NULL) + { + const void *extracted_build_id; + ssize_t s = dwelf_elf_gnu_build_id(elf, &extracted_build_id); + if (s > 0) + { + /* Success: replace the build_id pointer/len with the binary blob + that elfutils is keeping for us. It'll remain valid until elf_end(). */ + build_id = (unsigned char*) extracted_build_id; + build_id_len = s; + } + else + fprintf (stderr, "Cannot extract build-id from %s: %s\n", build_id, elf_errmsg(-1)); + } + + char *cache_name; + int rc = 0; + + /* Check whether FILETYPE is valid and call the appropriate + debuginfod_find_* function. If FILETYPE is "source" + then ensure a FILENAME was also supplied as an argument. */ + if (strcmp(argv[remaining], "debuginfo") == 0) + rc = debuginfod_find_debuginfo(client, + build_id, build_id_len, + &cache_name); + else if (strcmp(argv[remaining], "executable") == 0) + rc = debuginfod_find_executable(client, + build_id, build_id_len, + &cache_name); + else if (strcmp(argv[remaining], "source") == 0) + { + if (remaining+2 == argc || argv[remaining+2][0] != '/') + { + fprintf(stderr, "If FILETYPE is \"source\" then absolute /FILENAME must be given\n"); + return 1; + } + rc = debuginfod_find_source(client, + build_id, build_id_len, + argv[remaining+2], &cache_name); + } + else + { + argp_help (&argp, stderr, ARGP_HELP_USAGE, argv[0]); + return 1; + } + + if (verbose) + { + const char* url = debuginfod_get_url (client); + if (url != NULL) + fprintf(stderr, "Downloaded from %s\n", url); + } + + debuginfod_end (client); + if (elf) + elf_end(elf); + if (fd >= 0) + close (fd); + + if (rc < 0) + { + fprintf(stderr, "Server query failed: %s\n", strerror(-rc)); + return 1; + } + + printf("%s\n", cache_name); + free (cache_name); + + return 0; +} diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx new file mode 100644 index 00000000..e0948eab --- /dev/null +++ b/debuginfod/debuginfod.cxx @@ -0,0 +1,3615 @@ +/* Debuginfo-over-http server. + Copyright (C) 2019-2021 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + + +/* cargo-cult from libdwfl linux-kernel-modules.c */ +/* In case we have a bad fts we include this before config.h because it + can't handle _FILE_OFFSET_BITS. + Everything we need here is fine if its declarations just come first. + Also, include sys/types.h before fts. On some systems fts.h is not self + contained. */ +#ifdef BAD_FTS + #include + #include +#endif + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +extern "C" { +#include "printversion.h" +} + +#include "debuginfod.h" +#include +#include + +#include +#ifdef __GNUC__ +#undef __attribute__ /* glibc bug - rhbz 1763325 */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* If fts.h is included before config.h, its indirect inclusions may not + give us the right LFS aliases of these functions, so map them manually. */ +#ifdef BAD_FTS + #ifdef _FILE_OFFSET_BITS + #define open open64 + #define fopen fopen64 + #endif +#else + #include + #include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include // on rhel7 gcc 4.8, not competent +#include +// #include +using namespace std; + +#include +#include + +#include + +#if MHD_VERSION >= 0x00097002 +// libmicrohttpd 0.9.71 broke API +#define MHD_RESULT enum MHD_Result +#else +#define MHD_RESULT int +#endif + +#include +#include +#include +#include + +#ifdef __linux__ +#include +#endif + +#ifdef __linux__ +#define tid() syscall(SYS_gettid) +#else +#define tid() pthread_self() +#endif + + +inline bool +string_endswith(const string& haystack, const string& needle) +{ + return (haystack.size() >= needle.size() && + equal(haystack.end()-needle.size(), haystack.end(), + needle.begin())); +} + + +// Roll this identifier for every sqlite schema incompatibility. +#define BUILDIDS "buildids9" + +#if SQLITE_VERSION_NUMBER >= 3008000 +#define WITHOUT_ROWID "without rowid" +#else +#define WITHOUT_ROWID "" +#endif + +static const char DEBUGINFOD_SQLITE_DDL[] = + "pragma foreign_keys = on;\n" + "pragma synchronous = 0;\n" // disable fsync()s - this cache is disposable across a machine crash + "pragma journal_mode = wal;\n" // https://sqlite.org/wal.html + "pragma wal_checkpoint = truncate;\n" // clean out any preexisting wal file + "pragma journal_size_limit = 0;\n" // limit steady state file (between grooming, which also =truncate's) + "pragma auto_vacuum = incremental;\n" // https://sqlite.org/pragma.html + "pragma busy_timeout = 1000;\n" // https://sqlite.org/pragma.html + // NB: all these are overridable with -D option + + // Normalization table for interning file names + "create table if not exists " BUILDIDS "_files (\n" + " id integer primary key not null,\n" + " name text unique not null\n" + " );\n" + // Normalization table for interning buildids + "create table if not exists " BUILDIDS "_buildids (\n" + " id integer primary key not null,\n" + " hex text unique not null);\n" + // Track the completion of scanning of a given file & sourcetype at given time + "create table if not exists " BUILDIDS "_file_mtime_scanned (\n" + " mtime integer not null,\n" + " file integer not null,\n" + " size integer not null,\n" // in bytes + " sourcetype text(1) not null\n" + " check (sourcetype IN ('F', 'R')),\n" + " foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " primary key (file, mtime, sourcetype)\n" + " ) " WITHOUT_ROWID ";\n" + "create table if not exists " BUILDIDS "_f_de (\n" + " buildid integer not null,\n" + " debuginfo_p integer not null,\n" + " executable_p integer not null,\n" + " file integer not null,\n" + " mtime integer not null,\n" + " foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n" + " primary key (buildid, file, mtime)\n" + " ) " WITHOUT_ROWID ";\n" + "create table if not exists " BUILDIDS "_f_s (\n" + " buildid integer not null,\n" + " artifactsrc integer not null,\n" + " file integer not null,\n" // NB: not necessarily entered into _mtime_scanned + " mtime integer not null,\n" + " foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (artifactsrc) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n" + " primary key (buildid, artifactsrc, file, mtime)\n" + " ) " WITHOUT_ROWID ";\n" + "create table if not exists " BUILDIDS "_r_de (\n" + " buildid integer not null,\n" + " debuginfo_p integer not null,\n" + " executable_p integer not null,\n" + " file integer not null,\n" + " mtime integer not null,\n" + " content integer not null,\n" + " foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (content) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n" + " primary key (buildid, debuginfo_p, executable_p, file, content, mtime)\n" + " ) " WITHOUT_ROWID ";\n" + "create table if not exists " BUILDIDS "_r_sref (\n" // outgoing dwarf sourcefile references from rpm + " buildid integer not null,\n" + " artifactsrc integer not null,\n" + " foreign key (artifactsrc) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n" + " primary key (buildid, artifactsrc)\n" + " ) " WITHOUT_ROWID ";\n" + "create table if not exists " BUILDIDS "_r_sdef (\n" // rpm contents that may satisfy sref + " file integer not null,\n" + " mtime integer not null,\n" + " content integer not null,\n" + " foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " foreign key (content) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n" + " primary key (content, file, mtime)\n" + " ) " WITHOUT_ROWID ";\n" + // create views to glue together some of the above tables, for webapi D queries + "create view if not exists " BUILDIDS "_query_d as \n" + "select\n" + " b.hex as buildid, n.mtime, 'F' as sourcetype, f0.name as source0, n.mtime as mtime, null as source1\n" + " from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_f_de n\n" + " where b.id = n.buildid and f0.id = n.file and n.debuginfo_p = 1\n" + "union all select\n" + " b.hex as buildid, n.mtime, 'R' as sourcetype, f0.name as source0, n.mtime as mtime, f1.name as source1\n" + " from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files f1, " BUILDIDS "_r_de n\n" + " where b.id = n.buildid and f0.id = n.file and f1.id = n.content and n.debuginfo_p = 1\n" + ";" + // ... and for E queries + "create view if not exists " BUILDIDS "_query_e as \n" + "select\n" + " b.hex as buildid, n.mtime, 'F' as sourcetype, f0.name as source0, n.mtime as mtime, null as source1\n" + " from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_f_de n\n" + " where b.id = n.buildid and f0.id = n.file and n.executable_p = 1\n" + "union all select\n" + " b.hex as buildid, n.mtime, 'R' as sourcetype, f0.name as source0, n.mtime as mtime, f1.name as source1\n" + " from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files f1, " BUILDIDS "_r_de n\n" + " where b.id = n.buildid and f0.id = n.file and f1.id = n.content and n.executable_p = 1\n" + ";" + // ... and for S queries + "create view if not exists " BUILDIDS "_query_s as \n" + "select\n" + " b.hex as buildid, fs.name as artifactsrc, 'F' as sourcetype, f0.name as source0, n.mtime as mtime, null as source1, null as source0ref\n" + " from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files fs, " BUILDIDS "_f_s n\n" + " where b.id = n.buildid and f0.id = n.file and fs.id = n.artifactsrc\n" + "union all select\n" + " b.hex as buildid, f1.name as artifactsrc, 'R' as sourcetype, f0.name as source0, sd.mtime as mtime, f1.name as source1, fsref.name as source0ref\n" + " from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files f1, " BUILDIDS "_files fsref, " + " " BUILDIDS "_r_sdef sd, " BUILDIDS "_r_sref sr, " BUILDIDS "_r_de sde\n" + " where b.id = sr.buildid and f0.id = sd.file and fsref.id = sde.file and f1.id = sd.content\n" + " and sr.artifactsrc = sd.content and sde.buildid = sr.buildid\n" + ";" + // and for startup overview counts + "drop view if exists " BUILDIDS "_stats;\n" + "create view if not exists " BUILDIDS "_stats as\n" + " select 'file d/e' as label,count(*) as quantity from " BUILDIDS "_f_de\n" + "union all select 'file s',count(*) from " BUILDIDS "_f_s\n" + "union all select 'archive d/e',count(*) from " BUILDIDS "_r_de\n" + "union all select 'archive sref',count(*) from " BUILDIDS "_r_sref\n" + "union all select 'archive sdef',count(*) from " BUILDIDS "_r_sdef\n" + "union all select 'buildids',count(*) from " BUILDIDS "_buildids\n" + "union all select 'filenames',count(*) from " BUILDIDS "_files\n" + "union all select 'files scanned (#)',count(*) from " BUILDIDS "_file_mtime_scanned\n" + "union all select 'files scanned (mb)',coalesce(sum(size)/1024/1024,0) from " BUILDIDS "_file_mtime_scanned\n" +#if SQLITE_VERSION_NUMBER >= 3016000 + "union all select 'index db size (mb)',page_count*page_size/1024/1024 as size FROM pragma_page_count(), pragma_page_size()\n" +#endif + ";\n" + +// schema change history & garbage collection +// +// XXX: we could have migration queries here to bring prior-schema +// data over instead of just dropping it. +// +// buildids9: widen the mtime_scanned table + "" // <<< we are here +// buildids8: slim the sref table + "drop table if exists buildids8_f_de;\n" + "drop table if exists buildids8_f_s;\n" + "drop table if exists buildids8_r_de;\n" + "drop table if exists buildids8_r_sref;\n" + "drop table if exists buildids8_r_sdef;\n" + "drop table if exists buildids8_file_mtime_scanned;\n" + "drop table if exists buildids8_files;\n" + "drop table if exists buildids8_buildids;\n" +// buildids7: separate _norm table into dense subtype tables + "drop table if exists buildids7_f_de;\n" + "drop table if exists buildids7_f_s;\n" + "drop table if exists buildids7_r_de;\n" + "drop table if exists buildids7_r_sref;\n" + "drop table if exists buildids7_r_sdef;\n" + "drop table if exists buildids7_file_mtime_scanned;\n" + "drop table if exists buildids7_files;\n" + "drop table if exists buildids7_buildids;\n" +// buildids6: drop bolo/rfolo again, represent sources / rpmcontents in main table + "drop table if exists buildids6_norm;\n" + "drop table if exists buildids6_files;\n" + "drop table if exists buildids6_buildids;\n" + "drop view if exists buildids6;\n" +// buildids5: redefine srcfile1 column to be '.'-less (for rpms) + "drop table if exists buildids5_norm;\n" + "drop table if exists buildids5_files;\n" + "drop table if exists buildids5_buildids;\n" + "drop table if exists buildids5_bolo;\n" + "drop table if exists buildids5_rfolo;\n" + "drop view if exists buildids5;\n" +// buildids4: introduce rpmfile RFOLO + "drop table if exists buildids4_norm;\n" + "drop table if exists buildids4_files;\n" + "drop table if exists buildids4_buildids;\n" + "drop table if exists buildids4_bolo;\n" + "drop table if exists buildids4_rfolo;\n" + "drop view if exists buildids4;\n" +// buildids3*: split out srcfile BOLO + "drop table if exists buildids3_norm;\n" + "drop table if exists buildids3_files;\n" + "drop table if exists buildids3_buildids;\n" + "drop table if exists buildids3_bolo;\n" + "drop view if exists buildids3;\n" +// buildids2: normalized buildid and filenames into interning tables; + "drop table if exists buildids2_norm;\n" + "drop table if exists buildids2_files;\n" + "drop table if exists buildids2_buildids;\n" + "drop view if exists buildids2;\n" + // buildids1: made buildid and artifacttype NULLable, to represent cached-negative +// lookups from sources, e.g. files or rpms that contain no buildid-indexable content + "drop table if exists buildids1;\n" +// buildids: original + "drop table if exists buildids;\n" + ; + +static const char DEBUGINFOD_SQLITE_CLEANUP_DDL[] = + "pragma wal_checkpoint = truncate;\n" // clean out any preexisting wal file + ; + + + + +/* Name and version of program. */ +/* ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; */ // not this simple for C++ + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = + { + { NULL, 0, NULL, 0, "Scanners:", 1 }, + { "scan-file-dir", 'F', NULL, 0, "Enable ELF/DWARF file scanning.", 0 }, + { "scan-rpm-dir", 'R', NULL, 0, "Enable RPM scanning.", 0 }, + { "scan-deb-dir", 'U', NULL, 0, "Enable DEB scanning.", 0 }, + { "scan-archive", 'Z', "EXT=CMD", 0, "Enable arbitrary archive scanning.", 0 }, + // "source-oci-imageregistry" ... + + { NULL, 0, NULL, 0, "Options:", 2 }, + { "logical", 'L', NULL, 0, "Follow symlinks, default=ignore.", 0 }, + { "rescan-time", 't', "SECONDS", 0, "Number of seconds to wait between rescans, 0=disable.", 0 }, + { "groom-time", 'g', "SECONDS", 0, "Number of seconds to wait between database grooming, 0=disable.", 0 }, + { "maxigroom", 'G', NULL, 0, "Run a complete database groom/shrink pass at startup.", 0 }, + { "concurrency", 'c', "NUM", 0, "Limit scanning thread concurrency to NUM.", 0 }, + { "include", 'I', "REGEX", 0, "Include files matching REGEX, default=all.", 0 }, + { "exclude", 'X', "REGEX", 0, "Exclude files matching REGEX, default=none.", 0 }, + { "port", 'p', "NUM", 0, "HTTP port to listen on, default 8002.", 0 }, + { "database", 'd', "FILE", 0, "Path to sqlite database.", 0 }, + { "ddl", 'D', "SQL", 0, "Apply extra sqlite ddl/pragma to connection.", 0 }, + { "verbose", 'v', NULL, 0, "Increase verbosity.", 0 }, +#define ARGP_KEY_FDCACHE_FDS 0x1001 + { "fdcache-fds", ARGP_KEY_FDCACHE_FDS, "NUM", 0, "Maximum number of archive files to keep in fdcache.", 0 }, +#define ARGP_KEY_FDCACHE_MBS 0x1002 + { "fdcache-mbs", ARGP_KEY_FDCACHE_MBS, "MB", 0, "Maximum total size of archive file fdcache.", 0 }, +#define ARGP_KEY_FDCACHE_PREFETCH 0x1003 + { "fdcache-prefetch", ARGP_KEY_FDCACHE_PREFETCH, "NUM", 0, "Number of archive files to prefetch into fdcache.", 0 }, +#define ARGP_KEY_FDCACHE_MINTMP 0x1004 + { "fdcache-mintmp", ARGP_KEY_FDCACHE_MINTMP, "NUM", 0, "Minimum free space% on tmpdir.", 0 }, + { NULL, 0, NULL, 0, NULL, 0 } + }; + +/* Short description of program. */ +static const char doc[] = "Serve debuginfo-related content across HTTP from files under PATHs."; + +/* Strings for arguments in help texts. */ +static const char args_doc[] = "[PATH ...]"; + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = + { + options, parse_opt, args_doc, doc, NULL, NULL, NULL + }; + + +static string db_path; +static sqlite3 *db; // single connection, serialized across all our threads! +static sqlite3 *dbq; // webapi query-servicing readonly connection, serialized ditto! +static unsigned verbose; +static volatile sig_atomic_t interrupted = 0; +static volatile sig_atomic_t forced_rescan_count = 0; +static volatile sig_atomic_t sigusr1 = 0; +static volatile sig_atomic_t forced_groom_count = 0; +static volatile sig_atomic_t sigusr2 = 0; +static unsigned http_port = 8002; +static unsigned rescan_s = 300; +static unsigned groom_s = 86400; +static bool maxigroom = false; +static unsigned concurrency = std::thread::hardware_concurrency() ?: 1; +static set source_paths; +static bool scan_files = false; +static map scan_archives; +static vector extra_ddl; +static regex_t file_include_regex; +static regex_t file_exclude_regex; +static bool traverse_logical; +static long fdcache_fds; +static long fdcache_mbs; +static long fdcache_prefetch; +static long fdcache_mintmp; +static string tmpdir; + +static void set_metric(const string& key, double value); +// static void inc_metric(const string& key); +static void set_metric(const string& metric, + const string& lname, const string& lvalue, + double value); +static void inc_metric(const string& metric, + const string& lname, const string& lvalue); +static void add_metric(const string& metric, + const string& lname, const string& lvalue, + double value); +// static void add_metric(const string& metric, double value); + +class tmp_inc_metric { // a RAII style wrapper for exception-safe scoped increment & decrement + string m, n, v; +public: + tmp_inc_metric(const string& mname, const string& lname, const string& lvalue): + m(mname), n(lname), v(lvalue) + { + add_metric (m, n, v, 1); + } + ~tmp_inc_metric() + { + add_metric (m, n, v, -1); + } +}; + +class tmp_ms_metric { // a RAII style wrapper for exception-safe scoped timing + string m, n, v; + struct timespec ts_start; +public: + tmp_ms_metric(const string& mname, const string& lname, const string& lvalue): + m(mname), n(lname), v(lvalue) + { + clock_gettime (CLOCK_MONOTONIC, & ts_start); + } + ~tmp_ms_metric() + { + struct timespec ts_end; + clock_gettime (CLOCK_MONOTONIC, & ts_end); + double deltas = (ts_end.tv_sec - ts_start.tv_sec) + + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; + + add_metric (m + "_milliseconds_sum", n, v, (deltas*1000.0)); + inc_metric (m + "_milliseconds_count", n, v); + } +}; + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + int rc; + switch (key) + { + case 'v': verbose ++; break; + case 'd': db_path = string(arg); break; + case 'p': http_port = (unsigned) atoi(arg); + if (http_port == 0 || http_port > 65535) + argp_failure(state, 1, EINVAL, "port number"); + break; + case 'F': scan_files = true; break; + case 'R': + scan_archives[".rpm"]="cat"; // libarchive groks rpm natively + break; + case 'U': + scan_archives[".deb"]="(bsdtar -O -x -f - data.tar\\*)<"; + scan_archives[".ddeb"]="(bsdtar -O -x -f - data.tar\\*)<"; + scan_archives[".ipk"]="(bsdtar -O -x -f - data.tar\\*)<"; + // .udeb too? + break; + case 'Z': + { + char* extension = strchr(arg, '='); + if (arg[0] == '\0') + argp_failure(state, 1, EINVAL, "missing EXT"); + else if (extension) + scan_archives[string(arg, (extension-arg))]=string(extension+1); + else + scan_archives[string(arg)]=string("cat"); + } + break; + case 'L': + traverse_logical = true; + break; + case 'D': extra_ddl.push_back(string(arg)); break; + case 't': + rescan_s = (unsigned) atoi(arg); + break; + case 'g': + groom_s = (unsigned) atoi(arg); + break; + case 'G': + maxigroom = true; + break; + case 'c': + concurrency = (unsigned) atoi(arg); + if (concurrency < 1) concurrency = 1; + break; + case 'I': + // NB: no problem with unconditional free here - an earlier failed regcomp would exit program + regfree (&file_include_regex); + rc = regcomp (&file_include_regex, arg, REG_EXTENDED|REG_NOSUB); + if (rc != 0) + argp_failure(state, 1, EINVAL, "regular expression"); + break; + case 'X': + regfree (&file_exclude_regex); + rc = regcomp (&file_exclude_regex, arg, REG_EXTENDED|REG_NOSUB); + if (rc != 0) + argp_failure(state, 1, EINVAL, "regular expression"); + break; + case ARGP_KEY_FDCACHE_FDS: + fdcache_fds = atol (arg); + break; + case ARGP_KEY_FDCACHE_MBS: + fdcache_mbs = atol (arg); + break; + case ARGP_KEY_FDCACHE_PREFETCH: + fdcache_prefetch = atol (arg); + break; + case ARGP_KEY_FDCACHE_MINTMP: + fdcache_mintmp = atol (arg); + break; + case ARGP_KEY_ARG: + source_paths.insert(string(arg)); + break; + // case 'h': argp_state_help (state, stderr, ARGP_HELP_LONG|ARGP_HELP_EXIT_OK); + default: return ARGP_ERR_UNKNOWN; + } + + return 0; +} + + +//////////////////////////////////////////////////////////////////////// + + +// represent errors that may get reported to an ostream and/or a libmicrohttpd connection + +struct reportable_exception +{ + int code; + string message; + + reportable_exception(int c, const string& m): code(c), message(m) {} + reportable_exception(const string& m): code(503), message(m) {} + reportable_exception(): code(503), message() {} + + void report(ostream& o) const; // defined under obatched() class below + + MHD_RESULT mhd_send_response(MHD_Connection* c) const { + MHD_Response* r = MHD_create_response_from_buffer (message.size(), + (void*) message.c_str(), + MHD_RESPMEM_MUST_COPY); + MHD_add_response_header (r, "Content-Type", "text/plain"); + MHD_RESULT rc = MHD_queue_response (c, code, r); + MHD_destroy_response (r); + return rc; + } +}; + + +struct sqlite_exception: public reportable_exception +{ + sqlite_exception(int rc, const string& msg): + reportable_exception(string("sqlite3 error: ") + msg + ": " + string(sqlite3_errstr(rc) ?: "?")) { + inc_metric("error_count","sqlite3",sqlite3_errstr(rc)); + } +}; + +struct libc_exception: public reportable_exception +{ + libc_exception(int rc, const string& msg): + reportable_exception(string("libc error: ") + msg + ": " + string(strerror(rc) ?: "?")) { + inc_metric("error_count","libc",strerror(rc)); + } +}; + + +struct archive_exception: public reportable_exception +{ + archive_exception(const string& msg): + reportable_exception(string("libarchive error: ") + msg) { + inc_metric("error_count","libarchive",msg); + } + archive_exception(struct archive* a, const string& msg): + reportable_exception(string("libarchive error: ") + msg + ": " + string(archive_error_string(a) ?: "?")) { + inc_metric("error_count","libarchive",msg + ": " + string(archive_error_string(a) ?: "?")); + } +}; + + +struct elfutils_exception: public reportable_exception +{ + elfutils_exception(int rc, const string& msg): + reportable_exception(string("elfutils error: ") + msg + ": " + string(elf_errmsg(rc) ?: "?")) { + inc_metric("error_count","elfutils",elf_errmsg(rc)); + } +}; + + +//////////////////////////////////////////////////////////////////////// + +template +class workq +{ + set q; // eliminate duplicates + mutex mtx; + condition_variable cv; + bool dead; + unsigned idlers; + +public: + workq() { dead = false; idlers = 0; } + ~workq() {} + + void push_back(const Payload& p) + { + unique_lock lock(mtx); + q.insert (p); + set_metric("thread_work_pending","role","scan", q.size()); + cv.notify_all(); + } + + // kill this workqueue, wake up all idlers / scanners + void nuke() { + unique_lock lock(mtx); + // optional: q.clear(); + dead = true; + cv.notify_all(); + } + + // clear the workqueue, when scanning is interrupted with USR2 + void clear() { + unique_lock lock(mtx); + q.clear(); + set_metric("thread_work_pending","role","scan", q.size()); + cv.notify_all(); // maybe wake up waiting idlers + } + + // block this scanner thread until there is work to do and no active + bool wait_front (Payload& p) + { + unique_lock lock(mtx); + while (!dead && (q.size() == 0 || idlers > 0)) + cv.wait(lock); + if (dead) + return false; + else + { + p = * q.begin(); + q.erase (q.begin()); + set_metric("thread_work_pending","role","scan", q.size()); + if (q.size() == 0) + cv.notify_all(); // maybe wake up waiting idlers + return true; + } + } + + // block this idler thread until there is no work to do + void wait_idle () + { + unique_lock lock(mtx); + cv.notify_all(); // maybe wake up waiting scanners + while (!dead && (q.size() != 0)) + cv.wait(lock); + idlers ++; + } + + void done_idle () + { + unique_lock lock(mtx); + idlers --; + cv.notify_all(); // maybe wake up waiting scanners, but probably not (shutting down) + } +}; + +typedef struct stat stat_t; +typedef pair scan_payload; +inline bool operator< (const scan_payload& a, const scan_payload& b) +{ + return a.first < b.first; // don't bother compare the stat fields +} +static workq scanq; // just a single one +// producer & idler: thread_main_fts_source_paths() +// consumer: thread_main_scanner() +// idler: thread_main_groom() + + + +//////////////////////////////////////////////////////////////////////// + + +// Print a standard timestamp. +static ostream& +timestamp (ostream &o) +{ + char datebuf[80]; + char *now2 = NULL; + time_t now_t = time(NULL); + struct tm *now = gmtime (&now_t); + if (now) + { + (void) strftime (datebuf, sizeof (datebuf), "%c", now); + now2 = datebuf; + } + + return o << "[" << (now2 ? now2 : "") << "] " + << "(" << getpid () << "/" << tid() << "): "; +} + + +// A little class that impersonates an ostream to the extent that it can +// take << streaming operations. It batches up the bits into an internal +// stringstream until it is destroyed; then flushes to the original ostream. +// It adds a timestamp +class obatched +{ +private: + ostream& o; + stringstream stro; + static mutex lock; +public: + obatched(ostream& oo, bool timestamp_p = true): o(oo) + { + if (timestamp_p) + timestamp(stro); + } + ~obatched() + { + unique_lock do_not_cross_the_streams(obatched::lock); + o << stro.str(); + o.flush(); + } + operator ostream& () { return stro; } + template ostream& operator << (const T& t) { stro << t; return stro; } +}; +mutex obatched::lock; // just the one, since cout/cerr iostreams are not thread-safe + + +void reportable_exception::report(ostream& o) const { + obatched(o) << message << endl; +} + + +//////////////////////////////////////////////////////////////////////// + + +// RAII style sqlite prepared-statement holder that matches { } block lifetime + +struct sqlite_ps +{ +private: + sqlite3* db; + const string nickname; + const string sql; + sqlite3_stmt *pp; + + sqlite_ps(const sqlite_ps&); // make uncopyable + sqlite_ps& operator=(const sqlite_ps &); // make unassignable + +public: + sqlite_ps (sqlite3* d, const string& n, const string& s): db(d), nickname(n), sql(s) { + // tmp_ms_metric tick("sqlite3","prep",nickname); + if (verbose > 4) + obatched(clog) << nickname << " prep " << sql << endl; + int rc = sqlite3_prepare_v2 (db, sql.c_str(), -1 /* to \0 */, & this->pp, NULL); + if (rc != SQLITE_OK) + throw sqlite_exception(rc, "prepare " + sql); + } + + sqlite_ps& reset() + { + tmp_ms_metric tick("sqlite3","reset",nickname); + sqlite3_reset(this->pp); + return *this; + } + + sqlite_ps& bind(int parameter, const string& str) + { + if (verbose > 4) + obatched(clog) << nickname << " bind " << parameter << "=" << str << endl; + int rc = sqlite3_bind_text (this->pp, parameter, str.c_str(), -1, SQLITE_TRANSIENT); + if (rc != SQLITE_OK) + throw sqlite_exception(rc, "sqlite3 bind"); + return *this; + } + + sqlite_ps& bind(int parameter, int64_t value) + { + if (verbose > 4) + obatched(clog) << nickname << " bind " << parameter << "=" << value << endl; + int rc = sqlite3_bind_int64 (this->pp, parameter, value); + if (rc != SQLITE_OK) + throw sqlite_exception(rc, "sqlite3 bind"); + return *this; + } + + sqlite_ps& bind(int parameter) + { + if (verbose > 4) + obatched(clog) << nickname << " bind " << parameter << "=" << "NULL" << endl; + int rc = sqlite3_bind_null (this->pp, parameter); + if (rc != SQLITE_OK) + throw sqlite_exception(rc, "sqlite3 bind"); + return *this; + } + + + void step_ok_done() { + tmp_ms_metric tick("sqlite3","step_done",nickname); + int rc = sqlite3_step (this->pp); + if (verbose > 4) + obatched(clog) << nickname << " step-ok-done(" << sqlite3_errstr(rc) << ") " << sql << endl; + if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW) + throw sqlite_exception(rc, "sqlite3 step"); + (void) sqlite3_reset (this->pp); + } + + + int step() { + tmp_ms_metric tick("sqlite3","step",nickname); + int rc = sqlite3_step (this->pp); + if (verbose > 4) + obatched(clog) << nickname << " step(" << sqlite3_errstr(rc) << ") " << sql << endl; + return rc; + } + + ~sqlite_ps () { sqlite3_finalize (this->pp); } + operator sqlite3_stmt* () { return this->pp; } +}; + + +//////////////////////////////////////////////////////////////////////// + +// RAII style templated autocloser + +template +struct defer_dtor +{ +public: + typedef Ignore (*dtor_fn) (Payload); + +private: + Payload p; + dtor_fn fn; + +public: + defer_dtor(Payload _p, dtor_fn _fn): p(_p), fn(_fn) {} + ~defer_dtor() { (void) (*fn)(p); } + +private: + defer_dtor(const defer_dtor&); // make uncopyable + defer_dtor& operator=(const defer_dtor &); // make unassignable +}; + + + +//////////////////////////////////////////////////////////////////////// + + +static string +header_censor(const string& str) +{ + string y; + for (auto&& x : str) + { + if (isalnum(x) || x == '/' || x == '.' || x == ',' || x == '_' || x == ':') + y += x; + } + return y; +} + + +static string +conninfo (struct MHD_Connection * conn) +{ + char hostname[256]; // RFC1035 + char servname[256]; + int sts = -1; + + if (conn == 0) + return "internal"; + + /* Look up client address data. */ + const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn, + MHD_CONNECTION_INFO_CLIENT_ADDRESS); + struct sockaddr *so = u ? u->client_addr : 0; + + if (so && so->sa_family == AF_INET) { + sts = getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), servname, + sizeof (servname), NI_NUMERICHOST | NI_NUMERICSERV); + } else if (so && so->sa_family == AF_INET6) { + sts = getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), + servname, sizeof (servname), NI_NUMERICHOST | NI_NUMERICSERV); + } + if (sts != 0) { + hostname[0] = servname[0] = '\0'; + } + + // extract headers relevant to administration + const char* user_agent = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; + const char* x_forwarded_for = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; + // NB: these are untrustworthy, beware if machine-processing log files + + return string(hostname) + string(":") + string(servname) + + string(" UA:") + header_censor(string(user_agent)) + + string(" XFF:") + header_censor(string(x_forwarded_for)); +} + + + +//////////////////////////////////////////////////////////////////////// + + +static void +add_mhd_last_modified (struct MHD_Response *resp, time_t mtime) +{ + struct tm *now = gmtime (&mtime); + if (now != NULL) + { + char datebuf[80]; + size_t rc = strftime (datebuf, sizeof (datebuf), "%a, %d %b %Y %T GMT", now); + if (rc > 0 && rc < sizeof (datebuf)) + (void) MHD_add_response_header (resp, "Last-Modified", datebuf); + } + + (void) MHD_add_response_header (resp, "Cache-Control", "public"); +} + + + +static struct MHD_Response* +handle_buildid_f_match (bool internal_req_t, + int64_t b_mtime, + const string& b_source0, + int *result_fd) +{ + (void) internal_req_t; // ignored + int fd = open(b_source0.c_str(), O_RDONLY); + if (fd < 0) + throw libc_exception (errno, string("open ") + b_source0); + + // NB: use manual close(2) in error case instead of defer_dtor, because + // in the normal case, we want to hand the fd over to libmicrohttpd for + // file transfer. + + struct stat s; + int rc = fstat(fd, &s); + if (rc < 0) + { + close(fd); + throw libc_exception (errno, string("fstat ") + b_source0); + } + + if ((int64_t) s.st_mtime != b_mtime) + { + if (verbose) + obatched(clog) << "mtime mismatch for " << b_source0 << endl; + close(fd); + return 0; + } + + inc_metric ("http_responses_total","result","file"); + struct MHD_Response* r = MHD_create_response_from_fd ((uint64_t) s.st_size, fd); + if (r == 0) + { + if (verbose) + obatched(clog) << "cannot create fd-response for " << b_source0 << endl; + close(fd); + } + else + { + MHD_add_response_header (r, "Content-Type", "application/octet-stream"); + add_mhd_last_modified (r, s.st_mtime); + if (verbose > 1) + obatched(clog) << "serving file " << b_source0 << endl; + /* libmicrohttpd will close it. */ + if (result_fd) + *result_fd = fd; + } + + return r; +} + + +// quote all questionable characters of str for safe passage through a sh -c expansion. +static string +shell_escape(const string& str) +{ + string y; + for (auto&& x : str) + { + if (! isalnum(x) && x != '/') + y += "\\"; + y += x; + } + return y; +} + + +// PR25548: Perform POSIX / RFC3986 style path canonicalization on the input string. +// +// Namely: +// // -> / +// /foo/../ -> / +// /./ -> / +// +// This mapping is done on dwarf-side source path names, which may +// include these constructs, so we can deal with debuginfod clients +// that accidentally canonicalize the paths. +// +// realpath(3) is close but not quite right, because it also resolves +// symbolic links. Symlinks at the debuginfod server have nothing to +// do with the build-time symlinks, thus they must not be considered. +// +// see also curl Curl_dedotdotify() aka RFC3986, which we mostly follow here +// see also libc __realpath() +// see also llvm llvm::sys::path::remove_dots() +static string +canon_pathname (const string& input) +{ + string i = input; // 5.2.4 (1) + string o; + + while (i.size() != 0) + { + // 5.2.4 (2) A + if (i.substr(0,3) == "../") + i = i.substr(3); + else if(i.substr(0,2) == "./") + i = i.substr(2); + + // 5.2.4 (2) B + else if (i.substr(0,3) == "/./") + i = i.substr(2); + else if (i == "/.") + i = ""; // no need to handle "/." complete-path-segment case; we're dealing with file names + + // 5.2.4 (2) C + else if (i.substr(0,4) == "/../") { + i = i.substr(3); + string::size_type sl = o.rfind("/"); + if (sl != string::npos) + o = o.substr(0, sl); + else + o = ""; + } else if (i == "/..") + i = ""; // no need to handle "/.." complete-path-segment case; we're dealing with file names + + // 5.2.4 (2) D + // no need to handle these cases; we're dealing with file names + else if (i == ".") + i = ""; + else if (i == "..") + i = ""; + + // POSIX special: map // to / + else if (i.substr(0,2) == "//") + i = i.substr(1); + + // 5.2.4 (2) E + else { + string::size_type next_slash = i.find("/", (i[0]=='/' ? 1 : 0)); // skip first slash + o += i.substr(0, next_slash); + if (next_slash == string::npos) + i = ""; + else + i = i.substr(next_slash); + } + } + + return o; +} + + +// Estimate available free space for a given filesystem via statfs(2). +// Return true if the free fraction is known to be smaller than the +// given minimum percentage. Also update a related metric. +bool statfs_free_enough_p(const string& path, const string& label, long minfree = 0) +{ + struct statfs sfs; + int rc = statfs(path.c_str(), &sfs); + if (rc == 0) + { + double s = (double) sfs.f_bavail / (double) sfs.f_blocks; + set_metric("filesys_free_ratio","purpose",label, s); + return ((s * 100.0) < minfree); + } + return false; +} + + + +// A map-like class that owns a cache of file descriptors (indexed by +// file / content names). +// +// If only it could use fd's instead of file names ... but we can't +// dup(2) to create independent descriptors for the same unlinked +// files, so would have to use some goofy linux /proc/self/fd/%d +// hack such as the following + +#if 0 +int superdup(int fd) +{ +#ifdef __linux__ + char *fdpath = NULL; + int rc = asprintf(& fdpath, "/proc/self/fd/%d", fd); + int newfd; + if (rc >= 0) + newfd = open(fdpath, O_RDONLY); + else + newfd = -1; + free (fdpath); + return newfd; +#else + return -1; +#endif +} +#endif + +class libarchive_fdcache +{ +private: + mutex fdcache_lock; + + struct fdcache_entry + { + string archive; + string entry; + string fd; + double fd_size_mb; // slightly rounded up megabytes + }; + deque lru; // @head: most recently used + long max_fds; + long max_mbs; + +public: + void set_metrics() + { + double total_mb = 0.0; + for (auto i = lru.begin(); i < lru.end(); i++) + total_mb += i->fd_size_mb; + set_metric("fdcache_bytes", (int64_t)(total_mb*1024.0*1024.0)); + set_metric("fdcache_count", lru.size()); + } + + void intern(const string& a, const string& b, string fd, off_t sz, bool front_p) + { + { + unique_lock lock(fdcache_lock); + for (auto i = lru.begin(); i < lru.end(); i++) // nuke preexisting copy + { + if (i->archive == a && i->entry == b) + { + unlink (i->fd.c_str()); + lru.erase(i); + inc_metric("fdcache_op_count","op","dequeue"); + break; // must not continue iterating + } + } + double mb = (sz+65535)/1048576.0; // round up to 64K block + fdcache_entry n = { a, b, fd, mb }; + if (front_p) + { + inc_metric("fdcache_op_count","op","enqueue_front"); + lru.push_front(n); + } + else + { + inc_metric("fdcache_op_count","op","enqueue_back"); + lru.push_back(n); + } + if (verbose > 3) + obatched(clog) << "fdcache interned a=" << a << " b=" << b + << " fd=" << fd << " mb=" << mb << " front=" << front_p << endl; + } + set_metrics(); + + // NB: we age the cache at lookup time too + if (statfs_free_enough_p(tmpdir, "tmpdir", fdcache_mintmp)) + { + inc_metric("fdcache_op_count","op","emerg-flush"); + obatched(clog) << "fdcache emergency flush for filling tmpdir" << endl; + this->limit(0, 0); // emergency flush + } + else if (front_p) + this->limit(max_fds, max_mbs); // age cache if required + } + + int lookup(const string& a, const string& b) + { + int fd = -1; + { + unique_lock lock(fdcache_lock); + for (auto i = lru.begin(); i < lru.end(); i++) + { + if (i->archive == a && i->entry == b) + { // found it; move it to head of lru + fdcache_entry n = *i; + lru.erase(i); // invalidates i, so no more iteration! + lru.push_front(n); + inc_metric("fdcache_op_count","op","requeue_front"); + fd = open(n.fd.c_str(), O_RDONLY); // NB: no problem if dup() fails; looks like cache miss + break; + } + } + } + + if (statfs_free_enough_p(tmpdir, "tmpdir", fdcache_mintmp)) + { + inc_metric("fdcache_op_count","op","emerg-flush"); + obatched(clog) << "fdcache emergency flush for filling tmpdir"; + this->limit(0, 0); // emergency flush + } + else if (fd >= 0) + this->limit(max_fds, max_mbs); // age cache if required + + return fd; + } + + int probe(const string& a, const string& b) // just a cache residency check - don't modify LRU state, don't open + { + unique_lock lock(fdcache_lock); + for (auto i = lru.begin(); i < lru.end(); i++) + { + if (i->archive == a && i->entry == b) + { + inc_metric("fdcache_op_count","op","probe_hit"); + return true; + } + } + inc_metric("fdcache_op_count","op","probe_miss"); + return false; + } + + void clear(const string& a, const string& b) + { + unique_lock lock(fdcache_lock); + for (auto i = lru.begin(); i < lru.end(); i++) + { + if (i->archive == a && i->entry == b) + { // found it; move it to head of lru + fdcache_entry n = *i; + lru.erase(i); // invalidates i, so no more iteration! + inc_metric("fdcache_op_count","op","clear"); + unlink (n.fd.c_str()); + set_metrics(); + return; + } + } + } + + + void limit(long maxfds, long maxmbs, bool metrics_p = true) + { + if (verbose > 3 && (this->max_fds != maxfds || this->max_mbs != maxmbs)) + obatched(clog) << "fdcache limited to maxfds=" << maxfds << " maxmbs=" << maxmbs << endl; + + unique_lock lock(fdcache_lock); + this->max_fds = maxfds; + this->max_mbs = maxmbs; + + long total_fd = 0; + double total_mb = 0.0; + for (auto i = lru.begin(); i < lru.end(); i++) + { + // accumulate totals from most recently used one going backward + total_fd ++; + total_mb += i->fd_size_mb; + if (total_fd > max_fds || total_mb > max_mbs) + { + // found the cut here point! + + for (auto j = i; j < lru.end(); j++) // close all the fds from here on in + { + if (verbose > 3) + obatched(clog) << "fdcache evicted a=" << j->archive << " b=" << j->entry + << " fd=" << j->fd << " mb=" << j->fd_size_mb << endl; + if (metrics_p) + inc_metric("fdcache_op_count","op","evict"); + unlink (j->fd.c_str()); + } + + lru.erase(i, lru.end()); // erase the nodes generally + break; + } + } + if (metrics_p) set_metrics(); + } + + + ~libarchive_fdcache() + { + // unlink any fdcache entries in $TMPDIR + // don't update metrics; those globals may be already destroyed + limit(0, 0, false); + } +}; +static libarchive_fdcache fdcache; + + +// For security/portability reasons, many distro-package archives have +// a "./" in front of path names; others have nothing, others have +// "/". Canonicalize them all to a single leading "/", with the +// assumption that this matches the dwarf-derived file names too. +string canonicalized_archive_entry_pathname(struct archive_entry *e) +{ + string fn = archive_entry_pathname(e); + if (fn.size() == 0) + return fn; + if (fn[0] == '/') + return fn; + if (fn[0] == '.') + return fn.substr(1); + else + return string("/")+fn; +} + + + +static struct MHD_Response* +handle_buildid_r_match (bool internal_req_p, + int64_t b_mtime, + const string& b_source0, + const string& b_source1, + int *result_fd) +{ + struct stat fs; + int rc = stat (b_source0.c_str(), &fs); + if (rc != 0) + throw libc_exception (errno, string("stat ") + b_source0); + + if ((int64_t) fs.st_mtime != b_mtime) + { + if (verbose) + obatched(clog) << "mtime mismatch for " << b_source0 << endl; + return 0; + } + + // check for a match in the fdcache first + int fd = fdcache.lookup(b_source0, b_source1); + while (fd >= 0) // got one!; NB: this is really an if() with a possible branch out to the end + { + rc = fstat(fd, &fs); + if (rc < 0) // disappeared? + { + if (verbose) + obatched(clog) << "cannot fstat fdcache " << b_source0 << endl; + close(fd); + fdcache.clear(b_source0, b_source1); + break; // branch out of if "loop", to try new libarchive fetch attempt + } + + struct MHD_Response* r = MHD_create_response_from_fd (fs.st_size, fd); + if (r == 0) + { + if (verbose) + obatched(clog) << "cannot create fd-response for " << b_source0 << endl; + close(fd); + break; // branch out of if "loop", to try new libarchive fetch attempt + } + + inc_metric ("http_responses_total","result","archive fdcache"); + + MHD_add_response_header (r, "Content-Type", "application/octet-stream"); + add_mhd_last_modified (r, fs.st_mtime); + if (verbose > 1) + obatched(clog) << "serving fdcache archive " << b_source0 << " file " << b_source1 << endl; + /* libmicrohttpd will close it. */ + if (result_fd) + *result_fd = fd; + return r; + // NB: see, we never go around the 'loop' more than once + } + + // no match ... grumble, must process the archive + string archive_decoder = "/dev/null"; + string archive_extension = ""; + for (auto&& arch : scan_archives) + if (string_endswith(b_source0, arch.first)) + { + archive_extension = arch.first; + archive_decoder = arch.second; + } + FILE* fp; + defer_dtor::dtor_fn dfn; + if (archive_decoder != "cat") + { + string popen_cmd = archive_decoder + " " + shell_escape(b_source0); + fp = popen (popen_cmd.c_str(), "r"); // "e" O_CLOEXEC? + dfn = pclose; + if (fp == NULL) + throw libc_exception (errno, string("popen ") + popen_cmd); + } + else + { + fp = fopen (b_source0.c_str(), "r"); + dfn = fclose; + if (fp == NULL) + throw libc_exception (errno, string("fopen ") + b_source0); + } + defer_dtor fp_closer (fp, dfn); + + struct archive *a; + a = archive_read_new(); + if (a == NULL) + throw archive_exception("cannot create archive reader"); + defer_dtor archive_closer (a, archive_read_free); + + rc = archive_read_support_format_all(a); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot select all format"); + rc = archive_read_support_filter_all(a); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot select all filters"); + + rc = archive_read_open_FILE (a, fp); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot open archive from pipe"); + + // archive traversal is in three stages, no, four stages: + // 1) skip entries whose names do not match the requested one + // 2) extract the matching entry name (set r = result) + // 3) extract some number of prefetched entries (just into fdcache) + // 4) abort any further processing + struct MHD_Response* r = 0; // will set in stage 2 + unsigned prefetch_count = + internal_req_p ? 0 : fdcache_prefetch; // will decrement in stage 3 + + while(r == 0 || prefetch_count > 0) // stage 1, 2, or 3 + { + if (interrupted) + break; + + struct archive_entry *e; + rc = archive_read_next_header (a, &e); + if (rc != ARCHIVE_OK) + break; + + if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely + continue; + + string fn = canonicalized_archive_entry_pathname (e); + if ((r == 0) && (fn != b_source1)) // stage 1 + continue; + + if (fdcache.probe (b_source0, fn)) // skip if already interned + continue; + + // extract this file to a temporary file + char* tmppath = NULL; + rc = asprintf (&tmppath, "%s/debuginfod.XXXXXX", tmpdir.c_str()); + if (rc < 0) + throw libc_exception (ENOMEM, "cannot allocate tmppath"); + defer_dtor tmmpath_freer (tmppath, free); + fd = mkstemp (tmppath); + if (fd < 0) + throw libc_exception (errno, "cannot create temporary file"); + // NB: don't unlink (tmppath), as fdcache will take charge of it. + + // NB: this can take many uninterruptible seconds for a huge file + rc = archive_read_data_into_fd (a, fd); + if (rc != ARCHIVE_OK) // e.g. ENOSPC! + { + close (fd); + unlink (tmppath); + throw archive_exception(a, "cannot extract file"); + } + + // Set the mtime so the fdcache file mtimes, even prefetched ones, + // propagate to future webapi clients. + struct timeval tvs[2]; + tvs[0].tv_sec = tvs[1].tv_sec = archive_entry_mtime(e); + tvs[0].tv_usec = tvs[1].tv_usec = 0; + (void) futimes (fd, tvs); /* best effort */ + + if (r != 0) // stage 3 + { + // NB: now we know we have a complete reusable file; make fdcache + // responsible for unlinking it later. + fdcache.intern(b_source0, fn, + tmppath, archive_entry_size(e), + false); // prefetched ones go to back of lru + prefetch_count --; + close (fd); // we're not saving this fd to make a mhd-response from! + continue; + } + + // NB: now we know we have a complete reusable file; make fdcache + // responsible for unlinking it later. + fdcache.intern(b_source0, b_source1, + tmppath, archive_entry_size(e), + true); // requested ones go to the front of lru + + inc_metric ("http_responses_total","result",archive_extension + " archive"); + r = MHD_create_response_from_fd (archive_entry_size(e), fd); + if (r == 0) + { + if (verbose) + obatched(clog) << "cannot create fd-response for " << b_source0 << endl; + close(fd); + break; // assume no chance of better luck around another iteration; no other copies of same file + } + else + { + MHD_add_response_header (r, "Content-Type", "application/octet-stream"); + add_mhd_last_modified (r, archive_entry_mtime(e)); + if (verbose > 1) + obatched(clog) << "serving archive " << b_source0 << " file " << b_source1 << endl; + /* libmicrohttpd will close it. */ + if (result_fd) + *result_fd = fd; + continue; + } + } + + // XXX: rpm/file not found: delete this R entry? + return r; +} + + +static struct MHD_Response* +handle_buildid_match (bool internal_req_p, + int64_t b_mtime, + const string& b_stype, + const string& b_source0, + const string& b_source1, + int *result_fd) +{ + try + { + if (b_stype == "F") + return handle_buildid_f_match(internal_req_p, b_mtime, b_source0, result_fd); + else if (b_stype == "R") + return handle_buildid_r_match(internal_req_p, b_mtime, b_source0, b_source1, result_fd); + } + catch (const reportable_exception &e) + { + e.report(clog); + // Report but swallow libc etc. errors here; let the caller + // iterate to other matches of the content. + } + + return 0; +} + + +static int +debuginfod_find_progress (debuginfod_client *, long a, long b) +{ + if (verbose > 4) + obatched(clog) << "federated debuginfod progress=" << a << "/" << b << endl; + + return interrupted; +} + + +// a little lru pool of debuginfod_client*s for reuse between query threads + +mutex dc_pool_lock; +deque dc_pool; + +debuginfod_client* debuginfod_pool_begin() +{ + unique_lock lock(dc_pool_lock); + if (dc_pool.size() > 0) + { + inc_metric("dc_pool_op_count","op","begin-reuse"); + debuginfod_client *c = dc_pool.front(); + dc_pool.pop_front(); + return c; + } + inc_metric("dc_pool_op_count","op","begin-new"); + return debuginfod_begin(); +} + + +void debuginfod_pool_groom() +{ + unique_lock lock(dc_pool_lock); + while (dc_pool.size() > 0) + { + inc_metric("dc_pool_op_count","op","end"); + debuginfod_end(dc_pool.front()); + dc_pool.pop_front(); + } +} + + +void debuginfod_pool_end(debuginfod_client* c) +{ + unique_lock lock(dc_pool_lock); + inc_metric("dc_pool_op_count","op","end-save"); + dc_pool.push_front(c); // accelerate reuse, vs. push_back +} + + +static struct MHD_Response* +handle_buildid (MHD_Connection* conn, + const string& buildid /* unsafe */, + const string& artifacttype /* unsafe */, + const string& suffix /* unsafe */, + int *result_fd) +{ + // validate artifacttype + string atype_code; + if (artifacttype == "debuginfo") atype_code = "D"; + else if (artifacttype == "executable") atype_code = "E"; + else if (artifacttype == "source") atype_code = "S"; + else throw reportable_exception("invalid artifacttype"); + + inc_metric("http_requests_total", "type", artifacttype); + + if (atype_code == "S" && suffix == "") + throw reportable_exception("invalid source suffix"); + + // validate buildid + if ((buildid.size() < 2) || // not empty + (buildid.size() % 2) || // even number + (buildid.find_first_not_of("0123456789abcdef") != string::npos)) // pure tasty lowercase hex + throw reportable_exception("invalid buildid"); + + if (verbose > 1) + obatched(clog) << "searching for buildid=" << buildid << " artifacttype=" << artifacttype + << " suffix=" << suffix << endl; + + // If invoked from the scanner threads, use the scanners' read-write + // connection. Otherwise use the web query threads' read-only connection. + sqlite3 *thisdb = (conn == 0) ? db : dbq; + + sqlite_ps *pp = 0; + + if (atype_code == "D") + { + pp = new sqlite_ps (thisdb, "mhd-query-d", + "select mtime, sourcetype, source0, source1 from " BUILDIDS "_query_d where buildid = ? " + "order by mtime desc"); + pp->reset(); + pp->bind(1, buildid); + } + else if (atype_code == "E") + { + pp = new sqlite_ps (thisdb, "mhd-query-e", + "select mtime, sourcetype, source0, source1 from " BUILDIDS "_query_e where buildid = ? " + "order by mtime desc"); + pp->reset(); + pp->bind(1, buildid); + } + else if (atype_code == "S") + { + // PR25548 + // Incoming source queries may come in with either dwarf-level OR canonicalized paths. + // We let the query pass with either one. + + pp = new sqlite_ps (thisdb, "mhd-query-s", + "select mtime, sourcetype, source0, source1 from " BUILDIDS "_query_s where buildid = ? and artifactsrc in (?,?) " + "order by sharedprefix(source0,source0ref) desc, mtime desc"); + pp->reset(); + pp->bind(1, buildid); + // NB: we don't store the non-canonicalized path names any more, but old databases + // might have them (and no canon ones), so we keep searching for both. + pp->bind(2, suffix); + pp->bind(3, canon_pathname(suffix)); + } + unique_ptr ps_closer(pp); // release pp if exception or return + + // consume all the rows + while (1) + { + int rc = pp->step(); + if (rc == SQLITE_DONE) break; + if (rc != SQLITE_ROW) + throw sqlite_exception(rc, "step"); + + int64_t b_mtime = sqlite3_column_int64 (*pp, 0); + string b_stype = string((const char*) sqlite3_column_text (*pp, 1) ?: ""); /* by DDL may not be NULL */ + string b_source0 = string((const char*) sqlite3_column_text (*pp, 2) ?: ""); /* may be NULL */ + string b_source1 = string((const char*) sqlite3_column_text (*pp, 3) ?: ""); /* may be NULL */ + + if (verbose > 1) + obatched(clog) << "found mtime=" << b_mtime << " stype=" << b_stype + << " source0=" << b_source0 << " source1=" << b_source1 << endl; + + // Try accessing the located match. + // XXX: in case of multiple matches, attempt them in parallel? + auto r = handle_buildid_match (conn ? false : true, + b_mtime, b_stype, b_source0, b_source1, result_fd); + if (r) + return r; + } + pp->reset(); + + // We couldn't find it in the database. Last ditch effort + // is to defer to other debuginfo servers. + + int fd = -1; + debuginfod_client *client = debuginfod_pool_begin (); + if (client != NULL) + { + debuginfod_set_progressfn (client, & debuginfod_find_progress); + + if (conn) + { + // Transcribe incoming User-Agent: + string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; + string ua_complete = string("User-Agent: ") + ua; + debuginfod_add_http_header (client, ua_complete.c_str()); + + // Compute larger XFF:, for avoiding info loss during + // federation, and for future cyclicity detection. + string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; + if (xff != "") + xff += string(", "); // comma separated list + + // Compute the client's numeric IP address only - so can't merge with conninfo() + const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn, + MHD_CONNECTION_INFO_CLIENT_ADDRESS); + struct sockaddr *so = u ? u->client_addr : 0; + char hostname[256] = ""; // RFC1035 + if (so && so->sa_family == AF_INET) + (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0, + NI_NUMERICHOST); + else if (so && so->sa_family == AF_INET6) + (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0, + NI_NUMERICHOST); + + string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname); + debuginfod_add_http_header (client, xff_complete.c_str()); + } + + if (artifacttype == "debuginfo") + fd = debuginfod_find_debuginfo (client, + (const unsigned char*) buildid.c_str(), + 0, NULL); + else if (artifacttype == "executable") + fd = debuginfod_find_executable (client, + (const unsigned char*) buildid.c_str(), + 0, NULL); + else if (artifacttype == "source") + fd = debuginfod_find_source (client, + (const unsigned char*) buildid.c_str(), + 0, suffix.c_str(), NULL); + } + else + fd = -errno; /* Set by debuginfod_begin. */ + debuginfod_pool_end (client); + + if (fd >= 0) + { + inc_metric ("http_responses_total","result","upstream"); + struct stat s; + int rc = fstat (fd, &s); + if (rc == 0) + { + auto r = MHD_create_response_from_fd ((uint64_t) s.st_size, fd); + if (r) + { + MHD_add_response_header (r, "Content-Type", "application/octet-stream"); + add_mhd_last_modified (r, s.st_mtime); + if (verbose > 1) + obatched(clog) << "serving file from upstream debuginfod/cache" << endl; + if (result_fd) + *result_fd = fd; + return r; // NB: don't close fd; libmicrohttpd will + } + } + close (fd); + } + else + switch(fd) + { + case -ENOSYS: + break; + case -ENOENT: + break; + default: // some more tricky error + throw libc_exception(-fd, "upstream debuginfod query failed"); + } + + throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found"); +} + + +//////////////////////////////////////////////////////////////////////// + +static map metrics; // arbitrary data for /metrics query +// NB: store int64_t since all our metrics are integers; prometheus accepts double +static mutex metrics_lock; +// NB: these objects get released during the process exit via global dtors +// do not call them from within other global dtors + +// utility function for assembling prometheus-compatible +// name="escaped-value" strings +// https://prometheus.io/docs/instrumenting/exposition_formats/ +static string +metric_label(const string& name, const string& value) +{ + string x = name + "=\""; + for (auto&& c : value) + switch(c) + { + case '\\': x += "\\\\"; break; + case '\"': x += "\\\""; break; + case '\n': x += "\\n"; break; + default: x += c; break; + } + x += "\""; + return x; +} + + +// add prometheus-format metric name + label tuple (if any) + value + +static void +set_metric(const string& metric, double value) +{ + unique_lock lock(metrics_lock); + metrics[metric] = value; +} +#if 0 /* unused */ +static void +inc_metric(const string& metric) +{ + unique_lock lock(metrics_lock); + metrics[metric] ++; +} +#endif +static void +set_metric(const string& metric, + const string& lname, const string& lvalue, + double value) +{ + string key = (metric + "{" + metric_label(lname, lvalue) + "}"); + unique_lock lock(metrics_lock); + metrics[key] = value; +} + +static void +inc_metric(const string& metric, + const string& lname, const string& lvalue) +{ + string key = (metric + "{" + metric_label(lname, lvalue) + "}"); + unique_lock lock(metrics_lock); + metrics[key] ++; +} +static void +add_metric(const string& metric, + const string& lname, const string& lvalue, + double value) +{ + string key = (metric + "{" + metric_label(lname, lvalue) + "}"); + unique_lock lock(metrics_lock); + metrics[key] += value; +} +#if 0 +static void +add_metric(const string& metric, + double value) +{ + unique_lock lock(metrics_lock); + metrics[metric] += value; +} +#endif + + +// and more for higher arity labels if needed + + +static struct MHD_Response* +handle_metrics (off_t* size) +{ + stringstream o; + { + unique_lock lock(metrics_lock); + for (auto&& i : metrics) + o << i.first + << " " + << std::setprecision(std::numeric_limits::digits10 + 1) + << i.second + << endl; + } + const string& os = o.str(); + MHD_Response* r = MHD_create_response_from_buffer (os.size(), + (void*) os.c_str(), + MHD_RESPMEM_MUST_COPY); + *size = os.size(); + MHD_add_response_header (r, "Content-Type", "text/plain"); + return r; +} + +static struct MHD_Response* +handle_root (off_t* size) +{ + static string version = "debuginfod (" + string (PACKAGE_NAME) + ") " + + string (PACKAGE_VERSION); + MHD_Response* r = MHD_create_response_from_buffer (version.size (), + (void *) version.c_str (), + MHD_RESPMEM_PERSISTENT); + *size = version.size (); + MHD_add_response_header (r, "Content-Type", "text/plain"); + return r; +} + + +//////////////////////////////////////////////////////////////////////// + + +/* libmicrohttpd callback */ +static MHD_RESULT +handler_cb (void * /*cls*/, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char * /*version*/, + const char * /*upload_data*/, + size_t * /*upload_data_size*/, + void ** ptr) +{ + struct MHD_Response *r = NULL; + string url_copy = url; + + /* libmicrohttpd always makes (at least) two callbacks: once just + past the headers, and one after the request body is finished + being received. If we process things early (first callback) and + queue a response, libmicrohttpd would suppress http keep-alive + (via connection->read_closed = true). */ + static int aptr; /* just some random object to use as a flag */ + if (&aptr != *ptr) + { + /* do never respond on first call */ + *ptr = &aptr; + return MHD_YES; + } + *ptr = NULL; /* reset when done */ + +#if MHD_VERSION >= 0x00097002 + enum MHD_Result rc; +#else + int rc = MHD_NO; // mhd +#endif + int http_code = 500; + off_t http_size = -1; + struct timespec ts_start, ts_end; + clock_gettime (CLOCK_MONOTONIC, &ts_start); + + try + { + if (string(method) != "GET") + throw reportable_exception(400, "we support GET only"); + + /* Start decoding the URL. */ + size_t slash1 = url_copy.find('/', 1); + string url1 = url_copy.substr(0, slash1); // ok even if slash1 not found + + if (slash1 != string::npos && url1 == "/buildid") + { + tmp_inc_metric m ("thread_busy", "role", "http-buildid"); + size_t slash2 = url_copy.find('/', slash1+1); + if (slash2 == string::npos) + throw reportable_exception("/buildid/ webapi error, need buildid"); + + string buildid = url_copy.substr(slash1+1, slash2-slash1-1); + + size_t slash3 = url_copy.find('/', slash2+1); + string artifacttype, suffix; + if (slash3 == string::npos) + { + artifacttype = url_copy.substr(slash2+1); + suffix = ""; + } + else + { + artifacttype = url_copy.substr(slash2+1, slash3-slash2-1); + suffix = url_copy.substr(slash3); // include the slash in the suffix + } + + // get the resulting fd so we can report its size + int fd; + r = handle_buildid(connection, buildid, artifacttype, suffix, &fd); + if (r) + { + struct stat fs; + if (fstat(fd, &fs) == 0) + http_size = fs.st_size; + // libmicrohttpd will close (fd); + } + } + else if (url1 == "/metrics") + { + tmp_inc_metric m ("thread_busy", "role", "http-metrics"); + inc_metric("http_requests_total", "type", "metrics"); + r = handle_metrics(& http_size); + } + else if (url1 == "/") + { + inc_metric("http_requests_total", "type", "/"); + r = handle_root(& http_size); + } + else + throw reportable_exception("webapi error, unrecognized '" + url1 + "'"); + + if (r == 0) + throw reportable_exception("internal error, missing response"); + + rc = MHD_queue_response (connection, MHD_HTTP_OK, r); + http_code = MHD_HTTP_OK; + MHD_destroy_response (r); + } + catch (const reportable_exception& e) + { + inc_metric("http_responses_total","result","error"); + e.report(clog); + http_code = e.code; + http_size = e.message.size(); + rc = e.mhd_send_response (connection); + } + + clock_gettime (CLOCK_MONOTONIC, &ts_end); + double deltas = (ts_end.tv_sec - ts_start.tv_sec) + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; + obatched(clog) << conninfo(connection) + << ' ' << method << ' ' << url + << ' ' << http_code << ' ' << http_size + << ' ' << (int)(deltas*1000) << "ms" + << endl; + + // related prometheus metrics + string http_code_str = to_string(http_code); + if (http_size >= 0) + add_metric("http_responses_transfer_bytes_sum","code",http_code_str, + http_size); + inc_metric("http_responses_transfer_bytes_count","code",http_code_str); + + add_metric("http_responses_duration_milliseconds_sum","code",http_code_str, + deltas*1000); // prometheus prefers _seconds and floating point + inc_metric("http_responses_duration_milliseconds_count","code",http_code_str); + + return rc; +} + + +//////////////////////////////////////////////////////////////////////// +// borrowed originally from src/nm.c get_local_names() + +static void +dwarf_extract_source_paths (Elf *elf, set& debug_sourcefiles) + noexcept // no exceptions - so we can simplify the altdbg resource release at end +{ + Dwarf* dbg = dwarf_begin_elf (elf, DWARF_C_READ, NULL); + if (dbg == NULL) + return; + + Dwarf* altdbg = NULL; + int altdbg_fd = -1; + + // DWZ handling: if we have an unsatisfied debug-alt-link, add an + // empty string into the outgoing sourcefiles set, so the caller + // should know that our data is incomplete. + const char *alt_name_p; + const void *alt_build_id; // elfutils-owned memory + ssize_t sz = dwelf_dwarf_gnu_debugaltlink (dbg, &alt_name_p, &alt_build_id); + if (sz > 0) // got one! + { + string buildid; + unsigned char* build_id_bytes = (unsigned char*) alt_build_id; + for (ssize_t idx=0; idx> 4]; + buildid += "0123456789abcdef"[build_id_bytes[idx] & 0xf]; + } + + if (verbose > 3) + obatched(clog) << "Need altdebug buildid=" << buildid << endl; + + // but is it unsatisfied the normal elfutils ways? + Dwarf* alt = dwarf_getalt (dbg); + if (alt == NULL) + { + // Yup, unsatisfied the normal way. Maybe we can satisfy it + // from our own debuginfod database. + int alt_fd; + struct MHD_Response *r = 0; + try + { + r = handle_buildid (0, buildid, "debuginfo", "", &alt_fd); + } + catch (const reportable_exception& e) + { + // swallow exceptions + } + + // NB: this is not actually recursive! This invokes the web-query + // path, which cannot get back into the scan code paths. + if (r) + { + // Found it! + altdbg_fd = dup(alt_fd); // ok if this fails, downstream failures ok + alt = altdbg = dwarf_begin (altdbg_fd, DWARF_C_READ); + // NB: must close this dwarf and this fd at the bottom of the function! + MHD_destroy_response (r); // will close alt_fd + if (alt) + dwarf_setalt (dbg, alt); + } + } + else + { + // NB: dwarf_setalt(alt) inappropriate - already done! + // NB: altdbg will stay 0 so nothing tries to redundantly dealloc. + } + + if (alt) + { + if (verbose > 3) + obatched(clog) << "Resolved altdebug buildid=" << buildid << endl; + } + else // (alt == NULL) - signal possible presence of poor debuginfo + { + debug_sourcefiles.insert(""); + if (verbose > 3) + obatched(clog) << "Unresolved altdebug buildid=" << buildid << endl; + } + } + + Dwarf_Off offset = 0; + Dwarf_Off old_offset; + size_t hsize; + + while (dwarf_nextcu (dbg, old_offset = offset, &offset, &hsize, NULL, NULL, NULL) == 0) + { + Dwarf_Die cudie_mem; + Dwarf_Die *cudie = dwarf_offdie (dbg, old_offset + hsize, &cudie_mem); + + if (cudie == NULL) + continue; + if (dwarf_tag (cudie) != DW_TAG_compile_unit) + continue; + + const char *cuname = dwarf_diename(cudie) ?: "unknown"; + + Dwarf_Files *files; + size_t nfiles; + if (dwarf_getsrcfiles (cudie, &files, &nfiles) != 0) + continue; + + // extract DW_AT_comp_dir to resolve relative file names + const char *comp_dir = ""; + const char *const *dirs; + size_t ndirs; + if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 && + dirs[0] != NULL) + comp_dir = dirs[0]; + if (comp_dir == NULL) + comp_dir = ""; + + if (verbose > 3) + obatched(clog) << "searching for sources for cu=" << cuname << " comp_dir=" << comp_dir + << " #files=" << nfiles << " #dirs=" << ndirs << endl; + + if (comp_dir[0] == '\0' && cuname[0] != '/') + { + // This is a common symptom for dwz-compressed debug files, + // where the altdebug file cannot be resolved. + if (verbose > 3) + obatched(clog) << "skipping cu=" << cuname << " due to empty comp_dir" << endl; + continue; + } + + for (size_t f = 1; f < nfiles; f++) + { + const char *hat = dwarf_filesrc (files, f, NULL, NULL); + if (hat == NULL) + continue; + + if (string(hat) == "") // gcc intrinsics, don't bother record + continue; + + string waldo; + if (hat[0] == '/') // absolute + waldo = (string (hat)); + else if (comp_dir[0] != '\0') // comp_dir relative + waldo = (string (comp_dir) + string("/") + string (hat)); + else + { + if (verbose > 3) + obatched(clog) << "skipping hat=" << hat << " due to empty comp_dir" << endl; + continue; + } + + // NB: this is the 'waldo' that a dbginfo client will have + // to supply for us to give them the file The comp_dir + // prefixing is a definite complication. Otherwise we'd + // have to return a setof comp_dirs (one per CU!) with + // corresponding filesrc[] names, instead of one absolute + // resoved set. Maybe we'll have to do that anyway. XXX + + if (verbose > 4) + obatched(clog) << waldo + << (debug_sourcefiles.find(waldo)==debug_sourcefiles.end() ? " new" : " dup") << endl; + + debug_sourcefiles.insert (waldo); + } + } + + dwarf_end(dbg); + if (altdbg) + dwarf_end(altdbg); + if (altdbg_fd >= 0) + close(altdbg_fd); +} + + + +static void +elf_classify (int fd, bool &executable_p, bool &debuginfo_p, string &buildid, set& debug_sourcefiles) +{ + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL); + if (elf == NULL) + return; + + try // catch our types of errors and clean up the Elf* object + { + if (elf_kind (elf) != ELF_K_ELF) + { + elf_end (elf); + return; + } + + GElf_Ehdr ehdr_storage; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_storage); + if (ehdr == NULL) + { + elf_end (elf); + return; + } + auto elf_type = ehdr->e_type; + + const void *build_id; // elfutils-owned memory + ssize_t sz = dwelf_elf_gnu_build_id (elf, & build_id); + if (sz <= 0) + { + // It's not a diagnostic-worthy error for an elf file to lack build-id. + // It might just be very old. + elf_end (elf); + return; + } + + // build_id is a raw byte array; convert to hexadecimal *lowercase* + unsigned char* build_id_bytes = (unsigned char*) build_id; + for (ssize_t idx=0; idx> 4]; + buildid += "0123456789abcdef"[build_id_bytes[idx] & 0xf]; + } + + // now decide whether it's an executable - namely, any allocatable section has + // PROGBITS; + if (elf_type == ET_EXEC || elf_type == ET_DYN) + { + size_t shnum; + int rc = elf_getshdrnum (elf, &shnum); + if (rc < 0) + throw elfutils_exception(rc, "getshdrnum"); + + executable_p = false; + for (size_t sc = 0; sc < shnum; sc++) + { + Elf_Scn *scn = elf_getscn (elf, sc); + if (scn == NULL) + continue; + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + continue; + + // allocated (loadable / vm-addr-assigned) section with available content? + if ((shdr->sh_type == SHT_PROGBITS) && (shdr->sh_flags & SHF_ALLOC)) + { + if (verbose > 4) + obatched(clog) << "executable due to SHF_ALLOC SHT_PROGBITS sc=" << sc << endl; + executable_p = true; + break; // no need to keep looking for others + } + } // iterate over sections + } // executable_p classification + + // now decide whether it's a debuginfo - namely, if it has any .debug* or .zdebug* sections + // logic mostly stolen from fweimer@redhat.com's elfclassify drafts + size_t shstrndx; + int rc = elf_getshdrstrndx (elf, &shstrndx); + if (rc < 0) + throw elfutils_exception(rc, "getshdrstrndx"); + + Elf_Scn *scn = NULL; + bool symtab_p = false; + bool bits_alloc_p = false; + while (true) + { + scn = elf_nextscn (elf, scn); + if (scn == NULL) + break; + GElf_Shdr shdr_storage; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_storage); + if (shdr == NULL) + break; + const char *section_name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (section_name == NULL) + break; + if (startswith (section_name, ".debug_line") || + startswith (section_name, ".zdebug_line")) + { + debuginfo_p = true; + dwarf_extract_source_paths (elf, debug_sourcefiles); + break; // expecting only one .*debug_line, so no need to look for others + } + else if (startswith (section_name, ".debug_") || + startswith (section_name, ".zdebug_")) + { + debuginfo_p = true; + // NB: don't break; need to parse .debug_line for sources + } + else if (shdr->sh_type == SHT_SYMTAB) + { + symtab_p = true; + } + else if (shdr->sh_type != SHT_NOBITS + && shdr->sh_type != SHT_NOTE + && (shdr->sh_flags & SHF_ALLOC) != 0) + { + bits_alloc_p = true; + } + } + + // For more expansive elf/split-debuginfo classification, we + // want to identify as debuginfo "strip -s"-produced files + // without .debug_info* (like libicudata), but we don't want to + // identify "strip -g" executables (with .symtab left there). + if (symtab_p && !bits_alloc_p) + debuginfo_p = true; + } + catch (const reportable_exception& e) + { + e.report(clog); + } + elf_end (elf); +} + + +static void +scan_source_file (const string& rps, const stat_t& st, + sqlite_ps& ps_upsert_buildids, + sqlite_ps& ps_upsert_files, + sqlite_ps& ps_upsert_de, + sqlite_ps& ps_upsert_s, + sqlite_ps& ps_query, + sqlite_ps& ps_scan_done, + unsigned& fts_cached, + unsigned& fts_executable, + unsigned& fts_debuginfo, + unsigned& fts_sourcefiles) +{ + /* See if we know of it already. */ + int rc = ps_query + .reset() + .bind(1, rps) + .bind(2, st.st_mtime) + .step(); + ps_query.reset(); + if (rc == SQLITE_ROW) // i.e., a result, as opposed to DONE (no results) + // no need to recheck a file/version we already know + // specifically, no need to elf-begin a file we already determined is non-elf + // (so is stored with buildid=NULL) + { + fts_cached++; + return; + } + + bool executable_p = false, debuginfo_p = false; // E and/or D + string buildid; + set sourcefiles; + + int fd = open (rps.c_str(), O_RDONLY); + try + { + if (fd >= 0) + elf_classify (fd, executable_p, debuginfo_p, buildid, sourcefiles); + else + throw libc_exception(errno, string("open ") + rps); + add_metric ("scanned_bytes_total","source","file", + st.st_size); + inc_metric ("scanned_files_total","source","file"); + } + // NB: we catch exceptions here too, so that we can + // cache the corrupt-elf case (!executable_p && + // !debuginfo_p) just below, just as if we had an + // EPERM error from open(2). + catch (const reportable_exception& e) + { + e.report(clog); + } + + if (fd >= 0) + close (fd); + + // register this file name in the interning table + ps_upsert_files + .reset() + .bind(1, rps) + .step_ok_done(); + + if (buildid == "") + { + // no point storing an elf file without buildid + executable_p = false; + debuginfo_p = false; + } + else + { + // register this build-id in the interning table + ps_upsert_buildids + .reset() + .bind(1, buildid) + .step_ok_done(); + } + + if (executable_p) + fts_executable ++; + if (debuginfo_p) + fts_debuginfo ++; + if (executable_p || debuginfo_p) + { + ps_upsert_de + .reset() + .bind(1, buildid) + .bind(2, debuginfo_p ? 1 : 0) + .bind(3, executable_p ? 1 : 0) + .bind(4, rps) + .bind(5, st.st_mtime) + .step_ok_done(); + } + if (executable_p) + inc_metric("found_executable_total","source","files"); + if (debuginfo_p) + inc_metric("found_debuginfo_total","source","files"); + + if (sourcefiles.size() && buildid != "") + { + fts_sourcefiles += sourcefiles.size(); + + for (auto&& dwarfsrc : sourcefiles) + { + char *srp = realpath(dwarfsrc.c_str(), NULL); + if (srp == NULL) // also if DWZ unresolved dwarfsrc="" + continue; // unresolvable files are not a serious problem + // throw libc_exception(errno, "fts/file realpath " + srcpath); + string srps = string(srp); + free (srp); + + struct stat sfs; + rc = stat(srps.c_str(), &sfs); + if (rc != 0) + continue; + + if (verbose > 2) + obatched(clog) << "recorded buildid=" << buildid << " file=" << srps + << " mtime=" << sfs.st_mtime + << " as source " << dwarfsrc << endl; + + ps_upsert_files + .reset() + .bind(1, srps) + .step_ok_done(); + + // PR25548: store canonicalized dwarfsrc path + string dwarfsrc_canon = canon_pathname (dwarfsrc); + if (dwarfsrc_canon != dwarfsrc) + { + if (verbose > 3) + obatched(clog) << "canonicalized src=" << dwarfsrc << " alias=" << dwarfsrc_canon << endl; + } + + ps_upsert_files + .reset() + .bind(1, dwarfsrc_canon) + .step_ok_done(); + + ps_upsert_s + .reset() + .bind(1, buildid) + .bind(2, dwarfsrc_canon) + .bind(3, srps) + .bind(4, sfs.st_mtime) + .step_ok_done(); + + inc_metric("found_sourcerefs_total","source","files"); + } + } + + ps_scan_done + .reset() + .bind(1, rps) + .bind(2, st.st_mtime) + .bind(3, st.st_size) + .step_ok_done(); + + if (verbose > 2) + obatched(clog) << "recorded buildid=" << buildid << " file=" << rps + << " mtime=" << st.st_mtime << " atype=" + << (executable_p ? "E" : "") + << (debuginfo_p ? "D" : "") << endl; +} + + + + + +// Analyze given archive file of given age; record buildids / exec/debuginfo-ness of its +// constituent files with given upsert statements. +static void +archive_classify (const string& rps, string& archive_extension, + sqlite_ps& ps_upsert_buildids, sqlite_ps& ps_upsert_files, + sqlite_ps& ps_upsert_de, sqlite_ps& ps_upsert_sref, sqlite_ps& ps_upsert_sdef, + time_t mtime, + unsigned& fts_executable, unsigned& fts_debuginfo, unsigned& fts_sref, unsigned& fts_sdef, + bool& fts_sref_complete_p) +{ + string archive_decoder = "/dev/null"; + for (auto&& arch : scan_archives) + if (string_endswith(rps, arch.first)) + { + archive_extension = arch.first; + archive_decoder = arch.second; + } + + FILE* fp; + defer_dtor::dtor_fn dfn; + if (archive_decoder != "cat") + { + string popen_cmd = archive_decoder + " " + shell_escape(rps); + fp = popen (popen_cmd.c_str(), "r"); // "e" O_CLOEXEC? + dfn = pclose; + if (fp == NULL) + throw libc_exception (errno, string("popen ") + popen_cmd); + } + else + { + fp = fopen (rps.c_str(), "r"); + dfn = fclose; + if (fp == NULL) + throw libc_exception (errno, string("fopen ") + rps); + } + defer_dtor fp_closer (fp, dfn); + + struct archive *a; + a = archive_read_new(); + if (a == NULL) + throw archive_exception("cannot create archive reader"); + defer_dtor archive_closer (a, archive_read_free); + + int rc = archive_read_support_format_all(a); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot select all formats"); + rc = archive_read_support_filter_all(a); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot select all filters"); + + rc = archive_read_open_FILE (a, fp); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot open archive from pipe"); + + if (verbose > 3) + obatched(clog) << "libarchive scanning " << rps << endl; + + while(1) // parse archive entries + { + if (interrupted) + break; + + try + { + struct archive_entry *e; + rc = archive_read_next_header (a, &e); + if (rc != ARCHIVE_OK) + break; + + if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely + continue; + + string fn = canonicalized_archive_entry_pathname (e); + + if (verbose > 3) + obatched(clog) << "libarchive checking " << fn << endl; + + // extract this file to a temporary file + char* tmppath = NULL; + rc = asprintf (&tmppath, "%s/debuginfod.XXXXXX", tmpdir.c_str()); + if (rc < 0) + throw libc_exception (ENOMEM, "cannot allocate tmppath"); + defer_dtor tmmpath_freer (tmppath, free); + int fd = mkstemp (tmppath); + if (fd < 0) + throw libc_exception (errno, "cannot create temporary file"); + unlink (tmppath); // unlink now so OS will release the file as soon as we close the fd + defer_dtor minifd_closer (fd, close); + + rc = archive_read_data_into_fd (a, fd); + if (rc != ARCHIVE_OK) + throw archive_exception(a, "cannot extract file"); + + // finally ... time to run elf_classify on this bad boy and update the database + bool executable_p = false, debuginfo_p = false; + string buildid; + set sourcefiles; + elf_classify (fd, executable_p, debuginfo_p, buildid, sourcefiles); + // NB: might throw + + if (buildid != "") // intern buildid + { + ps_upsert_buildids + .reset() + .bind(1, buildid) + .step_ok_done(); + } + + ps_upsert_files // register this rpm constituent file name in interning table + .reset() + .bind(1, fn) + .step_ok_done(); + + if (sourcefiles.size() > 0) // sref records needed + { + // NB: we intern each source file once. Once raw, as it + // appears in the DWARF file list coming back from + // elf_classify() - because it'll end up in the + // _norm.artifactsrc column. We don't also put another + // version with a '.' at the front, even though that's + // how rpm/cpio packs names, because we hide that from + // the database for storage efficiency. + + for (auto&& s : sourcefiles) + { + if (s == "") + { + fts_sref_complete_p = false; + continue; + } + + // PR25548: store canonicalized source path + const string& dwarfsrc = s; + string dwarfsrc_canon = canon_pathname (dwarfsrc); + if (dwarfsrc_canon != dwarfsrc) + { + if (verbose > 3) + obatched(clog) << "canonicalized src=" << dwarfsrc << " alias=" << dwarfsrc_canon << endl; + } + + ps_upsert_files + .reset() + .bind(1, dwarfsrc_canon) + .step_ok_done(); + + ps_upsert_sref + .reset() + .bind(1, buildid) + .bind(2, dwarfsrc_canon) + .step_ok_done(); + + fts_sref ++; + } + } + + if (executable_p) + fts_executable ++; + if (debuginfo_p) + fts_debuginfo ++; + + if (executable_p || debuginfo_p) + { + ps_upsert_de + .reset() + .bind(1, buildid) + .bind(2, debuginfo_p ? 1 : 0) + .bind(3, executable_p ? 1 : 0) + .bind(4, rps) + .bind(5, mtime) + .bind(6, fn) + .step_ok_done(); + } + else // potential source - sdef record + { + fts_sdef ++; + ps_upsert_sdef + .reset() + .bind(1, rps) + .bind(2, mtime) + .bind(3, fn) + .step_ok_done(); + } + + if ((verbose > 2) && (executable_p || debuginfo_p)) + obatched(clog) << "recorded buildid=" << buildid << " rpm=" << rps << " file=" << fn + << " mtime=" << mtime << " atype=" + << (executable_p ? "E" : "") + << (debuginfo_p ? "D" : "") + << " sourcefiles=" << sourcefiles.size() << endl; + + } + catch (const reportable_exception& e) + { + e.report(clog); + } + } +} + + + +// scan for archive files such as .rpm +static void +scan_archive_file (const string& rps, const stat_t& st, + sqlite_ps& ps_upsert_buildids, + sqlite_ps& ps_upsert_files, + sqlite_ps& ps_upsert_de, + sqlite_ps& ps_upsert_sref, + sqlite_ps& ps_upsert_sdef, + sqlite_ps& ps_query, + sqlite_ps& ps_scan_done, + unsigned& fts_cached, + unsigned& fts_executable, + unsigned& fts_debuginfo, + unsigned& fts_sref, + unsigned& fts_sdef) +{ + /* See if we know of it already. */ + int rc = ps_query + .reset() + .bind(1, rps) + .bind(2, st.st_mtime) + .step(); + ps_query.reset(); + if (rc == SQLITE_ROW) // i.e., a result, as opposed to DONE (no results) + // no need to recheck a file/version we already know + // specifically, no need to parse this archive again, since we already have + // it as a D or E or S record, + // (so is stored with buildid=NULL) + { + fts_cached ++; + return; + } + + // intern the archive file name + ps_upsert_files + .reset() + .bind(1, rps) + .step_ok_done(); + + // extract the archive contents + unsigned my_fts_executable = 0, my_fts_debuginfo = 0, my_fts_sref = 0, my_fts_sdef = 0; + bool my_fts_sref_complete_p = true; + try + { + string archive_extension; + archive_classify (rps, archive_extension, + ps_upsert_buildids, ps_upsert_files, + ps_upsert_de, ps_upsert_sref, ps_upsert_sdef, // dalt + st.st_mtime, + my_fts_executable, my_fts_debuginfo, my_fts_sref, my_fts_sdef, + my_fts_sref_complete_p); + add_metric ("scanned_bytes_total","source",archive_extension + " archive", + st.st_size); + inc_metric ("scanned_files_total","source",archive_extension + " archive"); + add_metric("found_debuginfo_total","source",archive_extension + " archive", + my_fts_debuginfo); + add_metric("found_executable_total","source",archive_extension + " archive", + my_fts_executable); + add_metric("found_sourcerefs_total","source",archive_extension + " archive", + my_fts_sref); + } + catch (const reportable_exception& e) + { + e.report(clog); + } + + if (verbose > 2) + obatched(clog) << "scanned archive=" << rps + << " mtime=" << st.st_mtime + << " executables=" << my_fts_executable + << " debuginfos=" << my_fts_debuginfo + << " srefs=" << my_fts_sref + << " sdefs=" << my_fts_sdef + << endl; + + fts_executable += my_fts_executable; + fts_debuginfo += my_fts_debuginfo; + fts_sref += my_fts_sref; + fts_sdef += my_fts_sdef; + + if (my_fts_sref_complete_p) // leave incomplete? + ps_scan_done + .reset() + .bind(1, rps) + .bind(2, st.st_mtime) + .bind(3, st.st_size) + .step_ok_done(); +} + + + +//////////////////////////////////////////////////////////////////////// + + + +// The thread that consumes file names off of the scanq. We hold +// the persistent sqlite_ps's at this level and delegate file/archive +// scanning to other functions. +static void* +thread_main_scanner (void* arg) +{ + (void) arg; + + // all the prepared statements fit to use, the _f_ set: + sqlite_ps ps_f_upsert_buildids (db, "file-buildids-intern", "insert or ignore into " BUILDIDS "_buildids VALUES (NULL, ?);"); + sqlite_ps ps_f_upsert_files (db, "file-files-intern", "insert or ignore into " BUILDIDS "_files VALUES (NULL, ?);"); + sqlite_ps ps_f_upsert_de (db, "file-de-upsert", + "insert or ignore into " BUILDIDS "_f_de " + "(buildid, debuginfo_p, executable_p, file, mtime) " + "values ((select id from " BUILDIDS "_buildids where hex = ?)," + " ?,?," + " (select id from " BUILDIDS "_files where name = ?), ?);"); + sqlite_ps ps_f_upsert_s (db, "file-s-upsert", + "insert or ignore into " BUILDIDS "_f_s " + "(buildid, artifactsrc, file, mtime) " + "values ((select id from " BUILDIDS "_buildids where hex = ?)," + " (select id from " BUILDIDS "_files where name = ?)," + " (select id from " BUILDIDS "_files where name = ?)," + " ?);"); + sqlite_ps ps_f_query (db, "file-negativehit-find", + "select 1 from " BUILDIDS "_file_mtime_scanned where sourcetype = 'F' " + "and file = (select id from " BUILDIDS "_files where name = ?) and mtime = ?;"); + sqlite_ps ps_f_scan_done (db, "file-scanned", + "insert or ignore into " BUILDIDS "_file_mtime_scanned (sourcetype, file, mtime, size)" + "values ('F', (select id from " BUILDIDS "_files where name = ?), ?, ?);"); + + // and now for the _r_ set + sqlite_ps ps_r_upsert_buildids (db, "rpm-buildid-intern", "insert or ignore into " BUILDIDS "_buildids VALUES (NULL, ?);"); + sqlite_ps ps_r_upsert_files (db, "rpm-file-intern", "insert or ignore into " BUILDIDS "_files VALUES (NULL, ?);"); + sqlite_ps ps_r_upsert_de (db, "rpm-de-insert", + "insert or ignore into " BUILDIDS "_r_de (buildid, debuginfo_p, executable_p, file, mtime, content) values (" + "(select id from " BUILDIDS "_buildids where hex = ?), ?, ?, " + "(select id from " BUILDIDS "_files where name = ?), ?, " + "(select id from " BUILDIDS "_files where name = ?));"); + sqlite_ps ps_r_upsert_sref (db, "rpm-sref-insert", + "insert or ignore into " BUILDIDS "_r_sref (buildid, artifactsrc) values (" + "(select id from " BUILDIDS "_buildids where hex = ?), " + "(select id from " BUILDIDS "_files where name = ?));"); + sqlite_ps ps_r_upsert_sdef (db, "rpm-sdef-insert", + "insert or ignore into " BUILDIDS "_r_sdef (file, mtime, content) values (" + "(select id from " BUILDIDS "_files where name = ?), ?," + "(select id from " BUILDIDS "_files where name = ?));"); + sqlite_ps ps_r_query (db, "rpm-negativehit-query", + "select 1 from " BUILDIDS "_file_mtime_scanned where " + "sourcetype = 'R' and file = (select id from " BUILDIDS "_files where name = ?) and mtime = ?;"); + sqlite_ps ps_r_scan_done (db, "rpm-scanned", + "insert or ignore into " BUILDIDS "_file_mtime_scanned (sourcetype, file, mtime, size)" + "values ('R', (select id from " BUILDIDS "_files where name = ?), ?, ?);"); + + + unsigned fts_cached = 0, fts_executable = 0, fts_debuginfo = 0, fts_sourcefiles = 0; + unsigned fts_sref = 0, fts_sdef = 0; + + add_metric("thread_count", "role", "scan", 1); + add_metric("thread_busy", "role", "scan", 1); + while (! interrupted) + { + scan_payload p; + + add_metric("thread_busy", "role", "scan", -1); + bool gotone = scanq.wait_front(p); + add_metric("thread_busy", "role", "scan", 1); + + if (! gotone) continue; // go back to waiting + + try + { + bool scan_archive = false; + for (auto&& arch : scan_archives) + if (string_endswith(p.first, arch.first)) + scan_archive = true; + + if (scan_archive) + scan_archive_file (p.first, p.second, + ps_r_upsert_buildids, + ps_r_upsert_files, + ps_r_upsert_de, + ps_r_upsert_sref, + ps_r_upsert_sdef, + ps_r_query, + ps_r_scan_done, + fts_cached, + fts_executable, + fts_debuginfo, + fts_sref, + fts_sdef); + + if (scan_files) // NB: maybe "else if" ? + scan_source_file (p.first, p.second, + ps_f_upsert_buildids, + ps_f_upsert_files, + ps_f_upsert_de, + ps_f_upsert_s, + ps_f_query, + ps_f_scan_done, + fts_cached, fts_executable, fts_debuginfo, fts_sourcefiles); + } + catch (const reportable_exception& e) + { + e.report(cerr); + } + + if (fts_cached || fts_executable || fts_debuginfo || fts_sourcefiles || fts_sref || fts_sdef) + {} // NB: not just if a successful scan - we might have encountered -ENOSPC & failed + (void) statfs_free_enough_p(db_path, "database"); // report sqlite filesystem size + (void) statfs_free_enough_p(tmpdir, "tmpdir"); // this too, in case of fdcache/tmpfile usage + + // finished a scanning step -- not a "loop", because we just + // consume the traversal loop's work, whenever + inc_metric("thread_work_total","role","scan"); + } + + + add_metric("thread_busy", "role", "scan", -1); + return 0; +} + + + +// The thread that traverses all the source_paths and enqueues all the +// matching files into the file/archive scan queue. +static void +scan_source_paths() +{ + // NB: fedora 31 glibc/fts(3) crashes inside fts_read() on empty + // path list. + if (source_paths.empty()) + return; + + // Turn the source_paths into an fts(3)-compatible char**. Since + // source_paths[] does not change after argv processing, the + // c_str()'s are safe to keep around awile. + vector sps; + for (auto&& sp: source_paths) + sps.push_back(sp.c_str()); + sps.push_back(NULL); + + FTS *fts = fts_open ((char * const *)sps.data(), + (traverse_logical ? FTS_LOGICAL : FTS_PHYSICAL|FTS_XDEV) + | FTS_NOCHDIR /* multithreaded */, + NULL); + if (fts == NULL) + throw libc_exception(errno, "cannot fts_open"); + defer_dtor fts_cleanup (fts, fts_close); + + struct timespec ts_start, ts_end; + clock_gettime (CLOCK_MONOTONIC, &ts_start); + unsigned fts_scanned = 0, fts_regex = 0; + + FTSENT *f; + while ((f = fts_read (fts)) != NULL) + { + if (interrupted) break; + + if (sigusr2 != forced_groom_count) // stop early if groom triggered + { + scanq.clear(); // clear previously issued work for scanner threads + break; + } + + fts_scanned ++; + + if (verbose > 2) + obatched(clog) << "fts traversing " << f->fts_path << endl; + + switch (f->fts_info) + { + case FTS_F: + { + /* Found a file. Convert it to an absolute path, so + the buildid database does not have relative path + names that are unresolvable from a subsequent run + in a different cwd. */ + char *rp = realpath(f->fts_path, NULL); + if (rp == NULL) + continue; // ignore dangling symlink or such + string rps = string(rp); + free (rp); + + bool ri = !regexec (&file_include_regex, rps.c_str(), 0, 0, 0); + bool rx = !regexec (&file_exclude_regex, rps.c_str(), 0, 0, 0); + if (!ri || rx) + { + if (verbose > 3) + obatched(clog) << "fts skipped by regex " + << (!ri ? "I" : "") << (rx ? "X" : "") << endl; + fts_regex ++; + if (!ri) + inc_metric("traversed_total","type","file-skipped-I"); + if (rx) + inc_metric("traversed_total","type","file-skipped-X"); + } + else + { + scanq.push_back (make_pair(rps, *f->fts_statp)); + inc_metric("traversed_total","type","file"); + } + } + break; + + case FTS_ERR: + case FTS_NS: + // report on some types of errors because they may reflect fixable misconfiguration + { + auto x = libc_exception(f->fts_errno, string("fts traversal ") + string(f->fts_path)); + x.report(cerr); + } + inc_metric("traversed_total","type","error"); + break; + + case FTS_SL: // ignore, but count because debuginfod -L would traverse these + inc_metric("traversed_total","type","symlink"); + break; + + case FTS_D: // ignore + inc_metric("traversed_total","type","directory"); + break; + + default: // ignore + inc_metric("traversed_total","type","other"); + break; + } + } + clock_gettime (CLOCK_MONOTONIC, &ts_end); + double deltas = (ts_end.tv_sec - ts_start.tv_sec) + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; + + obatched(clog) << "fts traversed source paths in " << deltas << "s, scanned=" << fts_scanned + << ", regex-skipped=" << fts_regex << endl; +} + + +static void* +thread_main_fts_source_paths (void* arg) +{ + (void) arg; // ignore; we operate on global data + + set_metric("thread_tid", "role","traverse", tid()); + add_metric("thread_count", "role", "traverse", 1); + + time_t last_rescan = 0; + + while (! interrupted) + { + sleep (1); + scanq.wait_idle(); // don't start a new traversal while scanners haven't finished the job + scanq.done_idle(); // release the hounds + if (interrupted) break; + + time_t now = time(NULL); + bool rescan_now = false; + if (last_rescan == 0) // at least one initial rescan is documented even for -t0 + rescan_now = true; + if (rescan_s > 0 && (long)now > (long)(last_rescan + rescan_s)) + rescan_now = true; + if (sigusr1 != forced_rescan_count) + { + forced_rescan_count = sigusr1; + rescan_now = true; + } + if (rescan_now) + { + set_metric("thread_busy", "role","traverse", 1); + try + { + scan_source_paths(); + } + catch (const reportable_exception& e) + { + e.report(cerr); + } + last_rescan = time(NULL); // NB: now was before scanning + // finished a traversal loop + inc_metric("thread_work_total", "role","traverse"); + set_metric("thread_busy", "role","traverse", 0); + } + } + + return 0; +} + + + +//////////////////////////////////////////////////////////////////////// + +static void +database_stats_report() +{ + sqlite_ps ps_query (db, "database-overview", + "select label,quantity from " BUILDIDS "_stats"); + + obatched(clog) << "database record counts:" << endl; + while (1) + { + if (interrupted) break; + if (sigusr1 != forced_rescan_count) // stop early if scan triggered + break; + + int rc = ps_query.step(); + if (rc == SQLITE_DONE) break; + if (rc != SQLITE_ROW) + throw sqlite_exception(rc, "step"); + + obatched(clog) + << right << setw(20) << ((const char*) sqlite3_column_text(ps_query, 0) ?: (const char*) "NULL") + << " " + << (sqlite3_column_text(ps_query, 1) ?: (const unsigned char*) "NULL") + << endl; + + set_metric("groom", "statistic", + ((const char*) sqlite3_column_text(ps_query, 0) ?: (const char*) "NULL"), + (sqlite3_column_double(ps_query, 1))); + } +} + + +// Do a round of database grooming that might take many minutes to run. +void groom() +{ + obatched(clog) << "grooming database" << endl; + + struct timespec ts_start, ts_end; + clock_gettime (CLOCK_MONOTONIC, &ts_start); + + // scan for files that have disappeared + sqlite_ps files (db, "check old files", "select s.mtime, s.file, f.name from " + BUILDIDS "_file_mtime_scanned s, " BUILDIDS "_files f " + "where f.id = s.file"); + sqlite_ps files_del_f_de (db, "nuke f_de", "delete from " BUILDIDS "_f_de where file = ? and mtime = ?"); + sqlite_ps files_del_r_de (db, "nuke r_de", "delete from " BUILDIDS "_r_de where file = ? and mtime = ?"); + sqlite_ps files_del_scan (db, "nuke f_m_s", "delete from " BUILDIDS "_file_mtime_scanned " + "where file = ? and mtime = ?"); + files.reset(); + while(1) + { + if (interrupted) break; + + int rc = files.step(); + if (rc != SQLITE_ROW) + break; + + int64_t mtime = sqlite3_column_int64 (files, 0); + int64_t fileid = sqlite3_column_int64 (files, 1); + const char* filename = ((const char*) sqlite3_column_text (files, 2) ?: ""); + struct stat s; + rc = stat(filename, &s); + if (rc < 0 || (mtime != (int64_t) s.st_mtime)) + { + if (verbose > 2) + obatched(clog) << "groom: forgetting file=" << filename << " mtime=" << mtime << endl; + files_del_f_de.reset().bind(1,fileid).bind(2,mtime).step_ok_done(); + files_del_r_de.reset().bind(1,fileid).bind(2,mtime).step_ok_done(); + files_del_scan.reset().bind(1,fileid).bind(2,mtime).step_ok_done(); + inc_metric("groomed_total", "decision", "stale"); + } + else + inc_metric("groomed_total", "decision", "fresh"); + + if (sigusr1 != forced_rescan_count) // stop early if scan triggered + break; + } + files.reset(); + + // delete buildids with no references in _r_de or _f_de tables; + // cascades to _r_sref & _f_s records + sqlite_ps buildids_del (db, "nuke orphan buildids", + "delete from " BUILDIDS "_buildids " + "where not exists (select 1 from " BUILDIDS "_f_de d where " BUILDIDS "_buildids.id = d.buildid) " + "and not exists (select 1 from " BUILDIDS "_r_de d where " BUILDIDS "_buildids.id = d.buildid)"); + buildids_del.reset().step_ok_done(); + + if (interrupted) return; + + // NB: "vacuum" is too heavy for even daily runs: it rewrites the entire db, so is done as maxigroom -G + sqlite_ps g1 (db, "incremental vacuum", "pragma incremental_vacuum"); + g1.reset().step_ok_done(); + sqlite_ps g2 (db, "optimize", "pragma optimize"); + g2.reset().step_ok_done(); + sqlite_ps g3 (db, "wal checkpoint", "pragma wal_checkpoint=truncate"); + g3.reset().step_ok_done(); + + database_stats_report(); + + (void) statfs_free_enough_p(db_path, "database"); // report sqlite filesystem size + + sqlite3_db_release_memory(db); // shrink the process if possible + sqlite3_db_release_memory(dbq); // ... for both connections + debuginfod_pool_groom(); // and release any debuginfod_client objects we've been holding onto + + fdcache.limit(0,0); // release the fdcache contents + fdcache.limit(fdcache_fds,fdcache_mbs); // restore status quo parameters + + clock_gettime (CLOCK_MONOTONIC, &ts_end); + double deltas = (ts_end.tv_sec - ts_start.tv_sec) + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; + + obatched(clog) << "groomed database in " << deltas << "s" << endl; +} + + +static void* +thread_main_groom (void* /*arg*/) +{ + set_metric("thread_tid", "role", "groom", tid()); + add_metric("thread_count", "role", "groom", 1); + + time_t last_groom = 0; + + while (1) + { + sleep (1); + scanq.wait_idle(); // PR25394: block scanners during grooming! + if (interrupted) break; + + time_t now = time(NULL); + bool groom_now = false; + if (last_groom == 0) // at least one initial groom is documented even for -g0 + groom_now = true; + if (groom_s > 0 && (long)now > (long)(last_groom + groom_s)) + groom_now = true; + if (sigusr2 != forced_groom_count) + { + forced_groom_count = sigusr2; + groom_now = true; + } + if (groom_now) + { + set_metric("thread_busy", "role", "groom", 1); + try + { + groom (); + } + catch (const sqlite_exception& e) + { + obatched(cerr) << e.message << endl; + } + last_groom = time(NULL); // NB: now was before grooming + // finished a grooming loop + inc_metric("thread_work_total", "role", "groom"); + set_metric("thread_busy", "role", "groom", 0); + } + + scanq.done_idle(); + } + + return 0; +} + + +//////////////////////////////////////////////////////////////////////// + + +static void +signal_handler (int /* sig */) +{ + interrupted ++; + + if (db) + sqlite3_interrupt (db); + if (dbq) + sqlite3_interrupt (dbq); + + // NB: don't do anything else in here +} + +static void +sigusr1_handler (int /* sig */) +{ + sigusr1 ++; + // NB: don't do anything else in here +} + +static void +sigusr2_handler (int /* sig */) +{ + sigusr2 ++; + // NB: don't do anything else in here +} + + + + + +// A user-defined sqlite function, to score the sharedness of the +// prefix of two strings. This is used to compare candidate debuginfo +// / source-rpm names, so that the closest match +// (directory-topology-wise closest) is found. This is important in +// case the same sref (source file name) is in many -debuginfo or +// -debugsource RPMs, such as when multiple versions/releases of the +// same package are in the database. + +static void sqlite3_sharedprefix_fn (sqlite3_context* c, int argc, sqlite3_value** argv) +{ + if (argc != 2) + sqlite3_result_error(c, "expect 2 string arguments", -1); + else if ((sqlite3_value_type(argv[0]) != SQLITE_TEXT) || + (sqlite3_value_type(argv[1]) != SQLITE_TEXT)) + sqlite3_result_null(c); + else + { + const unsigned char* a = sqlite3_value_text (argv[0]); + const unsigned char* b = sqlite3_value_text (argv[1]); + int i = 0; + while (*a++ == *b++) + i++; + sqlite3_result_int (c, i); + } +} + + +int +main (int argc, char *argv[]) +{ + (void) setlocale (LC_ALL, ""); + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + (void) textdomain (PACKAGE_TARNAME); + + /* Tell the library which version we are expecting. */ + elf_version (EV_CURRENT); + + tmpdir = string(getenv("TMPDIR") ?: "/tmp"); + + /* Set computed default values. */ + db_path = string(getenv("HOME") ?: "/") + string("/.debuginfod.sqlite"); /* XDG? */ + int rc = regcomp (& file_include_regex, ".*", REG_EXTENDED|REG_NOSUB); // match everything + if (rc != 0) + error (EXIT_FAILURE, 0, "regcomp failure: %d", rc); + rc = regcomp (& file_exclude_regex, "^$", REG_EXTENDED|REG_NOSUB); // match nothing + if (rc != 0) + error (EXIT_FAILURE, 0, "regcomp failure: %d", rc); + + // default parameters for fdcache are computed from system stats + struct statfs sfs; + rc = statfs(tmpdir.c_str(), &sfs); + if (rc < 0) + fdcache_mbs = 1024; // 1 gigabyte + else + fdcache_mbs = sfs.f_bavail * sfs.f_bsize / 1024 / 1024 / 4; // 25% of free space + fdcache_mintmp = 25; // emergency flush at 25% remaining (75% full) + fdcache_prefetch = 64; // guesstimate storage is this much less costly than re-decompression + fdcache_fds = (concurrency + fdcache_prefetch) * 2; + + /* Parse and process arguments. */ + int remaining; + argp_program_version_hook = print_version; // this works + (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL); + if (remaining != argc) + error (EXIT_FAILURE, 0, + "unexpected argument: %s", argv[remaining]); + + if (scan_archives.size()==0 && !scan_files && source_paths.size()>0) + obatched(clog) << "warning: without -F -R -U -Z, ignoring PATHs" << endl; + + fdcache.limit(fdcache_fds, fdcache_mbs); + + (void) signal (SIGPIPE, SIG_IGN); // microhttpd can generate it incidentally, ignore + (void) signal (SIGINT, signal_handler); // ^C + (void) signal (SIGHUP, signal_handler); // EOF + (void) signal (SIGTERM, signal_handler); // systemd + (void) signal (SIGUSR1, sigusr1_handler); // end-user + (void) signal (SIGUSR2, sigusr2_handler); // end-user + + /* Get database ready. */ + rc = sqlite3_open_v2 (db_path.c_str(), &db, (SQLITE_OPEN_READWRITE + |SQLITE_OPEN_URI + |SQLITE_OPEN_PRIVATECACHE + |SQLITE_OPEN_CREATE + |SQLITE_OPEN_FULLMUTEX), /* thread-safe */ + NULL); + if (rc == SQLITE_CORRUPT) + { + (void) unlink (db_path.c_str()); + error (EXIT_FAILURE, 0, + "cannot open %s, deleted database: %s", db_path.c_str(), sqlite3_errmsg(db)); + } + else if (rc) + { + error (EXIT_FAILURE, 0, + "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(db)); + } + + // open the readonly query variant + // NB: PRIVATECACHE allows web queries to operate in parallel with + // much other grooming/scanning operation. + rc = sqlite3_open_v2 (db_path.c_str(), &dbq, (SQLITE_OPEN_READONLY + |SQLITE_OPEN_URI + |SQLITE_OPEN_PRIVATECACHE + |SQLITE_OPEN_FULLMUTEX), /* thread-safe */ + NULL); + if (rc) + { + error (EXIT_FAILURE, 0, + "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(dbq)); + } + + + obatched(clog) << "opened database " << db_path << endl; + obatched(clog) << "sqlite version " << sqlite3_version << endl; + + // add special string-prefix-similarity function used in rpm sref/sdef resolution + rc = sqlite3_create_function(dbq, "sharedprefix", 2, SQLITE_UTF8, NULL, + & sqlite3_sharedprefix_fn, NULL, NULL); + if (rc != SQLITE_OK) + error (EXIT_FAILURE, 0, + "cannot create sharedprefix function: %s", sqlite3_errmsg(dbq)); + + if (verbose > 3) + obatched(clog) << "ddl: " << DEBUGINFOD_SQLITE_DDL << endl; + rc = sqlite3_exec (db, DEBUGINFOD_SQLITE_DDL, NULL, NULL, NULL); + if (rc != SQLITE_OK) + { + error (EXIT_FAILURE, 0, + "cannot run database schema ddl: %s", sqlite3_errmsg(db)); + } + + // Start httpd server threads. Separate pool for IPv4 and IPv6, in + // case the host only has one protocol stack. + MHD_Daemon *d4 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION +#if MHD_VERSION >= 0x00095300 + | MHD_USE_INTERNAL_POLLING_THREAD +#else + | MHD_USE_SELECT_INTERNALLY +#endif + | MHD_USE_DEBUG, /* report errors to stderr */ + http_port, + NULL, NULL, /* default accept policy */ + handler_cb, NULL, /* handler callback */ + MHD_OPTION_END); + MHD_Daemon *d6 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION +#if MHD_VERSION >= 0x00095300 + | MHD_USE_INTERNAL_POLLING_THREAD +#else + | MHD_USE_SELECT_INTERNALLY +#endif + | MHD_USE_IPv6 + | MHD_USE_DEBUG, /* report errors to stderr */ + http_port, + NULL, NULL, /* default accept policy */ + handler_cb, NULL, /* handler callback */ + MHD_OPTION_END); + + if (d4 == NULL && d6 == NULL) // neither ipv4 nor ipv6? boo + { + sqlite3 *database = db; + sqlite3 *databaseq = dbq; + db = dbq = 0; // for signal_handler not to freak + sqlite3_close (databaseq); + sqlite3_close (database); + error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port); + } + + obatched(clog) << "started http server on " + << (d4 != NULL ? "IPv4 " : "") + << (d6 != NULL ? "IPv6 " : "") + << "port=" << http_port << endl; + + // add maxigroom sql if -G given + if (maxigroom) + { + obatched(clog) << "maxigrooming database, please wait." << endl; + extra_ddl.push_back("create index if not exists " BUILDIDS "_r_sref_arc on " BUILDIDS "_r_sref(artifactsrc);"); + extra_ddl.push_back("delete from " BUILDIDS "_r_sdef where not exists (select 1 from " BUILDIDS "_r_sref b where " BUILDIDS "_r_sdef.content = b.artifactsrc);"); + extra_ddl.push_back("drop index if exists " BUILDIDS "_r_sref_arc;"); + + // NB: we don't maxigroom the _files interning table. It'd require a temp index on all the + // tables that have file foreign-keys, which is a lot. + + // NB: with =delete, may take up 3x disk space total during vacuum process + // vs. =off (only 2x but may corrupt database if program dies mid-vacuum) + // vs. =wal (>3x observed, but safe) + extra_ddl.push_back("pragma journal_mode=delete;"); + extra_ddl.push_back("vacuum;"); + extra_ddl.push_back("pragma journal_mode=wal;"); + } + + // run extra -D sql if given + for (auto&& i: extra_ddl) + { + if (verbose > 1) + obatched(clog) << "extra ddl:\n" << i << endl; + rc = sqlite3_exec (db, i.c_str(), NULL, NULL, NULL); + if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW) + error (0, 0, + "warning: cannot run database extra ddl %s: %s", i.c_str(), sqlite3_errmsg(db)); + } + + if (maxigroom) + obatched(clog) << "maxigroomed database" << endl; + + obatched(clog) << "search concurrency " << concurrency << endl; + obatched(clog) << "rescan time " << rescan_s << endl; + obatched(clog) << "fdcache fds " << fdcache_fds << endl; + obatched(clog) << "fdcache mbs " << fdcache_mbs << endl; + obatched(clog) << "fdcache prefetch " << fdcache_prefetch << endl; + obatched(clog) << "fdcache tmpdir " << tmpdir << endl; + obatched(clog) << "fdcache tmpdir min% " << fdcache_mintmp << endl; + obatched(clog) << "groom time " << groom_s << endl; + if (scan_archives.size()>0) + { + obatched ob(clog); + auto& o = ob << "scanning archive types "; + for (auto&& arch : scan_archives) + o << arch.first << "(" << arch.second << ") "; + o << endl; + } + const char* du = getenv(DEBUGINFOD_URLS_ENV_VAR); + if (du && du[0] != '\0') // set to non-empty string? + obatched(clog) << "upstream debuginfod servers: " << du << endl; + + vector all_threads; + + pthread_t pt; + rc = pthread_create (& pt, NULL, thread_main_groom, NULL); + if (rc) + error (EXIT_FAILURE, rc, "cannot spawn thread to groom database\n"); + else + { +#ifdef HAVE_PTHREAD_SETNAME_NP + (void) pthread_setname_np (pt, "groom"); +#endif + all_threads.push_back(pt); + } + + if (scan_files || scan_archives.size() > 0) + { + rc = pthread_create (& pt, NULL, thread_main_fts_source_paths, NULL); + if (rc) + error (EXIT_FAILURE, rc, "cannot spawn thread to traverse source paths\n"); +#ifdef HAVE_PTHREAD_SETNAME_NP + (void) pthread_setname_np (pt, "traverse"); +#endif + all_threads.push_back(pt); + + for (unsigned i=0; i. */ + +#ifndef _DEBUGINFOD_CLIENT_H +#define _DEBUGINFOD_CLIENT_H 1 + +/* Names of environment variables that control the client logic. */ +#define DEBUGINFOD_URLS_ENV_VAR "DEBUGINFOD_URLS" +#define DEBUGINFOD_CACHE_PATH_ENV_VAR "DEBUGINFOD_CACHE_PATH" +#define DEBUGINFOD_TIMEOUT_ENV_VAR "DEBUGINFOD_TIMEOUT" +#define DEBUGINFOD_PROGRESS_ENV_VAR "DEBUGINFOD_PROGRESS" +#define DEBUGINFOD_VERBOSE_ENV_VAR "DEBUGINFOD_VERBOSE" + +/* The libdebuginfod soname. */ +#define DEBUGINFOD_SONAME "libdebuginfod.so.1" + +/* Handle for debuginfod-client connection. */ +typedef struct debuginfod_client debuginfod_client; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create a handle for a new debuginfod-client session. */ +debuginfod_client *debuginfod_begin (void); + +/* Query the urls contained in $DEBUGINFOD_URLS for a file with + the specified type and build id. If build_id_len == 0, the + build_id is supplied as a lowercase hexadecimal string; otherwise + it is a binary blob of given length. + + If successful, return a file descriptor to the target, otherwise + return a posix error code. If successful, set *path to a + strdup'd copy of the name of the same file in the cache. + Caller must free() it later. */ + +int debuginfod_find_debuginfo (debuginfod_client *client, + const unsigned char *build_id, + int build_id_len, + char **path); + +int debuginfod_find_executable (debuginfod_client *client, + const unsigned char *build_id, + int build_id_len, + char **path); + +int debuginfod_find_source (debuginfod_client *client, + const unsigned char *build_id, + int build_id_len, + const char *filename, + char **path); + +typedef int (*debuginfod_progressfn_t)(debuginfod_client *c, long a, long b); +void debuginfod_set_progressfn(debuginfod_client *c, + debuginfod_progressfn_t fn); + +void debuginfod_set_verbose_fd(debuginfod_client *c, int fd); + +/* Set the user parameter. */ +void debuginfod_set_user_data (debuginfod_client *client, void *value); + +/* Get the user parameter. */ +void* debuginfod_get_user_data (debuginfod_client *client); + +/* Get the current or last active URL, if known. */ +const char* debuginfod_get_url (debuginfod_client *client); + +/* Add an outgoing HTTP request "Header: Value". Copies string. */ +int debuginfod_add_http_header (debuginfod_client *client, const char* header); + +/* Release debuginfod client connection context handle. */ +void debuginfod_end (debuginfod_client *client); + +#ifdef __cplusplus +} +#endif + + +#endif /* _DEBUGINFOD_CLIENT_H */ diff --git a/debuginfod/debuginfod.h.in b/debuginfod/debuginfod.h.in new file mode 100644 index 00000000..559ea947 --- /dev/null +++ b/debuginfod/debuginfod.h.in @@ -0,0 +1,104 @@ +/* External declarations for the libdebuginfod client library. + Copyright (C) 2019-2020 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _DEBUGINFOD_CLIENT_H +#define _DEBUGINFOD_CLIENT_H 1 + +/* Names of environment variables that control the client logic. */ +#define DEBUGINFOD_URLS_ENV_VAR "DEBUGINFOD_URLS" +#define DEBUGINFOD_CACHE_PATH_ENV_VAR "DEBUGINFOD_CACHE_PATH" +#define DEBUGINFOD_TIMEOUT_ENV_VAR "DEBUGINFOD_TIMEOUT" +#define DEBUGINFOD_PROGRESS_ENV_VAR "DEBUGINFOD_PROGRESS" +#define DEBUGINFOD_VERBOSE_ENV_VAR "DEBUGINFOD_VERBOSE" + +/* The libdebuginfod soname. */ +#define DEBUGINFOD_SONAME "@LIBDEBUGINFOD_SONAME@" + +/* Handle for debuginfod-client connection. */ +typedef struct debuginfod_client debuginfod_client; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create a handle for a new debuginfod-client session. */ +debuginfod_client *debuginfod_begin (void); + +/* Query the urls contained in $DEBUGINFOD_URLS for a file with + the specified type and build id. If build_id_len == 0, the + build_id is supplied as a lowercase hexadecimal string; otherwise + it is a binary blob of given length. + + If successful, return a file descriptor to the target, otherwise + return a posix error code. If successful, set *path to a + strdup'd copy of the name of the same file in the cache. + Caller must free() it later. */ + +int debuginfod_find_debuginfo (debuginfod_client *client, + const unsigned char *build_id, + int build_id_len, + char **path); + +int debuginfod_find_executable (debuginfod_client *client, + const unsigned char *build_id, + int build_id_len, + char **path); + +int debuginfod_find_source (debuginfod_client *client, + const unsigned char *build_id, + int build_id_len, + const char *filename, + char **path); + +typedef int (*debuginfod_progressfn_t)(debuginfod_client *c, long a, long b); +void debuginfod_set_progressfn(debuginfod_client *c, + debuginfod_progressfn_t fn); + +void debuginfod_set_verbose_fd(debuginfod_client *c, int fd); + +/* Set the user parameter. */ +void debuginfod_set_user_data (debuginfod_client *client, void *value); + +/* Get the user parameter. */ +void* debuginfod_get_user_data (debuginfod_client *client); + +/* Get the current or last active URL, if known. */ +const char* debuginfod_get_url (debuginfod_client *client); + +/* Add an outgoing HTTP request "Header: Value". Copies string. */ +int debuginfod_add_http_header (debuginfod_client *client, const char* header); + +/* Release debuginfod client connection context handle. */ +void debuginfod_end (debuginfod_client *client); + +#ifdef __cplusplus +} +#endif + + +#endif /* _DEBUGINFOD_CLIENT_H */ diff --git a/debuginfod/libdebuginfod.map b/debuginfod/libdebuginfod.map new file mode 100644 index 00000000..7d2f5882 --- /dev/null +++ b/debuginfod/libdebuginfod.map @@ -0,0 +1,20 @@ +ELFUTILS_0 { }; +ELFUTILS_0.178 { + global: + debuginfod_begin; + debuginfod_end; + debuginfod_find_debuginfo; + debuginfod_find_executable; + debuginfod_find_source; + debuginfod_set_progressfn; +} ELFUTILS_0; +ELFUTILS_0.179 { + global: + debuginfod_set_user_data; + debuginfod_get_user_data; + debuginfod_get_url; + debuginfod_add_http_header; +} ELFUTILS_0.178; +ELFUTILS_0.183 { + debuginfod_set_verbose_fd; +} ELFUTILS_0.179; diff --git a/doc/COPYING-GFDL b/doc/COPYING-GFDL new file mode 100644 index 00000000..98310abe --- /dev/null +++ b/doc/COPYING-GFDL @@ -0,0 +1,455 @@ +This license applies to the eu-readelf.1 man page which was forked +from the binutils readelf version of the man page. The rest of the +documentation is provided under the license found in the top level +directory. + + GNU Free Documentation License + Version 1.3, 3 November 2008 + + + Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The "publisher" means any person or entity that distributes copies of +the Document to the public. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no +other conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to +give them a chance to provide you with an updated version of the +Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other +documents released under this License, and replace the individual +copies of this License in the various documents with a single copy +that is included in the collection, provided that you follow the rules +of this License for verbatim copying of each of the documents in all +other respects. + +You may extract a single document from such a collection, and +distribute it individually under this License, provided you insert a +copy of this License into the extracted document, and follow this +License in all other respects regarding verbatim copying of that +document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions of the +GNU Free Documentation License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. See +https://www.gnu.org/licenses/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +11. RELICENSING + +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +"Massive Multiauthor Collaboration" (or "MMC") contained in the site +means any set of copyrightable works thus published on the MMC site. + +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +"Incorporate" means to publish or republish a Document, in whole or in +part, as part of another Document. + +An MMC is "eligible for relicensing" if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole or +in part into the MMC, (1) had no cover texts or invariant sections, and +(2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/doc/ChangeLog b/doc/ChangeLog new file mode 100644 index 00000000..05fcd23d --- /dev/null +++ b/doc/ChangeLog @@ -0,0 +1,201 @@ +2021-04-23 Frank Ch. Eigler + + PR27701 + * debuginfod_find_debuginfo.3: Specify sequential reuse policy of + debuginfod_client objects. + +2021-02-04 Frank Ch. Eigler + + * debuginfod.8: Mention new --fdcache-mintmp option. + +2020-12-11 Dmitry V. Levin + + * debuginfod.8: Fix spelling typos. + * debuginfod_find_debuginfo.3: Likewise. + * elfutils.sgml: Likewise. + * readelf.1: Likewise. + +2020-12-06 Dmitry V. Levin + + * debuginfod_find_debuginfo.3: Document DEBUGINFOD_SONAME macro. + +2020-11-11 Mark Wielaard + + * debuginfod_find_debuginfo.3: Document debuginfod_set_verbose_fd + and DEBUGINFOD_VERBOSE. + * debuginfod_set_verbose_fd.3: New redirect to + debuginfod_find_debuginfo.3 + +2020-10-29 Frank Ch. Eigler + + PR26775 + * debuginfod.8: Document that SIGUSR1 interrupts the groom + cycle, and SIGUSR2 interrupts rescan. + +2020-10-25 Mark Wielaard + + * debuginfod_find_debuginfo.3 (ECONNREFUSED): Document that this + is also returned for a bad HTTPS server certificate. + +2020-10-07 Frank Ch. Eigler + + * debuginfod-find.1: Add missing .br for SYNOPSIS section. + +2020-06-19 Mark Wielaard + + * Makefile.am: Guard all client manpages with LIBDEBUGINFOD. + +2020-03-29 Mark Wielaard + + * debuginfod_find_debuginfo.3 (HTTP HEADER): Document the expected + header format and purpose. + +2020-03-28 Frank Ch. Eigler + + * debuginfod.8: Document valid --port=NUM range, excludes 0. + +2020-03-27 Frank Ch. Eigler + + * debuginfod-find.1: Document /path/-based buildid passing. + +2020-03-24 Frank Ch. Eigler + + * debuginfod_add_http_header.3: New function, documented ... + * debuginfod_find_debuginfo.3: ... here. + * Makefile.am (notrans_dist_*_man3): Add it. + +2020-03-26 Frank Ch. Eigler + + * debuginfod.8 (-R): Note zstd compression complications + and workaround. + +2020-03-24 Frank Ch. Eigler + + * debuginfod-find.1, debuginfod_find_debuginfo.3: Document + source path canonicalization. + +2020-03-22 Frank Ch. Eigler + + * debuginfod_get_url.3: New function, documented ... + * debuginfod_find_debuginfo.3: ... here. + * Makefile.am (notrans_dist_*_man3): Add it. + +2020-03-22 Frank Ch. Eigler + + * debuginfod_get_user.3, _set_user.3: New functions, documented ... + * debuginfod_find_debuginfo.3: ... here. + * Makefile.am (notrans_dist_*_man3): List all debuginfod .3 functions. + +2020-02-25 Frank Ch. Eigler + + * debuginfod.8: Note that -R works just like -Z.rpm . + +2020-02-25 Frank Ch. Eigler + + * debuginfod.8: Document new --fdcache-prefetch option. + +2020-02-05 Frank Ch. Eigler + + * debuginfod.8: Document new -Z flag and tweak other bits. + +2020-01-10 Mark Wielaard + + * debuginfod_find_debuginfo.3 (DEBUGINFOD_PROGRESS): Mention progress + output goes to stderr. + +2020-01-11 Frank Ch. Eigler + + * debuginfod.8: Rework sections dealing with traversal/scanning, + explaining new threading model. + +2020-01-02 Mark Wielaard + + * debuginfod.8 (DEBUGINFOD_TIMEOUT): Document as seconds to + provide 100K, default 90. + * debuginfod-find.1 (DEBUGINFOD_TIMEOUT): Likewise. + * debuginfod_find_debuginfo.3 (DEBUGINFOD_TIMEOUT): Likewise. + +2019-12-22 Frank Ch. Eigler + + * debuginfod-find.1: Bump default timeout to 30. + * debuginfod_find_debuginfo.3: Ditto. + Document $DEBUGINFOD_PROGRESS. + +2019-11-26 Frank Ch. Eigler + Aaron Merey + + * debuginfod.8, find-debuginfo.1, debuginfod_*.3: New files. + +2019-09-02 Mark Wielaard + + * readelf.1 (symbols): Add optional section name. + (dyn-sym): Document new option. + +2019-08-28 Mark Wielaard + + * COPYING: Rename to... + * COPYING-GFDL: ... this. + +2019-08-23 Ben Woodard + + * Updated the eu-readelf man page to make it match the options + that eu-readelf actually supports. + +2019-08-22 Ben Woodard S + + * Move the .1 man pages to the correct place. + +2019-08-21 Ben Woodard + + * Updated Changelog + * Added README + +2019-08-20 Ben Woodard + + * Added eu-elfclassify.1 man page based upon --help + * Forked binutils readelf page to make eu-readelf.1 man page + * Modified eu-readelf.1 to add -n:: option. + * Disabled sgml file building per mjw. + * Added man pages to Makefile.am + +2019-06-20 Ben Woodard + + * Added the beginnings of some man pages + +2019-08-21 Ben Woodard + + * Updated Changelog + * Added README + +2019-08-20 Ben Woodard + + * Added eu-elfclassify.1 man page based upon --help + * Forked binutils readelf page to make eu-readelf.1 man page + * Modified eu-readelf.1 to add -n:: option. + * Disabled sgml file building per mjw. + * Added man pages to Makefile.am + +2019-06-20 Ben Woodard + + * Added the beginnings of some man pages + +2005-04-29 Ulrich Drepper + + * elfutils.sgml: Some typo fixes and a few extensions. + Patch by Eric Christopher . + +2005-02-22 Ulrich Drepper + + * Makefile.am: Prefer pdf. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 00000000..ef66fb88 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,41 @@ +## Process this file with automake to create Makefile.in +## Configure input file for elfutils. +## +## Copyright (C) 1996-2001, 2002, 2005, 2019-2020 Red Hat, Inc. +## This file is part of elfutils. +## +## 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 3 of the License, or +## (at your option) any later version. +## +## elfutils 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, see . +EXTRA_DIST = COPYING-GFDL README +dist_man1_MANS=readelf.1 elfclassify.1 +notrans_dist_man3_MANS=elf_update.3 elf_getdata.3 elf_clone.3 elf_begin.3 +notrans_dist_man8_MANS= +notrans_dist_man1_MANS= + +if DEBUGINFOD +notrans_dist_man8_MANS += debuginfod.8 +endif + +if LIBDEBUGINFOD +notrans_dist_man3_MANS += debuginfod_add_http_header.3 +notrans_dist_man3_MANS += debuginfod_begin.3 +notrans_dist_man3_MANS += debuginfod_end.3 +notrans_dist_man3_MANS += debuginfod_find_debuginfo.3 +notrans_dist_man3_MANS += debuginfod_find_executable.3 +notrans_dist_man3_MANS += debuginfod_find_source.3 +notrans_dist_man3_MANS += debuginfod_get_user_data.3 +notrans_dist_man3_MANS += debuginfod_get_url.3 +notrans_dist_man3_MANS += debuginfod_set_progressfn.3 +notrans_dist_man3_MANS += debuginfod_set_user_data.3 +notrans_dist_man1_MANS += debuginfod-find.1 +endif diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 00000000..d387101b --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,697 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@DEBUGINFOD_TRUE@am__append_1 = debuginfod.8 +@LIBDEBUGINFOD_TRUE@am__append_2 = debuginfod_add_http_header.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_begin.3 debuginfod_end.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_find_debuginfo.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_find_executable.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_find_source.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_get_user_data.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_get_url.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_set_progressfn.3 \ +@LIBDEBUGINFOD_TRUE@ debuginfod_set_user_data.3 +@LIBDEBUGINFOD_TRUE@am__append_3 = debuginfod-find.1 +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(man8dir)" +man3dir = $(mandir)/man3 +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(dist_man1_MANS) $(notrans_dist_man1_MANS) $(notrans_dist_man3_MANS) $(notrans_dist_man8_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(dist_man1_MANS) $(notrans_dist_man1_MANS) \ + $(notrans_dist_man3_MANS) $(notrans_dist_man8_MANS) \ + $(srcdir)/Makefile.in ChangeLog README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +EXTRA_DIST = COPYING-GFDL README +dist_man1_MANS = readelf.1 elfclassify.1 +notrans_dist_man3_MANS = elf_update.3 elf_getdata.3 elf_clone.3 \ + elf_begin.3 $(am__append_2) +notrans_dist_man8_MANS = $(am__append_1) +notrans_dist_man1_MANS = $(am__append_3) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-man1: $(dist_man1_MANS) $(notrans_dist_man1_MANS) + @$(NORMAL_INSTALL) + @list1='$(notrans_dist_man1_MANS)'; \ + list2=''; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed 'n;s,.*/,,;p;s,\.[^1][0-9a-z]*$$,.1,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + @list1='$(dist_man1_MANS)'; \ + list2=''; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(notrans_dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed 's,.*/,,;s,\.[^1][0-9a-z]*$$,.1,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man3: $(notrans_dist_man3_MANS) + @$(NORMAL_INSTALL) + @list1='$(notrans_dist_man3_MANS)'; \ + list2=''; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed 'n;s,.*/,,;p;s,\.[^3][0-9a-z]*$$,.3,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(notrans_dist_man3_MANS)'; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed 's,.*/,,;s,\.[^3][0-9a-z]*$$,.3,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-man8: $(notrans_dist_man8_MANS) + @$(NORMAL_INSTALL) + @list1='$(notrans_dist_man8_MANS)'; \ + list2=''; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed 'n;s,.*/,,;p;s,\.[^8][0-9a-z]*$$,.8,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(notrans_dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed 's,.*/,,;s,\.[^8][0-9a-z]*$$,.8,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 install-man3 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + +uninstall-man: uninstall-man1 uninstall-man3 uninstall-man8 + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man1 install-man3 \ + install-man8 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ + uninstall uninstall-am uninstall-man uninstall-man1 \ + uninstall-man3 uninstall-man8 + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/README b/doc/README new file mode 100644 index 00000000..67f61fac --- /dev/null +++ b/doc/README @@ -0,0 +1,20 @@ +The elfutils documentation is very much a work in +progress. Contributions are welcome. +Please reports bugs at https://sourceware.org/bugzilla/ +Please send additions and patches to: elfutils-devel@sourceware.org + +The elfutils utilities are a new implementation of many of the +utilities found in binutils and consequently, the documentation for +most of the tools has been the the man pages for binutils. For example +you could refer to readelf's man page for instructions on +eu-readelf. This has been fine up until this point but as tools gain +new capabilities, they will need to have their own individual man +page. Forking the man pages from binutils is acceptable and the +current plan of action. + +New utilities that do not have an analog in binutils can have their +initial man pages generated using a tool like help2man. + +The C language interfaces for libelf, libdw, and libdwfl are in +particular need of documentation. The aspirational goal is write these +in sphinx. \ No newline at end of file diff --git a/doc/debuginfod-find.1 b/doc/debuginfod-find.1 new file mode 100644 index 00000000..12d4ec2d --- /dev/null +++ b/doc/debuginfod-find.1 @@ -0,0 +1,160 @@ +'\"! tbl | nroff \-man +'\" t macro stdmacro + +.de SAMPLE +.br +.RS 0 +.nf +.nh +.. +.de ESAMPLE +.hy +.fi +.RE +.. + +.TH DEBUGINFOD-FIND 1 +.SH NAME +debuginfod-find \- request debuginfo-related data + +.SH SYNOPSIS +.B debuginfod-find [\fIOPTION\fP]... debuginfo \fIBUILDID\fP +.br +.B debuginfod-find [\fIOPTION\fP]... debuginfo \fIPATH\fP +.br +.B debuginfod-find [\fIOPTION\fP]... executable \fIBUILDID\fP +.br +.B debuginfod-find [\fIOPTION\fP]... executable \fIPATH\fP +.br +.B debuginfod-find [\fIOPTION\fP]... source \fIBUILDID\fP \fI/FILENAME\fP +.br +.B debuginfod-find [\fIOPTION\fP]... source \fIPATH\fP \fI/FILENAME\fP + +.SH DESCRIPTION +\fBdebuginfod-find\fP queries one or more \fBdebuginfod\fP servers for +debuginfo-related data. In case of a match, it saves the the +requested file into a local cache, prints the file name to standard +output, and exits with a success status of 0. In case of any error, +it exits with a failure status and an error message to standard error. + +.\" Much of the following text is duplicated with debuginfod.8 + +The debuginfod system uses buildids to identify debuginfo-related data. +These are stored as binary notes in ELF/DWARF files, and are +represented as lowercase hexadecimal. For example, for a program +/bin/ls, look at the ELF note GNU_BUILD_ID: + +.SAMPLE +% readelf -n /bin/ls | grep -A4 build.id +Note section [ 4] '.note.gnu.buildid' of 36 bytes at offset 0x340: +Owner Data size Type +GNU 20 GNU_BUILD_ID +Build ID: 8713b9c3fb8a720137a4a08b325905c7aaf8429d +.ESAMPLE + +Then the hexadecimal BUILDID is simply: + +.SAMPLE +8713b9c3fb8a720137a4a08b325905c7aaf8429d +.ESAMPLE + +In place of the hexadecimal \fIBUILDID\fP, debuginfod-find also +accepts a path name to to an ELF binary, from which it extracts the +buildid. In this case, ensure the file name has some character other +than \fB[0-9a-f]\fP. Files ambiguously named files like +"\fBdeadbeef\fP" can be passed with a \fB./deadbeef\fP extra path +component. + + +.SS debuginfo \fIBUILDID\fP + +If the given buildid is known to a server, this request will result +in a binary object that contains the customary \fB.*debug_*\fP +sections. This may be a split debuginfo file as created by +\fBstrip\fP, or it may be an original unstripped executable. + +.SS executable \fIBUILDID\fP + +If the given buildid is known to the server, this request will result +in a binary object that contains the normal executable segments. This +may be a executable stripped by \fBstrip\fP, or it may be an original +unstripped executable. \fBET_DYN\fP shared libraries are considered +to be a type of executable. + +.SS source \fIBUILDID\fP \fI/SOURCE/FILE\fP + +If the given buildid is known to the server, this request will result +in a binary object that contains the source file mentioned. The path +should be absolute. Relative path names commonly appear in the DWARF +file's source directory, but these paths are relative to +individual compilation unit AT_comp_dir paths, and yet an executable +is made up of multiple CUs. Therefore, to disambiguate, debuginfod +expects source queries to prefix relative path names with the CU +compilation-directory, followed by a mandatory "/". + +Note: the caller may or may not elide \fB../\fP or \fB/./\fP or extraneous +\fB///\fP sorts of path components in the directory names. debuginfod +accepts both forms. Specifically, debuginfod canonicalizes path names +according to RFC3986 section 5.2.4 (Remove Dot Segments), plus reducing +any \fB//\fP to \fB/\fP in the path. + +For example: +.TS +l l. +#include source BUILDID /usr/include/stdio.h +/path/to/foo.c source BUILDID /path/to/foo.c +\../bar/foo.c AT_comp_dir=/zoo/ source BUILDID /zoo//../bar/foo.c +.TE + +.SH "OPTIONS" + +.TP +.B "\-v" +Increase verbosity, including printing frequent download-progress messages. + + +.SH "SECURITY" + +debuginfod-find \fBdoes not\fP include any particular security +features. It trusts that the binaries returned by the debuginfod(s) +are accurate. Therefore, the list of servers should include only +trustworthy ones. If accessed across HTTP rather than HTTPS, the +network should be trustworthy. Authentication information through +the internal \fIlibcurl\fP library is not currently enabled, except +for the basic plaintext \%\fIhttp[s]://userid:password@hostname/\fP style. +(The debuginfod server does not perform authentication, but a front-end +proxy server could.) + +.SH "ENVIRONMENT VARIABLES" + +.TP 21 +.B DEBUGINFOD_URLS +This environment variable contains a list of URL prefixes for trusted +debuginfod instances. Alternate URL prefixes are separated by space. + +.TP 21 +.B DEBUGINFOD_TIMEOUT +This environment variable governs the timeout for each debuginfod HTTP +connection. A server that fails to provide at least 100K of data +within this many seconds is skipped. The default is 90 seconds. (Zero +or negative means "no timeout".) + +.TP 21 +.B DEBUGINFOD_CACHE_PATH +This environment variable governs the location of the cache where +downloaded files are kept. It is cleaned periodically as this program +is reexecuted. Cache management parameters may be set by files under +this directory: see the \fBdebuginfod_find_debuginfo(3)\fP man page +for details. The default is $HOME/.debuginfod_client_cache. + +.SH "FILES" +.LP +.PD .1v +.TP 20 +.B $HOME/.debuginfod_client_cache +Default cache directory. +.PD + +.SH "SEE ALSO" +.I "debuginfod(8)" +.I "debuginfod_find_debuginfod(3)" diff --git a/doc/debuginfod.8 b/doc/debuginfod.8 new file mode 100644 index 00000000..1ba42cf6 --- /dev/null +++ b/doc/debuginfod.8 @@ -0,0 +1,455 @@ +'\"! tbl | nroff \-man +'\" t macro stdmacro + +.de SAMPLE +.br +.RS 0 +.nf +.nh +.. +.de ESAMPLE +.hy +.fi +.RE +.. + +.TH DEBUGINFOD 8 +.SH NAME +debuginfod \- debuginfo-related http file-server daemon + +.SH SYNOPSIS +.B debuginfod +[\fIOPTION\fP]... [\fIPATH\fP]... + +.SH DESCRIPTION +\fBdebuginfod\fP serves debuginfo-related artifacts over HTTP. It +periodically scans a set of directories for ELF/DWARF files and their +associated source code, as well as archive files containing the above, to +build an index by their buildid. This index is used when remote +clients use the HTTP webapi, to fetch these files by the same buildid. + +If a debuginfod cannot service a given buildid artifact request +itself, and it is configured with information about upstream +debuginfod servers, it queries them for the same information, just as +\fBdebuginfod-find\fP would. If successful, it locally caches then +relays the file content to the original requester. + +Indexing the given PATHs proceeds using multiple threads. One thread +periodically traverses all the given PATHs logically or physically +(see the \fB\-L\fP option). Duplicate PATHs are ignored. You may use +a file name for a PATH, but source code indexing may be incomplete; +prefer using a directory that contains the binaries. The traversal +thread enumerates all matching files (see the \fB\-I\fP and \fB\-X\fP +options) into a work queue. A collection of scanner threads (see the +\fB\-c\fP option) wait at the work queue to analyze files in parallel. + +If the \fB\-F\fP option is given, each file is scanned as an ELF/DWARF +file. Source files are matched with DWARF files based on the +AT_comp_dir (compilation directory) attributes inside it. Caution: +source files listed in the DWARF may be a path \fIanywhere\fP in the +file system, and debuginfod will readily serve their content on +demand. (Imagine a doctored DWARF file that lists \fI/etc/passwd\fP +as a source file.) If this is a concern, audit your binaries with +tools such as: + +.SAMPLE +% eu-readelf -wline BINARY | sed -n '/^Directory.table/,/^File.name.table/p' +or +% eu-readelf -wline BINARY | sed -n '/^Directory.table/,/^Line.number/p' +or even use debuginfod itself: +% debuginfod -vvv -d :memory: -F BINARY 2>&1 | grep 'recorded.*source' +^C +.ESAMPLE + +If any of the \fB\-R\fP, \fB-U\fP, or \fB-Z\fP options is given, each +file is scanned as an archive file that may contain ELF/DWARF/source +files. Archive files are recognized by extension. If \-R is given, +".rpm" files are scanned; if \-U is given, ".deb" and ".ddeb" files +are scanned; if \-Z is given, the listed extensions are scanned. +Because of complications such as DWZ-compressed debuginfo, may require +\fItwo\fP traversal passes to identify all source code. Source files +for RPMs are only served from other RPMs, so the caution for \-F does +not apply. Note that due to Debian/Ubuntu packaging policies & +mechanisms, debuginfod cannot resolve source files for DEB/DDEB at +all. + +If no PATH is listed, or none of the scanning options is given, then +\fBdebuginfod\fP will simply serve content that it accumulated into +its index in all previous runs, and federate to any upstream +debuginfod servers. + + +.SH OPTIONS + +.TP +.B "\-F" +Activate ELF/DWARF file scanning. The default is off. + +.TP +.B "\-Z EXT" "\-Z EXT=CMD" +Activate an additional pattern in archive scanning. Files with name +extension EXT (include the dot) will be processed. If CMD is given, +it is invoked with the file name added to its argument list, and +should produce a common archive on its standard output. Otherwise, +the file is read as if CMD were "cat". Since debuginfod internally +uses \fBlibarchive\fP to read archive files, it can accept a wide +range of archive formats and compression modes. The default is no +additional patterns. This option may be repeated. + +.TP +.B "\-R" +Activate RPM patterns in archive scanning. The default is off. +Equivalent to \fB\%\-Z\~.rpm=cat\fP, since libarchive can natively +process RPM archives. If your version of libarchive is much older +than 2020, be aware that some distributions have switched to an +incompatible zstd compression for their payload. You may experiment +with \fB\%\-Z\ .rpm='(rpm2cpio|zstdcat)<'\fP instead of \fB\-R\fP. + +.TP +.B "\-U" +Activate DEB/DDEB patterns in archive scanning. The default is off. +Equivalent to \fB\%\-Z\ .deb='dpkg-deb\ \-\-fsys\-tarfile\fP' +\fB\%\-Z\ .ddeb='dpkg-deb\ \-\-fsys\-tarfile'\fP. + +.TP +.B "\-d FILE" "\-\-database=FILE" +Set the path of the sqlite database used to store the index. This +file is disposable in the sense that a later rescan will repopulate +data. It will contain absolute file path names, so it may not be +portable across machines. It may be frequently read/written, so it +should be on a fast filesystem. It should not be shared across +machines or users, to maximize sqlite locking performance. The +default database file is \%$HOME/.debuginfod.sqlite. + +.TP +.B "\-D SQL" "\-\-ddl=SQL" +Execute given sqlite statement after the database is opened and +initialized as extra DDL (SQL data definition language). This may be +useful to tune performance-related pragmas or indexes. May be +repeated. The default is nothing extra. + +.TP +.B "\-p NUM" "\-\-port=NUM" +Set the TCP port number (0 < NUM < 65536) on which debuginfod should +listen, to service HTTP requests. Both IPv4 and IPV6 sockets are +opened, if possible. The webapi is documented below. The default +port number is 8002. + +.TP +.B "\-I REGEX" "\-\-include=REGEX" "\-X REGEX" "\-\-exclude=REGEX" +Govern the inclusion and exclusion of file names under the search +paths. The regular expressions are interpreted as unanchored POSIX +extended REs, thus may include alternation. They are evaluated +against the full path of each file, based on its \fBrealpath(3)\fP +canonicalization. By default, all files are included and none are +excluded. A file that matches both include and exclude REGEX is +excluded. (The \fIcontents\fP of archive files are not subject to +inclusion or exclusion filtering: they are all processed.) Only the +last of each type of regular expression given is used. + +.TP +.B "\-t SECONDS" "\-\-rescan\-time=SECONDS" +Set the rescan time for the file and archive directories. This is the +amount of time the traversal thread will wait after finishing a scan, +before doing it again. A rescan for unchanged files is fast (because +the index also stores the file mtimes). A time of zero is acceptable, +and means that only one initial scan should performed. The default +rescan time is 300 seconds. Receiving a SIGUSR1 signal triggers a new +scan, independent of the rescan time (including if it was zero), +interrupting a groom pass (if any). + +.TP +.B "\-g SECONDS" "\-\-groom\-time=SECONDS" +Set the groom time for the index database. This is the amount of time +the grooming thread will wait after finishing a grooming pass before +doing it again. A groom operation quickly rescans all previously +scanned files, only to see if they are still present and current, so +it can deindex obsolete files. See also the \fIDATA MANAGEMENT\fP +section. The default groom time is 86400 seconds (1 day). A time of +zero is acceptable, and means that only one initial groom should be +performed. Receiving a SIGUSR2 signal triggers a new grooming pass, +independent of the groom time (including if it was zero), interrupting +a rescan pass (if any).. + +.TP +.B "\-G" +Run an extraordinary maximal-grooming pass at debuginfod startup. +This pass can take considerable time, because it tries to remove any +debuginfo-unrelated content from the archive-related parts of the index. +It should not be run if any recent archive-related indexing operations +were aborted early. It can take considerable space, because it +finishes up with an sqlite "vacuum" operation, which repacks the +database file by triplicating it temporarily. The default is not to +do maximal-grooming. See also the \fIDATA MANAGEMENT\fP section. + +.TP +.B "\-c NUM" "\-\-concurrency=NUM" +Set the concurrency limit for the scanning queue threads, which work +together to process archives & files located by the traversal thread. +This important for controlling CPU-intensive operations like parsing +an ELF file and especially decompressing archives. The default is the +number of processors on the system; the minimum is 1. + +.TP +.B "\-L" +Traverse symbolic links encountered during traversal of the PATHs, +including across devices - as in \fIfind\ -L\fP. The default is to +traverse the physical directory structure only, stay on the same +device, and ignore symlinks - as in \fIfind\ -P\ -xdev\fP. Caution: a +loops in the symbolic directory tree might lead to \fIinfinite +traversal\fP. + +.TP +.B "\-\-fdcache\-fds=NUM" "\-\-fdcache\-mbs=MB" "\-\-fdcache\-prefetch=NUM2" +Configure limits on a cache that keeps recently extracted files from +archives. Up to NUM requested files and up to a total of MB megabytes +will be kept extracted, in order to avoid having to decompress their +archives over and over again. In addition, up to NUM2 other files +from an archive may be prefetched into the cache before they are even +requested. The default NUM, NUM2, and MB values depend on the +concurrency of the system, and on the available disk space on the +$TMPDIR or \fB/tmp\fP filesystem. This is because that is where the +most recently used extracted files are kept. Grooming cleans this +cache. + +.TP +.B "\-\-fdcache\-mintmp=NUM" +Configure a disk space threshold for emergency flushing of the cache. +The filesystem holding the cache is checked periodically. If the +available space falls below the given percentage, the cache is +flushed, and the fdcache will stay disabled until the next groom +cycle. This mechanism, along a few associated /metrics on the webapi, +are intended to give an operator notice about storage scarcity - which +can translate to RAM scarcity if the disk happens to be on a RAM +virtual disk. The default threshold is 25%. + +.TP +.B "\-v" +Increase verbosity of logging to the standard error file descriptor. +May be repeated to increase details. The default verbosity is 0. + +.SH WEBAPI + +.\" Much of the following text is duplicated with debuginfod-find.1 + +debuginfod's webapi resembles ordinary file service, where a GET +request with a path containing a known buildid results in a file. +Unknown buildid / request combinations result in HTTP error codes. +This file service resemblance is intentional, so that an installation +can take advantage of standard HTTP management infrastructure. + +There are three requests. In each case, the buildid is encoded as a +lowercase hexadecimal string. For example, for a program \fI/bin/ls\fP, +look at the ELF note GNU_BUILD_ID: + +.SAMPLE +% readelf -n /bin/ls | grep -A4 build.id +Note section [ 4] '.note.gnu.buildid' of 36 bytes at offset 0x340: +Owner Data size Type +GNU 20 GNU_BUILD_ID +Build ID: 8713b9c3fb8a720137a4a08b325905c7aaf8429d +.ESAMPLE + +Then the hexadecimal BUILDID is simply: + +.SAMPLE +8713b9c3fb8a720137a4a08b325905c7aaf8429d +.ESAMPLE + +.SS /buildid/\fIBUILDID\fP/debuginfo + +If the given buildid is known to the server, this request will result +in a binary object that contains the customary \fB.*debug_*\fP +sections. This may be a split debuginfo file as created by +\fBstrip\fP, or it may be an original unstripped executable. + +.SS /buildid/\fIBUILDID\fP/executable + +If the given buildid is known to the server, this request will result +in a binary object that contains the normal executable segments. This +may be a executable stripped by \fBstrip\fP, or it may be an original +unstripped executable. \fBET_DYN\fP shared libraries are considered +to be a type of executable. + +.SS /buildid/\fIBUILDID\fP/source\fI/SOURCE/FILE\fP + +If the given buildid is known to the server, this request will result +in a binary object that contains the source file mentioned. The path +should be absolute. Relative path names commonly appear in the DWARF +file's source directory, but these paths are relative to +individual compilation unit AT_comp_dir paths, and yet an executable +is made up of multiple CUs. Therefore, to disambiguate, debuginfod +expects source queries to prefix relative path names with the CU +compilation-directory, followed by a mandatory "/". + +Note: the caller may or may not elide \fB../\fP or \fB/./\fP or extraneous +\fB///\fP sorts of path components in the directory names. debuginfod +accepts both forms. Specifically, debuginfod canonicalizes path names +according to RFC3986 section 5.2.4 (Remove Dot Segments), plus reducing +any \fB//\fP to \fB/\fP in the path. + +For example: +.TS +l l. +#include /buildid/BUILDID/source/usr/include/stdio.h +/path/to/foo.c /buildid/BUILDID/source/path/to/foo.c +\../bar/foo.c AT_comp_dir=/zoo/ /buildid/BUILDID/source/zoo//../bar/foo.c +.TE + +.SS /metrics + +This endpoint returns a Prometheus formatted text/plain dump of a +variety of statistics about the operation of the debuginfod server. +The exact set of metrics and their meanings may change in future +versions. Caution: configuration information (path names, versions) +may be disclosed. + +.SH DATA MANAGEMENT + +debuginfod stores its index in an sqlite database in a densely packed +set of interlinked tables. While the representation is as efficient +as we have been able to make it, it still takes a considerable amount +of data to record all debuginfo-related data of potentially a great +many files. This section offers some advice about the implications. + +As a general explanation for size, consider that debuginfod indexes +ELF/DWARF files, it stores their names and referenced source file +names, and buildids will be stored. When indexing archives, it stores +every file name \fIof or in\fP an archive, every buildid, plus every +source file name referenced from a DWARF file. (Indexing archives +takes more space because the source files often reside in separate +subpackages that may not be indexed at the same pass, so extra +metadata has to be kept.) + +Getting down to numbers, in the case of Fedora RPMs (essentially, +gzip-compressed cpio files), the sqlite index database tends to be +from 0.5% to 3% of their size. It's larger for binaries that are +assembled out of a great many source files, or packages that carry +much debuginfo-unrelated content. It may be even larger during the +indexing phase due to temporary sqlite write-ahead-logging files; +these are checkpointed (cleaned out and removed) at shutdown. It may +be helpful to apply tight \-I or \-X regular-expression constraints to +exclude files from scanning that you know have no debuginfo-relevant +content. + +As debuginfod runs, it periodically rescans its target directories, +and any new content found is added to the database. Old content, such +as data for files that have disappeared or that have been replaced +with newer versions is removed at a periodic \fIgrooming\fP pass. +This means that the sqlite files grow fast during initial indexing, +slowly during index rescans, and periodically shrink during grooming. +There is also an optional one-shot \fImaximal grooming\fP pass is +available. It removes information debuginfo-unrelated data from the +archive content index such as file names found in archives ("archive +sdef" records) that are not referred to as source files from any +binaries find in archives ("archive sref" records). This can save +considerable disk space. However, it is slow and temporarily requires +up to twice the database size as free space. Worse: it may result in +missing source-code info if the archive traversals were interrupted, +so that not all source file references were known. Use it rarely to +polish a complete index. + +You should ensure that ample disk space remains available. (The flood +of error messages on -ENOSPC is ugly and nagging. But, like for most +other errors, debuginfod will resume when resources permit.) If +necessary, debuginfod can be stopped, the database file moved or +removed, and debuginfod restarted. + +sqlite offers several performance-related options in the form of +pragmas. Some may be useful to fine-tune the defaults plus the +debuginfod extras. The \-D option may be useful to tell debuginfod to +execute the given bits of SQL after the basic schema creation +commands. For example, the "synchronous", "cache_size", +"auto_vacuum", "threads", "journal_mode" pragmas may be fun to tweak +via \-D, if you're searching for peak performance. The "optimize", +"wal_checkpoint" pragmas may be useful to run periodically, outside +debuginfod. The default settings are performance- rather than +reliability-oriented, so a hardware crash might corrupt the database. +In these cases, it may be necessary to manually delete the sqlite +database and start over. + +As debuginfod changes in the future, we may have no choice but to +change the database schema in an incompatible manner. If this +happens, new versions of debuginfod will issue SQL statements to +\fIdrop\fP all prior schema & data, and start over. So, disk space +will not be wasted for retaining a no-longer-useable dataset. + +In summary, if your system can bear a 0.5%-3% index-to-archive-dataset +size ratio, and slow growth afterwards, you should not need to +worry about disk space. If a system crash corrupts the database, +or you want to force debuginfod to reset and start over, simply +erase the sqlite file before restarting debuginfod. + + +.SH SECURITY + +debuginfod \fBdoes not\fP include any particular security features. +While it is robust with respect to inputs, some abuse is possible. It +forks a new thread for each incoming HTTP request, which could lead to +a denial-of-service in terms of RAM, CPU, disk I/O, or network I/O. +If this is a problem, users are advised to install debuginfod with a +HTTPS reverse-proxy front-end that enforces site policies for +firewalling, authentication, integrity, authorization, and load +control. The \fI/metrics\fP webapi endpoint is probably not +appropriate for disclosure to the public. + +When relaying queries to upstream debuginfods, debuginfod \fBdoes not\fP +include any particular security features. It trusts that the binaries +returned by the debuginfods are accurate. Therefore, the list of +servers should include only trustworthy ones. If accessed across HTTP +rather than HTTPS, the network should be trustworthy. Authentication +information through the internal \fIlibcurl\fP library is not currently +enabled. + + +.SH "ENVIRONMENT VARIABLES" + +.TP +.B TMPDIR +This environment variable points to a file system to be used for +temporary files. The default is /tmp. + +.TP +.B DEBUGINFOD_URLS +This environment variable contains a list of URL prefixes for trusted +debuginfod instances. Alternate URL prefixes are separated by space. +Avoid referential loops that cause a server to contact itself, directly +or indirectly - the results would be hilarious. + +.TP +.B DEBUGINFOD_TIMEOUT +This environment variable governs the timeout for each debuginfod HTTP +connection. A server that fails to provide at least 100K of data +within this many seconds is skipped. The default is 90 seconds. (Zero +or negative means "no timeout".) + + +.TP +.B DEBUGINFOD_CACHE_PATH +This environment variable governs the location of the cache where +downloaded files are kept. It is cleaned periodically as this +program is reexecuted. If XDG_CACHE_HOME is set then +$XDG_CACHE_HOME/debuginfod_client is the default location, otherwise +$HOME/.cache/debuginfod_client is used. For more information regarding +the client cache see \fIdebuginfod_find_debuginfo(3)\fP. + +.SH FILES +.LP +.PD .1v +.TP 20 +.B $HOME/.debuginfod.sqlite +Default database file. +.PD + +.TP 20 +.B $XDG_CACHE_HOME/debuginfod_client +Default cache directory for content from upstream debuginfods. +If XDG_CACHE_HOME is not set then \fB$HOME/.cache/debuginfod_client\fP +is used. +.PD + + +.SH "SEE ALSO" +.I "debuginfod-find(1)" +.I "sqlite3(1)" +.I \%https://prometheus.io/docs/instrumenting/exporters/ diff --git a/doc/debuginfod_add_http_header.3 b/doc/debuginfod_add_http_header.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_add_http_header.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_begin.3 b/doc/debuginfod_begin.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_begin.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_end.3 b/doc/debuginfod_end.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_end.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_find_debuginfo.3 b/doc/debuginfod_find_debuginfo.3 new file mode 100644 index 00000000..5ae44a98 --- /dev/null +++ b/doc/debuginfod_find_debuginfo.3 @@ -0,0 +1,349 @@ +'\"! tbl | nroff \-man +'\" t macro stdmacro + +.de SAMPLE +.br +.RS 0 +.nf +.nh +.. +.de ESAMPLE +.hy +.fi +.RE +.. + +.TH DEBUGINFOD_FIND_* 3 +.SH NAME +debuginfod_find_debuginfo \- request debuginfo from debuginfod + +.SH SYNOPSIS +.nf +.B #include +.PP +Link with \fB-ldebuginfod\fP. + +CONNECTION HANDLE + +.BI "debuginfod_client *debuginfod_begin(void);" +.BI "void debuginfod_end(debuginfod_client *" client ");" + +LOOKUP FUNCTIONS + +.BI "int debuginfod_find_debuginfo(debuginfod_client *" client "," +.BI " const unsigned char *" build_id "," +.BI " int " build_id_len "," +.BI " char ** " path ");" +.BI "int debuginfod_find_executable(debuginfod_client *" client "," +.BI " const unsigned char *" build_id "," +.BI " int " build_id_len "," +.BI " char ** " path ");" +.BI "int debuginfod_find_source(debuginfod_client *" client "," +.BI " const unsigned char *" build_id "," +.BI " int " build_id_len "," +.BI " const char *" filename "," +.BI " char ** " path ");" + +OPTIONAL FUNCTIONS + +.BI "typedef int (*debuginfod_progressfn_t)(debuginfod_client *" client "," +.BI " long a, long b);" +.BI "void debuginfod_set_progressfn(debuginfod_client *" client "," +.BI " debuginfod_progressfn_t " progressfn ");" +.BI "void debuginfod_set_verbose_fd(debuginfod_client *" client "," +.BI " int " fd ");" +.BI "void debuginfod_set_user_data(debuginfod_client *" client "," +.BI " void *" data ");" +.BI "void* debuginfod_get_user_data(debuginfod_client *" client ");" +.BI "const char* debuginfod_get_url(debuginfod_client *" client ");" +.BI "int debuginfod_add_http_header(debuginfod_client *" client "," +.BI " const char* " header ");" + +.SH DESCRIPTION + +.BR debuginfod_begin () +creates a \fBdebuginfod_client\fP connection handle that should be used +with all other calls. +.BR debuginfod_end () +should be called on the \fBclient\fP handle to release all state and +storage when done. + +.BR debuginfod_find_debuginfo (), +.BR debuginfod_find_executable (), +and +.BR debuginfod_find_source () +query the debuginfod server URLs contained in +.BR $DEBUGINFOD_URLS +(see below) for the debuginfo, executable or source file with the +given \fIbuild_id\fP. \fIbuild_id\fP should be a pointer to either +a null-terminated, lowercase hex string or a binary blob. If +\fIbuild_id\fP is given as a hex string, \fIbuild_id_len\fP should +be 0. Otherwise \fIbuild_id_len\fP should be the number of bytes in +the binary blob. + +.BR debuginfod_find_source () +also requires a \fIfilename\fP in order to specify a particular +source file. \fIfilename\fP should be an absolute path that includes +the compilation directory of the CU associated with the source file. +Relative path names commonly appear in the DWARF file's source directory, +but these paths are relative to individual compilation unit AT_comp_dir +paths, and yet an executable is made up of multiple CUs. Therefore, to +disambiguate, debuginfod expects source queries to prefix relative path +names with the CU compilation-directory, followed by a mandatory "/". + +Note: the caller may or may not elide \fB../\fP or \fB/./\fP or extraneous +\fB///\fP sorts of path components in the directory names. debuginfod +accepts both forms. Specifically, debuginfod canonicalizes path names +according to RFC3986 section 5.2.4 (Remove Dot Segments), plus reducing +any \fB//\fP to \fB/\fP in the path. + +If \fIpath\fP is not NULL and the query is successful, \fIpath\fP is set +to the path of the file in the cache. The caller must \fBfree\fP() this value. + +The URLs in \fB$DEBUGINFOD_URLS\fP may be queried in parallel. As soon +as a debuginfod server begins transferring the target file all of the +connections to the other servers are closed. + +A \fBclient\fP handle should be used from only one thread at a time. +A handle may be reused for a series of lookups, which can improve +performance due to retention of connections and caches. + +.SH "RETURN VALUE" + +\fBdebuginfod_begin\fP returns the \fBdebuginfod_client\fP handle to +use with all other calls. On error \fBNULL\fP will be returned and +\fBerrno\fP will be set. + +If a find family function is successful, the resulting file is saved +to the client cache and a file descriptor to that file is returned. +The caller needs to \fBclose\fP() this descriptor. Otherwise, a +negative error code is returned. + +.SH "OPTIONAL FUNCTIONS" + +A small number of optional functions are available to tune or query +the operation of the debuginfod client. + +.SS "PROGRESS CALLBACK" + +As the \fBdebuginfod_find_*\fP() functions may block for seconds or +longer, a progress callback function is called periodically, if +configured with +.BR debuginfod_set_progressfn (). +This function sets a new progress callback function (or NULL) for the +client handle. + +The given callback function is called from the context of each thread +that is invoking any of the other lookup functions. It is given two +numeric parameters that, if thought of as a numerator \fIa\fP and +denominator \fIb\fP, together represent a completion fraction +\fIa/b\fP. The denominator may be zero initially, until a quantity +such as an exact download size becomes known. + +The progress callback function is also the supported way to +\fIinterrupt\fP the download operation. (The library does \fInot\fP +modify or trigger signals.) The progress callback must return 0 to +continue the work, or any other value to stop work as soon as +possible. Consequently, the \fBdebuginfod_find_*\fP() function will +likely return with an error, but might still succeed. + +.SS "VERBOSE OUTPUT" + +The \fBdebuginfod_find_*\fP() functions may use several techniques +to retrieve the requested files, through the cache or through one +or multiple servers or file URLs. To show how a query is handled the +.BR debuginfod_set_verbose_fd () +can be used to set a particular file descriptor on which verbose +output is given about the query steps and eventual errors encountered. + +.SS "USER DATA POINTER" + +A single \fIvoid *\fP pointer associated with the connection handle +may be set any time via +.BR \%debuginfod_set_user_data () , +and retrieved via +.BR \%debuginfod_get_user_data () . +The value is undefined if unset. + +.SS "URL" + +The URL of the current or most recent outgoing download, if known, +may be retrieved via +.BR \%debuginfod_get_url () +from the progressfn callback, or afterwards. It may be NULL. +The resulting string is owned by the library, and must not be modified +or freed. The caller should copy it if it is needed beyond the release +of the client object. + +.SS "HTTP HEADER" + +Before each lookup function is initiated, a client application may +add HTTP request headers. These are reset after each lookup function. +.BR \%debuginfod_add_http_header () +may be called with strings of the form +.BR \%"Header:\~value" . +These strings are copied by the library. A zero return value +indicates success, but out-of-memory conditions may result in +a non-zero \fI-ENOMEM\fP. If the string is in the wrong form +\fI-EINVAL\fP will be returned. + +Note that the current debuginfod-client library implementation uses +libcurl, but you shouldn't rely on that fact. Don't use this function +for replacing any standard headers, except for the User-Agent mentioned +below. The only supported usage of this function is for adding an +optional header which might or might not be passed through to the +server for logging purposes only. + +By default, the library adds a descriptive \fIUser-Agent:\fP +header to outgoing requests. If the client application adds +a header with the same name, this default is suppressed. + +.SH "CACHE" +If the query is successful, the \fBdebuginfod_find_*\fP() functions save +the target file to a local cache. The location of the cache is controlled +by the \fB$DEBUGINFOD_CACHE_PATH\fP environment variable (see below). +Cleaning of the cache is controlled by the \fIcache_clean_interval_s\fP +and \fImax_unused_age_s\fP files, which are found in the +\fB$DEBUGINFOD_CACHE_PATH\fP directory. \fIcache_clean_interval_s\fP controls +how frequently the cache is traversed for cleaning and \fImax_unused_age_s\fP +controls how long a file can go unused (fstat(2) atime) before it's +removed from the cache during cleaning. These files should contain only an +ASCII decimal integer representing the interval or max unused age in seconds. +The default is one day and one week, respectively. Values of zero mean "immediately". + +.SH "MACROS" + +.SS "DEBUGINFOD_SONAME" + +Defined to the string that could be passed to +.BR dlopen (3) +if the library is loaded at runtime, for example + +.PP +.in +4n +.EX +void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY); +.EE +.in + +.SH "SECURITY" +.BR debuginfod_find_debuginfo (), +.BR debuginfod_find_executable (), +and +.BR debuginfod_find_source () +\fBdo not\fP include any particular security +features. They trust that the binaries returned by the debuginfod(s) +are accurate. Therefore, the list of servers should include only +trustworthy ones. If accessed across HTTP rather than HTTPS, the +network should be trustworthy. Passing user authentication information +through the internal \fIlibcurl\fP library is not currently enabled, except +for the basic plaintext \%\fIhttp[s]://userid:password@hostname/\fP style. +(The debuginfod server does not perform authentication, but a front-end +proxy server could.) + +.SH "ENVIRONMENT VARIABLES" + +.TP 21 +.B DEBUGINFOD_URLS +This environment variable contains a list of URL prefixes for trusted +debuginfod instances. Alternate URL prefixes are separated by space. + +.TP 21 +.B DEBUGINFOD_TIMEOUT +This environment variable governs the timeout for each debuginfod HTTP +connection. A server that fails to provide at least 100K of data +within this many seconds is skipped. The default is 90 seconds. (Zero +or negative means "no timeout".) + +.TP 21 +.B DEBUGINFOD_PROGRESS +This environment variable governs the default progress function. If +set, and if a progressfn is not explicitly set, then the library will +configure a default progressfn. This function will append a simple +progress message periodically to stderr. The default is no progress +function output. + +.TP 21 +.B DEBUGINFOD_VERBOSE +This environment variable governs the default file descriptor for +verbose output. If set, and if a verbose fd is not explicitly set, +then the verbose output will be produced on STDERR_FILENO. + +.TP 21 +.B DEBUGINFOD_CACHE_PATH +This environment variable governs the location of the cache where +downloaded files are kept. It is cleaned periodically as this +program is reexecuted. If XDG_CACHE_HOME is set then +$XDG_CACHE_HOME/debuginfod_client is the default location, otherwise +$HOME/.cache/debuginfod_client is used. + + +.SH "ERRORS" +The following list is not comprehensive. Error codes may also +originate from calls to various C Library functions. + +.TP +.BR EACCESS +Denied access to resource located at the URL. + +.TP +.BR ECONNREFUSED +Unable to connect to remote host. Also returned when an HTTPS connection +couldn't be verified (bad certificate). + +.TP +.BR ECONNRESET +Unable to either send or receive network data. + +.TP +.BR EHOSTUNREACH +Unable to resolve remote host. + +.TP +.BR EINVAL +One or more arguments are incorrectly formatted. \fIbuild_id\fP may +be too long (greater than 256 characters), \fIfilename\fP may not +be an absolute path or a debuginfod URL is malformed. + +.TP +.BR EIO +Unable to write data received from server to local file. + +.TP +.BR EMLINK +Too many HTTP redirects. + +.TP +.BR ENETUNREACH +Unable to initialize network connection. + +.TP +.BR ENOENT +Could not find the resource located at URL. Often this error code +indicates that a debuginfod server was successfully contacted but +the server could not find the target file. + +.TP +.BR ENOMEM +System is unable to allocate resources. + +.TP +.BR ENOSYS +\fB$DEBUGINFOD_URLS\fP is not defined. + +.TP +.BR ETIME +Query failed due to timeout. \fB$DEBUGINFOD_TIMEOUT\fP controls +the timeout duration. See debuginfod(8) for more information. + +.SH "FILES" +.LP +.PD .1v +.TP 20 +.B $HOME/.debuginfod_client_cache +Default cache directory. If XDG_CACHE_HOME is not set then +\fB$HOME/.cache/debuginfod_client\fP is used. +.PD + +.SH "SEE ALSO" +.I "debuginfod(8)" diff --git a/doc/debuginfod_find_executable.3 b/doc/debuginfod_find_executable.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_find_executable.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_find_source.3 b/doc/debuginfod_find_source.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_find_source.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_get_url.3 b/doc/debuginfod_get_url.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_get_url.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_get_user_data.3 b/doc/debuginfod_get_user_data.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_get_user_data.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_set_progressfn.3 b/doc/debuginfod_set_progressfn.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_set_progressfn.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/debuginfod_set_user_data.3 b/doc/debuginfod_set_user_data.3 new file mode 100644 index 00000000..16279936 --- /dev/null +++ b/doc/debuginfod_set_user_data.3 @@ -0,0 +1 @@ +.so man3/debuginfod_find_debuginfo.3 diff --git a/doc/elf_begin.3 b/doc/elf_begin.3 new file mode 100644 index 00000000..6a1d0c27 --- /dev/null +++ b/doc/elf_begin.3 @@ -0,0 +1,37 @@ +.\" Modified Thu Sep 5 2017 by Ben Woodard +.\" +.TH ELF_BEGIN 3 2017-09-05 "Libelf" "Libelf Programmer's Manual" +.SH NAME +elf_begin \- Return descriptor for ELF file. +.nf +.SH SYNOPSIS +.B #include +.sp +.BI "Elf *elf_begin (int " filedes ", Elf_Cmd " cmd ", Elf *" ref ");" +.BI "Elf *elf_clone (int " filedes ", Elf_Cmd " cmd ");" +.BI "int elf_end (Elf *" elf ");" +.fi +.SH DESCRIPTION +The +.BR elf_begin () +.SH RETURN VALUE +.SH ERRORS +elf_begin ELF_E_NO_VERSION ELF_E_INVALID_FILE ELF_E_INVALID_CMD ELF_E_NOMEM +elf_clone ELF_E_NOMEM +elf_end +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lbw29 lb lb +l l l. +Interface Attribute Value +T{ +.BR elf_begin (), +.BR elf_clone (), +.BR elf_end () +T} Thread safety MT-Safe +.TE + +.SH SEE ALSO diff --git a/doc/elf_clone.3 b/doc/elf_clone.3 new file mode 100644 index 00000000..38ec9217 --- /dev/null +++ b/doc/elf_clone.3 @@ -0,0 +1,14 @@ +.\" Modified Thu Sep 5 2017 by Ben Woodard +.\" +.TH ELF_CLONE 3 2017-09-05 "Libelf" "Libelf Programmer's Manual" +.SH NAME +elf_clone \- Create a clone of an existing ELF descriptor. +.nf +.SH SYNOPSIS +.B #include +.sp +.BI "Elf *elf_clone (int " filedes ", Elf_Cmd " cmd ");" +.fi +.SH DESCRIPTION +The +.BR elf_clone () diff --git a/doc/elf_getdata.3 b/doc/elf_getdata.3 new file mode 100644 index 00000000..44d9304e --- /dev/null +++ b/doc/elf_getdata.3 @@ -0,0 +1,28 @@ +.\" Modified Thu Aug 17 2017 by Ben Woodard +.\" +.TH ELF_GETDATA 3 2017-08-17 "Libelf" "Libelf Programmer's Manual" +.SH NAME +elf_getdata \- Get washed data of section +.nf +.SH SYNOPSIS +.B #include +.sp +.BI "Elf_Data * elf_getdata (Elf_Scn *" scn ", Elf_Data *" data ");" +.fi +.SH DESCRIPTION +The +.BR elf_getdata () +function allows the user to retrieve the data buffers of the section +.I scn + . There can be more than one buffer if the user explicitly added them. +When a file is read the libelf library creates exactly one data buffer. + +The first buffer in the list can be obtained by passing a null pointer in the +parameter data. To get the next data buffer the previously returned value must +be passed in the data parameter. If there are no more buffer left in the list a +null pointer is returned. + +If the data parameter is not a null pointer it must be a descriptor for a +buffer associated with the section scn . If this is not the case a null pointer +is returned. To facilitate error handling elf_getdata also returns a null +pointer if the scn parameter is a null pointer. diff --git a/doc/elf_update.3 b/doc/elf_update.3 new file mode 100644 index 00000000..d0a7ab10 --- /dev/null +++ b/doc/elf_update.3 @@ -0,0 +1,14 @@ +.\" Modified Thu Sep 5 2017 by Ben Woodard +.\" +.TH ELF_UPDATE 3 2017-09-05 "Libelf" "Libelf Programmer's Manual" +.SH NAME +elf_update \- update an ELF descriptor +.nf +.SH SYNOPSIS +.B #include +.sp +.BI "off_t elf_update (Elf *" elf ", Elf_Cmd " cmd ");" +.fi +.SH DESCRIPTION +The +.BR elf_update () diff --git a/doc/elfclassify.1 b/doc/elfclassify.1 new file mode 100644 index 00000000..cbfdae48 --- /dev/null +++ b/doc/elfclassify.1 @@ -0,0 +1,197 @@ +.\" Copyright 2019 Red Hat Inc. +.\" Tue 2019-Aug 20 Ben Woodard +.\" Florian Wiemer +.\" Mark Wielaard +.\" Contact elfutils-devel@sourceware.org to correct errors or typos. +.TH EU-ELFCLASSIFY 1 "2019-Aug-20" "elfutils" +.SH "NAME" +eu-elfclassify \- Determine the type of an ELF file. +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +eu-elfclassify [\fB\-\-core\fR] + [\fB\-\-debug-only\fR] + [\fB\-\-elf\fR] + [\fB\-\-elf\-archive\fR] + [\fB\-\-elf\-file\fR] + [\fB\-\-executable\fR] + [\fB\-\-library\fR] + [\fB\-\-linux\-kernel\-module\fR] + [\fB\-\-loadable\fR] + [\fB\-\-program\fR] + [\fB\-\-shared\fR] + [\fB\-\-unstripped\fR] + [\fB\-f\fR|\fB \-\-file\fR] + [\fB\-\-no\-stdin\fR] + [\fB\-\-stdin\fR] + [\fB\-\-stdin0\fR] + [\fB\-z\fR|\fB \-\-compressed\fR] + [\fB\-\-matching\fR] + [\fB\-\-no\-print\fR] + [\fB\-\-not\-matching\fR] + [\fB\-\-print\fR] + [\fB\-\-print0\fR] + [\fB\-q\fR|\fB \-\-quiet\fR] + [\fB\-v\fR|\fB \-\-verbose\fR] + [\fB\-?\fR|\fB \-\-help\fR] + [\fB\-\-usage\fR] + [\fB\-V\fR|\fB \-\-version\fR] + \fIelffile\fR... +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fBeu-elfclassify\fR identifies the primary purpose of a particular kind of + \s-1ELF\s0 file or files +.SH "OPTIONS" +.IX Header "OPTIONS" +The long and short forms of options, shown here as alternatives, are +equivalent. All of the classification options must apply at the same time to a +particular file. Classification options can be negated using a +\fB\-\-not\-\fR prefix. +.SS "Classification Options" +.IX Subsection "Classification Options" +.IP "\fB\-\-core\fR" 4 +.IX Item "--core" +.PD +File is an ELF core dump file. +.IP "\FB\-\-debug\-only\fR" 4 +.IX Item "--debug-only" +.PD +File is a debug only ELF file (separate .debug, .dwo or dwz multi-file). +.IP "\fB\-\-elf\fR" 4 +.IX Item "--elf" +.PD +File looks like an ELF object or archive/static library (default). +.IP "\fB\-\-elf\-archive\fR" 4 +.IX Item "--elf-archive" +.PD +File is an ELF archive or static library. +.IP "\fB\-\-elf\-file\fR" 4 +.IX Item "--elf-file" +.PD +File is an regular ELF object (not an archive/static library). +.IP "\fB\-\-executable\fR" 4 +.IX Item "--executable" +.PD +File is (primarily) an ELF program executable (not primarily a DS.O) +.IP "\fB\-\-library\fR" 4 +.IX Item "--library" +.PD +File is an ELF shared object (DSO) (might also be an executable). +.IP "\fB\-\-linux\-kernel\-module\fR" 4 +.IX Item "--linux-kernel-module" +.PD +File is a linux kernel module. +.IP "\fB\-\-loadable\fR" 4 +.IX Item "--loadable" +.PD +File is a loadable ELF object (program or shared object). +.IP "\fB\--program\fR" 4 +.IX Item "--program" +.PD +File is an ELF program executable (might also be a DSO). +.IP "\fB\-\-shared\fR" 4 +.IX Item "--shared" +.PD +File is (primarily) an ELF shared object (DSO) (not primarily an executable). +.IP "\fB\-\-unstripped\fR" 4 +.IX Item "--unstripped" +.PD +File is an ELF file with symbol table or .debug_* sections and can be stripped +further. +.SS "Input flags" +.IX Subsection "Input flags" +.IP "\fB\-f\fR" 4 +.IX Item "-f" +.PD 0 +.IP "\fB\-\-file\fR" 4 +.IX Item "--file" +.PD +Only classify regular (not symlink nor special device) files. +.IP "\fB\-\-no\-stdin\fR" 4 +.IX Item "--no-stdin" +.PD +Do not read files from standard input (default). +.IP "\fB\-\-stdin\fR" 4 +.IX Item "--stdin" +.PD +Also read file names to process from standard input, separated by newlines. +.IP "\fB\-\-stdin0\fR" 4 +.IX Item "--stdin0" +.PD +Also read file names to process from standard input, separated by ASCII NUL +bytes. +.IP "\fB\-z\fR" 4 +.IX Item "-z" +.PD 0 +.IP "\fB\-\-compressed\fR" 4 +.IX Item "--compressed" +.PD +Try to open compressed files or embedded (kernel) ELF images. +.SS "Output flags" +.IX Subsection "Output flags" +.IP "\fB\-\-matching\fR" 4 +.IX Item "--matching" +.PD +If printing file names, print matching files (default). +.IP "\fB\-\-no\-print\fR" 4 +.IX Item "--no-print" +.PD +Do not output file names. +.IP "\fB\-\-not\-matching\fR" 4 +.IX Item "--not-matching" +.PD +If printing file names, print files that do not match. +.IP "\fB\-\-print\fR" 4 +.IX Item "--print" +.PD +Output names of files, separated by newline. +.IP "\fB\-\-print0\fR" 4 +.IX Item "--print0" +.PD +Output names of files, separated by ASCII NUL. +.SS " Additional flags" +.IX Subsection " Additional flags" +.IP "\fB\-q\fR" 4 +.IX Item "-q," +.PD +.IP "\fB\-\-quiet\fR" 4 +.IX Item "--quiet" +.PD +Suppress some error output (counterpart to --verbose). +.IP "\fB\-v\fR" 4 +.IX Item "-v" +.PD +.IP "\fB\-\-verbose\fR" 4 +.IX Item "--verbose" +.PD +Output additional information (can be specified multiple times). +.IP "\fB\-?\fR" 4 +.IX Item "-?" +.PD +.IP "\fB\-\-help\fR" 4 +.IX Item "--help" +.PD +Give this help list. +.IP "\fB\-\-usage\fR" 4 +.IX Item "--usage" +.PD +Give a short usage message. +.IP "\fB\-V\fR" 4 +.IX Item "-V" +.PD +.IP "\fB\-\-version\fR" 4 +.IX Item "--version" +.PD +Print program version. + +.SH "AUTHOR" +.IX Header "AUTHOR" +Written by Florian Wiemer. +.SH "REPORTING BUGS" +.IX Header "REPORTING BUGS" +Please reports bugs at https://sourceware.org/bugzilla/ +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright © 2019 Red Hat Inc. License GPLv3+: GNU GPL version 3 or +later . This is free software: you +are free to change and redistribute it. There is NO WARRANTY, to the +extent permitted by law. diff --git a/doc/readelf.1 b/doc/readelf.1 new file mode 100644 index 00000000..6a843f66 --- /dev/null +++ b/doc/readelf.1 @@ -0,0 +1,511 @@ +.\" Modified from readelf.1 man page +.\" Tue 2019-Aug 20 by Ben Woodard +.\" Contact elfutils-devel@sourceware.org to correct errors or typos. +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1q +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.if !\nF .nr F 0 +.if \nF>0 \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "EU-READELF 1" +.TH EU-READELF 1 "2019-Aug-20" "elfutils" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +eu-readelf \- Displays information about ELF files. +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +eu-readelf [\fB\-a\fR|\fB\-\-all\fR] + [\fB\-h\fR|\fB\-\-file\-header\fR] + [\fB\-l\fR|\fB\-\-program\-headers\fR|\fB\-\-segments\fR] + [\fB\-S\fR|\fB\-\-section\-headers\fR|\fB\-\-sections\fR] + [\fB\-g\fR|\fB\-\-section\-groups\fR] + [\fB\-e\fR|\fB\-\-exception\fR] + [\fB\-s\fR|\fB\-\-symbols\fR] [section name] ] + [\fB\-\-dyn-syms\fR] + [\fB\-n\fR|\fB\-\-notes\fR [section name] ] + [\fB\-r\fR|\fB\-\-relocs\fR] + [\fB\-d\fR|\fB\-\-dynamic\fR] + [\fB\-V\fR|\fB\-\-version\-info\fR] + [\fB\-A\fR|\fB\-\-arch\-specific\fR] + [\fB\-x\fR |\fB\-\-hex\-dump=\fR] + [\fB\-p\fR |\fB\-\-string\-dump=\fR] + [\fB\-z\fR|\fB\-\-decompress\fR] + [\fB\-c\fR|\fB\-\-archive\-index\fR] + [\fB\-\-dwarf\-skeleton\fR ] + [\fB\-\-elf\-section\fR [section] ] + [\fB\-w\fR| + \fB\-\-debug\-dump\fR[=line,=decodedline,=info,=info+,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=ranges,=gdb_index,=addr]] + [\fB\-I\fR|\fB\-\-histogram\fR] + [\fB\-v\fR|\fB\-\-version\fR] + [\fB\-W\fR|\fB\-\-wide\fR] + [\fB\-H\fR|\fB\-\-help\fR] + \fIelffile\fR... +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fBeu-readelf\fR displays information about one or more \s-1ELF\s0 format object +files. The options control what particular information to display. +.PP +\&\fIelffile\fR... are the object files to be examined. 32\-bit and +64\-bit \s-1ELF\s0 files are supported, as are archives containing \s-1ELF\s0 files. +.PP +This program performs a similar function to \fBobjdump\fR but it +goes into more detail and it exists independently of the \s-1BFD\s0 +library, so if there is a bug in \s-1BFD\s0 then readelf will not be +affected. +.SH "OPTIONS" +.IX Header "OPTIONS" +The long and short forms of options, shown here as alternatives, are +equivalent. At least one option in addition to \fB\-v\fR or \fB\-H\fR must be +given. +.SS "ELF Input Selection" +.IX Subsection "ELF Input Selection" +.IP "\fB\-\-dwarf\-skeleton \fR" 4 +.IX Item "--dwarf-skeleton " +.PD +Used with -w to find the skeleton Compile Units in FILE associated +with the Split Compile units in a .dwo input file. +.IP "\fB\-\-elf\-section [section]\fR" 4 +.IX Item "--elf-section [section]" +.PD +Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data +.SS "ELF Output Selection" +.IX Subsection "ELF Output Selection" +.IP "\fB\-a\fR" 4 +.IX Item "-a" +.PD 0 +.IP "\fB\-\-all\fR" 4 +.IX Item "--all" +.PD +Equivalent to specifying \fB\-\-file\-header\fR, +\&\fB\-\-program\-headers\fR, \fB\-\-sections\fR, \fB\-\-symbols\fR, +\&\fB\-\-relocs\fR, \fB\-\-dynamic\fR, \fB\-\-notes\fR, +\&\fB\-\-version\-info\fR, \fB\-\-arch\-specific\fR, +\&\fB\-\-section\-groups\fR and \fB\-\-histogram\fR. +.Sp +.IP "\fB\-h\fR" 4 +.IX Item "-h" +.PD 0 +.IP "\fB\-\-file\-header\fR" 4 +.IX Item "--file-header" +.PD +Displays the information contained in the \s-1ELF\s0 header at the start of the +file. +.IP "\fB\-l\fR" 4 +.IX Item "-l" +.PD 0 +.IP "\fB\-\-program\-headers\fR" 4 +.IX Item "--program-headers" +.IP "\fB\-\-segments\fR" 4 +.IX Item "--segments" +.PD +Displays the information contained in the file's segment headers, if it +has any. +.IP "\fB\-S\fR" 4 +.IX Item "-S" +.PD 0 +.IP "\fB\-\-sections\fR" 4 +.IX Item "--sections" +.IP "\fB\-\-section\-headers\fR" 4 +.IX Item "--section-headers" +.PD +Displays the information contained in the file's section headers, if it +has any. +.IP "\fB\-g\fR" 4 +.IX Item "-g" +.PD 0 +.IP "\fB\-\-section\-groups\fR" 4 +.IX Item "--section-groups" +.PD +Displays the information contained in the file's section groups, if it +has any. +.IP "\fB\-I\fR" 4 +.IX Item "-I" +.PD 0 +.IP "\fB\-\-histogram\fR" 4 +.IX Item "--histogram" +.PD +Display a histogram of bucket list lengths when displaying the contents +of the symbol tables. +.IP "\fB\-s\fR" 4 +.IX Item "-s" +.PD 0 +.IP "\fB\-\-symbols\fR [section name]" 4 +.IX Item "--symbols" +.PD +Displays the entries in symbol table section of the file, if it has one. +If a symbol has version information associated with it then this is +displayed as well. The version string is displayed as a suffix to the +symbol name, preceded by an @ character. For example +\&\fBfoo@VER_1\fR. If the version is the default version to be used +when resolving unversioned references to the symbol then it is +displayed as a suffix preceded by two @ characters. For example +\&\fBfoo@@VER_2\fR. +.IP "\fB\-\-dyn-syms\fR" 4 +.IX Item "--dyn-syms" +.PD +Display (only) the dynamic symbol table. +.IP "\fB\-e\fR" 4 +.IX Item "-e" +.PD 0 +.IP "\fB\-\-exception\fR" 4 +.IX Item "--exception" +.PD +Display sections for exception handling. +.IP "\fB\-n\fR" 4 +.IX Item "-n [section name]" +.PD 0 +.IP "\fB\-\-notes [section name]\fR" 4 +.IX Item "--notes" +.PD +Displays the contents of the \s-1NOTE\s0 segments and/or sections, if any. +.IP "\fB\-r\fR" 4 +.IX Item "-r" +.PD 0 +.IP "\fB\-\-relocs\fR" 4 +.IX Item "--relocs" +.PD +Displays the contents of the file's relocation section, if it has one. +.IP "\fB\-d\fR" 4 +.IX Item "-d" +.PD 0 +.IP "\fB\-\-dynamic\fR" 4 +.IX Item "--dynamic" +.PD +Displays the contents of the file's dynamic section, if it has one. +.IP "\fB\-V\fR" 4 +.IX Item "-V" +.PD 0 +.IP "\fB\-\-version\-info\fR" 4 +.IX Item "--version-info" +.PD +Displays the contents of the version sections in the file, it they +exist. +.IP "\fB\-A\fR" 4 +.IX Item "-A" +.PD 0 +.IP "\fB\-\-arch\-specific\fR" 4 +.IX Item "--arch-specific" +.PD +Displays architecture-specific information in the file, if there +is any. +.SS "Additional output selection" +.IX Subsection "Additional output selection" +.IP "\fB\-x \fR" 4 +.IX Item "-x " +.PD 0 +.IP "\fB\-\-hex\-dump=\fR" 4 +.IX Item "--hex-dump=" +.PD +Displays the contents of the indicated section name as a hexadecimal bytes. +.IP "\fB\-w\fR" 4 +.IX Item "-w" +.PD 0 +.IP "\fB\-\-debug\-dump[=decodedline,=info,=info+,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=ranges,=gdb_index,=addr]\fR" 4 +.IX Item "--debug-dump[=line,=decodedline,=info,=info+,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=ranges,=gdb_index,=addr]" +.PD +Displays the contents of the \s-1DWARF\s0 debug sections in the file, if any +are present. Compressed debug sections are automatically decompressed +(temporarily) before they are displayed. If one or more of the +optional letters or words follows the switch then only those type(s) +of data will be dumped. The letters and words refer to the following +information: +.RS 4 +.PD 0 +.ie n .IP """=abbrev""" 4 +.el .IP "\f(CW=abbrev\fR" 4 +.IX Item "=abbrev" +.PD +Displays the contents of the \fB.debug_abbrev\fR section. +.PD 0 +.ie n .IP """=addr""" 4 +.el .IP "\f(CW=addr\fR" 4 +.IX Item "=addr" +.PD +Displays the contents of the \fB.debug_addr\fR section. +.PD 0 +.ie n .IP """=frames""" 4 +.el .IP "\f(CW=frames\fR" 4 +.IX Item "=frames" +.PD +Display the raw contents of a \fB.debug_frame\fR section. +.PD 0 +.ie n .IP """=gdb_index""" 4 +.el .IP "\f(CW=gdb_index\fR" 4 +.IX Item "=gdb_index" +.PD +Displays the contents of the \fB.gdb_index\fR and/or +\&\fB.debug_names\fR sections. +.PD 0 +.ie n .IP """=info""" 4 +.el .IP "\f(CW=info\fR" 4 +.IX Item "=info" +.PD +Displays the contents of the \fB.debug_info\fR section. +.PD 0 +.ie n .IP """=info+""" 4 +.el .IP "\f(CW=info+\fR" 4 +.IX Item "=info+" +.PD +Displays the contents of the \fB.debug_info\fR section, plus any skeleton +unit will be immediately followed by the corresponding split compile unit +(from the .dwo file). To show the difference between "regular" CUs and +split CUs print offsets and references between { and } instead of [ and ]. +.PD 0 +.ie n .IP """=decodedline""" 4 +.el .IP "\f(CW=decodedline\fR" 4 +.IX Item "=decodedline" +.PD +Displays the interpreted contents of the \fB.debug_line\fR section. +.PD 0 +.ie n .IP """=macro""" 4 +.el .IP "\f(CW=macro\fR" 4 +.IX Item "=macro" +.PD +Displays the contents of the \fB.debug_macro\fR and/or +\&\fB.debug_macinfo\fR sections. +.PD 0 +.ie n .IP """=loc""" 4 +.el .IP "\f(CW=loc\fR" 4 +.IX Item "=loc" +.PD +Displays the contents of the \fB.debug_loc\fR and/or +\&\fB.debug_loclists\fR sections. +.PD 0 +.ie n .IP """=pubnames""" 4 +.el .IP "\f(CW=pubnames\fR" 4 +.IX Item "=pubnames" +.PD +Displays the contents of the \fB.debug_pubnames\fR and/or +\&\fB.debug_gnu_pubnames\fR sections. +.PD 0 +.ie n .IP """=aranges""" 4 +.el .IP "\f(CW=aranges\fR" 4 +.IX Item "=aranges" +.PD +Displays the contents of the \fB.debug_aranges\fR section. +.PD 0 +.ie n .IP """=ranges""" 4 +.el .IP "\f(CW=ranges\fR" 4 +.IX Item "=ranges" +.PD +Displays the contents of the \fB.debug_ranges\fR and/or +\&\fB.debug_rnglists\fR sections. +.PD 0 +.ie n .IP """=str""" 4 +.el .IP "\f(CW=str\fR" 4 +.IX Item "=str" +.PD +Displays the contents of the \fB.debug_str\fR, \fB.debug_line_str\fR +and/or \fB.debug_str_offsets\fR sections. +.PD 0 +.RS 4 +.Sp +Note: displaying the contents of \fB.debug_static_funcs\fR, +\&\fB.debug_static_vars\fR and \fBdebug_weaknames\fR sections is not +currently supported. +.RE +.IP "\fB\-p \fR" 4 +.IX Item "-p " +.PD 0 +.IP "\fB\-\-string\-dump=\fR" 4 +.IX Item "--string-dump=" +.PD +Displays the contents of the indicated section as printable strings. +A number identifies a particular section by index in the section table; +any other string identifies all sections with that name in the object file. +.IP "\fB\-c\fR" 4 +.IX Item "-c" +.PD 0 +.IP "\fB\-\-archive\-index\fR" 4 +.IX Item "--archive-index" +.PD +Displays the file symbol index information contained in the header part +of binary archives. Performs the same function as the \fBt\fR +command to \fBar\fR, but without using the \s-1BFD\s0 library. +.SS "Output control" +.IX Subsection "Output control" +.IP "\fB\-z\fR" 4 +.IX Item "-z" +.PD 0 +.IP "\fB\-\-decompress\fR" 4 +.IX Item "--decompress" +.PD +Requests that the section(s) being dumped by \fBx\fR, \fBR\fR or +\&\fBp\fR options are decompressed before being displayed. If the +section(s) are not compressed then they are displayed as is. +.IP "\fB\-v\fR" 4 +.IX Item "-v" +.PD 0 +.IP "\fB\-\-version\fR" 4 +.IX Item "--version" +.PD +Display the version number of eu-readelf. +.IP "\fB\-W\fR" 4 +.IX Item "-W" +.PD 0 +.IP "\fB\-\-wide\fR" 4 +.IX Item "--wide" +.PD +Ignored for compatibility (lines always wide). +.IP "\fB\-H\fR" 4 +.IX Item "-H" +.PD 0 +.IP "\fB\-\-help\fR" 4 +.IX Item "--help" +.PD +Display the command line options understood by \fBeu-readelf\fR. +.IP "\fB@\fR\fIfile\fR" 4 +.IX Item "@file" +Read command-line options from \fIfile\fR. The options read are +inserted in place of the original @\fIfile\fR option. If \fIfile\fR +does not exist, or cannot be read, then the option will be treated +literally, and not removed. +.Sp +Options in \fIfile\fR are separated by whitespace. A whitespace +character may be included in an option by surrounding the entire +option in either single or double quotes. Any character (including a +backslash) may be included by prefixing the character to be included +with a backslash. The \fIfile\fR may itself contain additional +@\fIfile\fR options; any such options will be processed recursively. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fIobjdump\fR\|(1), \fIreadelf\fR\|(1) and the Info entries for +\fIbinutils\fR. +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright (c) 1991\-2018 Free Software Foundation, Inc. + +Copyright (c) 2019 Red Hat Inc. +.PP +Permission is granted to copy, distribute and/or modify this document +under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +or any later version published by the Free Software Foundation; +with no Invariant Sections, with no Front-Cover Texts, and with no +Back-Cover Texts. A copy of the license is included in the +section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/elfutils.spec b/elfutils.spec new file mode 100644 index 00000000..83c0d5ae --- /dev/null +++ b/elfutils.spec @@ -0,0 +1,1209 @@ +# -*- rpm-spec-*- +Name: elfutils +Version: 0.185 +Release: 1 +URL: http://elfutils.org/ +License: GPLv3+ and (GPLv2+ or LGPLv3+) and GFDL +Source: ftp://sourceware.org/pub/elfutils/%{version}/elfutils-%{version}.tar.bz2 +Summary: A collection of utilities and DSOs to handle ELF files and DWARF data + +Requires: elfutils-libelf = %{version}-%{release} +Requires: elfutils-libs = %{version}-%{release} +# Can be a Recommends if rpm supports that +Requires: elfutils-debuginfod-client = %{version}-%{release} + +BuildRequires: gcc +# For libstdc++ demangle support +BuildRequires: gcc-c++ + +BuildRequires: gettext +BuildRequires: bison +BuildRequires: flex + +# Compression support +BuildRequires: zlib-devel +BuildRequires: bzip2-devel +BuildRequires: xz-devel +BuildRequires: libzstd-devel + +# For debuginfod +BuildRequires: pkgconfig(libmicrohttpd) >= 0.9.33 +BuildRequires: pkgconfig(libcurl) >= 7.29.0 +BuildRequires: pkgconfig(sqlite3) >= 3.7.17 +BuildRequires: pkgconfig(libarchive) >= 3.1.2 + +# For tests need to bunzip2 test files. +BuildRequires: bzip2 +BuildRequires: zstd +# For the run-debuginfod-find.sh test case in %%check for /usr/sbin/ss etc. +BuildRequires: iproute +BuildRequires: procps +BuildRequires: bsdtar +BuildRequires: curl + +%define _gnu %{nil} +%define _programprefix eu- + +%description +Elfutils is a collection of utilities, including stack (to show +backtraces), nm (for listing symbols from object files), size +(for listing the section sizes of an object or archive file), +strip (for discarding symbols), readelf (to see the raw ELF file +structures), elflint (to check for well-formed ELF files) and +elfcompress (to compress or decompress ELF sections). + +%package libs +Summary: Libraries to handle compiled objects +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libelf = %{version}-%{release} +Requires: default-yama-scope +# Can be a Recommends if rpm supports that +Requires: elfutils-debuginfod-client = %{version}-%{release} + +%description libs +The elfutils-libs package contains libraries which implement DWARF, ELF, +and machine-specific ELF handling and process introspection. These +libraries are used by the programs in the elfutils package. The +elfutils-devel package enables building other programs using these +libraries. + +%package devel +Summary: Development libraries to handle compiled objects +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libs = %{version}-%{release} +Requires: elfutils-libelf-devel = %{version}-%{release} +# Can be a Recommends if rpm supports that +Requires: elfutils-debuginfod-client-devel = %{version}-%{release} + +%description devel +The elfutils-devel package contains the libraries to create +applications for handling compiled objects. libdw provides access +to the DWARF debugging information. libasm provides a programmable +assembler interface. + +%package devel-static +Summary: Static archives to handle compiled objects +License: GPLv2+ or LGPLv3+ +Requires: elfutils-devel = %{version}-%{release} +Requires: elfutils-libelf-devel-static = %{version}-%{release} + +%description devel-static +The elfutils-devel-static package contains the static archives +with the code to handle compiled objects. + +%package libelf +Summary: Library to read and write ELF files +License: GPLv2+ or LGPLv3+ + +%description libelf +The elfutils-libelf package provides a DSO which allows reading and +writing ELF files on a high level. Third party programs depend on +this package to read internals of ELF files. The programs of the +elfutils package use it also to generate new ELF files. + +%package libelf-devel +Summary: Development support for libelf +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libelf = %{version}-%{release} +Conflicts: libelf-devel + +%description libelf-devel +The elfutils-libelf-devel package contains the libraries to create +applications for handling compiled objects. libelf allows you to +access the internals of the ELF object file format, so you can see the +different sections of an ELF file. + +%package libelf-devel-static +Summary: Static archive of libelf +License: GPLv2+ or LGPLv3+ +Requires: elfutils-libelf-devel = %{version}-%{release} +Conflicts: libelf-devel + +%description libelf-devel-static +The elfutils-libelf-static package contains the static archive +for libelf. + +%package default-yama-scope +Summary: Default yama attach scope sysctl setting +License: GPLv2+ or LGPLv3+ +Provides: default-yama-scope +BuildArch: noarch + +%description default-yama-scope +Yama sysctl setting to enable default attach scope settings +enabling programs to use ptrace attach, access to +/proc/PID/{mem,personality,stack,syscall}, and the syscalls +process_vm_readv and process_vm_writev which are used for +interprocess services, communication and introspection +(like synchronisation, signaling, debugging, tracing and +profiling) of processes. + +%package debuginfod-client +Summary: Library and command line client for build-id HTTP ELF/DWARF server +License: GPLv3+ and (GPLv2+ or LGPLv3+) + +%package debuginfod-client-devel +Summary: Libraries and headers to build debuginfod client applications +License: GPLv2+ or LGPLv3+ +Requires: elfutils-debuginfod-client = %{version}-%{release} + +%package debuginfod +Summary: HTTP ELF/DWARF file server addressed by build-id +License: GPLv3+ +Requires: elfutils-libs = %{version}-%{release} +Requires: elfutils-libelf = %{version}-%{release} +Requires: elfutils-debuginfod-client = %{version}-%{release} +BuildRequires: systemd +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires(pre): shadow-utils +# To extract .deb files with a bsdtar (= libarchive) subshell +Requires: bsdtar + +%description debuginfod-client +The elfutils-debuginfod-client package contains shared libraries +dynamically loaded from -ldw, which use a debuginfod service +to look up debuginfo and associated data. Also includes a +command-line frontend. + +%description debuginfod-client-devel +The elfutils-debuginfod-client-devel package contains the libraries +to create applications to use the debuginfod service. + +%description debuginfod +The elfutils-debuginfod package contains the debuginfod binary +and control files for a service that can provide ELF/DWARF +files to remote clients, based on build-id identification. +The ELF/DWARF file searching functions in libdwfl can query +such servers to download those files on demand. + +%prep +%setup -q + +%build +%configure --program-prefix=%{_programprefix} --enable-debuginfod --enable-debuginfod-urls +make -s %{?_smp_mflags} + +%install +rm -rf ${RPM_BUILD_ROOT} +mkdir -p ${RPM_BUILD_ROOT}%{_prefix} + +%make_install + +chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/lib*.so* +mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod +touch ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod/debuginfod.sqlite + +# XXX Nuke unpackaged files +( cd ${RPM_BUILD_ROOT} + rm -f .%{_includedir}/elfutils/libasm.h + rm -f .%{_libdir}/libasm.so + rm -f .%{_libdir}/libasm.a +) + +install -Dm0644 config/10-default-yama-scope.conf ${RPM_BUILD_ROOT}%{_sysctldir}/10-default-yama-scope.conf + +install -Dm0644 config/debuginfod.service ${RPM_BUILD_ROOT}%{_unitdir}/debuginfod.service +install -Dm0644 config/debuginfod.sysconfig ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/debuginfod +mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod +touch ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod/debuginfod.sqlite + +%check +make -s %{?_smp_mflags} check + +%post libs -p /sbin/ldconfig +%postun libs -p /sbin/ldconfig +%post libelf -p /sbin/ldconfig +%postun libelf -p /sbin/ldconfig +%post debuginfod-client -p /sbin/ldconfig +%postun debuginfod-client -p /sbin/ldconfig + +%post default-yama-scope +# Due to circular dependencies might not be installed yet, so double check. +# (systemd -> elfutils-libs -> default-yama-scope -> systemd) +if [ -x /usr/lib/systemd/systemd-sysctl ] ; then +%sysctl_apply 10-default-yama-scope.conf +fi + +%files +%license COPYING COPYING-GPLV2 COPYING-LGPLV3 doc/COPYING-GFDL +%doc README TODO CONTRIBUTING +%{_bindir}/eu-addr2line +%{_bindir}/eu-ar +%{_bindir}/eu-elfclassify +%{_bindir}/eu-elfcmp +%{_bindir}/eu-elfcompress +%{_bindir}/eu-elflint +%{_bindir}/eu-findtextrel +%{_bindir}/eu-make-debug-archive +%{_bindir}/eu-nm +%{_bindir}/eu-objdump +%{_bindir}/eu-ranlib +%{_bindir}/eu-readelf +%{_bindir}/eu-size +%{_bindir}/eu-stack +%{_bindir}/eu-strings +%{_bindir}/eu-strip +%{_bindir}/eu-unstrip +%{_mandir}/man1/eu-*.1* + +%files libs +%license COPYING-GPLV2 COPYING-LGPLV3 +%{_libdir}/libasm-%{version}.so +%{_libdir}/libdw-%{version}.so +%{_libdir}/libasm.so.* +%{_libdir}/libdw.so.* + +%files devel +%{_includedir}/dwarf.h +%dir %{_includedir}/elfutils +%{_includedir}/elfutils/elf-knowledge.h +%{_includedir}/elfutils/known-dwarf.h +#%{_includedir}/elfutils/libasm.h +%{_includedir}/elfutils/libdw.h +%{_includedir}/elfutils/libdwfl.h +%{_includedir}/elfutils/libdwelf.h +%{_includedir}/elfutils/version.h +#%{_libdir}/libasm.so +%{_libdir}/libdw.so +%{_libdir}/pkgconfig/libdw.pc + +%files devel-static +%{_libdir}/libdw.a +#%{_libdir}/libasm.a + +%files libelf +%license COPYING-GPLV2 COPYING-LGPLV3 +%{_libdir}/libelf-%{version}.so +%{_libdir}/libelf.so.* +%{_datadir}/locale/*/LC_MESSAGES/elfutils.mo + +%files libelf-devel +%{_includedir}/libelf.h +%{_includedir}/gelf.h +%{_includedir}/nlist.h +%{_libdir}/libelf.so +%{_libdir}/pkgconfig/libelf.pc +%{_mandir}/man3/elf_*.3* + +%files libelf-devel-static +%{_libdir}/libelf.a + +%files default-yama-scope +%{_sysctldir}/10-default-yama-scope.conf + +%files debuginfod-client +%defattr(-,root,root) +%{_libdir}/libdebuginfod-%{version}.so +%{_libdir}/libdebuginfod.so.* +%{_bindir}/debuginfod-find +%{_mandir}/man1/debuginfod-find.1* +%config(noreplace) %{_sysconfdir}/profile.d/* + +%files debuginfod-client-devel +%defattr(-,root,root) +%{_libdir}/pkgconfig/libdebuginfod.pc +%{_mandir}/man3/debuginfod_*.3* +%{_includedir}/elfutils/debuginfod.h +%{_libdir}/libdebuginfod.so + +%files debuginfod +%defattr(-,root,root) +%{_bindir}/debuginfod +%config(noreplace) %{_sysconfdir}/sysconfig/debuginfod +%{_unitdir}/debuginfod.service +%{_sysconfdir}/sysconfig/debuginfod +%{_mandir}/man8/debuginfod.8* + +%dir %attr(0700,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod +%ghost %attr(0600,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod/debuginfod.sqlite + +%pre debuginfod +getent group debuginfod >/dev/null || groupadd -r debuginfod +getent passwd debuginfod >/dev/null || \ + useradd -r -g debuginfod -d /var/cache/debuginfod -s /sbin/nologin \ + -c "elfutils debuginfo server" debuginfod +exit 0 + +%post debuginfod +%systemd_post debuginfod.service + +%postun debuginfod +%systemd_postun_with_restart debuginfod.service + +%changelog +* Sat May 22 2021 Mark Wielaard 0.185-1 +- debuginfod-client: Simplify curl handle reuse so downloads which + return an error are retried. +- elfcompress: Always exit with code 0 when the operation succeeds + (even when nothing was done). On error the exit code is + now always 1. + +* Mon May 10 2021 Mark Wielaard 0.184-1 +- debuginfod: Use libarchive's bsdtar as the .deb-family file unpacker. +- debuginfod-client: Client caches negative results. If a query for a + file failed with 404, an empty 000 permission + file is created in the cache. This will prevent + requesting the same file for the next 10 minutes. +- Client objects now carry long-lived curl handles + for outgoing connections. This makes it more + efficient for multiple sequential queries, because + the TCP connections and/or TLS state info are kept + around awhile, avoiding O(100ms) setup latencies. +- libdw: handle DW_FORM_indirect when reading attributes +- translations: Update Polish translation. + +* Fri Feb 5 2021 Mark Wielaard 0.183-1 +- debuginfod: New thread-busy metric and more detailed error metrics. + New --fdcache-mintmp and tracking of filesystem freespace. +- debigonfod-client: DEBUGINFOD_SONAME macro added to debuginfod.h can + be used to dlopen the libdebuginfod.so library. + New function debuginfod_set_verbose_fd and DEBUGINFOD_VERBOSE + environment variable. +- config: profile.sh and profile.csh won't export DEBUGINFOD_URLS + unless configured --enable-debuginfod-urls[=URLS] +- elflint, readelf: Recognize SHF_GNU_RETAIN. + Handle SHT_X86_64_UNWIND as valid relocation target type. + +* Sat Oct 31 2020 Mark Wielaard 0.182-1 +- backends: Support for tilegx has been removed. +- config: New /etc/profile.d files to provide default $DEBUGINFOD_URLS. +- debuginfod: More efficient package traversal, tolerate various + errors during scanning, grooming progress is more visible and + interruptible, more prometheus metrics. +- debuginfod-client: Now supports compressed (kernel) ELF images. +- libdwfl: Add ZSTD compression support. + +* Tue Sep 8 2020 Mark Wielaard 0.181-1 +- libelf: elf_update now compensates (fixes up) a bad sh_addralign + for SHF_COMPRESSED sections. +- libdebuginfod: configure now takes --enable-libdebuginfod=dummy or + --disable-libdebuginfod for bootstrapping. + DEBUGINFOD_URLS now accepts "scheme-free" urls + (guessing at what the user meant, either http:// or file://) +- readelf, elflint: Handle aarch64 bti, pac bits in dynamic table and + gnu property notes. +- libdw, readelf: Recognize DW_CFA_AARCH64_negate_ra_state. Allows + unwinding on arm64 for code that is compiled for PAC + (Pointer Authentication Code) as long as it isn't enabled. + +* Thu Jun 11 2020 Mark Wielaard 0.180-1 +- elflint: Allow SHF_EXCLUDE as generic section flag when --gnu is given. +- libdw, readelf: Handle GCC LTO .gnu.debuglto_ prefix. +- libdw: Use correct CU to resolve file names in dwarf_decl_file. +- libdwfl: Handle debugaltlink in dwfl_standard_find_debuginfo. +- size: Also obey radix printing for bsd format. +- nm: Explicitly print weak 'V' or 'T' and common 'C' symbols. + +* Mon Mar 30 2020 Mark Wielaard 0.179-1 +- debuginfod-client: When DEBUGINFOD_PROGRESS is set and the program + doesn't install its own debuginfod_progressfn_t show download + progress on stderr. + DEBUGINFOD_TIMEOUT is now defined as seconds to get at least 100K, + defaults to 90 seconds. + Default to $XDG_CACHE_HOME/debuginfod_client. + New functions debuginfod_set_user_data, debuginfod_get_user_data, + debuginfod_get_url and debuginfod_add_http_header. + Support for file:// URLs. +- debuginfod: Uses libarchive directly for reading rpm archives. + Support for indexing .deb/.ddeb archives through dpkg-deb or bsdtar. + Generic archive support through -Z EXT[=CMD]. Which can be used for + example for arch-linux pacman files by using -Z '.tar.zst=zstdcat'. + Better logging using User-Agent and X-Forwarded-For headers. + More prometheus metrics. + Support for eliding dots or extraneous slashes in path names. +- debuginfod-find: Accept /path/names in place of buildid hex. +- libelf: Handle PN_XNUM in elf_getphdrnum before shdr 0 is cached. + Ensure zlib resource cleanup on failure. +- libdwfl: dwfl_linux_kernel_find_elf and dwfl_linux_kernel_report_offline + now find and handle a compressed vmlinuz image. +- readelf, elflint: Handle PT_GNU_PROPERTY. +- translations: Updated Ukrainian translation. + +* Tue Nov 26 2019 Mark Wielaard 0.178-1 +- debuginfod: New server, client tool and library to index and fetch + ELF/DWARF files addressed by build-id through HTTP. +- doc: There are now some manual pages for functions and tools. +- backends: The libebl libraries are no longer dynamically loaded + through dlopen, but are now compiled into libdw.so directly. +- readelf: -n, --notes now takes an optional "SECTION" argument. + -p and -x now also handle section numbers. + New option --dyn-sym to show just the dynamic symbol table. +- libcpu: Add RISC-V disassembler. +- libdw: Abbrevs and DIEs can now be read concurrently by multiple + threads through the same Dwarf handle. +- libdwfl: Will try to use debuginfod when installed as fallback to + retrieve ELF and DWARF debug data files by build-id. + +* Tue Aug 13 2019 Mark Wielaard 0.177-1 +- elfclassify: New tool to analyze ELF objects. +- readelf: Print DW_AT_data_member_location as decimal offset. + Decode DW_AT_discr_list block attributes. +- libdw: Add DW_AT_GNU_numerator, DW_AT_GNU_denominator and DW_AT_GNU_bias. +- libdwelf: Add dwelf_elf_e_machine_string. + dwelf_elf_begin now only returns NULL when there is an error + reading or decompressing a file. If the file is not an ELF file + an ELF handle of type ELF_K_NONE is returned. +- backends: Add support for C-SKY. + +* Thu Feb 14 2019 Mark Wielaard 0.176-1 +- build: Add new --enable-install-elfh option. + Do NOT use this for system installs (it overrides glibc elf.h). +- backends: riscv improved core file and return value location support. +- Fixes CVE-2019-7146, CVE-2019-7148, CVE-2019-7149, CVE-2019-7150, + CVE-2019-7664, CVE-2019-7665. + +* Wed Nov 14 2018 Mark Wielaard 0.175-1 +- readelf: Handle multiple .debug_macro sections. + Recognize and parse GNU Property notes, NT_VERSION notes and + GNU Build Attribute ELF Notes. +- strip: Handle SHT_GROUP correctly. + Add strip --reloc-debug-sections-only option. + Handle relocations against GNU compressed sections. +- libdwelf: New function dwelf_elf_begin. +- libcpu: Recognize bpf jump variants BPF_JLT, BPF_JLE, BPF_JSLT + and BPF_JSLE. +- backends: RISCV handles ADD/SUB relocations. + Handle SHT_X86_64_UNWIND. +- Fixes CVE-2018-18310, CVE-2018-18520 and CVE-2018-18521. + +* Fri Sep 14 2018 Mark Wielaard 0.174-1 +- libelf, libdw and all tools now handle extended shnum and shstrndx + correctly. +- elfcompress: Don't rewrite input file if no section data needs + updating. Try harder to keep same file mode bits (suid) on rewrite. +- strip: Handle mixed (out of order) allocated/non-allocated sections. +- unstrip: Handle SHT_GROUP sections. +- backends: RISCV and M68K now have backend implementations to + generate CFI based backtraces. +- Fixes CVE-2018-16062, CVE-2018-16402 and CVE-2018-16403. + +* Fri Jun 29 2018 Mark Wielaard,,, 0.173-1 +- More fixes for crashes and hangs found by afl-fuzz. In particular + various functions now detect and break infinite loops caused by bad + DIE tree cycles. +- readelf: Will now lookup the size and signedness of constant value + types to display them correctly (and not just how they were encoded). +- libdw: New function dwarf_next_lines to read CU-less .debug_line data. + dwarf_begin_elf now accepts ELF files containing just .debug_line + or .debug_frame sections (which can be read without needing a DIE + tree from the .debug_info section). + Removed dwarf_getscn_info, which was never implemented. +- backends: Handle BPF simple relocations. + The RISCV backends now handles ABI specific CFI and knows about + RISCV register types and names. + +* Mon Jun 11 2018 Mark Wielaard 0.172-1 +- No functional changes compared to 0.171. +- Various bug fixes in libdw and eu-readelf dealing with bad DWARF5 + data. Thanks to running the afl fuzzer on eu-readelf and various + testcases. +- eu-readelf -N is ~15% faster. + +* Fri Jun 01 2018 Mark Wielaard 0.171-1 +- DWARF5 and split dwarf, including GNU DebugFission, support. +- readelf: Handle all new DWARF5 sections. + --debug-dump=info+ will show split unit DIEs when found. + --dwarf-skeleton can be used when inspecting a .dwo file. + Recognizes GNU locviews with --debug-dump=loc. +- libdw: New functions dwarf_die_addr_die, dwarf_get_units, + dwarf_getabbrevattr_data and dwarf_cu_info. + libdw will now try to resolve the alt file on first use + when not set yet with dwarf_set_alt. + dwarf_aggregate_size() now works with multi-dimensional arrays. +- libdwfl: Use process_vm_readv when available instead of ptrace. +- backends: Add a RISC-V backend. + +* Wed Aug 2 2017 Mark Wielaard 0.170-1 +- libdw: Added new DWARF5 attribute, tag, character encoding, + language code, calling convention, defaulted member function + and macro constants to dwarf.h. + New functions dwarf_default_lower_bound and dwarf_line_file. + dwarf_peel_type now handles DWARF5 immutable, packed and shared tags. + dwarf_getmacros now handles DWARF5 .debug_macro sections. +- strip: Add -R, --remove-section=SECTION and --keep-section=SECTION. +- backends: The bpf disassembler is now always build on all platforms. + +* Fri May 5 2017 Mark Wielaard 0.169-1 +- backends: Add support for EM_PPC64 GNU_ATTRIBUTES. + Frame pointer unwinding fallback support for i386, x86_64, aarch64. +- translations: Update Polish translation. + +* Tue Dec 27 2016 Mark Wielaard 0.168-1 +- http://elfutils.org/ is now hosted at http://sourceware.org/elfutils/ +- libelf: gelf_newehdr and gelf_newehdr now return void *. +- libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1). +- readelf: Add optional --symbols[=SECTION] argument to select section name. + +* Thu Aug 4 2016 Mark Wielaard 0.167-1 +- libasm: Add eBPF disassembler for EM_BPF files. +- backends: Add m68k and BPF backends. +- ld: Removed. +- dwelf: Add ELF/DWARF string table creation functions. + dwelf_strtab_init, dwelf_strtab_add, dwelf_strtab_add_len, + dwelf_strtab_finalize, dwelf_strent_off, dwelf_strent_str and + dwelf_strtab_free. + +* Thu Mar 31 2016 Mark Wielaard 0.166-1 +- config: The default program prefix for the installed tools is now + eu-. Use configure --program-prefix="" to not use a program prefix. + +* Fri Jan 8 2016 Mark Wielaard 0.165-1 +- elfcompress: New utility to compress or decompress ELF sections. +- readelf: Add -z,--decompress option. +- libelf: Add elf_compress, elf_compress_gnu, elf32_getchdr, + elf64_getchdr and gelf_getchdr. +- libdwelf: New function dwelf_scn_gnu_compressed_size. +- config: Add libelf and libdw pkg-config files. +- backends: sparc support for core and live backtraces. +- translations: Updated Polish translation. + +* Thu Oct 15 2015 Mark Wielaard 0.164-1 +- strip, unstrip: Handle ELF files with merged strtab/shstrtab + tables. Handle missing SHF_INFO_LINK section flags. +- libelf: Use int64_t for offsets in libelf.h instead of loff_t. +- libdw: dwarf.h Add preliminary DWARF5 DW_LANG_Haskell. +- libdwfl: dwfl_standard_find_debuginfo now searches any subdir of + the binary path under the debuginfo root when the separate + debug file couldn't be found by build-id. + dwfl_linux_proc_attach can now be called before any Dwfl_Modules + have been reported. +- backends: Better sparc and sparc64 support. +- translations: Updated Ukrainian translation. +- Provide default-yama-scope subpackage. + +* Fri Jun 19 2015 Mark Wielaard 0.163-1 +- Bug fixes only, no new features. + +* Wed Jun 10 2015 Mark Wielaard 0.162-1 +- libdw: Install new header elfutils/known-dwarf.h. + dwarf.h Add preliminary DWARF5 constants DW_TAG_atomic_type, + DW_LANG_Fortran03, DW_LANG_Fortran08. dwarf_peel_type now also + handles DW_TAG_atomic_type. +- addr2line: Input addresses are now always interpreted as + hexadecimal numbers, never as octal or decimal numbers. + New option -a, --addresses to print address before each entry. + New option -C, --demangle to show demangled symbols. + New option --pretty-print to print all information on one line. +- ar: CVE-2014-9447 Directory traversal vulnerability in ar + extraction. +- backends: x32 support. + +* Thu Dec 18 2014 Mark Wielaard 0.161-1 +- libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses + dwarf_peel_type to also provide the sizes of qualified types. + dwarf_getmacros will now serve either of .debug_macro and + .debug_macinfo transparently. New interfaces dwarf_getmacros_off, + dwarf_macro_getsrcfiles, dwarf_macro_getparamcnt, and + dwarf_macro_param are available for more generalized inspection of + macros and their parameters. + dwarf.h: Add DW_AT_GNU_deleted, DW_AT_noreturn, DW_LANG_C11, + DW_LANG_C_plus_plus_11 and DW_LANG_C_plus_plus_14. + +* Mon Aug 25 2014 Mark Wielaard 0.160-1 +- libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die. + dwarf.h remove non-existing DW_TAG_mutable_type. +- libdwfl: Handle LZMA .ko.xz compressed kernel modules. +- unstrip: New option -F, --force to combining files even if some ELF + headers don't seem to match. +- backends: Handle ARM THUMB functions. Add support for ppc64le ELFv2 abi. + +* Sat May 17 2014 Mark Wielaard 0.159-1 +- stack: New option -d, --debugname to lookup DWARF debuginfo name + for frame. New option -i, --inlines to show inlined frames + using DWARF debuginfo. +- libdwelf: New libdwelf.h header for libdw.so DWARF ELF Low-level + Functions. New function dwelf_elf_gnu_debuglink, + dwelf_dwarf_gnu_debugaltlink, and dwelf_elf_gnu_build_id. +- libdw: Support for DWZ multifile forms DW_FORM_GNU_ref_alt and + DW_FORM_GNU_strp_alt is now enabled by default and no longer + experimental. Added new functions dwarf_getalt and dwarf_setalt + to get or set the alternative debug file used for the alt FORMs. + The dwfl_linux_proc_find_elf callback will now find ELF from + process memory for (deleted) files if the Dwfl has process state + attached. +- libdwfl: The dwfl_build_id_find_debuginfo and + dwfl_standard_find_debuginfo functions will now try to + resolve and set the alternative debug file. +- backends: Add CFI unwinding for arm. Relies on .debug_frame. + Add arm process initial register state compatible mode to AARCH64. + Add aarch64 native and core unwind support. +- other: All separate elfutils-robustify patches have been merged. + CVE-2014-0172 Check overflow before calling malloc to uncompress + data. + +* Fri Jan 3 2014 Mark Wielaard 0.158-1 +- libdwfl: dwfl_core_file_report has new parameter executable. + New functions dwfl_module_getsymtab_first_global, + dwfl_module_getsym_info and dwfl_module_addrinfo. + Added unwinder with type Dwfl_Thread_Callbacks, opaque types + Dwfl_Thread and Dwfl_Frame and functions dwfl_attach_state, + dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread, + dwfl_thread_state_registers, dwfl_thread_state_register_pc, + dwfl_getthread_frames, dwfl_getthreads, dwfl_thread_getframes + and dwfl_frame_pc. +- addr2line: New option -x to show the section an address was found in. +- stack: New utility that uses the new unwinder for processes and cores. +- backends: Unwinder support for i386, x86_64, s390, s390x, ppc and ppc64. + aarch64 support. + +* Mon Sep 30 2013 Mark Wielaard 0.157-1 +- libdw: Add new functions dwarf_getlocations, dwarf_getlocation_attr + and dwarf_getlocation_die. +- readelf: Show contents of NT_SIGINFO and NT_FILE core notes. +- addr2line: Support -i, --inlines output option. +- backends: abi_cfi hook for arm, ppc and s390. + +* Thu Jul 25 2013 Jan Kratochvil 0.156-1 +- lib: New macro COMPAT_VERSION_NEWPROTO. +- libdw: Handle GNU extension opcodes in dwarf_getlocation. +- libdwfl: Fix STB_GLOBAL over STB_WEAK preference in + dwfl_module_addrsym. Add minisymtab support. Add + parameter add_p_vaddr to dwfl_report_elf. Use DT_DEBUG + library search first. +- libebl: Handle new core note types in EBL. +- backends: Interpret NT_ARM_VFP. Implement core file + registers parsing for s390/s390x. +- readelf: Add --elf-section input option to inspect an embedded ELF + file. Add -U, --unresolved-address-offsets output control. + Add --debug-dump=decodedline support. Accept version + 8 .gdb_index section format. Adjust output formatting width. + When highpc is in constant form print it also as address. + Display raw .debug_aranges. Use libdw only for decodedaranges. +- elflint: Add __bss_start__ to the list of allowed symbols. +- tests: Add configure --enable-valgrind option to run all tests + under valgrind. Enable automake parallel-tests for make check. +- translations: Updated Polish translation. +- Updates for Automake 1.13. + +* Fri Aug 24 2012 Mark Wielaard 0.155-1 +- libelf: elf*_xlatetomd now works for cross-endian ELF note data. + elf_getshdr now works consistently on non-mmaped ELF files after + calling elf_cntl(ELF_C_FDREAD). Implement support for + ar archives with 64-bit symbol table. +- libdw: dwarf.h corrected the DW_LANG_ObjC constant name (was + DW_LANG_Objc). Any existing sources using the old name will + have to be updated. Add DW_MACRO_GNU .debug_macro type + encodings constants, DW_ATE_UTF and DW_OP_GNU_parameter_ref to + dwarf.h. Experimental support for DWZ multifile forms + DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. Disabled by + default. Use configure --enable-dwz to test it. +- readelf: Add .debug_macro parsing support. Add .gdb_index + version 7 parsing support. Recognize DW_OP_GNU_parameter_ref. +- backends: Add support for Tilera TILE-Gx processor. +- translations: Updated Ukrainian translation. + +* Fri Jun 22 2012 Mark Wielaard 0.154-1 +- libelf: [g]elf[32|64]_offscn() do not match SHT_NOBITS sections at + OFFSET. +- libdw: dwarf_highpc function now handles DWARF 4 DW_AT_high_pc + constant form. Fix bug using dwarf_next_unit to iterate over + .debug_types. +- elflint: Now accepts gold linker produced executables. +- The license is now GPLv2/LGPLv3+ for the libraries and GPLv3+ for + stand-alone programs. There is now also a formal CONTRIBUTING + document describing how to submit patches. + +* Thu Feb 23 2012 Mark Wielaard 0.153-1 +- libdw: Support reading .zdebug_* DWARF sections compressed via zlib. +- libdwfl: Speed up dwfl_module_addrsym. +- nm: Support C++ demangling. +- ar: Support D modifier for "deterministic output" with no + uid/gid/mtime info. The U modifier is the inverse. elfutils + can be configured with the --enable-deterministic-archives option + to make the D behavior the default when U is not specified. +- ranlib: Support -D and -U flags with same meaning. +- readelf: Improve output of -wline. Add support for printing SDT elf + notes. Add printing of .gdb_index section. Support for + typed DWARF stack, call_site and entry_value. +- strip: Add --reloc-debug-sections option. Improved SHT_GROUP + sections handling. + +* Tue Feb 15 2011 0.152-1 +- Various build and warning nits fixed for newest GCC and Autoconf. +- libdwfl: Yet another prelink-related fix for another regression. + Look for Linux kernel images in files named with compression + suffixes. +- elfcmp: New flag --ignore-build-id to ignore differing build ID + bits. New flag -l/--verbose to print all differences. + +* Wed Jan 12 2011 0.151-1 +- libdwfl: Fix for more prelink cases with separate debug file. +- strip: New flag --strip-sections to remove section headers entirely. + +* Mon Nov 22 2010 0.150-1 +- libdw: Fix for handling huge .debug_aranges section. +- libdwfl: Fix for handling prelinked DSO with separate debug file. +- findtextrel: Fix diagnostics to work with usual section ordering. +- libebl: i386 backend fix for multi-register integer return value + location. + +* Mon Sep 13 2010 0.149-1 +- libdw: Decode new DW_OP_GNU_implicit_pointer operation; new + function dwarf_getlocation_implicit_pointer. +- libdwfl: New function dwfl_dwarf_line. +- addr2line: New flag -F/--flags to print more DWARF line information + details. +- strip: -g recognizes .gdb_index as a debugging section. + +* Mon Jun 28 2010 0.148-1 +- libdw: Accept DWARF 4 format: new functions dwarf_next_unit, + dwarf_offdie_types. New functions dwarf_lineisa, + dwarf_linediscriminator, dwarf_lineop_index. +- libdwfl: Fixes in core-file handling, support cores from PIEs. + When working from build IDs, don't open a named file that + mismatches. +- readelf: Handle DWARF 4 formats. + +* Mon May 3 2010 Ulrich Drepper 0.147-1 +- libdw: Fixes in CFI handling, best possible handling of bogus CFA + ops. +- libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r + bugs. + +* Wed Apr 21 2010 0.146-1 +- libdwfl: New function dwfl_core_file_report. + +* Tue Feb 23 2010 Ulrich Drepper 0.145-1 +- Fix build with --disable-dependency-tracking. +- Fix build with most recent glibc headers. +- libelf: More robust to bogus section headers. +- libdw: Fix CFI decoding. +- libdwfl: Fix address bias returned by CFI accessors. Fix core + file module layout identification. +- readelf: Fix CFI decoding. + +* Thu Jan 14 2010 0.144-1 +- libelf: New function elf_getphdrnum. Now support using more than + 65536 program headers in a file. +- libdw: New function dwarf_aggregate_size for computing (constant) + type sizes, including array_type cases with nontrivial + calculation. +- readelf: Don't give errors for missing info under -a. + Handle Linux "VMCOREINFO" notes under -n. + +* Mon Sep 21 2009 0.143-1 +- libdw: Various convenience functions for individual attributes now + use dwarf_attr_integrate to look up indirect inherited + attributes. Location expression handling now supports + DW_OP_implicit_value. +- libdwfl: Support automatic decompression of files in XZ format, + and of Linux kernel images made with bzip2 or LZMA (as well + as gzip). + +* Mon Jun 29 2009 0.142-1 +- libelf: Add elf_getshdrnum alias for elf_getshnum and elf_getshdrstrndx alias + for elf_getshstrndx and deprecate original names. Sun screwed up + their implementation and asked for a solution. +- libebl: Add support for STB_GNU_UNIQUE. +- elflint: Add support for STB_GNU_UNIQUE. +- readelf: Add -N option, speeds up DWARF printing without address->name lookups. +- libdw: Add support for decoding DWARF CFI into location description form. + Handle some new DWARF 3 expression operations previously omitted. + Basic handling of some new encodings slated for DWARF + +* Thu Apr 23 2009 Ulrich Drepper 0.141-1 +- libebl: sparc backend fixes; some more arm backend support +- libdwfl: fix dwfl_module_build_id for prelinked DSO case; + fixes in core file support; dwfl_module_getsym interface + improved for non-address symbols +- strip: fix infinite loop on strange inputs with -f +- addr2line: take -j/--section=NAME option for binutils compatibility + (same effect as '(NAME)0x123' syntax already supported) + +* Mon Feb 16 2009 Ulrich Drepper 0.140-1 +- libelf: Fix regression in creation of section header +- libdwfl: Less strict behavior if DWARF reader is just used to + display data + +* Thu Jan 22 2009 Ulrich Drepper 0.139-1 +- libcpu: Add Intel SSE4 disassembler support +- readelf: Implement call frame information and exception handling + dumping. Add -e option. Enable it implicitly for -a. +- elflint: Check PT_GNU_EH_FRAME program header entry. +- libdwfl: Support automatic gzip/bzip2 decompression of ELF files. + +* Wed Dec 31 2008 Roland McGrath 0.138-1 +- Install header file for applications to use in + source version compatibility checks. +- libebl: backend fixes for i386 TLS relocs; backend support for + NT_386_IOPERM +- libcpu: disassembler fixes +- libdwfl: bug fixes +- libelf: bug fixes +- nm: bug fixes for handling corrupt input files + +* Tue Aug 26 2008 Ulrich Drepper 0.137-1 +- Minor fixes for unreleased 0.136 release. + +* Mon Aug 25 2008 Ulrich Drepper 0.136-1 +- libdwfl: bug fixes; new segment interfaces; all the libdwfl-based + tools now support --core=COREFILE option + +* Mon May 12 2008 Ulrich Drepper 0.135-1 +- libdwfl: bug fixes +- strip: changed handling of ET_REL files wrt symbol tables and relocs + +* Tue Apr 8 2008 Ulrich Drepper 0.134-1 +- elflint: backend improvements for sparc, alpha +- libdwfl, libelf: bug fixes + +* Sat Mar 1 2008 Ulrich Drepper 0.133-1 +- readelf, elflint, libebl: SHT_GNU_ATTRIBUTE section handling (readelf -A) +- readelf: core note handling for NT_386_TLS, NT_PPC_SPE, Alpha NT_AUXV +- libdwfl: bug fixes and optimization in relocation handling +- elfcmp: bug fix for non-allocated section handling +- ld: implement newer features of binutils linker. + +* Mon Jan 21 2008 Ulrich Drepper 0.132-1 +- libcpu: Implement x86 and x86-64 disassembler. +- libasm: Add interface for disassembler. +- all programs: add debugging of branch prediction. +- libelf: new function elf_scnshndx. + +* Sun Nov 11 2007 Ulrich Drepper 0.131-1 +- libdw: DW_FORM_ref_addr support; dwarf_formref entry point now depreca +ted; bug fixes for oddly-formatted DWARF +- libdwfl: bug fixes in offline archive support, symbol table handling; + apply partial relocations for dwfl_module_address_section on +ET_REL +- libebl: powerpc backend support for Altivec registers + +* Mon Oct 15 2007 Ulrich Drepper 0.130-1 +- readelf: -p option can take an argument like -x for one section, + or no argument (as before) for all SHF_STRINGS sections; + new option --archive-index (or -c); improved -n output for +core files, on many machines +- libelf: new function elf_getdata_rawchunk, replaces gelf_rawchunk; + new functions gelf_getnote, gelf_getauxv, gelf_update_auxv +- readelf, elflint: handle SHT_NOTE sections without requiring phdrs +- elflint: stricter checks on debug sections +- libdwfl: new functions dwfl_build_id_find_elf, dwfl_build_id_find_debu +ginfo, dwfl_module_build_id, dwfl_module_report_build_id; suppo +rt dynamic symbol tables found via phdrs; dwfl_standard_find_de +buginfo now uses build IDs when available +- unstrip: new option --list (or -n) +- libebl: backend improvements for sparc, alpha, powerpc + +* Tue Aug 14 2007 Ulrich Drepper 0.129-1 +- readelf: new options --hex-dump (or -x), --strings (or -p) +- addr2line: new option --symbols (or -S) + +* Wed Apr 18 2007 Ulrich Drepper 0.127-1 +- libdw: new function dwarf_getsrcdirs +- libdwfl: new functions dwfl_module_addrsym, dwfl_report_begin_add, + dwfl_module_address_section + +* Mon Feb 5 2007 Ulrich Drepper 0.126-1 +- new program: ar + +* Mon Dec 18 2006 Ulrich Drepper 0.125-1 +- elflint: Compare DT_GNU_HASH tests. +- move archives into -static RPMs +- libelf, elflint: better support for core file handling + +* Tue Oct 10 2006 Ulrich Drepper 0.124-1 +- libebl: sparc backend support for return value location +- libebl, libdwfl: backend register name support extended with more info +- libelf, libdw: bug fixes for unaligned accesses on machines that care +- readelf, elflint: trivial bugs fixed + +* Mon Aug 14 2006 Roland McGrath 0.123-1 +- libebl: Backend build fixes, thanks to Stepan Kasal. +- libebl: ia64 backend support for register names, return value location +- libdwfl: Handle truncated linux kernel module section names. +- libdwfl: Look for linux kernel vmlinux files with .debug suffix. +- elflint: Fix checks to permit --hash-style=gnu format. + +* Wed Jul 12 2006 Ulrich Drepper 0.122-1 +- libebl: add function to test for relative relocation +- elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks +- elflint, readelf: add support for DT_GNU_HASHlibelf: add elf_gnu_hash +- elflint, readelf: add support for 64-bit SysV-style hash tables +- libdwfl: new functions dwfl_module_getsymtab, dwfl_module_getsym. + +* Wed Jun 14 2006 0.121-1 +- libelf: bug fixes for rewriting existing files when using mmap. +- make all installed headers usable in C++ code. +- readelf: better output format. +- elflint: fix tests of dynamic section content. +- ld: Implement --as-needed, --execstack, PT_GNU_STACK. Many small patc +hes. +- libdw, libdwfl: handle files without aranges info. + +* Tue Apr 4 2006 Ulrich Drepper 0.120-1 +- Bug fixes. +- dwarf.h updated for DWARF 3.0 final specification. +- libdwfl: New function dwfl_version. +- The license is now GPL for most files. The libelf, libebl, libdw,and +libdwfl libraries have additional exceptions. Add reference toOIN. + +* Thu Jan 12 2006 Roland McGrath 0.119-1 +- elflint: more tests. +- libdwfl: New function dwfl_module_register_names. +- libebl: New backend hook for register names. + +* Tue Dec 6 2005 Ulrich Drepper 0.118-1 +- elflint: more tests. +- libdwfl: New function dwfl_module_register_names. +- libebl: New backend hook for register names. + +* Thu Nov 17 2005 Ulrich Drepper 0.117-1 +- libdwfl: New function dwfl_module_return_value_location. +- libebl: Backend improvements for several CPUs. + +* Mon Oct 31 2005 Ulrich Drepper 0.116-1 +- libdw: New functions dwarf_ranges, dwarf_entrypc, dwarf_diecu, d +warf_entry_breakpoints. Removed Dwarf_Func type and functions d +warf_func_name, dwarf_func_lowpc, dwarf_func_highpc, dwarf_func_ +entrypc, dwarf_func_die; dwarf_getfuncs callback now uses Dwarf_ +Die, and dwarf_func_file, dwarf_func_line, dwarf_func_col replac +ed by dwarf_decl_file, dwarf_decl_line, dwarf_decl_column; dwarf +_func_inline, dwarf_func_inline_instances now take Dwarf_Die. Ty +pe Dwarf_Loc renamed to Dwarf_Op; dwarf_getloclist, dwarf_addrlo +clists renamed dwarf_getlocation, dwarf_getlocation_addr. + +* Fri Sep 2 2005 Ulrich Drepper 0.115-1 +- libelf: speed-ups of non-mmap reading. +- strings: New program. +- Implement --enable-gcov option for configure. +- libdw: New function dwarf_getscopes_die. + +* Wed Aug 24 2005 Ulrich Drepper 0.114-1 +- libelf: new function elf_getaroff +- libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_inst +ances. +- libdwfl: New functions dwfl_report_offline, dwfl_offline_section_addre +ss, dwfl_linux_kernel_report_offline. +- ranlib: new program + +* Mon Aug 15 2005 Ulrich Drepper 0.114-1 +- libelf: new function elf_getaroff +- ranlib: new program + +* Wed Aug 10 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. Allow .rodata +sectionto have STRINGS and MERGE flag set. +- strip: add some more compatibility with binutils. + +* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. Allow .rodata +sectionto have STRINGS and MERGE flag set. + +* Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. + +* Fri Aug 5 2005 Ulrich Drepper <@redhat.com> 0.112-1 +- elfcmp: some more relaxation. +- elflint: many more tests, especially regarding to symbol versioning. +- libelf: Add elfXX_offscn and gelf_offscn. +- libasm: asm_begin interface changes. +- libebl: Add three new interfaces to directly access machine, class, an +ddata encoding information. +- objdump: New program. Just the beginning. + +* Thu Jul 28 2005 Ulrich Drepper <@redhat.com> 0.111-1 +- libdw: now contains all of libdwfl. The latter is not installed anymore. +- elfcmp: little usability tweak, name and index of differing section is + printed. + +* Sun Jul 24 2005 Ulrich Drepper <@redhat.com> 0.110-1 +- libelf: fix a numbe rof problems with elf_update +- elfcmp: fix a few bugs. Compare gaps. +- Fix a few PLT problems and mudflap build issues. +- libebl: Don't expose Ebl structure definition in libebl.h. It's now p +rivate. + +* Thu Jul 21 2005 Ulrich Drepper <@redhat.com> 0.109-1 +- libebl: Check for matching modules. +- elflint: Check that copy relocations only happen for OBJECT or NOTYPE +symbols. +- elfcmp: New program. +- libdwfl: New library. + +* Mon May 9 2005 Ulrich Drepper <@redhat.com> 0.108-1 +- strip: fix bug introduced in last change +- libdw: records returned by dwarf_getsrclines are now sorted by address + +* Sun May 8 2005 Ulrich Drepper <@redhat.com> 0.108-1 +- strip: fix bug introduced in last change + +* Sun May 8 2005 Ulrich Drepper <@redhat.com> 0.107-1 +- readelf: improve DWARF output format +- strip: support Linux kernel modules + +* Fri Apr 29 2005 Ulrich Drepper 0.107-1 +- readelf: improve DWARF output format + +* Mon Apr 4 2005 Ulrich Drepper 0.106-1 +- libdw: Updated dwarf.h from DWARF3 speclibdw: add new functions dwarf_f +unc_entrypc, dwarf_func_file, dwarf_func_line,dwarf_func_col, dwarf_ge +tsrc_file + +* Fri Apr 1 2005 Ulrich Drepper 0.105-1 +- addr2line: New program +- libdw: add new functions: dwarf_addrdie, dwarf_macro_*, dwarf_getfuncs +,dwarf_func_*. +- findtextrel: use dwarf_addrdie + +* Mon Mar 28 2005 Ulrich Drepper 0.104-1 +- findtextrel: New program. + +* Mon Mar 21 2005 Ulrich Drepper 0.103-1 +- libdw: Fix using libdw.h with gcc < 4 and C++ code. Compiler bug. + +* Tue Feb 22 2005 Ulrich Drepper 0.102-1 +- More Makefile and spec file cleanups. + +* Fri Jan 16 2004 Jakub Jelinek 0.94-1 +- upgrade to 0.94 + +* Fri Jan 16 2004 Jakub Jelinek 0.93-1 +- upgrade to 0.93 + +* Thu Jan 8 2004 Jakub Jelinek 0.92-1 +- full version +- macroized spec file for GPL or OSL builds +- include only libelf under GPL plus wrapper scripts + +* Wed Jan 7 2004 Jakub Jelinek 0.91-2 +- macroized spec file for GPL or OSL builds + +* Wed Jan 7 2004 Ulrich Drepper +- split elfutils-devel into two packages. + +* Wed Jan 7 2004 Jakub Jelinek 0.91-1 +- include only libelf under GPL plus wrapper scripts + +* Tue Dec 23 2003 Jeff Johnson 0.89-3 +- readelf, not readline, in %%description (#111214). + +* Fri Sep 26 2003 Bill Nottingham 0.89-1 +- update to 0.89 (fix eu-strip) + +* Tue Sep 23 2003 Jakub Jelinek 0.86-3 +- update to 0.86 (fix eu-strip on s390x/alpha) +- libebl is an archive now; remove references to DSO + +* Mon Jul 14 2003 Jeff Johnson 0.84-3 +- upgrade to 0.84 (readelf/elflint improvements, rawhide bugs fixed). + +* Fri Jul 11 2003 Jeff Johnson 0.83-3 +- upgrade to 0.83 (fix invalid ELf handle on *.so strip, more). + +* Wed Jul 9 2003 Jeff Johnson 0.82-3 +- upgrade to 0.82 (strip tests fixed on big-endian). + +* Tue Jul 8 2003 Jeff Johnson 0.81-3 +- upgrade to 0.81 (strip excludes unused symtable entries, test borked). + +* Thu Jun 26 2003 Jeff Johnson 0.80-3 +- upgrade to 0.80 (debugedit changes for kernel in progress). + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Wed May 21 2003 Jeff Johnson 0.79-2 +- upgrade to 0.79 (correct formats for size_t, more of libdw "works"). + +* Mon May 19 2003 Jeff Johnson 0.78-2 +- upgrade to 0.78 (libdwarf bugfix, libdw additions). + +* Mon Feb 24 2003 Elliot Lee +- debuginfo rebuild + +* Thu Feb 20 2003 Jeff Johnson 0.76-2 +- use the correct way of identifying the section via the sh_info link. + +* Sat Feb 15 2003 Jakub Jelinek 0.75-2 +- update to 0.75 (eu-strip -g fix) + +* Tue Feb 11 2003 Jakub Jelinek 0.74-2 +- update to 0.74 (fix for writing with some non-dirty sections) + +* Thu Feb 6 2003 Jeff Johnson 0.73-3 +- another -0.73 update (with sparc fixes). +- do "make check" in %%check, not %%install, section. + +* Mon Jan 27 2003 Jeff Johnson 0.73-2 +- update to 0.73 (with s390 fixes). + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Wed Jan 22 2003 Jakub Jelinek 0.72-4 +- fix arguments to gelf_getsymshndx and elf_getshstrndx +- fix other warnings +- re-enable checks on s390x + +* Sat Jan 11 2003 Karsten Hopp 0.72-3 +- temporarily disable checks on s390x, until someone has + time to look at it + +* Thu Dec 12 2002 Jakub Jelinek 0.72-2 +- update to 0.72 + +* Wed Dec 11 2002 Jakub Jelinek 0.71-2 +- update to 0.71 + +* Wed Dec 11 2002 Jeff Johnson 0.69-4 +- update to 0.69. +- add "make check" and segfault avoidance patch. +- elfutils-libelf needs to run ldconfig. + +* Tue Dec 10 2002 Jeff Johnson 0.68-2 +- update to 0.68. + +* Fri Dec 6 2002 Jeff Johnson 0.67-2 +- update to 0.67. + +* Tue Dec 3 2002 Jeff Johnson 0.65-2 +- update to 0.65. + +* Mon Dec 2 2002 Jeff Johnson 0.64-2 +- update to 0.64. + +* Sun Dec 1 2002 Ulrich Drepper 0.64 +- split packages further into elfutils-libelf + +* Sat Nov 30 2002 Jeff Johnson 0.63-2 +- update to 0.63. + +* Fri Nov 29 2002 Ulrich Drepper 0.62 +- Adjust for dropping libtool + +* Sun Nov 24 2002 Jeff Johnson 0.59-2 +- update to 0.59 + +* Thu Nov 14 2002 Jeff Johnson 0.56-2 +- update to 0.56 + +* Thu Nov 7 2002 Jeff Johnson 0.54-2 +- update to 0.54 + +* Sun Oct 27 2002 Jeff Johnson 0.53-2 +- update to 0.53 +- drop x86_64 hack, ICE fixed in gcc-3.2-11. + +* Sat Oct 26 2002 Jeff Johnson 0.52-3 +- get beehive to punch a rhpkg generated package. + +* Wed Oct 23 2002 Jeff Johnson 0.52-2 +- build in 8.0.1. +- x86_64: avoid gcc-3.2 ICE on x86_64 for now. + +* Tue Oct 22 2002 Ulrich Drepper 0.52 +- Add libelf-devel to conflicts for elfutils-devel + +* Mon Oct 21 2002 Ulrich Drepper 0.50 +- Split into runtime and devel package + +* Fri Oct 18 2002 Ulrich Drepper 0.49 +- integrate into official sources + +* Wed Oct 16 2002 Jeff Johnson 0.46-1 +- Swaddle. diff --git a/lib/ChangeLog b/lib/ChangeLog new file mode 100644 index 00000000..dd3ebcab --- /dev/null +++ b/lib/ChangeLog @@ -0,0 +1,338 @@ +2021-04-19 Martin Liska + + * system.h (startswith): New function. + (pwrite_retry): Cast to char *. + (write_retry): Likewise. + (pread_retry): Likewise. + +2021-02-05 Mark Wielaard + + * printversion.c (print_version): Update copyright year. + +2020-12-16 Dmitry V. Levin + + * color.c (parse_opt): Replace gettext(...) and + dgettext("elfutils, ...) with _(...). + * printversion.c (print_version): Replace gettext(...) with _(...). + * system.h (sgettext): Likewise. + + * eu-config.h (_): New macro. + * xmalloc.c (_): Remove. + +2020-11-01 Érico N. Rolim + + * system.h (ACCESSPERMS): Define macro if it doesn't exist. + (ALLPERMS): Likewise. + (DEFFILEMODE): Likewise. + +2020-06-11 Mark Wielaaard + + * printversion.c (print_version): Update copyright year. + +2019-08-25 Srđan Milaković + + * dynamicsizehash_concurrent.{c,h}: New files. + * Makefile.am (noinst_HEADERS): Added dynamicsizehash_concurrent.h. + +2019-08-25 Jonathon Anderson + + * stdatomic-fbsd.h: New file, taken from FreeBSD. + * atomics.h: New file. + * Makefile.am (noinst_HEADERS): Added *.h above. + +2019-05-03 Rosen Penev + + * color.c (parse_opt): Cast program_invocation_short_name to char *. + +2018-11-04 Mark Wielaard + + * bpf.h: Add BPF_JLT, BPF_JLE, BPF_JSLT and BPF_JSLE. + +2018-07-04 Ross Burton + + * color.c: Remove error.h, add system.h include. + * system.h: Add error.h include. + * xmalloc.c: Remove error.h include. + +2018-06-01 Mark Wielaard + + * printversion.c (print_version): Update copyright year. + +2018-02-09 Joshua Watt + + * eu-config.h (FALLTHROUGH): New macro. + +2017-10-16 Mark Wielaard + + * md5.{c,h}: Removed. + * sha1.{c,h}: Likewise. + * Makefile.am (libeu_a_SOURCES): Remove md5.c and sha1.c. + (noinst_HEADERS): Remove md5.h and sha1.h. + +2017-08-18 Ulf Hermann + + * eu-config.h: Define attribute_packed to either + __attribute__((packed)) or __attribute__((packed, gcc_struct)). + +2017-04-27 Ulf Hermann + + * eu-config.h: Define attribute_hidden to be empty if the compiler + doesn't support it. + +2017-04-27 Ulf Hermann + + * Makefile.am: Use fpic_CFLAGS. + +2017-07-18 Mark Wielaard + + * bpf.h: New file. + * Makefile.am (noinst_HEADERS): Add bpf.h + +2017-05-05 Mark Wielaard + + * printversion.c (print_version): Update copyright year. + +2017-04-20 Ulf Hermann + + * crc32.c: include config.h. + * system.h: Don't include config.h. + +2017-02-16 Ulf Hermann + + * Makefile.am (libeu_a_SOURCES): Remove version.c, add printversion.c + (noinst_HEADERS): Add printversion.h + * version.c: Moved to printversion.c. + * printversion.c: New file, moved from version.c, + remove stdio.h, argp.h, system.h includes, + add printversion.h include. + * printversion.h: New file. + * system.h: Remove argp.h include, + (ARGP_PROGRAM_VERSION_HOOK_DEF, ARGP_PROGRAM_BUG_ADDRESS_DEF): Remove. + (print_version): Remove. + +2017-02-15 Ulf Hermann + + * system.h: Provide mempcpy if it doesn't exist. + * xstrndup.c: Include system.h. + +2017-02-15 Ulf Hermann + + * crc32_file.c: Use _SC_PAGESIZE rather than _SC_PAGE_SIZE. + +2017-02-14 Ulf Hermann + + * color.h: New file. + * color.c: Include color.h. + * libeu.h: Remove color handling. + * Makefile.am (noinst_HEADERS): Add color.h. + +2016-12-29 Luiz Angelo Daros de Luca + + * crc32_file.c: Include system.h. + * system.h: Remove semi-colon after TEMP_FAILURE_RETRY definition. + +2016-12-24 Mark Wielaard + + * version.c: New source file. + * Makefile.am (libeu_a_SOURCES): Add version.c + * system.h (print_version): New function definition. + +2016-10-11 Akihiko Odaki + + * fixedsizehash.h (CONCAT): Use __CONCAT when available. + * system.h: Include config.h and errno.h. + (powerof2): Define if not already defined. + (TEMP_FAILURE_RETRY): Define when not yet defined. + +2015-10-11 Akihiko Odaki + + * Makefile.am (noinst_HEADERS): Add libeu.h. + * color.c: Remove system.h include, add libeu.h include. + * crc32_file.c: Likewise. + * fixedsizehash.h: Remove sys/param.h include. + * libeu.h: New file. + * system.h: Include sys/param.h. + (xmalloc, xcalloc, xrealloc, xstrdup, xstrndup, crc32, crc32_file, + color_argp, color_enum, color_*): Move definitions to libeu.h. + * xstrdup.c: Remove system.h include, add libeu.h include. + * xstrndup.c: Remove system.h include, add libeu.h and stdint.h + includes. + +2015-09-24 Jose E. Marchesi + + * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid relocation + overflows in some platforms. + +2015-09-22 Mark Wielaard + + * dynamicsizehash.c: Remove old-style function definitions. + * md5.c: Likewise. + * sha1.c: Likewise. + * xmalloc.c: Likewise. + * xstrdup.c: Likewise. + * xstrndup.c: Likewise. + +2015-05-31 Mark Wielaard + + * eu-config.h (ALLOW_UNALIGNED): Define when ! CHECK_UNDEFINED. + +2015-04-23 Max Filippov + + * eu-config.h: Use SYMBOL_VERSIONING as guard. + +2014-01-17 Lei Zhang + + * crc32_file.c: Include config.h. + +2013-12-12 Josh Stone + + * dynamicsizehash.c (lookup): Add a shortcut around division. + +2013-04-30 Jan Kratochvil + + * eu-config.h (COMPAT_VERSION_NEWPROTO): New. Twice. + +2013-04-26 Jan Kratochvil + + * system.h (LE64, BE64): Move here the definitions from + libdwfl/link_map.c. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2012-10-09 Adam Markey + + * system.h: Changed pwrite_retry, write_retry, and pread_retry to + handle case where not all data was read/written. + +2012-10-08 Jan Kratochvil + + * system.h (eu_static_assert): New macro. + +2012-01-21 Ulrich Drepper + + * Makefile.am (libeu_a_SOURCES): Add color.c. + * system.h: Declare color_argp. Define color_enum. Declare + color_* variables. + * color.c: New file. + +2011-10-02 Ulrich Drepper + + * system.h: Declare __cxa_demangle. + +2011-07-09 Roland McGrath + + * sha1.c (be64_copy): New function. + (sha1_finish_ctx): Use it. + * md5.c (le64_copy): New function. + (md5_finish_ctx): Use it. + * system.h (LE32, BE32): New macros, using and . + * md5.c (SWAP): Use LE32. + * sha1.c (SWAP): Use BE32. + +2010-06-16 Roland McGrath + + * dynamicsizehash.h (HASHTYPE): New macro. + (struct): Use size_t for table sizes. + * dynamicsizehash.c: Likewise. Use HASHTYPE for hash values. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2009-08-09 Roland McGrath + + * eu-config.h (OLD_VERSION, NEW_VERSION, COMPAT_VERSION): New macros. + +2009-01-23 Roland McGrath + + * eu-config.h: Add multiple inclusion protection. + +2009-01-17 Ulrich Drepper + + * system.h (ARGP_PROGRAM_VERSION_HOOK_DEF): Define. + (ARGP_PROGRAM_BUG_ADDRESS_DEF): Define. + +2009-01-10 Ulrich Drepper + + * eu-config.h: Remove tls_key_t, key_create, getspecific, setspecific, + once_define, and once_execute macros. Use USE_LOCKS instead of + USE_TLS. + +2008-08-25 Roland McGrath + + * eu-config.h [USE_TLS] (RWLOCK_CALL): New macro. + (rwlock_init, rwlock_fini, rwlock_rdlock, rwlock_wrlock, rwlock_unlock): + Use it. + +2008-08-24 Roland McGrath + + * eu-config.h: New file. + * Makefile.am (noinst_HEADERS): Add it. + +2008-02-01 Ulrich Drepper + + * Makefile.am (libeu_a_SOURCES): Add sha1.c. + (noinst_HEADERS): Add sha1.h. + * sha1.c: New file. + * sha1.h: New file. + +2008-01-31 Ulrich Drepper + + * Makefile.am (libeu_a_SOURCES): Add md5.c. + (noinst_HEADERS): Add md5.h. + * md5.c: New file. + * md5.h: New file. + +2006-04-04 Ulrich Drepper + + * Makefile.am (libeu_a_SOURCES): We don't need xstrdup in the moment. + +2005-08-28 Ulrich Drepper + + * system.h: Define pwrite_retry, write_retry, and pread_retry. + +2005-08-06 Ulrich Drepper + + * Makefile.am (xmalloc_CFLAGS): Define only if !GPROF. + +2005-05-03 Roland McGrath + + * crc32_file.c: New file. + * Makefile.am (libeu_a_SOURCES): Add it. + * system.h: Declare crc32_file. + +2005-04-30 Ulrich Drepper + + * Makefile.am: Use -ffunction-sections for xmalloc.c. + +2005-02-15 Ulrich Drepper + + * dynamicsizehash.c (lookup): Mark val parameter as possibly unused. + +2005-02-06 Ulrich Drepper + + * fixedsizehash.h: Mark unused parameters. Correct CLASS and + const order for fshash_find. + + * Makefile.am: Cleanup AM_CFLAGS handling. Add -Wunused -Wextra. + +2005-02-05 Ulrich Drepper + + * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fpic and -fmudflap. + +2004-01-17 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + +2003-09-22 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add -fpic. + + * Makefile.am (noinst_HEADERS): Add list.h. + * list.h: New file. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 00000000..97bf7329 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,47 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 1996-2011 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +AM_CFLAGS += $(fpic_CFLAGS) +AM_CPPFLAGS += -I$(srcdir)/../libelf + +noinst_LIBRARIES = libeu.a + +libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \ + crc32.c crc32_file.c \ + color.c printversion.c + +noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \ + eu-config.h color.h printversion.h bpf.h \ + atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h +EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c + +if !GPROF +xmalloc_CFLAGS = -ffunction-sections +endif diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 00000000..c065cc3e --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,726 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libeu_a_AR = $(AR) $(ARFLAGS) +libeu_a_LIBADD = +am_libeu_a_OBJECTS = xstrdup.$(OBJEXT) xstrndup.$(OBJEXT) \ + xmalloc.$(OBJEXT) next_prime.$(OBJEXT) crc32.$(OBJEXT) \ + crc32_file.$(OBJEXT) color.$(OBJEXT) printversion.$(OBJEXT) +libeu_a_OBJECTS = $(am_libeu_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/color.Po ./$(DEPDIR)/crc32.Po \ + ./$(DEPDIR)/crc32_file.Po ./$(DEPDIR)/next_prime.Po \ + ./$(DEPDIR)/printversion.Po ./$(DEPDIR)/xmalloc.Po \ + ./$(DEPDIR)/xstrdup.Po ./$(DEPDIR)/xstrndup.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libeu_a_SOURCES) +DIST_SOURCES = $(libeu_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(srcdir)/../libelf + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes \ + $(TRAMPOLINES_WARNING) $(LOGICAL_OP_WARNING) \ + $(DUPLICATED_COND_WARNING) $(NULL_DEREFERENCE_WARNING) \ + $(IMPLICIT_FALLTHROUGH_WARNING) $(if \ + $($(*F)_no_Werror),,-Werror) $(if \ + $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \ + $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) $(if \ + $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) $(fpic_CFLAGS) +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +noinst_LIBRARIES = libeu.a +libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \ + crc32.c crc32_file.c \ + color.c printversion.c + +noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \ + eu-config.h color.h printversion.h bpf.h \ + atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h + +EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c +@GPROF_FALSE@xmalloc_CFLAGS = -ffunction-sections +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libeu.a: $(libeu_a_OBJECTS) $(libeu_a_DEPENDENCIES) $(EXTRA_libeu_a_DEPENDENCIES) + $(AM_V_at)-rm -f libeu.a + $(AM_V_AR)$(libeu_a_AR) libeu.a $(libeu_a_OBJECTS) $(libeu_a_LIBADD) + $(AM_V_at)$(RANLIB) libeu.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc32_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/next_prime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printversion.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrdup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrndup.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/color.Po + -rm -f ./$(DEPDIR)/crc32.Po + -rm -f ./$(DEPDIR)/crc32_file.Po + -rm -f ./$(DEPDIR)/next_prime.Po + -rm -f ./$(DEPDIR)/printversion.Po + -rm -f ./$(DEPDIR)/xmalloc.Po + -rm -f ./$(DEPDIR)/xstrdup.Po + -rm -f ./$(DEPDIR)/xstrndup.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/color.Po + -rm -f ./$(DEPDIR)/crc32.Po + -rm -f ./$(DEPDIR)/crc32_file.Po + -rm -f ./$(DEPDIR)/next_prime.Po + -rm -f ./$(DEPDIR)/printversion.Po + -rm -f ./$(DEPDIR)/xmalloc.Po + -rm -f ./$(DEPDIR)/xstrdup.Po + -rm -f ./$(DEPDIR)/xstrndup.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/atomics.h b/lib/atomics.h new file mode 100644 index 00000000..ffd12f87 --- /dev/null +++ b/lib/atomics.h @@ -0,0 +1,37 @@ +/* Conditional wrapper header for C11-style atomics. + Copyright (C) 2019-2019 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include "config.h" + +#if HAVE_STDATOMIC_H +/* If possible, use the compiler's preferred atomics. */ +# include +#else +/* Otherwise, try to use the builtins provided by this compiler. */ +# include "stdatomic-fbsd.h" +#endif /* HAVE_STDATOMIC_H */ diff --git a/lib/bpf.h b/lib/bpf.h new file mode 100644 index 00000000..efb26f8f --- /dev/null +++ b/lib/bpf.h @@ -0,0 +1,86 @@ +/* Minimal extended BPF constants as alternative for linux/bpf.h. */ + +#ifndef _ELFUTILS_BPF_H +#define _ELFUTILS_BPF_H 1 + +#include + +#define BPF_CLASS(code) ((code) & 0x07) + +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +#define BPF_ALU64 0x07 + +#define BPF_JNE 0x50 +#define BPF_JSGT 0x60 +#define BPF_JSGE 0x70 +#define BPF_CALL 0x80 +#define BPF_EXIT 0x90 +#define BPF_JLT 0xa0 +#define BPF_JLE 0xb0 +#define BPF_JSLT 0xc0 +#define BPF_JSLE 0xd0 + +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 + +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +#define BPF_DW 0x18 +#define BPF_XADD 0xc0 + +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 + +#define BPF_MOV 0xb0 +#define BPF_ARSH 0xc0 + +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 + +#define BPF_K 0x00 +#define BPF_X 0x08 + +#define BPF_END 0xd0 +#define BPF_TO_LE 0x00 +#define BPF_TO_BE 0x08 + +#define BPF_PSEUDO_MAP_FD 1 + +#define MAX_BPF_REG 10 + +struct bpf_insn +{ + uint8_t code; + uint8_t dst_reg:4; + uint8_t src_reg:4; + int16_t off; + int32_t imm; +}; + +#endif diff --git a/lib/color.c b/lib/color.c new file mode 100644 index 00000000..454cb7ca --- /dev/null +++ b/lib/color.c @@ -0,0 +1,238 @@ +/* Handling of color output. + Copyright (C) 2011 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2011. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include "system.h" +#include "libeu.h" +#include "color.h" + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Option values. */ +#define OPT_COLOR 0x100100 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { "color", OPT_COLOR, "WHEN", OPTION_ARG_OPTIONAL, + N_("colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'"), 0 }, + + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Parser data structure. */ +const struct argp color_argp = + { + options, parse_opt, NULL, NULL, NULL, NULL, NULL + }; + +/* Coloring mode. */ +enum color_enum color_mode; + +/* Colors to use for the various components. */ +char *color_address = ""; +char *color_bytes = ""; +char *color_mnemonic = ""; +char *color_operand = NULL; +char *color_operand1 = ""; +char *color_operand2 = ""; +char *color_operand3 = ""; +char *color_operand4 = ""; +char *color_operand5 = ""; +char *color_label = ""; +char *color_undef = ""; +char *color_undef_tls = ""; +char *color_undef_weak = ""; +char *color_symbol = ""; +char *color_tls = ""; +char *color_weak = ""; + +const char color_off[] = "\e[0m"; + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case OPT_COLOR: + if (arg == NULL) + color_mode = color_always; + else + { + static const struct + { + const char str[7]; + enum color_enum mode; + } values[] = + { + { "always", color_always }, + { "yes", color_always }, + { "force", color_always }, + { "never", color_never }, + { "no", color_never }, + { "none", color_never }, + { "auto", color_auto }, + { "tty", color_auto }, + { "if-tty", color_auto } + }; + const int nvalues = sizeof (values) / sizeof (values[0]); + int i; + for (i = 0; i < nvalues; ++i) + if (strcmp (arg, values[i].str) == 0) + { + color_mode = values[i].mode; + if (color_mode == color_auto) + color_mode + = isatty (STDOUT_FILENO) ? color_always : color_never; + break; + } + if (i == nvalues) + { + error (0, 0, _("\ +%s: invalid argument '%s' for '--color'\n\ +valid arguments are:\n\ + - 'always', 'yes', 'force'\n\ + - 'never', 'no', 'none'\n\ + - 'auto', 'tty', 'if-tty'\n"), + program_invocation_short_name, arg); + argp_help (&color_argp, stderr, ARGP_HELP_SEE, + (char *) program_invocation_short_name); + exit (EXIT_FAILURE); + } + } + + if (color_mode == color_always) + { + const char *env = getenv ("ELFUTILS_COLORS"); + if (env != NULL) + { + do + { + const char *start = env; + while (*env != '=' && *env != '\0') + ++env; + if (*env == '=' && env != start) + { + size_t name_len = env - start; + const char *val = ++env; + env = strchrnul (env, ':'); + if (val != env) + { + static const struct + { + unsigned char len; + const char name[sizeof (char *) - 1]; + char **varp; + } known[] = + { +#define E(name, var) { sizeof (#name) - 1, #name, &color_##var } + E (a, address), + E (b, bytes), + E (m, mnemonic), + E (o, operand), + E (o1, operand1), + E (o2, operand2), + E (o3, operand3), + E (o4, operand4), + E (o5, operand5), + E (l, label), + E (u, undef), + E (ut, undef_tls), + E (uw, undef_weak), + E (sy, symbol), + E (st, tls), + E (sw, weak), + }; + const size_t nknown = (sizeof (known) + / sizeof (known[0])); + + for (size_t i = 0; i < nknown; ++i) + if (name_len == known[i].len + && memcmp (start, known[i].name, name_len) == 0) + { + if (asprintf (known[i].varp, "\e[%.*sm", + (int) (env - val), val) < 0) + error (EXIT_FAILURE, errno, + _("cannot allocate memory")); + break; + } + } + if (*env == ':') + ++env; + } + } + while (*env != '\0'); + + if (color_operand != NULL) + { + if (color_operand1[0] == '\0') + color_operand1 = color_operand; + if (color_operand2[0] == '\0') + color_operand2 = color_operand; + if (color_operand3[0] == '\0') + color_operand3 = color_operand; + if (color_operand4[0] == '\0') + color_operand4 = color_operand; + if (color_operand5[0] == '\0') + color_operand5 = color_operand; + } + } +#if 0 + else + { + // XXX Just for testing. + color_address = xstrdup ("\e[38;5;166;1m"); + color_bytes = xstrdup ("\e[38;5;141m"); + color_mnemonic = xstrdup ("\e[38;5;202;1m"); + color_operand1 = xstrdup ("\e[38;5;220m"); + color_operand2 = xstrdup ("\e[38;5;48m"); + color_operand = xstrdup ("\e[38;5;112m"); + color_label = xstrdup ("\e[38;5;21m"); + } +#endif + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} diff --git a/lib/color.h b/lib/color.h new file mode 100644 index 00000000..cb241435 --- /dev/null +++ b/lib/color.h @@ -0,0 +1,65 @@ +/* Handling of color output. + Copyright (C) 2017 The Qt Company + This file is part of elfutils. + Written by Ulrich Drepper , 2011. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +#ifndef COLOR_H +#define COLOR_H 1 + +/* Command line parser. */ +extern const struct argp color_argp; + +/* Coloring mode. */ +enum color_enum + { + color_never = 0, + color_always, + color_auto + } __attribute__ ((packed)); +extern enum color_enum color_mode; + +/* Colors to use for the various components. */ +extern char *color_address; +extern char *color_bytes; +extern char *color_mnemonic; +extern char *color_operand1; +extern char *color_operand2; +extern char *color_operand3; +extern char *color_operand4; +extern char *color_operand5; +extern char *color_label; +extern char *color_undef; +extern char *color_undef_tls; +extern char *color_undef_weak; +extern char *color_symbol; +extern char *color_tls; +extern char *color_weak; + +extern const char color_off[]; + +#endif /* color.h */ diff --git a/lib/crc32.c b/lib/crc32.c new file mode 100644 index 00000000..758602ea --- /dev/null +++ b/lib/crc32.c @@ -0,0 +1,102 @@ +/* Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include "system.h" + + +/* Table computed with Mark Adler's makecrc.c utility. */ +static const uint32_t crc32_table[256] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d +}; + +uint32_t +crc32 (uint32_t crc, unsigned char *buf, size_t len) +{ + unsigned char *end; + + crc = ~crc; + for (end = buf + len; buf < end; ++buf) + crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); + return ~crc; +} diff --git a/lib/crc32_file.c b/lib/crc32_file.c new file mode 100644 index 00000000..f7607d0b --- /dev/null +++ b/lib/crc32_file.c @@ -0,0 +1,92 @@ +/* Compute CRC32 checksum of file contents. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libeu.h" +#include +#include +#include +#include +#include "system.h" + +int +crc32_file (int fd, uint32_t *resp) +{ + unsigned char buffer[1024 * 8]; + uint32_t crc = 0; + off_t off = 0; + ssize_t count; + + struct stat st; + if (fstat (fd, &st) == 0) + { + /* Try mapping in the file data. */ + size_t mapsize = st.st_size; + void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0); + if (mapped == MAP_FAILED && errno == ENOMEM) + { + const size_t pagesize = sysconf (_SC_PAGESIZE); + mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize; + while (mapsize >= pagesize + && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, + fd, 0)) == MAP_FAILED && errno == ENOMEM) + mapsize /= 2; + } + if (mapped != MAP_FAILED) + { + do + { + if (st.st_size <= (off_t) mapsize) + { + *resp = crc32 (crc, mapped, st.st_size); + munmap (mapped, mapsize); + return 0; + } + crc = crc32 (crc, mapped, mapsize); + off += mapsize; + st.st_size -= mapsize; + } while (mmap (mapped, mapsize, PROT_READ, MAP_FIXED|MAP_PRIVATE, + fd, off) == mapped); + munmap (mapped, mapsize); + } + } + + while ((count = TEMP_FAILURE_RETRY (pread (fd, buffer, sizeof buffer, + off))) > 0) + { + off += count; + crc = crc32 (crc, buffer, count); + } + + *resp = crc; + + return count == 0 ? 0 : -1; +} diff --git a/lib/dynamicsizehash.c b/lib/dynamicsizehash.c new file mode 100644 index 00000000..f9406eba --- /dev/null +++ b/lib/dynamicsizehash.c @@ -0,0 +1,315 @@ +/* Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include +#include + +/* Before including this file the following macros must be defined: + + NAME name of the hash table structure. + TYPE data type of the hash table entries + COMPARE comparison function taking two pointers to TYPE objects + + The following macros if present select features: + + ITERATE iterating over the table entries is possible + REVERSE iterate in reverse order of insert + */ + + +static size_t +lookup (NAME *htab, HASHTYPE hval, TYPE val __attribute__ ((unused))) +{ + /* First hash function: simply take the modul but prevent zero. Small values + can skip the division, which helps performance when this is common. */ + size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size); + + if (htab->table[idx].hashval != 0) + { + HASHTYPE hash; + + if (htab->table[idx].hashval == hval + && COMPARE (htab->table[idx].data, val) == 0) + return idx; + + /* Second hash function as suggested in [Knuth]. */ + hash = 1 + hval % (htab->size - 2); + + do + { + if (idx <= hash) + idx = htab->size + idx - hash; + else + idx -= hash; + + /* If entry is found use it. */ + if (htab->table[idx].hashval == hval + && COMPARE (htab->table[idx].data, val) == 0) + return idx; + } + while (htab->table[idx].hashval); + } + return idx; +} + + +static void +insert_entry_2 (NAME *htab, HASHTYPE hval, size_t idx, TYPE data) +{ +#ifdef ITERATE + if (htab->table[idx].hashval == 0) + { +# ifdef REVERSE + htab->table[idx].next = htab->first; + htab->first = &htab->table[idx]; +# else + /* Add the new value to the list. */ + if (htab->first == NULL) + htab->first = htab->table[idx].next = &htab->table[idx]; + else + { + htab->table[idx].next = htab->first->next; + htab->first = htab->first->next = &htab->table[idx]; + } +# endif + } +#endif + + htab->table[idx].hashval = hval; + htab->table[idx].data = data; + + ++htab->filled; + if (100 * htab->filled > 90 * htab->size) + { + /* Table is filled more than 90%. Resize the table. */ +#ifdef ITERATE + __typeof__ (htab->first) first; +# ifndef REVERSE + __typeof__ (htab->first) runp; +# endif +#else + size_t old_size = htab->size; +#endif +#define _TABLE(name) \ + name##_ent *table = htab->table +#define TABLE(name) _TABLE (name) + TABLE(NAME); + + htab->size = next_prime (htab->size * 2); + htab->filled = 0; +#ifdef ITERATE + first = htab->first; + htab->first = NULL; +#endif + htab->table = calloc ((1 + htab->size), sizeof (htab->table[0])); + if (htab->table == NULL) + { + /* We cannot enlarge the table. Live with what we got. This + might lead to an infinite loop at some point, though. */ + htab->table = table; + return; + } + + /* Add the old entries to the new table. When iteration is + supported we maintain the order. */ +#ifdef ITERATE +# ifdef REVERSE + while (first != NULL) + { + insert_entry_2 (htab, first->hashval, + lookup (htab, first->hashval, first->data), + first->data); + + first = first->next; + } +# else + assert (first != NULL); + runp = first = first->next; + do + insert_entry_2 (htab, runp->hashval, + lookup (htab, runp->hashval, runp->data), runp->data); + while ((runp = runp->next) != first); +# endif +#else + for (idx = 1; idx <= old_size; ++idx) + if (table[idx].hashval != 0) + insert_entry_2 (htab, table[idx].hashval, + lookup (htab, table[idx].hashval, table[idx].data), + table[idx].data); +#endif + + free (table); + } +} + + +int +#define INIT(name) _INIT (name) +#define _INIT(name) \ + name##_init +INIT(NAME) (NAME *htab, size_t init_size) +{ + /* We need the size to be a prime. */ + init_size = next_prime (init_size); + + /* Initialize the data structure. */ + htab->size = init_size; + htab->filled = 0; +#ifdef ITERATE + htab->first = NULL; +#endif + htab->table = (void *) calloc ((init_size + 1), sizeof (htab->table[0])); + if (htab->table == NULL) + return -1; + + return 0; +} + + +int +#define FREE(name) _FREE (name) +#define _FREE(name) \ + name##_free +FREE(NAME) (NAME *htab) +{ + free (htab->table); + return 0; +} + + +int +#define INSERT(name) _INSERT (name) +#define _INSERT(name) \ + name##_insert +INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data) +{ + size_t idx; + + /* Make the hash value nonzero. */ + hval = hval ?: 1; + + idx = lookup (htab, hval, data); + + if (htab->table[idx].hashval != 0) + /* We don't want to overwrite the old value. */ + return -1; + + /* An empty bucket has been found. */ + insert_entry_2 (htab, hval, idx, data); + return 0; +} + + +#ifdef OVERWRITE +int +#define INSERT(name) _INSERT (name) +#define _INSERT(name) \ + name##_overwrite +INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data) +{ + size_t idx; + + /* Make the hash value nonzero. */ + hval = hval ?: 1; + + idx = lookup (htab, hval, data); + + /* The correct bucket has been found. */ + insert_entry_2 (htab, hval, idx, data); + return 0; +} +#endif + + +TYPE +#define FIND(name) _FIND (name) +#define _FIND(name) \ + name##_find +FIND(NAME) (NAME *htab, HASHTYPE hval, TYPE val) +{ + size_t idx; + + /* Make the hash value nonzero. */ + hval = hval ?: 1; + + idx = lookup (htab, hval, val); + + if (htab->table[idx].hashval == 0) + return NULL; + + return htab->table[idx].data; +} + + +#ifdef ITERATE +# define ITERATEFCT(name) _ITERATEFCT (name) +# define _ITERATEFCT(name) \ + name##_iterate +TYPE +ITERATEFCT(NAME) (NAME *htab, void **ptr) +{ + void *p = *ptr; + +# define TYPENAME(name) _TYPENAME (name) +# define _TYPENAME(name) name##_ent + +# ifdef REVERSE + if (p == NULL) + p = htab->first; + else + p = ((TYPENAME(NAME) *) p)->next; + + if (p == NULL) + { + *ptr = NULL; + return NULL; + } +# else + if (p == NULL) + { + if (htab->first == NULL) + return NULL; + p = htab->first->next; + } + else + { + if (p == htab->first) + return NULL; + + p = ((TYPENAME(NAME) *) p)->next; + } +# endif + + /* Prepare the next element. If possible this will pull the data + into the cache, for reading. */ + __builtin_prefetch (((TYPENAME(NAME) *) p)->next, 0, 2); + + return ((TYPENAME(NAME) *) (*ptr = p))->data; +} +#endif diff --git a/lib/dynamicsizehash.h b/lib/dynamicsizehash.h new file mode 100644 index 00000000..ccd41d0f --- /dev/null +++ b/lib/dynamicsizehash.h @@ -0,0 +1,127 @@ +/* Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include + +/* Before including this file the following macros must be defined: + + NAME name of the hash table structure. + TYPE data type of the hash table entries + + The following macros if present select features: + + ITERATE iterating over the table entries is possible + HASHTYPE integer type for hash values, default unsigned long int + */ + + +/* Optionally include an entry pointing to the first used entry. */ +#ifdef ITERATE +# define FIRST(name) name##_ent *first; +# define NEXT(name) struct name##_ent *next; +#else +# define FIRST(name) +# define NEXT(name) +#endif + +#ifndef HASHTYPE +# define HASHTYPE unsigned long int +#endif + + +/* Defined separately. */ +extern size_t next_prime (size_t seed); + + +/* Table entry type. */ +#define _DYNHASHENTTYPE(name) \ + typedef struct name##_ent \ + { \ + HASHTYPE hashval; \ + TYPE data; \ + NEXT (name) \ + } name##_ent +#define DYNHASHENTTYPE(name) _DYNHASHENTTYPE (name) +DYNHASHENTTYPE (NAME); + + +/* Type of the dynamic hash table data structure. */ +#define _DYNHASHTYPE(name) \ +typedef struct \ +{ \ + size_t size; \ + size_t filled; \ + name##_ent *table; \ + FIRST (name) \ +} name +#define DYNHASHTYPE(name) _DYNHASHTYPE (name) +DYNHASHTYPE (NAME); + + + +#define _FUNCTIONS(name) \ +/* Initialize the hash table. */ \ +extern int name##_init (name *htab, size_t init_size); \ + \ +/* Free resources allocated for hash table. */ \ +extern int name##_free (name *htab); \ + \ +/* Insert new entry. */ \ +extern int name##_insert (name *htab, HASHTYPE hval, TYPE data); \ + \ +/* Insert new entry, possibly overwrite old entry. */ \ +extern int name##_overwrite (name *htab, HASHTYPE hval, TYPE data); \ + \ +/* Find entry in hash table. */ \ +extern TYPE name##_find (name *htab, HASHTYPE hval, TYPE val); +#define FUNCTIONS(name) _FUNCTIONS (name) +FUNCTIONS (NAME) + + +#ifdef ITERATE +# define _XFUNCTIONS(name) \ +/* Get next element in table. */ \ +extern TYPE name##_iterate (name *htab, void **ptr); +# define XFUNCTIONS(name) _XFUNCTIONS (name) +XFUNCTIONS (NAME) +#endif + +#ifndef NO_UNDEF +# undef DYNHASHENTTYPE +# undef DYNHASHTYPE +# undef FUNCTIONS +# undef _FUNCTIONS +# undef XFUNCTIONS +# undef _XFUNCTIONS +# undef NAME +# undef TYPE +# undef ITERATE +# undef COMPARE +# undef FIRST +# undef NEXT +#endif diff --git a/lib/dynamicsizehash_concurrent.c b/lib/dynamicsizehash_concurrent.c new file mode 100644 index 00000000..2d53bec6 --- /dev/null +++ b/lib/dynamicsizehash_concurrent.c @@ -0,0 +1,482 @@ +/* Copyright (C) 2000-2019 Red Hat, Inc. + This file is part of elfutils. + Written by Srdan Milakovic , 2019. + Derived from Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include +#include +#include + +/* Before including this file the following macros must be defined: + + NAME name of the hash table structure. + TYPE data type of the hash table entries + */ + + +static size_t +lookup (NAME *htab, HASHTYPE hval) +{ + /* First hash function: simply take the modul but prevent zero. Small values + can skip the division, which helps performance when this is common. */ + size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size); + + HASHTYPE hash; + + hash = atomic_load_explicit(&htab->table[idx].hashval, + memory_order_acquire); + if (hash == hval) + return idx; + else if (hash == 0) + return 0; + + /* Second hash function as suggested in [Knuth]. */ + HASHTYPE second_hash = 1 + hval % (htab->size - 2); + + for(;;) + { + if (idx <= second_hash) + idx = htab->size + idx - second_hash; + else + idx -= second_hash; + + hash = atomic_load_explicit(&htab->table[idx].hashval, + memory_order_acquire); + if (hash == hval) + return idx; + else if (hash == 0) + return 0; + } +} + +static int +insert_helper (NAME *htab, HASHTYPE hval, TYPE val) +{ + /* First hash function: simply take the modul but prevent zero. Small values + can skip the division, which helps performance when this is common. */ + size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size); + + TYPE val_ptr; + HASHTYPE hash; + + hash = atomic_load_explicit(&htab->table[idx].hashval, + memory_order_acquire); + if (hash == hval) + return -1; + else if (hash == 0) + { + val_ptr = NULL; + atomic_compare_exchange_strong_explicit(&htab->table[idx].val_ptr, + (uintptr_t *) &val_ptr, + (uintptr_t) val, + memory_order_acquire, + memory_order_acquire); + + if (val_ptr == NULL) + { + atomic_store_explicit(&htab->table[idx].hashval, hval, + memory_order_release); + return 0; + } + else + { + do + { + hash = atomic_load_explicit(&htab->table[idx].hashval, + memory_order_acquire); + } + while (hash == 0); + if (hash == hval) + return -1; + } + } + + /* Second hash function as suggested in [Knuth]. */ + HASHTYPE second_hash = 1 + hval % (htab->size - 2); + + for(;;) + { + if (idx <= second_hash) + idx = htab->size + idx - second_hash; + else + idx -= second_hash; + + hash = atomic_load_explicit(&htab->table[idx].hashval, + memory_order_acquire); + if (hash == hval) + return -1; + else if (hash == 0) + { + val_ptr = NULL; + atomic_compare_exchange_strong_explicit(&htab->table[idx].val_ptr, + (uintptr_t *) &val_ptr, + (uintptr_t) val, + memory_order_acquire, + memory_order_acquire); + + if (val_ptr == NULL) + { + atomic_store_explicit(&htab->table[idx].hashval, hval, + memory_order_release); + return 0; + } + else + { + do + { + hash = atomic_load_explicit(&htab->table[idx].hashval, + memory_order_acquire); + } + while (hash == 0); + if (hash == hval) + return -1; + } + } + } +} + +#define NO_RESIZING 0u +#define ALLOCATING_MEMORY 1u +#define MOVING_DATA 3u +#define CLEANING 2u + +#define STATE_BITS 2u +#define STATE_INCREMENT (1u << STATE_BITS) +#define STATE_MASK (STATE_INCREMENT - 1) +#define GET_STATE(A) ((A) & STATE_MASK) + +#define IS_NO_RESIZE_OR_CLEANING(A) (((A) & 0x1u) == 0) + +#define GET_ACTIVE_WORKERS(A) ((A) >> STATE_BITS) + +#define INITIALIZATION_BLOCK_SIZE 256 +#define MOVE_BLOCK_SIZE 256 +#define CEIL(A, B) (((A) + (B) - 1) / (B)) + +/* Initializes records and copies the data from the old table. + It can share work with other threads */ +static void resize_helper(NAME *htab, int blocking) +{ + size_t num_old_blocks = CEIL(htab->old_size, MOVE_BLOCK_SIZE); + size_t num_new_blocks = CEIL(htab->size, INITIALIZATION_BLOCK_SIZE); + + size_t my_block; + size_t num_finished_blocks = 0; + + while ((my_block = atomic_fetch_add_explicit(&htab->next_init_block, 1, + memory_order_acquire)) + < num_new_blocks) + { + size_t record_it = my_block * INITIALIZATION_BLOCK_SIZE; + size_t record_end = (my_block + 1) * INITIALIZATION_BLOCK_SIZE; + if (record_end > htab->size) + record_end = htab->size; + + while (record_it++ != record_end) + { + atomic_init(&htab->table[record_it].hashval, (uintptr_t) NULL); + atomic_init(&htab->table[record_it].val_ptr, (uintptr_t) NULL); + } + + num_finished_blocks++; + } + + atomic_fetch_add_explicit(&htab->num_initialized_blocks, + num_finished_blocks, memory_order_release); + while (atomic_load_explicit(&htab->num_initialized_blocks, + memory_order_acquire) != num_new_blocks); + + /* All block are initialized, start moving */ + num_finished_blocks = 0; + while ((my_block = atomic_fetch_add_explicit(&htab->next_move_block, 1, + memory_order_acquire)) + < num_old_blocks) + { + size_t record_it = my_block * MOVE_BLOCK_SIZE; + size_t record_end = (my_block + 1) * MOVE_BLOCK_SIZE; + if (record_end > htab->old_size) + record_end = htab->old_size; + + while (record_it++ != record_end) + { + TYPE val_ptr = (TYPE) atomic_load_explicit( + &htab->old_table[record_it].val_ptr, + memory_order_acquire); + if (val_ptr == NULL) + continue; + + HASHTYPE hashval = atomic_load_explicit( + &htab->old_table[record_it].hashval, + memory_order_acquire); + assert(hashval); + + insert_helper(htab, hashval, val_ptr); + } + + num_finished_blocks++; + } + + atomic_fetch_add_explicit(&htab->num_moved_blocks, num_finished_blocks, + memory_order_release); + + if (blocking) + while (atomic_load_explicit(&htab->num_moved_blocks, + memory_order_acquire) != num_old_blocks); +} + +static void +resize_master(NAME *htab) +{ + htab->old_size = htab->size; + htab->old_table = htab->table; + + htab->size = next_prime(htab->size * 2); + htab->table = malloc((1 + htab->size) * sizeof(htab->table[0])); + assert(htab->table); + + /* Change state from ALLOCATING_MEMORY to MOVING_DATA */ + atomic_fetch_xor_explicit(&htab->resizing_state, + ALLOCATING_MEMORY ^ MOVING_DATA, + memory_order_release); + + resize_helper(htab, 1); + + /* Change state from MOVING_DATA to CLEANING */ + size_t resize_state = atomic_fetch_xor_explicit(&htab->resizing_state, + MOVING_DATA ^ CLEANING, + memory_order_acq_rel); + while (GET_ACTIVE_WORKERS(resize_state) != 0) + resize_state = atomic_load_explicit(&htab->resizing_state, + memory_order_acquire); + + /* There are no more active workers */ + atomic_store_explicit(&htab->next_init_block, 0, memory_order_relaxed); + atomic_store_explicit(&htab->num_initialized_blocks, 0, + memory_order_relaxed); + + atomic_store_explicit(&htab->next_move_block, 0, memory_order_relaxed); + atomic_store_explicit(&htab->num_moved_blocks, 0, memory_order_relaxed); + + free(htab->old_table); + + /* Change state to NO_RESIZING */ + atomic_fetch_xor_explicit(&htab->resizing_state, CLEANING ^ NO_RESIZING, + memory_order_relaxed); + +} + +static void +resize_worker(NAME *htab) +{ + size_t resize_state = atomic_load_explicit(&htab->resizing_state, + memory_order_acquire); + + /* If the resize has finished */ + if (IS_NO_RESIZE_OR_CLEANING(resize_state)) + return; + + /* Register as worker and check if the resize has finished in the meantime*/ + resize_state = atomic_fetch_add_explicit(&htab->resizing_state, + STATE_INCREMENT, + memory_order_acquire); + if (IS_NO_RESIZE_OR_CLEANING(resize_state)) + { + atomic_fetch_sub_explicit(&htab->resizing_state, STATE_INCREMENT, + memory_order_relaxed); + return; + } + + /* Wait while the new table is being allocated. */ + while (GET_STATE(resize_state) == ALLOCATING_MEMORY) + resize_state = atomic_load_explicit(&htab->resizing_state, + memory_order_acquire); + + /* Check if the resize is done */ + assert(GET_STATE(resize_state) != NO_RESIZING); + if (GET_STATE(resize_state) == CLEANING) + { + atomic_fetch_sub_explicit(&htab->resizing_state, STATE_INCREMENT, + memory_order_relaxed); + return; + } + + resize_helper(htab, 0); + + /* Deregister worker */ + atomic_fetch_sub_explicit(&htab->resizing_state, STATE_INCREMENT, + memory_order_release); +} + + +int +#define INIT(name) _INIT (name) +#define _INIT(name) \ + name##_init +INIT(NAME) (NAME *htab, size_t init_size) +{ + /* We need the size to be a prime. */ + init_size = next_prime (init_size); + + /* Initialize the data structure. */ + htab->size = init_size; + atomic_init(&htab->filled, 0); + atomic_init(&htab->resizing_state, 0); + + atomic_init(&htab->next_init_block, 0); + atomic_init(&htab->num_initialized_blocks, 0); + + atomic_init(&htab->next_move_block, 0); + atomic_init(&htab->num_moved_blocks, 0); + + pthread_rwlock_init(&htab->resize_rwl, NULL); + + htab->table = (void *) malloc ((init_size + 1) * sizeof (htab->table[0])); + if (htab->table == NULL) + return -1; + + for (size_t i = 0; i <= init_size; i++) + { + atomic_init(&htab->table[i].hashval, (uintptr_t) NULL); + atomic_init(&htab->table[i].val_ptr, (uintptr_t) NULL); + } + + return 0; +} + + +int +#define FREE(name) _FREE (name) +#define _FREE(name) \ +name##_free +FREE(NAME) (NAME *htab) +{ + pthread_rwlock_destroy(&htab->resize_rwl); + free (htab->table); + return 0; +} + + +int +#define INSERT(name) _INSERT (name) +#define _INSERT(name) \ +name##_insert +INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data) +{ + int incremented = 0; + + for(;;) + { + while (pthread_rwlock_tryrdlock(&htab->resize_rwl) != 0) + resize_worker(htab); + + size_t filled; + if (!incremented) + { + filled = atomic_fetch_add_explicit(&htab->filled, 1, + memory_order_acquire); + incremented = 1; + } + else + { + filled = atomic_load_explicit(&htab->filled, + memory_order_acquire); + } + + + if (100 * filled > 90 * htab->size) + { + /* Table is filled more than 90%. Resize the table. */ + + size_t resizing_state = atomic_load_explicit(&htab->resizing_state, + memory_order_acquire); + if (resizing_state == 0 && + atomic_compare_exchange_strong_explicit(&htab->resizing_state, + &resizing_state, + ALLOCATING_MEMORY, + memory_order_acquire, + memory_order_acquire)) + { + /* Master thread */ + pthread_rwlock_unlock(&htab->resize_rwl); + + pthread_rwlock_wrlock(&htab->resize_rwl); + resize_master(htab); + pthread_rwlock_unlock(&htab->resize_rwl); + + } + else + { + /* Worker thread */ + pthread_rwlock_unlock(&htab->resize_rwl); + resize_worker(htab); + } + } + else + { + /* Lock acquired, no need for resize*/ + break; + } + } + + int ret_val = insert_helper(htab, hval, data); + if (ret_val == -1) + atomic_fetch_sub_explicit(&htab->filled, 1, memory_order_relaxed); + pthread_rwlock_unlock(&htab->resize_rwl); + return ret_val; +} + + + +TYPE +#define FIND(name) _FIND (name) +#define _FIND(name) \ + name##_find +FIND(NAME) (NAME *htab, HASHTYPE hval) +{ + while (pthread_rwlock_tryrdlock(&htab->resize_rwl) != 0) + resize_worker(htab); + + size_t idx; + + /* Make the hash data nonzero. */ + hval = hval ?: 1; + idx = lookup(htab, hval); + + if (idx == 0) + { + pthread_rwlock_unlock(&htab->resize_rwl); + return NULL; + } + + /* get a copy before unlocking the lock */ + TYPE ret_val = (TYPE) atomic_load_explicit(&htab->table[idx].val_ptr, + memory_order_relaxed); + + pthread_rwlock_unlock(&htab->resize_rwl); + return ret_val; +} diff --git a/lib/dynamicsizehash_concurrent.h b/lib/dynamicsizehash_concurrent.h new file mode 100644 index 00000000..73e66e91 --- /dev/null +++ b/lib/dynamicsizehash_concurrent.h @@ -0,0 +1,118 @@ +/* Copyright (C) 2000-2019 Red Hat, Inc. + This file is part of elfutils. + Written by Srdan Milakovic , 2019. + Derived from Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include +#include "atomics.h" +/* Before including this file the following macros must be defined: + + NAME name of the hash table structure. + TYPE data type of the hash table entries + + The following macros if present select features: + + ITERATE iterating over the table entries is possible + HASHTYPE integer type for hash values, default unsigned long int + */ + + + +#ifndef HASHTYPE +# define HASHTYPE unsigned long int +#endif + +#ifndef RESIZE_BLOCK_SIZE +# define RESIZE_BLOCK_SIZE 256 +#endif + +/* Defined separately. */ +extern size_t next_prime (size_t seed); + + +/* Table entry type. */ +#define _DYNHASHCONENTTYPE(name) \ + typedef struct name##_ent \ + { \ + _Atomic(HASHTYPE) hashval; \ + atomic_uintptr_t val_ptr; \ + } name##_ent +#define DYNHASHENTTYPE(name) _DYNHASHCONENTTYPE (name) +DYNHASHENTTYPE (NAME); + +/* Type of the dynamic hash table data structure. */ +#define _DYNHASHCONTYPE(name) \ +typedef struct \ +{ \ + size_t size; \ + size_t old_size; \ + atomic_size_t filled; \ + name##_ent *table; \ + name##_ent *old_table; \ + atomic_size_t resizing_state; \ + atomic_size_t next_init_block; \ + atomic_size_t num_initialized_blocks; \ + atomic_size_t next_move_block; \ + atomic_size_t num_moved_blocks; \ + pthread_rwlock_t resize_rwl; \ +} name +#define DYNHASHTYPE(name) _DYNHASHCONTYPE (name) +DYNHASHTYPE (NAME); + + + +#define _FUNCTIONS(name) \ +/* Initialize the hash table. */ \ +extern int name##_init (name *htab, size_t init_size); \ + \ +/* Free resources allocated for hash table. */ \ +extern int name##_free (name *htab); \ + \ +/* Insert new entry. */ \ +extern int name##_insert (name *htab, HASHTYPE hval, TYPE data); \ + \ +/* Find entry in hash table. */ \ +extern TYPE name##_find (name *htab, HASHTYPE hval); +#define FUNCTIONS(name) _FUNCTIONS (name) +FUNCTIONS (NAME) + + +#ifndef NO_UNDEF +# undef DYNHASHENTTYPE +# undef DYNHASHTYPE +# undef FUNCTIONS +# undef _FUNCTIONS +# undef XFUNCTIONS +# undef _XFUNCTIONS +# undef NAME +# undef TYPE +# undef ITERATE +# undef COMPARE +# undef FIRST +# undef NEXT +#endif diff --git a/lib/eu-config.h b/lib/eu-config.h new file mode 100644 index 00000000..f0e3d07a --- /dev/null +++ b/lib/eu-config.h @@ -0,0 +1,210 @@ +/* Configuration definitions. + Copyright (C) 2008, 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef EU_CONFIG_H +#define EU_CONFIG_H 1 + +#ifdef USE_LOCKS +# include +# include +# define rwlock_define(class,name) class pthread_rwlock_t name +# define RWLOCK_CALL(call) \ + ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); }) +# define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL)) +# define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock)) +# define rwlock_rdlock(lock) RWLOCK_CALL (rdlock (&lock)) +# define rwlock_wrlock(lock) RWLOCK_CALL (wrlock (&lock)) +# define rwlock_unlock(lock) RWLOCK_CALL (unlock (&lock)) +#else +/* Eventually we will allow multi-threaded applications to use the + libraries. Therefore we will add the necessary locking although + the macros used expand to nothing for now. */ +# define rwlock_define(class,name) class int name +# define rwlock_init(lock) ((void) (lock)) +# define rwlock_fini(lock) ((void) (lock)) +# define rwlock_rdlock(lock) ((void) (lock)) +# define rwlock_wrlock(lock) ((void) (lock)) +# define rwlock_unlock(lock) ((void) (lock)) +#endif /* USE_LOCKS */ + +/* gettext helper macros. */ +#define N_(Str) Str +#define _(Str) dgettext ("elfutils", Str) + +/* Compiler-specific definitions. */ +#define strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); + +#ifdef __i386__ +# define internal_function __attribute__ ((regparm (3), stdcall)) +#else +# define internal_function /* nothing */ +#endif + +#define internal_strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function; + +#ifdef HAVE_VISIBILITY +#define attribute_hidden \ + __attribute__ ((visibility ("hidden"))) +#else +#define attribute_hidden /* empty */ +#endif + +#ifdef HAVE_GCC_STRUCT +#define attribute_packed \ + __attribute__ ((packed, gcc_struct)) +#else +#define attribute_packed \ + __attribute__ ((packed)) +#endif + +/* Define ALLOW_UNALIGNED if the architecture allows operations on + unaligned memory locations. */ +#define SANITIZE_UNDEFINED 1 +#if (defined __i386__ || defined __x86_64__) && ! CHECK_UNDEFINED +# define ALLOW_UNALIGNED 1 +#else +# define ALLOW_UNALIGNED 0 +#endif + +#if DEBUGPRED +# ifdef __x86_64__ +asm (".section predict_data, \"aw\"; .previous\n" + ".section predict_line, \"a\"; .previous\n" + ".section predict_file, \"a\"; .previous"); +# ifndef PIC +# define debugpred__(e, E) \ + ({ long int _e = !!(e); \ + asm volatile (".pushsection predict_data; ..predictcnt%=: .quad 0; .quad 0\n" \ + ".section predict_line; .quad %c1\n" \ + ".section predict_file; .quad %c2; .popsection\n" \ + "addq $1,..predictcnt%=(,%0,8)" \ + : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ + __builtin_expect (_e, E); \ + }) +# endif +# elif defined __i386__ +asm (".section predict_data, \"aw\"; .previous\n" + ".section predict_line, \"a\"; .previous\n" + ".section predict_file, \"a\"; .previous"); +# ifndef PIC +# define debugpred__(e, E) \ + ({ long int _e = !!(e); \ + asm volatile (".pushsection predict_data; ..predictcnt%=: .long 0; .long 0\n" \ + ".section predict_line; .long %c1\n" \ + ".section predict_file; .long %c2; .popsection\n" \ + "incl ..predictcnt%=(,%0,8)" \ + : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ + __builtin_expect (_e, E); \ + }) +# endif +# endif +# ifdef debugpred__ +# define unlikely(e) debugpred__ (e,0) +# define likely(e) debugpred__ (e,1) +# endif +#endif +#ifndef likely +# define unlikely(expr) __builtin_expect (!!(expr), 0) +# define likely(expr) __builtin_expect (!!(expr), 1) +#endif + +#define obstack_calloc(ob, size) \ + ({ size_t _s = (size); memset (obstack_alloc (ob, _s), '\0', _s); }) +#define obstack_strdup(ob, str) \ + ({ const char *_s = (str); obstack_copy0 (ob, _s, strlen (_s)); }) +#define obstack_strndup(ob, str, n) \ + ({ const char *_s = (str); obstack_copy0 (ob, _s, strnlen (_s, n)); }) + +#if __STDC_VERSION__ >= 199901L +# define flexarr_size /* empty */ +#else +# define flexarr_size 0 +#endif + +/* Calling conventions. */ +#ifdef __i386__ +# define CALLING_CONVENTION regparm (3), stdcall +# define AND_CALLING_CONVENTION , regparm (3), stdcall +#else +# define CALLING_CONVENTION +# define AND_CALLING_CONVENTION +#endif + +/* Avoid PLT entries. */ +#ifdef PIC +# define INTUSE(name) _INTUSE(name) +# define _INTUSE(name) __##name##_internal +# define INTDEF(name) _INTDEF(name) +# define _INTDEF(name) \ + extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name))); +# define INTDECL(name) _INTDECL(name) +# define _INTDECL(name) \ + extern __typeof__ (name) __##name##_internal attribute_hidden; +#else +# define INTUSE(name) name +# define INTDEF(name) /* empty */ +# define INTDECL(name) /* empty */ +#endif + +/* This macro is used by the tests conditionalize for standalone building. */ +#define ELFUTILS_HEADER(name) + + +#ifdef SYMBOL_VERSIONING +# define OLD_VERSION(name, version) \ + asm (".globl _compat." #version "." #name "\n" \ + "_compat." #version "." #name " = " #name "\n" \ + ".symver _compat." #version "." #name "," #name "@" #version); +# define NEW_VERSION(name, version) \ + asm (".symver " #name "," #name "@@@" #version); +# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ + asm (".symver _compat." #version "." #name "," #name "@" #version); \ + __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \ + asm ("_compat." #version "." #name); +# define COMPAT_VERSION(name, version, prefix) \ + asm (".symver _compat." #version "." #name "," #name "@" #version); \ + __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name); +#else +# define OLD_VERSION(name, version) /* Nothing for static linking. */ +# define NEW_VERSION(name, version) /* Nothing for static linking. */ +# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \ + error "should use #ifdef SYMBOL_VERSIONING" +# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING" +#endif + +#ifndef FALLTHROUGH +# ifdef HAVE_FALLTHROUGH +# define FALLTHROUGH __attribute__ ((fallthrough)) +# else +# define FALLTHROUGH ((void) 0) +# endif +#endif + +#endif /* eu-config.h */ diff --git a/lib/fixedsizehash.h b/lib/fixedsizehash.h new file mode 100644 index 00000000..dac2a5f5 --- /dev/null +++ b/lib/fixedsizehash.h @@ -0,0 +1,272 @@ +/* Fixed size hash table with internal linking. + Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include +#include +#include + +#include + +#ifdef __CONCAT +#define CONCAT(t1,t2) __CONCAT (t1,t2) +#else +#define STROF(t2) t2 +#define CONCAT_EXPANDED(t1,t2) t1 ## t2 +#define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2) +#endif + +/* Before including this file the following macros must be defined: + + TYPE data type of the hash table entries + HASHFCT name of the hashing function to use + HASHTYPE type used for the hashing value + COMPARE comparison function taking two pointers to TYPE objects + CLASS can be defined to `static' to avoid exporting the functions + PREFIX prefix to be used for function and data type names + STORE_POINTER if defined the table stores a pointer and not an element + of type TYPE + INSERT_HASH if defined alternate insert function which takes a hash + value is defined + NO_FINI_FCT if defined the fini function is not defined +*/ + + +/* Defined separately. */ +extern size_t next_prime (size_t seed); + + +/* Set default values. */ +#ifndef HASHTYPE +# define HASHTYPE size_t +#endif + +#ifndef CLASS +# define CLASS +#endif + +#ifndef PREFIX +# define PREFIX +#endif + + +/* The data structure. */ +struct CONCAT(PREFIX,fshash) +{ + size_t nslots; + struct CONCAT(PREFIX,fshashent) + { + HASHTYPE hval; +#ifdef STORE_POINTER +# define ENTRYP(el) (el).entry + TYPE *entry; +#else +# define ENTRYP(el) &(el).entry + TYPE entry; +#endif + } table[0]; +}; + + +/* Constructor for the hashing table. */ +CLASS struct CONCAT(PREFIX,fshash) * +CONCAT(PREFIX,fshash_init) (size_t nelems) +{ + struct CONCAT(PREFIX,fshash) *result; + /* We choose a size for the hashing table 150% over the number of + entries. This will guarantee short medium search lengths. */ + const size_t max_size_t = ~((size_t) 0); + + if (nelems >= (max_size_t / 3) * 2) + { + errno = EINVAL; + return NULL; + } + + /* Adjust the size to be used for the hashing table. */ + nelems = next_prime (MAX ((nelems * 3) / 2, 10)); + + /* Allocate the data structure for the result. */ + result = (struct CONCAT(PREFIX,fshash) *) + xcalloc (sizeof (struct CONCAT(PREFIX,fshash)) + + (nelems + 1) * sizeof (struct CONCAT(PREFIX,fshashent)), 1); + if (result == NULL) + return NULL; + + result->nslots = nelems; + + return result; +} + + +#ifndef NO_FINI_FCT +CLASS void +CONCAT(PREFIX,fshash_fini) (struct CONCAT(PREFIX,fshash) *htab) +{ + free (htab); +} +#endif + + +static struct CONCAT(PREFIX,fshashent) * +CONCAT(PREFIX,fshash_lookup) (struct CONCAT(PREFIX,fshash) *htab, + HASHTYPE hval, TYPE *data) +{ + size_t idx = 1 + hval % htab->nslots; + + if (htab->table[idx].hval != 0) + { + HASHTYPE hash; + + /* See whether this is the same entry. */ + if (htab->table[idx].hval == hval + && COMPARE (data, ENTRYP (htab->table[idx])) == 0) + return &htab->table[idx]; + + /* Second hash function as suggested in [Knuth]. */ + hash = 1 + hval % (htab->nslots - 2); + + do + { + if (idx <= hash) + idx = htab->nslots + idx - hash; + else + idx -= hash; + + if (htab->table[idx].hval == hval + && COMPARE (data, ENTRYP(htab->table[idx])) == 0) + return &htab->table[idx]; + } + while (htab->table[idx].hval != 0); + } + + return &htab->table[idx]; +} + + +CLASS int +__attribute__ ((unused)) +CONCAT(PREFIX,fshash_insert) (struct CONCAT(PREFIX,fshash) *htab, + const char *str, + size_t len __attribute__ ((unused)), TYPE *data) +{ + HASHTYPE hval = HASHFCT (str, len ?: strlen (str)); + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data); + if (slot->hval != 0) + /* We don't want to overwrite the old value. */ + return -1; + + slot->hval = hval; +#ifdef STORE_POINTER + slot->entry = data; +#else + slot->entry = *data; +#endif + + return 0; +} + + +#ifdef INSERT_HASH +CLASS int +__attribute__ ((unused)) +CONCAT(PREFIX,fshash_insert_hash) (struct CONCAT(PREFIX,fshash) *htab, + HASHTYPE hval, TYPE *data) +{ + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data); + if (slot->hval != 0) + /* We don't want to overwrite the old value. */ + return -1; + + slot->hval = hval; +#ifdef STORE_POINTER + slot->entry = data; +#else + slot->entry = *data; +#endif + + return 0; +} +#endif + + +CLASS int +__attribute__ ((unused)) +CONCAT(PREFIX,fshash_overwrite) (struct CONCAT(PREFIX,fshash) *htab, + const char *str, + size_t len __attribute__ ((unused)), + TYPE *data) +{ + HASHTYPE hval = HASHFCT (str, len ?: strlen (str)); + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data); + slot->hval = hval; +#ifdef STORE_POINTER + slot->entry = data; +#else + slot->entry = *data; +#endif + + return 0; +} + + +CLASS const TYPE * +CONCAT(PREFIX,fshash_find) (const struct CONCAT(PREFIX,fshash) *htab, + const char *str, + size_t len __attribute__ ((unused)), TYPE *data) +{ + HASHTYPE hval = HASHFCT (str, len ?: strlen (str)); + struct CONCAT(PREFIX,fshashent) *slot; + + slot = CONCAT(PREFIX,fshash_lookup) ((struct CONCAT(PREFIX,fshash) *) htab, + hval, data); + if (slot->hval == 0) + /* Not found. */ + return NULL; + + return ENTRYP(*slot); +} + + +/* Unset the macros we expect. */ +#undef TYPE +#undef HASHFCT +#undef HASHTYPE +#undef COMPARE +#undef CLASS +#undef PREFIX +#undef INSERT_HASH +#undef STORE_POINTER +#undef NO_FINI_FCT diff --git a/lib/libeu.h b/lib/libeu.h new file mode 100644 index 00000000..ecb4d011 --- /dev/null +++ b/lib/libeu.h @@ -0,0 +1,46 @@ +/* Declarations for the common library. + Copyright (C) 2006-2011 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef LIBEU_H +#define LIBEU_H + +#include +#include + +extern void *xmalloc (size_t) __attribute__ ((__malloc__)); +extern void *xcalloc (size_t, size_t) __attribute__ ((__malloc__)); +extern void *xrealloc (void *, size_t) __attribute__ ((__malloc__)); + +extern char *xstrdup (const char *) __attribute__ ((__malloc__)); +extern char *xstrndup (const char *, size_t) __attribute__ ((__malloc__)); + + +extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len); +extern int crc32_file (int fd, uint32_t *resp); + +#endif diff --git a/lib/list.h b/lib/list.h new file mode 100644 index 00000000..fc5c73cd --- /dev/null +++ b/lib/list.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef LIST_H +#define LIST_H 1 + +/* Add element to the end of a circular, double-linked list. */ +#define CDBL_LIST_ADD_REAR(first, newp) \ + do { \ + __typeof (newp) _newp = (newp); \ + assert (_newp->next == NULL); \ + assert (_newp->previous == NULL); \ + if (unlikely ((first) == NULL)) \ + (first) = _newp->next = _newp->previous = _newp; \ + else \ + { \ + _newp->next = (first); \ + _newp->previous = (first)->previous; \ + _newp->previous->next = _newp->next->previous = _newp; \ + } \ + } while (0) + +/* Remove element from circular, double-linked list. */ +#define CDBL_LIST_DEL(first, elem) \ + do { \ + __typeof (elem) _elem = (elem); \ + /* Check whether the element is indeed on the list. */ \ + assert (first != NULL && _elem != NULL \ + && (first != elem \ + || ({ __typeof (elem) _runp = first->next; \ + while (_runp != first) \ + if (_runp == _elem) \ + break; \ + else \ + _runp = _runp->next; \ + _runp == _elem; }))); \ + if (unlikely (_elem->next == _elem)) \ + first = NULL; \ + else \ + { \ + _elem->next->previous = _elem->previous; \ + _elem->previous->next = _elem->next; \ + if (unlikely (first == _elem)) \ + first = _elem->next; \ + } \ + assert ((_elem->next = _elem->previous = NULL, 1)); \ + } while (0) + + +/* Add element to the front of a single-linked list. */ +#define SNGL_LIST_PUSH(first, newp) \ + do { \ + __typeof (newp) _newp = (newp); \ + assert (_newp->next == NULL); \ + _newp->next = first; \ + first = _newp; \ + } while (0) + + +/* Add element to the rear of a circular single-linked list. */ +#define CSNGL_LIST_ADD_REAR(first, newp) \ + do { \ + __typeof (newp) _newp = (newp); \ + assert (_newp->next == NULL); \ + if (unlikely ((first) == NULL)) \ + (first) = _newp->next = _newp; \ + else \ + { \ + _newp->next = (first)->next; \ + (first) = (first)->next = _newp; \ + } \ + } while (0) + + +#endif /* list.h */ diff --git a/lib/next_prime.c b/lib/next_prime.c new file mode 100644 index 00000000..f2c921e3 --- /dev/null +++ b/lib/next_prime.c @@ -0,0 +1,66 @@ +/* Determine prime number. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include + + +/* Test whether CANDIDATE is a prime. */ +static int +is_prime (size_t candidate) +{ + /* No even number and none less than 10 will be passed here. */ + size_t divn = 3; + size_t sq = divn * divn; + + while (sq < candidate && candidate % divn != 0) + { + size_t old_sq = sq; + ++divn; + sq += 4 * divn; + if (sq < old_sq) + return 1; + ++divn; + } + + return candidate % divn != 0; +} + + +/* We need primes for the table size. */ +size_t +next_prime (size_t seed) +{ + /* Make it definitely odd. */ + seed |= 1; + + while (!is_prime (seed)) + seed += 2; + + return seed; +} diff --git a/lib/printversion.c b/lib/printversion.c new file mode 100644 index 00000000..adf127d6 --- /dev/null +++ b/lib/printversion.c @@ -0,0 +1,45 @@ +/* Common argp_print_version_hook for all tools. + Copyright (C) 2016, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "printversion.h" + +void +print_version (FILE *stream, struct argp_state *state) +{ + fprintf (stream, "%s (%s) %s\n", state->name, PACKAGE_NAME, PACKAGE_VERSION); + fprintf (stream, _("\ +Copyright (C) %s The elfutils developers <%s>.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), "2021", PACKAGE_URL); +} diff --git a/lib/printversion.h b/lib/printversion.h new file mode 100644 index 00000000..a9e059ff --- /dev/null +++ b/lib/printversion.h @@ -0,0 +1,49 @@ +/* Common argp_print_version_hook for all tools. + Copyright (C) 2017 The Qt Company Ltd. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef PRINTVERSION_H +#define PRINTVERSION_H 1 + +#include +#include + +/* Defined in version.c. Common ARGP_PROGRAM_VERSION_HOOK_DEF. */ +void print_version (FILE *stream, struct argp_state *state); + +/* We need define two variables, argp_program_version_hook and + argp_program_bug_address, in all programs. argp.h declares these + variables as non-const (which is correct in general). But we can + do better, it is not going to change. So we want to move them into + the .rodata section. Define macros to do the trick. */ +#define ARGP_PROGRAM_VERSION_HOOK_DEF \ + void (*const apvh) (FILE *, struct argp_state *) \ + __asm ("argp_program_version_hook") +#define ARGP_PROGRAM_BUG_ADDRESS_DEF \ + const char *const apba__ __asm ("argp_program_bug_address") + +#endif // PRINTVERSION_H diff --git a/lib/stdatomic-fbsd.h b/lib/stdatomic-fbsd.h new file mode 100644 index 00000000..49626662 --- /dev/null +++ b/lib/stdatomic-fbsd.h @@ -0,0 +1,442 @@ +/*- + * Copyright (c) 2011 Ed Schouten + * David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _STDATOMIC_H_ +#define _STDATOMIC_H_ + +#include +#include + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if !defined(__has_builtin) +#define __has_builtin(x) 0 +#endif +#if !defined(__GNUC_PREREQ__) +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +#define __GNUC_PREREQ__(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +#define __GNUC_PREREQ__(maj, min) 0 +#endif +#endif + +#if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) +#if __has_feature(c_atomic) +#define __CLANG_ATOMICS +#elif __GNUC_PREREQ__(4, 7) +#define __GNUC_ATOMICS +#elif !defined(__GNUC__) +#error "stdatomic.h does not support your compiler" +#endif +#endif + +/* + * language independent type to represent a Boolean value + */ + +typedef int __Bool; + +/* + * 7.17.1 Atomic lock-free macros. + */ + +#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE +#endif + +#if !defined(__CLANG_ATOMICS) +#define _Atomic(T) struct { volatile __typeof__(T) __val; } +#endif + +/* + * 7.17.2 Initialization. + */ + +#if defined(__CLANG_ATOMICS) +#define ATOMIC_VAR_INIT(value) (value) +#define atomic_init(obj, value) __c11_atomic_init(obj, value) +#else +#define ATOMIC_VAR_INIT(value) { .__val = (value) } +#define atomic_init(obj, value) ((void)((obj)->__val = (value))) +#endif + +/* + * Clang and recent GCC both provide predefined macros for the memory + * orderings. If we are using a compiler that doesn't define them, use the + * clang values - these will be ignored in the fallback path. + */ + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#endif +#ifndef __ATOMIC_CONSUME +#define __ATOMIC_CONSUME 1 +#endif +#ifndef __ATOMIC_ACQUIRE +#define __ATOMIC_ACQUIRE 2 +#endif +#ifndef __ATOMIC_RELEASE +#define __ATOMIC_RELEASE 3 +#endif +#ifndef __ATOMIC_ACQ_REL +#define __ATOMIC_ACQ_REL 4 +#endif +#ifndef __ATOMIC_SEQ_CST +#define __ATOMIC_SEQ_CST 5 +#endif + +/* + * 7.17.3 Order and consistency. + * + * The memory_order_* constants that denote the barrier behaviour of the + * atomic operations. + */ + +typedef enum { + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST +} memory_order; + +/* + * 7.17.4 Fences. + */ + +//#define __unused + +//static __inline void +//atomic_thread_fence(memory_order __order __unused) +//{ +// +//#ifdef __CLANG_ATOMICS +// __c11_atomic_thread_fence(__order); +//#elif defined(__GNUC_ATOMICS) +// __atomic_thread_fence(__order); +//#else +// __sync_synchronize(); +//#endif +//} +// +//static __inline void +//atomic_signal_fence(memory_order __order __unused) +//{ +// +//#ifdef __CLANG_ATOMICS +// __c11_atomic_signal_fence(__order); +//#elif defined(__GNUC_ATOMICS) +// __atomic_signal_fence(__order); +//#else +// __asm volatile ("" ::: "memory"); +//#endif +//} + +//#undef __unused + +/* + * 7.17.5 Lock-free property. + */ + +#if defined(_KERNEL) +/* Atomics in kernelspace are always lock-free. */ +#define atomic_is_lock_free(obj) \ + ((void)(obj), (__Bool)1) +#elif defined(__CLANG_ATOMICS) +#define atomic_is_lock_free(obj) \ + __atomic_is_lock_free(sizeof(*(obj)), obj) +#elif defined(__GNUC_ATOMICS) +#define atomic_is_lock_free(obj) \ + __atomic_is_lock_free(sizeof((obj)->__val), &(obj)->__val) +#else +#define atomic_is_lock_free(obj) \ + ((void)(obj), sizeof((obj)->__val) <= sizeof(void *)) +#endif + +/* + * 7.17.6 Atomic integer types. + */ + +typedef _Atomic(__Bool) atomic_bool; +typedef _Atomic(char) atomic_char; +typedef _Atomic(signed char) atomic_schar; +typedef _Atomic(unsigned char) atomic_uchar; +typedef _Atomic(short) atomic_short; +typedef _Atomic(unsigned short) atomic_ushort; +typedef _Atomic(int) atomic_int; +typedef _Atomic(unsigned int) atomic_uint; +typedef _Atomic(long) atomic_long; +typedef _Atomic(unsigned long) atomic_ulong; +typedef _Atomic(long long) atomic_llong; +typedef _Atomic(unsigned long long) atomic_ullong; +#if 0 +typedef _Atomic(char16_t) atomic_char16_t; +typedef _Atomic(char32_t) atomic_char32_t; +#endif +typedef _Atomic(wchar_t) atomic_wchar_t; +typedef _Atomic(int_least8_t) atomic_int_least8_t; +typedef _Atomic(uint_least8_t) atomic_uint_least8_t; +typedef _Atomic(int_least16_t) atomic_int_least16_t; +typedef _Atomic(uint_least16_t) atomic_uint_least16_t; +typedef _Atomic(int_least32_t) atomic_int_least32_t; +typedef _Atomic(uint_least32_t) atomic_uint_least32_t; +typedef _Atomic(int_least64_t) atomic_int_least64_t; +typedef _Atomic(uint_least64_t) atomic_uint_least64_t; +typedef _Atomic(int_fast8_t) atomic_int_fast8_t; +typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; +typedef _Atomic(int_fast16_t) atomic_int_fast16_t; +typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; +typedef _Atomic(int_fast32_t) atomic_int_fast32_t; +typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; +typedef _Atomic(int_fast64_t) atomic_int_fast64_t; +typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; +typedef _Atomic(intptr_t) atomic_intptr_t; +typedef _Atomic(uintptr_t) atomic_uintptr_t; +typedef _Atomic(size_t) atomic_size_t; +typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; +typedef _Atomic(intmax_t) atomic_intmax_t; +typedef _Atomic(uintmax_t) atomic_uintmax_t; + +/* + * 7.17.7 Operations on atomic types. + */ + +/* + * Compiler-specific operations. + */ + +#if defined(__CLANG_ATOMICS) +#define atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) \ + __c11_atomic_compare_exchange_strong(object, expected, desired, \ + success, failure) +#define atomic_compare_exchange_weak_explicit(object, expected, \ + desired, success, failure) \ + __c11_atomic_compare_exchange_weak(object, expected, desired, \ + success, failure) +#define atomic_exchange_explicit(object, desired, order) \ + __c11_atomic_exchange(object, desired, order) +#define atomic_fetch_add_explicit(object, operand, order) \ + __c11_atomic_fetch_add(object, operand, order) +#define atomic_fetch_and_explicit(object, operand, order) \ + __c11_atomic_fetch_and(object, operand, order) +#define atomic_fetch_or_explicit(object, operand, order) \ + __c11_atomic_fetch_or(object, operand, order) +#define atomic_fetch_sub_explicit(object, operand, order) \ + __c11_atomic_fetch_sub(object, operand, order) +#define atomic_fetch_xor_explicit(object, operand, order) \ + __c11_atomic_fetch_xor(object, operand, order) +#define atomic_load_explicit(object, order) \ + __c11_atomic_load(object, order) +#define atomic_store_explicit(object, desired, order) \ + __c11_atomic_store(object, desired, order) +#elif defined(__GNUC_ATOMICS) +#define atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) \ + __atomic_compare_exchange_n(&(object)->__val, expected, \ + desired, 0, success, failure) +#define atomic_compare_exchange_weak_explicit(object, expected, \ + desired, success, failure) \ + __atomic_compare_exchange_n(&(object)->__val, expected, \ + desired, 1, success, failure) +#define atomic_exchange_explicit(object, desired, order) \ + __atomic_exchange_n(&(object)->__val, desired, order) +#define atomic_fetch_add_explicit(object, operand, order) \ + __atomic_fetch_add(&(object)->__val, operand, order) +#define atomic_fetch_and_explicit(object, operand, order) \ + __atomic_fetch_and(&(object)->__val, operand, order) +#define atomic_fetch_or_explicit(object, operand, order) \ + __atomic_fetch_or(&(object)->__val, operand, order) +#define atomic_fetch_sub_explicit(object, operand, order) \ + __atomic_fetch_sub(&(object)->__val, operand, order) +#define atomic_fetch_xor_explicit(object, operand, order) \ + __atomic_fetch_xor(&(object)->__val, operand, order) +#define atomic_load_explicit(object, order) \ + __atomic_load_n(&(object)->__val, order) +#define atomic_store_explicit(object, desired, order) \ + __atomic_store_n(&(object)->__val, desired, order) +#else +#define __atomic_apply_stride(object, operand) \ + (((__typeof__((object)->__val))0) + (operand)) +#define atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) __extension__ ({ \ + __typeof__(expected) __ep = (expected); \ + __typeof__(*__ep) __e = *__ep; \ + (void)(success); (void)(failure); \ + (__Bool)((*__ep = __sync_val_compare_and_swap(&(object)->__val, \ + __e, desired)) == __e); \ +}) +#define atomic_compare_exchange_weak_explicit(object, expected, \ + desired, success, failure) \ + atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) +#if __has_builtin(__sync_swap) +/* Clang provides a full-barrier atomic exchange - use it if available. */ +#define atomic_exchange_explicit(object, desired, order) \ + ((void)(order), __sync_swap(&(object)->__val, desired)) +#else +/* + * __sync_lock_test_and_set() is only an acquire barrier in theory (although in + * practice it is usually a full barrier) so we need an explicit barrier before + * it. + */ +#define atomic_exchange_explicit(object, desired, order) \ +__extension__ ({ \ + __typeof__(object) __o = (object); \ + __typeof__(desired) __d = (desired); \ + (void)(order); \ + __sync_synchronize(); \ + __sync_lock_test_and_set(&(__o)->__val, __d); \ +}) +#endif +#define atomic_fetch_add_explicit(object, operand, order) \ + ((void)(order), __sync_fetch_and_add(&(object)->__val, \ + __atomic_apply_stride(object, operand))) +#define atomic_fetch_and_explicit(object, operand, order) \ + ((void)(order), __sync_fetch_and_and(&(object)->__val, operand)) +#define atomic_fetch_or_explicit(object, operand, order) \ + ((void)(order), __sync_fetch_and_or(&(object)->__val, operand)) +#define atomic_fetch_sub_explicit(object, operand, order) \ + ((void)(order), __sync_fetch_and_sub(&(object)->__val, \ + __atomic_apply_stride(object, operand))) +#define atomic_fetch_xor_explicit(object, operand, order) \ + ((void)(order), __sync_fetch_and_xor(&(object)->__val, operand)) +#define atomic_load_explicit(object, order) \ + ((void)(order), __sync_fetch_and_add(&(object)->__val, 0)) +#define atomic_store_explicit(object, desired, order) \ + ((void)atomic_exchange_explicit(object, desired, order)) +#endif + +/* + * Convenience functions. + * + * Don't provide these in kernel space. In kernel space, we should be + * disciplined enough to always provide explicit barriers. + */ + +#ifndef _KERNEL +#define atomic_compare_exchange_strong(object, expected, desired) \ + atomic_compare_exchange_strong_explicit(object, expected, \ + desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_weak_explicit(object, expected, \ + desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_exchange(object, desired) \ + atomic_exchange_explicit(object, desired, memory_order_seq_cst) +#define atomic_fetch_add(object, operand) \ + atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_and(object, operand) \ + atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_or(object, operand) \ + atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_sub(object, operand) \ + atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_xor(object, operand) \ + atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) +#define atomic_load(object) \ + atomic_load_explicit(object, memory_order_seq_cst) +#define atomic_store(object, desired) \ + atomic_store_explicit(object, desired, memory_order_seq_cst) +#endif /* !_KERNEL */ + +/* + * 7.17.8 Atomic flag type and operations. + * + * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some + * kind of compiler built-in type we could use? + */ + +typedef struct { + atomic_bool __flag; +} atomic_flag; + +#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(0) } + +static __inline __Bool +atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, + memory_order __order) +{ + return (atomic_exchange_explicit(&__object->__flag, 1, __order)); +} + +static __inline void +atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) +{ + + atomic_store_explicit(&__object->__flag, 0, __order); +} + +#ifndef _KERNEL +static __inline __Bool +atomic_flag_test_and_set(volatile atomic_flag *__object) +{ + + return (atomic_flag_test_and_set_explicit(__object, + memory_order_seq_cst)); +} + +static __inline void +atomic_flag_clear(volatile atomic_flag *__object) +{ + + atomic_flag_clear_explicit(__object, memory_order_seq_cst); +} +#endif /* !_KERNEL */ + +#endif /* !_STDATOMIC_H_ */ \ No newline at end of file diff --git a/lib/system.h b/lib/system.h new file mode 100644 index 00000000..cdf18ed7 --- /dev/null +++ b/lib/system.h @@ -0,0 +1,176 @@ +/* Declarations for common convenience functions. + Copyright (C) 2006-2011 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef LIB_SYSTEM_H +#define LIB_SYSTEM_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define LE32(n) (n) +# define LE64(n) (n) +# define BE32(n) bswap_32 (n) +# define BE64(n) bswap_64 (n) +#elif __BYTE_ORDER == __BIG_ENDIAN +# define BE32(n) (n) +# define BE64(n) (n) +# define LE32(n) bswap_32 (n) +# define LE64(n) bswap_64 (n) +#else +# error "Unknown byte order" +#endif + +#ifndef MAX +#define MAX(m, n) ((m) < (n) ? (n) : (m)) +#endif + +#ifndef MIN +#define MIN(m, n) ((m) < (n) ? (m) : (n)) +#endif + +#if !HAVE_DECL_POWEROF2 +#define powerof2(x) (((x) & ((x) - 1)) == 0) +#endif + +#if !HAVE_DECL_MEMPCPY +#define mempcpy(dest, src, n) \ + ((void *) ((char *) memcpy (dest, src, n) + (size_t) n)) +#endif + +/* Return TRUE if the start of STR matches PREFIX, FALSE otherwise. */ + +static inline int +startswith (const char *str, const char *prefix) +{ + return strncmp (str, prefix, strlen (prefix)) == 0; +} + +/* A special gettext function we use if the strings are too short. */ +#define sgettext(Str) \ + ({ const char *__res = strrchr (_(Str), '|'); \ + __res ? __res + 1 : Str; }) + +#define gettext_noop(Str) Str + +#ifndef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(expression) \ + ({ ssize_t __res; \ + do \ + __res = expression; \ + while (__res == -1 && errno == EINTR); \ + __res; }) +#endif + +#ifndef ACCESSPERMS +#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */ +#endif + +#ifndef ALLPERMS +#define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) /* 07777 */ +#endif + +#ifndef DEFFILEMODE +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666 */ +#endif + +static inline ssize_t __attribute__ ((unused)) +pwrite_retry (int fd, const void *buf, size_t len, off_t off) +{ + ssize_t recvd = 0; + + do + { + ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, ((char *)buf) + recvd, len - recvd, + off + recvd)); + if (ret <= 0) + return ret < 0 ? ret : recvd; + + recvd += ret; + } + while ((size_t) recvd < len); + + return recvd; +} + +static inline ssize_t __attribute__ ((unused)) +write_retry (int fd, const void *buf, size_t len) +{ + ssize_t recvd = 0; + + do + { + ssize_t ret = TEMP_FAILURE_RETRY (write (fd, ((char *)buf) + recvd, len - recvd)); + if (ret <= 0) + return ret < 0 ? ret : recvd; + + recvd += ret; + } + while ((size_t) recvd < len); + + return recvd; +} + +static inline ssize_t __attribute__ ((unused)) +pread_retry (int fd, void *buf, size_t len, off_t off) +{ + ssize_t recvd = 0; + + do + { + ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, ((char *)buf) + recvd, len - recvd, + off + recvd)); + if (ret <= 0) + return ret < 0 ? ret : recvd; + + recvd += ret; + } + while ((size_t) recvd < len); + + return recvd; +} + +/* The demangler from libstdc++. */ +extern char *__cxa_demangle (const char *mangled_name, char *output_buffer, + size_t *length, int *status); + +/* A static assertion. This will cause a compile-time error if EXPR, + which must be a compile-time constant, is false. */ + +#define eu_static_assert(expr) \ + extern int never_defined_just_used_for_checking[(expr) ? 1 : -1] \ + __attribute__ ((unused)) + +#endif /* system.h */ diff --git a/lib/xmalloc.c b/lib/xmalloc.c new file mode 100644 index 00000000..7c094985 --- /dev/null +++ b/lib/xmalloc.c @@ -0,0 +1,75 @@ +/* Convenience functions for allocation. + Copyright (C) 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include "system.h" + + +/* Allocate N bytes of memory dynamically, with error checking. */ +void * +xmalloc (size_t n) +{ + void *p; + + p = malloc (n); + if (p == NULL) + error (EXIT_FAILURE, 0, _("memory exhausted")); + return p; +} + + +/* Allocate memory for N elements of S bytes, with error checking. */ +void * +xcalloc (size_t n, size_t s) +{ + void *p; + + p = calloc (n, s); + if (p == NULL) + error (EXIT_FAILURE, 0, _("memory exhausted")); + return p; +} + + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. */ +void * +xrealloc (void *p, size_t n) +{ + p = realloc (p, n); + if (p == NULL) + error (EXIT_FAILURE, 0, _("memory exhausted")); + return p; +} diff --git a/lib/xstrdup.c b/lib/xstrdup.c new file mode 100644 index 00000000..ff1e3d4f --- /dev/null +++ b/lib/xstrdup.c @@ -0,0 +1,42 @@ +/* Convenience function for string allocation. + Copyright (C) 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libeu.h" + + +/* Return a newly allocated copy of STRING. */ +char * +xstrdup (const char *string) +{ + return strcpy (xmalloc (strlen (string) + 1), string); +} diff --git a/lib/xstrndup.c b/lib/xstrndup.c new file mode 100644 index 00000000..a257aa9a --- /dev/null +++ b/lib/xstrndup.c @@ -0,0 +1,46 @@ +/* Convenience function for string allocation. + Copyright (C) 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libeu.h" +#include "system.h" + +/* Return a newly allocated copy of STRING. */ +char * +xstrndup (const char *string, size_t n) +{ + char *res; + size_t len = strnlen (string, n); + *((char *) mempcpy ((res = xmalloc (len + 1)), string, len)) = '\0'; + return res; +} diff --git a/libasm/ChangeLog b/libasm/ChangeLog new file mode 100644 index 00000000..85e723e6 --- /dev/null +++ b/libasm/ChangeLog @@ -0,0 +1,289 @@ +2021-04-19 Martin Liska + + * libasmP.h (asm_emit_symbol_p): Use startswith. + +2020-12-16 Dmitry V. Levin + + * libasmP.h (_): Remove. + +2020-12-12 Dmitry V. Levin + + * asm_begin.c (prepare_binary_output): Fix spelling typo in comment. + * asm_end.c (binary_end): Likewise. + +2020-12-11 Dmitry V. Levin + + * Makefile.am (GCC_INCLUDE): Remove. + +2020-12-09 Dmitry V. Levin + + * Makefile.am (noinst_PROGRAMS): Rename to noinst_DATA. + (libasm_so_SOURCES): Remove. + (CLEANFILES): Add libasm.so. + +2020-11-30 Dmitry V. Levin + + * Makefile.am (libasm.so$(EXEEXT)): Drop $(EXEEXT) suffix. + +2020-10-29 Mark Wielaard + + * asm_align.c (__libasm_ensure_section_space): Use calloc, not + malloc to allocate extra space. + +2020-07-19 Mark Wielaard + + * libasmP.h: Include libebl.h after libasm.h. + +2020-07-05 Mark Wielaard + + * libasm.h: Include gelf.h. + +2020-04-25 Mark Wielaard + + * asm_end.c (text_end): Call fflush instead of fclose. + +2020-01-08 Mark Wielaard + + * libasm.h: Don't include libebl.h. Define an opaque Ebl handle. + * libasmP.h: Do include libebl.h. + +2019-08-28 Mark Wielaard + + * Makefile.am (libasm_so_DEPS): Replace libebl.a with libebl_pic.a. + +2019-03-06 Mark Wielaard + + * asm_end.c (binary_end): Check return value of gelf_update_ehdr. + +2018-10-19 Mark Wielaard + + * disasm_cb.c (read_symtab_exec): Check sh_entsize is not zero. + +2018-07-04 Ross Burton + + * asm_end.c: Remove error.h include. + * asm_newscn.c: Likewise. + * i386_gendis.c: Likewise and add system.h include. + * i386_lex.l: Likewise. + * i386_parse.y: Likewise. + +2017-02-27 Ulf Hermann + + * Makefile.am: Use dso_LDFLAGS. + +2017-02-17 Ulf Hermann + + * Makefile.am: Add libasm_so_DEPS to specify external libraries + that have to be linked in, and libasm_so_LIBS to specify the + archives libasm consists of. The dependencies include libeu.a. + (libasm_so_LDLIBS): Add $(libasm_so_DEPS). + (libasm_so$(EXEEXT): Use $(libasm_so_LIBS), + add --no-undefined,-z,defs,-z,relro, + drop the manual enumeration of dependencies, + specify the correct path for libasm.map. + +2017-04-27 Ulf Hermann + + * asm_end.c (binary_end): Fix nesting of braces. + +2017-02-12 Mark Wielaard + + * asm_newsym.c (asm_newsym): Increase TEMPSYMLEN to 13. + +2017-02-15 Ulf Hermann + + * disasm_str.c: Include system.h. + +2016-10-11 Akihiko Odaki + + * asm_align.c: Remove sys/param.h include. + +2016-07-08 Mark Wielaard + + * Makefile.am (AM_CPPFLAGS): Add libdwelf. + (libasm.so): Add libdw. + * asm_begin.c (prepare_binary_output): Use dwelf_strtab instead of + ebl_strtab. + * asm_end.c (binary_end): Likewise. + (__libasm_finictx): Likewise. + * asm_newabssym.c (asm_newabssym): Likewise. + * asm_newcomsym.c (asm_newcomsym): Likewise. + * asm_newscn.c (binary_newscn): Likewise. + * asm_newscngrp.c (asm_newscngrp): Likewise. + * asm_newsym.c (asm_newsym): Likewise. + * libasmP.h: Likewise. + * symbolhash.c (COMPARE): Likewise. + * symbolhash.h (COMPARE): Likewise. + +2016-06-28 Richard Henderson + + * disasm_cb.c (disasm_cb): Pass ebl to disasm hook. + +2016-02-12 Mark Wielaard + + * asm_begin.c (prepare_text_output): Only call __fsetlocking when + result isn't NULL. + +2015-10-05 Josh Stone + + * Makefile.am (libasm.so): Add AM_V_CCLD and AM_V_at silencers. + +2015-09-23 Mark Wielaard + + * asm_align.c (__libasm_ensure_section_space): Mark as + internal_function. + * asm_end.c (__libasm_finictx): Likewise. + * asm_error.c (__libasm_seterrno): Likewise. + +2015-09-22 Mark Wielaard + + * asm_*.c: Remove old-style function definitions. + +2015-09-04 Chih-Hung Hsieh + + * asm_addint8.c (FCT): Replace K&R function definition + with ansi-C definitions. + * asm_adduint8.c (UFCT): Likewise. + * asm_begin.c (asm_begin): Likewise. + +2014-12-18 Ulrich Drepper + + * Makefile.am: Suppress output of textrel_check command. + +2014-11-27 Mark Wielaard + + * Makefile.am (libasm.so): Use textrel_check. + +2014-04-13 Mark Wielaard + + * Makefile.am: Remove !MUDFLAP conditions. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2011-02-08 Roland McGrath + + * asm_newscn.c (asm_newscn): Remove unused variable. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2009-01-10 Ulrich Drepper + + * Makefile.am: Use USE_LOCKS instead of USE_TLS. + * asm_error.c: Always use __thread. Remove all !USE_TLS code. + +2008-12-03 Ulrich Drepper + + * Makefile.am [USE_TLS]: Like libasm.so with libpthread. + +2008-01-11 Ulrich Drepper + + * libasm.h (DisasmGetSymCB_t): Change type of fourth and fifth + parameter. + * disasm_cb.c: Adjust accordingly. + +2008-01-08 Roland McGrath + + * Makefile.am (euinclude): Variable removed. + (pkginclude_HEADERS): Set this instead of euinclude_HEADERS. + +2007-12-20 Ulrich Drepper + + * disasm_cb.c: Add initial support to resolve addresses to symbols. + +2007-02-05 Ulrich Drepper + + * disasm_begin.c: New file. + * disasm_cb.c: New file. + * disasm_end.c: New file. + * disasm_str.c: New file. + +2006-08-29 Roland McGrath + + * Makefile.am (CLEANFILES): Add libasm.so.$(VERSION). + +2005-11-13 Roland McGrath + + * Makefile.am (INCLUDES): Search in libdw. + +2005-09-02 Ulrich Drepper + + * asm_error.c (asm_errmsg): Unify error message. + +2005-08-28 Ulrich Drepper + + * Makefile.am: Use $(LINK) not $(CC) when creating DSO. + (%.os): Use COMPILE.os. + (COMPILE.os): Filter out gconv options. + +2005-08-02 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add -std=gnu99. + * asm_abort.c: Don't try to remove output file if there is none. + * asm_addint8.c: In print mode, print to file not stdout. + * asm_addsleb128.c: Likewise. + * asm_adduleb128.c: Likewise. + * asm_newscn.c: Likewise. + * asm_align.c: Implement print mode. + * asm_begin.c (asm_begin): Change interface. Take binary class and + byte order information from new Ebl parameter. + * libasm.h: Adjust prototype. + * asm_end.c (text_end): Close file if necesary. + * asm_error.c: Add new error ASM_E_IOERROR. + * libasmP.h: Add ASM_E_IOERROR definition. + +2005-02-15 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2. + + * asm_end.c (text_end): Mark parameter as possibly unused. + +2005-02-06 Ulrich Drepper + + * Makefile.am: Remove lint handling. + +2005-02-05 Ulrich Drepper + + * asm_end.c (binary_end): Don't terminate with error() in case + something goes wrong. + + * Makefile.am: Check for text relocations in constructed DSO. + + * Makefile.am (AM_CFLAGS): More warnings. Add -fmudflap for MUDFLAP. + + * asm_end.c (binary_end): Remove shadowing variables. + Little cleanups. + + * asm_newsym.c: Allocate memory for the string parameter. + +2005-02-04 Ulrich Drepper + + * asm_newscn_ingrp.c (asm_newscn_ingrp): Use INTUSE to reference + asm_newscn. + +2004-09-25 Ulrich Drepper + + * asm_error.c: Make compile with gcc 4.0. + +2004-01-20 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + +2004-01-18 Ulrich Drepper + + * libasmP.h (_): Use elfutils domain. + +2004-01-17 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + +2003-08-13 Ulrich Drepper + + * Makefile.in: Depend on libebl.a, not libebl.so. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/libasm/Makefile.am b/libasm/Makefile.am new file mode 100644 index 00000000..c2b54811 --- /dev/null +++ b/libasm/Makefile.am @@ -0,0 +1,88 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2002-2010 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +AM_CPPFLAGS += -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwelf + +VERSION = 1 + +lib_LIBRARIES = libasm.a +noinst_LIBRARIES = libasm_pic.a +noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so) +pkginclude_HEADERS = libasm.h + +libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \ + asm_getelf.c asm_newscn.c asm_newscn_ingrp.c \ + asm_newsubscn.c asm_newsym.c asm_newcomsym.c \ + asm_newabssym.c \ + asm_newscngrp.c asm_scngrp_newsignature.c \ + asm_fill.c asm_align.c asm_addstrz.c \ + asm_addint8.c asm_adduint8.c \ + asm_addint16.c asm_adduint16.c \ + asm_addint32.c asm_adduint32.c \ + asm_addint64.c asm_adduint64.c \ + asm_adduleb128.c asm_addsleb128.c \ + disasm_begin.c disasm_cb.c disasm_end.c disasm_str.c \ + symbolhash.c + +libasm_pic_a_SOURCES = +am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os) + +libasm_so_DEPS = ../lib/libeu.a ../libebl/libebl_pic.a ../libelf/libelf.so ../libdw/libdw.so +libasm_so_LDLIBS = $(libasm_so_DEPS) +if USE_LOCKS +libasm_so_LDLIBS += -lpthread +endif + +libasm_so_LIBS = libasm_pic.a +libasm.so: $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$@.$(VERSION) \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \ + $(libasm_so_LDLIBS) + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + +install: install-am libasm.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libasm.so $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so + ln -fs libasm-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libasm.so.$(VERSION) + ln -fs libasm.so.$(VERSION) $(DESTDIR)$(libdir)/libasm.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libasm.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libasm.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils + +noinst_HEADERS = libasmP.h symbolhash.h +EXTRA_DIST = libasm.map + +CLEANFILES += $(am_libasm_pic_a_OBJECTS) libasm.so libasm.so.$(VERSION) diff --git a/libasm/Makefile.in b/libasm/Makefile.in new file mode 100644 index 00000000..fa9ddcdf --- /dev/null +++ b/libasm/Makefile.in @@ -0,0 +1,950 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@USE_LOCKS_TRUE@am__append_2 = -lpthread +subdir = libasm +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(pkginclude_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)" +LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libasm_a_AR = $(AR) $(ARFLAGS) +libasm_a_LIBADD = +am_libasm_a_OBJECTS = asm_begin.$(OBJEXT) asm_abort.$(OBJEXT) \ + asm_end.$(OBJEXT) asm_error.$(OBJEXT) asm_getelf.$(OBJEXT) \ + asm_newscn.$(OBJEXT) asm_newscn_ingrp.$(OBJEXT) \ + asm_newsubscn.$(OBJEXT) asm_newsym.$(OBJEXT) \ + asm_newcomsym.$(OBJEXT) asm_newabssym.$(OBJEXT) \ + asm_newscngrp.$(OBJEXT) asm_scngrp_newsignature.$(OBJEXT) \ + asm_fill.$(OBJEXT) asm_align.$(OBJEXT) asm_addstrz.$(OBJEXT) \ + asm_addint8.$(OBJEXT) asm_adduint8.$(OBJEXT) \ + asm_addint16.$(OBJEXT) asm_adduint16.$(OBJEXT) \ + asm_addint32.$(OBJEXT) asm_adduint32.$(OBJEXT) \ + asm_addint64.$(OBJEXT) asm_adduint64.$(OBJEXT) \ + asm_adduleb128.$(OBJEXT) asm_addsleb128.$(OBJEXT) \ + disasm_begin.$(OBJEXT) disasm_cb.$(OBJEXT) \ + disasm_end.$(OBJEXT) disasm_str.$(OBJEXT) symbolhash.$(OBJEXT) +libasm_a_OBJECTS = $(am_libasm_a_OBJECTS) +libasm_pic_a_AR = $(AR) $(ARFLAGS) +libasm_pic_a_LIBADD = +libasm_pic_a_OBJECTS = $(am_libasm_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/asm_abort.Po \ + ./$(DEPDIR)/asm_addint16.Po ./$(DEPDIR)/asm_addint32.Po \ + ./$(DEPDIR)/asm_addint64.Po ./$(DEPDIR)/asm_addint8.Po \ + ./$(DEPDIR)/asm_addsleb128.Po ./$(DEPDIR)/asm_addstrz.Po \ + ./$(DEPDIR)/asm_adduint16.Po ./$(DEPDIR)/asm_adduint32.Po \ + ./$(DEPDIR)/asm_adduint64.Po ./$(DEPDIR)/asm_adduint8.Po \ + ./$(DEPDIR)/asm_adduleb128.Po ./$(DEPDIR)/asm_align.Po \ + ./$(DEPDIR)/asm_begin.Po ./$(DEPDIR)/asm_end.Po \ + ./$(DEPDIR)/asm_error.Po ./$(DEPDIR)/asm_fill.Po \ + ./$(DEPDIR)/asm_getelf.Po ./$(DEPDIR)/asm_newabssym.Po \ + ./$(DEPDIR)/asm_newcomsym.Po ./$(DEPDIR)/asm_newscn.Po \ + ./$(DEPDIR)/asm_newscn_ingrp.Po ./$(DEPDIR)/asm_newscngrp.Po \ + ./$(DEPDIR)/asm_newsubscn.Po ./$(DEPDIR)/asm_newsym.Po \ + ./$(DEPDIR)/asm_scngrp_newsignature.Po \ + ./$(DEPDIR)/disasm_begin.Po ./$(DEPDIR)/disasm_cb.Po \ + ./$(DEPDIR)/disasm_end.Po ./$(DEPDIR)/disasm_str.Po \ + ./$(DEPDIR)/symbolhash.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libasm_a_SOURCES) $(libasm_pic_a_SOURCES) +DIST_SOURCES = $(libasm_a_SOURCES) $(libasm_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(noinst_DATA) +HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl \ + -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwelf + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda $(am_libasm_pic_a_OBJECTS) libasm.so \ + libasm.so.$(VERSION) +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +lib_LIBRARIES = libasm.a +noinst_LIBRARIES = libasm_pic.a +noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so) +pkginclude_HEADERS = libasm.h +libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \ + asm_getelf.c asm_newscn.c asm_newscn_ingrp.c \ + asm_newsubscn.c asm_newsym.c asm_newcomsym.c \ + asm_newabssym.c \ + asm_newscngrp.c asm_scngrp_newsignature.c \ + asm_fill.c asm_align.c asm_addstrz.c \ + asm_addint8.c asm_adduint8.c \ + asm_addint16.c asm_adduint16.c \ + asm_addint32.c asm_adduint32.c \ + asm_addint64.c asm_adduint64.c \ + asm_adduleb128.c asm_addsleb128.c \ + disasm_begin.c disasm_cb.c disasm_end.c disasm_str.c \ + symbolhash.c + +libasm_pic_a_SOURCES = +am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os) +libasm_so_DEPS = ../lib/libeu.a ../libebl/libebl_pic.a ../libelf/libelf.so ../libdw/libdw.so +libasm_so_LDLIBS = $(libasm_so_DEPS) $(am__append_2) +libasm_so_LIBS = libasm_pic.a +noinst_HEADERS = libasmP.h symbolhash.h +EXTRA_DIST = libasm.map +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libasm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libasm/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libasm.a: $(libasm_a_OBJECTS) $(libasm_a_DEPENDENCIES) $(EXTRA_libasm_a_DEPENDENCIES) + $(AM_V_at)-rm -f libasm.a + $(AM_V_AR)$(libasm_a_AR) libasm.a $(libasm_a_OBJECTS) $(libasm_a_LIBADD) + $(AM_V_at)$(RANLIB) libasm.a + +libasm_pic.a: $(libasm_pic_a_OBJECTS) $(libasm_pic_a_DEPENDENCIES) $(EXTRA_libasm_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libasm_pic.a + $(AM_V_AR)$(libasm_pic_a_AR) libasm_pic.a $(libasm_pic_a_OBJECTS) $(libasm_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libasm_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_abort.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_addint16.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_addint32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_addint64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_addint8.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_addsleb128.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_addstrz.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_adduint16.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_adduint32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_adduint64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_adduint8.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_adduleb128.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_align.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_begin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_end.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_error.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_fill.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_getelf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newabssym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newcomsym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newscn_ingrp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newscngrp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newsubscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_newsym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm_scngrp_newsignature.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disasm_begin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disasm_cb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disasm_end.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disasm_str.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbolhash.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install-exec: install-exec-am +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/asm_abort.Po + -rm -f ./$(DEPDIR)/asm_addint16.Po + -rm -f ./$(DEPDIR)/asm_addint32.Po + -rm -f ./$(DEPDIR)/asm_addint64.Po + -rm -f ./$(DEPDIR)/asm_addint8.Po + -rm -f ./$(DEPDIR)/asm_addsleb128.Po + -rm -f ./$(DEPDIR)/asm_addstrz.Po + -rm -f ./$(DEPDIR)/asm_adduint16.Po + -rm -f ./$(DEPDIR)/asm_adduint32.Po + -rm -f ./$(DEPDIR)/asm_adduint64.Po + -rm -f ./$(DEPDIR)/asm_adduint8.Po + -rm -f ./$(DEPDIR)/asm_adduleb128.Po + -rm -f ./$(DEPDIR)/asm_align.Po + -rm -f ./$(DEPDIR)/asm_begin.Po + -rm -f ./$(DEPDIR)/asm_end.Po + -rm -f ./$(DEPDIR)/asm_error.Po + -rm -f ./$(DEPDIR)/asm_fill.Po + -rm -f ./$(DEPDIR)/asm_getelf.Po + -rm -f ./$(DEPDIR)/asm_newabssym.Po + -rm -f ./$(DEPDIR)/asm_newcomsym.Po + -rm -f ./$(DEPDIR)/asm_newscn.Po + -rm -f ./$(DEPDIR)/asm_newscn_ingrp.Po + -rm -f ./$(DEPDIR)/asm_newscngrp.Po + -rm -f ./$(DEPDIR)/asm_newsubscn.Po + -rm -f ./$(DEPDIR)/asm_newsym.Po + -rm -f ./$(DEPDIR)/asm_scngrp_newsignature.Po + -rm -f ./$(DEPDIR)/disasm_begin.Po + -rm -f ./$(DEPDIR)/disasm_cb.Po + -rm -f ./$(DEPDIR)/disasm_end.Po + -rm -f ./$(DEPDIR)/disasm_str.Po + -rm -f ./$(DEPDIR)/symbolhash.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/asm_abort.Po + -rm -f ./$(DEPDIR)/asm_addint16.Po + -rm -f ./$(DEPDIR)/asm_addint32.Po + -rm -f ./$(DEPDIR)/asm_addint64.Po + -rm -f ./$(DEPDIR)/asm_addint8.Po + -rm -f ./$(DEPDIR)/asm_addsleb128.Po + -rm -f ./$(DEPDIR)/asm_addstrz.Po + -rm -f ./$(DEPDIR)/asm_adduint16.Po + -rm -f ./$(DEPDIR)/asm_adduint32.Po + -rm -f ./$(DEPDIR)/asm_adduint64.Po + -rm -f ./$(DEPDIR)/asm_adduint8.Po + -rm -f ./$(DEPDIR)/asm_adduleb128.Po + -rm -f ./$(DEPDIR)/asm_align.Po + -rm -f ./$(DEPDIR)/asm_begin.Po + -rm -f ./$(DEPDIR)/asm_end.Po + -rm -f ./$(DEPDIR)/asm_error.Po + -rm -f ./$(DEPDIR)/asm_fill.Po + -rm -f ./$(DEPDIR)/asm_getelf.Po + -rm -f ./$(DEPDIR)/asm_newabssym.Po + -rm -f ./$(DEPDIR)/asm_newcomsym.Po + -rm -f ./$(DEPDIR)/asm_newscn.Po + -rm -f ./$(DEPDIR)/asm_newscn_ingrp.Po + -rm -f ./$(DEPDIR)/asm_newscngrp.Po + -rm -f ./$(DEPDIR)/asm_newsubscn.Po + -rm -f ./$(DEPDIR)/asm_newsym.Po + -rm -f ./$(DEPDIR)/asm_scngrp_newsignature.Po + -rm -f ./$(DEPDIR)/disasm_begin.Po + -rm -f ./$(DEPDIR)/disasm_cb.Po + -rm -f ./$(DEPDIR)/disasm_end.Po + -rm -f ./$(DEPDIR)/disasm_str.Po + -rm -f ./$(DEPDIR)/symbolhash.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLIBRARIES uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLIBRARIES install-man install-pdf \ + install-pdf-am install-pkgincludeHEADERS install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-libLIBRARIES uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) +libasm.so: $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$@.$(VERSION) \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \ + $(libasm_so_LDLIBS) + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + +install: install-am libasm.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libasm.so $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so + ln -fs libasm-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libasm.so.$(VERSION) + ln -fs libasm.so.$(VERSION) $(DESTDIR)$(libdir)/libasm.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libasm.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libasm.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libasm/asm_abort.c b/libasm/asm_abort.c new file mode 100644 index 00000000..12743dc6 --- /dev/null +++ b/libasm/asm_abort.c @@ -0,0 +1,60 @@ +/* Abort operations on the assembler context, free all resources. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include + + +int +asm_abort (AsmCtx_t *ctx) +{ + if (ctx == NULL) + /* Something went wrong earlier. */ + return -1; + + if (likely (! ctx->textp)) + /* First free the ELF file. We don't care about the result. */ + (void) elf_end (ctx->out.elf); + + /* Now close the temporary file and remove it. */ + if (ctx->fd != -1) + (void) unlink (ctx->tmp_fname); + + /* Free the resources. */ + __libasm_finictx (ctx); + + return 0; +} diff --git a/libasm/asm_addint16.c b/libasm/asm_addint16.c new file mode 100644 index 00000000..4ae45972 --- /dev/null +++ b/libasm/asm_addint16.c @@ -0,0 +1,32 @@ +/* Add integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define SIZE 16 + +#include "asm_addint8.c" diff --git a/libasm/asm_addint32.c b/libasm/asm_addint32.c new file mode 100644 index 00000000..776cf6f5 --- /dev/null +++ b/libasm/asm_addint32.c @@ -0,0 +1,32 @@ +/* Add integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define SIZE 32 + +#include "asm_addint8.c" diff --git a/libasm/asm_addint64.c b/libasm/asm_addint64.c new file mode 100644 index 00000000..ee338344 --- /dev/null +++ b/libasm/asm_addint64.c @@ -0,0 +1,32 @@ +/* Add integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define SIZE 64 + +#include "asm_addint8.c" diff --git a/libasm/asm_addint8.c b/libasm/asm_addint8.c new file mode 100644 index 00000000..bb7d40f2 --- /dev/null +++ b/libasm/asm_addint8.c @@ -0,0 +1,121 @@ +/* Add integer to a section. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include + +#ifndef SIZE +# define SIZE 8 +#endif + +#define FCT(size) _FCT(size) +#define _FCT(size) asm_addint##size +#define TYPE(size) _TYPE(size) +#define _TYPE(size) int##size##_t +#define BSWAP(size) _BSWAP(size) +#define _BSWAP(size) bswap_##size + + +int +FCT(SIZE) (AsmScn_t *asmscn, TYPE(SIZE) num) +{ + if (asmscn == NULL) + return -1; + + if (asmscn->type == SHT_NOBITS && unlikely (num != 0)) + { + __libasm_seterrno (ASM_E_TYPE); + return -1; + } + + if (unlikely (asmscn->ctx->textp)) + { + // XXX Needs to use backend specified pseudo-ops + if (SIZE == 8) + fprintf (asmscn->ctx->out.file, "\t.byte\t%" PRId8 "\n", (int8_t) num); + else if (SIZE == 16) + fprintf (asmscn->ctx->out.file, "\t.value\t%" PRId16 "\n", + (int16_t) num); + else if (SIZE == 32) + fprintf (asmscn->ctx->out.file, "\t.long\t%" PRId32 "\n", + (int32_t) num); + else + { + // XXX This is not necessary for 64-bit machines + bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA] + == ELFDATA2LSB); + + fprintf (asmscn->ctx->out.file, + "\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n", + (int32_t) (is_leb + ? num % 0x100000000ll : num / 0x100000000ll), + (int32_t) (is_leb + ? num / 0x100000000ll : num % 0x100000000ll)); + } + } + else + { +#if SIZE > 8 + bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA] + == ELFDATA2LSB); +#endif + TYPE(SIZE) var = num; + + /* Make sure we have enough room. */ + if (__libasm_ensure_section_space (asmscn, SIZE / 8) != 0) + return -1; + +#if SIZE > 8 + if ((BYTE_ORDER == LITTLE_ENDIAN && !is_leb) + || (BYTE_ORDER == BIG_ENDIAN && is_leb)) + var = BSWAP(SIZE) (var); +#endif + + /* Copy the variable value. */ + if (likely (asmscn->type == SHT_NOBITS)) + memcpy (&asmscn->content->data[asmscn->content->len], &var, SIZE / 8); + + /* Adjust the pointer in the data buffer. */ + asmscn->content->len += SIZE / 8; + + /* Increment the offset in the (sub)section. */ + asmscn->offset += SIZE / 8; + } + + return 0; +} +INTDEF(FCT(SIZE)) diff --git a/libasm/asm_addsleb128.c b/libasm/asm_addsleb128.c new file mode 100644 index 00000000..dc62c951 --- /dev/null +++ b/libasm/asm_addsleb128.c @@ -0,0 +1,97 @@ +/* Add signed little endian base 128 integer to a section. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include + + +int +asm_addsleb128 (AsmScn_t *asmscn, int32_t num) +{ + if (asmscn == NULL) + return -1; + + if (asmscn->type == SHT_NOBITS && unlikely (num != 0)) + { + __libasm_seterrno (ASM_E_TYPE); + return -1; + } + + if (unlikely (asmscn->ctx->textp)) + fprintf (asmscn->ctx->out.file, "\t.sleb128\t%" PRId32 "\n", num); + else + { + char tmpbuf[(sizeof (num) * 8 + 6) / 7]; + char *dest = tmpbuf; + uint32_t byte; + int32_t endval = num >> 31; + + if (num == 0) + byte = 0; + else + while (1) + { + byte = num & 0x7f; + + num >>= 7; + if (num == endval) + /* This is the last byte. */ + break; + + *dest++ = byte | 0x80; + } + + *dest++ = byte; + + /* Number of bytes produced. */ + size_t nbytes = dest - tmpbuf; + + /* Make sure we have enough room. */ + if (__libasm_ensure_section_space (asmscn, nbytes) != 0) + return -1; + + /* Copy the bytes. */ + if (likely (asmscn->type != SHT_NOBITS)) + memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes); + + /* Adjust the pointer in the data buffer. */ + asmscn->content->len += nbytes; + + /* Increment the offset in the (sub)section. */ + asmscn->offset += nbytes; + } + + return 0; +} diff --git a/libasm/asm_addstrz.c b/libasm/asm_addstrz.c new file mode 100644 index 00000000..26e06bb2 --- /dev/null +++ b/libasm/asm_addstrz.c @@ -0,0 +1,125 @@ +/* Add string to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include + + +/* Add zero terminated string STR of size LEN to (sub)section ASMSCN. */ +int +asm_addstrz (AsmScn_t *asmscn, const char *str, size_t len) +{ + if (asmscn == NULL) + return -1; + + if (unlikely (asmscn->type == SHT_NOBITS)) + { + if (len == 0) + { + if (str[0] != '\0') + { + __libasm_seterrno (ASM_E_TYPE); + return -1; + } + } + else + { + size_t cnt; + + for (cnt = 0; cnt < len; ++cnt) + if (str[cnt] != '\0') + { + __libasm_seterrno (ASM_E_TYPE); + return -1; + } + } + } + + if (len == 0) + len = strlen (str) + 1; + + if (unlikely (asmscn->ctx->textp)) + { + bool nextline = true; + + do + { + if (nextline) + { + fputs ("\t.string\t\"", asmscn->ctx->out.file); + nextline = false; + } + + if (*str == '\0') + fputs ("\\000", asmscn->ctx->out.file); + else if (! isascii (*str)) + fprintf (asmscn->ctx->out.file, "\\%03o", + (unsigned int) *((unsigned char *)str)); + else if (*str == '\\') + fputs ("\\\\", asmscn->ctx->out.file); + else if (*str == '\n') + { + fputs ("\\n\"", asmscn->ctx->out.file); + nextline = true; + } + else + fputc (*str, asmscn->ctx->out.file); + + ++str; + } + while (--len > 0 && (len > 1 || *str != '\0')); + + if (! nextline) + fputs ("\"\n", asmscn->ctx->out.file); + } + else + { + /* Make sure there is enough room. */ + if (__libasm_ensure_section_space (asmscn, len) != 0) + return -1; + + /* Copy the string. */ + memcpy (&asmscn->content->data[asmscn->content->len], str, len); + + /* Adjust the pointer in the data buffer. */ + asmscn->content->len += len; + + /* Increment the offset in the (sub)section. */ + asmscn->offset += len; + } + + return 0; +} diff --git a/libasm/asm_adduint16.c b/libasm/asm_adduint16.c new file mode 100644 index 00000000..65a13030 --- /dev/null +++ b/libasm/asm_adduint16.c @@ -0,0 +1,32 @@ +/* Add unsigned integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define SIZE 16 + +#include "asm_adduint8.c" diff --git a/libasm/asm_adduint32.c b/libasm/asm_adduint32.c new file mode 100644 index 00000000..9a3ec6d5 --- /dev/null +++ b/libasm/asm_adduint32.c @@ -0,0 +1,32 @@ +/* Add unsigned integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define SIZE 32 + +#include "asm_adduint8.c" diff --git a/libasm/asm_adduint64.c b/libasm/asm_adduint64.c new file mode 100644 index 00000000..b2c57a42 --- /dev/null +++ b/libasm/asm_adduint64.c @@ -0,0 +1,32 @@ +/* Add unsigned integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define SIZE 64 + +#include "asm_adduint8.c" diff --git a/libasm/asm_adduint8.c b/libasm/asm_adduint8.c new file mode 100644 index 00000000..18b67ddf --- /dev/null +++ b/libasm/asm_adduint8.c @@ -0,0 +1,54 @@ +/* Add unsigned integer to a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifndef SIZE +# define SIZE 8 +#endif + +#define UFCT(size) _UFCT(size) +#define _UFCT(size) asm_adduint##size +#define FCT(size) _FCT(size) +#define _FCT(size) asm_addint##size +#define UTYPE(size) _UTYPE(size) +#define _UTYPE(size) uint##size##_t +#define TYPE(size) _TYPE(size) +#define _TYPE(size) int##size##_t + + +int +UFCT(SIZE) (AsmScn_t *asmscn, UTYPE(SIZE) num) +{ + return INTUSE(FCT(SIZE)) (asmscn, (TYPE(SIZE)) num); +} diff --git a/libasm/asm_adduleb128.c b/libasm/asm_adduleb128.c new file mode 100644 index 00000000..96438cce --- /dev/null +++ b/libasm/asm_adduleb128.c @@ -0,0 +1,93 @@ +/* Add integer to a section. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libasmP.h" + + +int +asm_adduleb128 (AsmScn_t *asmscn, uint32_t num) +{ + if (asmscn == NULL) + return -1; + + if (asmscn->type == SHT_NOBITS && unlikely (num != 0)) + { + __libasm_seterrno (ASM_E_TYPE); + return -1; + } + + if (unlikely (asmscn->ctx->textp)) + fprintf (asmscn->ctx->out.file, "\t.uleb128\t%" PRIu32 "\n", num); + else + { + char tmpbuf[(sizeof (num) * 8 + 6) / 7]; + char *dest = tmpbuf; + uint32_t byte; + + while (1) + { + byte = num & 0x7f; + + num >>= 7; + if (num == 0) + /* This is the last byte. */ + break; + + *dest++ = byte | 0x80; + } + + *dest++ = byte; + + /* Number of bytes produced. */ + size_t nbytes = dest - tmpbuf; + + /* Make sure we have enough room. */ + if (__libasm_ensure_section_space (asmscn, nbytes) != 0) + return -1; + + /* Copy the bytes. */ + if (likely (asmscn->type != SHT_NOBITS)) + memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes); + + /* Adjust the pointer in the data buffer. */ + asmscn->content->len += nbytes; + + /* Increment the offset in the (sub)section. */ + asmscn->offset += nbytes; + } + + return 0; +} diff --git a/libasm/asm_align.c b/libasm/asm_align.c new file mode 100644 index 00000000..c8c671b2 --- /dev/null +++ b/libasm/asm_align.c @@ -0,0 +1,175 @@ +/* Align section. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include + + +int +asm_align (AsmScn_t *asmscn, GElf_Word value) +{ + if (asmscn == NULL) + /* An earlier error. */ + return -1; + + /* The alignment value must be a power of two. */ + if (unlikely (! powerof2 (value))) + { + __libasm_seterrno (ASM_E_INVALID); + return -1; + } + + if (unlikely (asmscn->ctx->textp)) + { + fprintf (asmscn->ctx->out.file, "\t.align %" PRId32 ", ", + (int32_t) value); + if (asmscn->pattern->len == 1) + fprintf (asmscn->ctx->out.file, "%02hhx\n", asmscn->pattern->bytes[0]); + else + { + fputc_unlocked ('"', asmscn->ctx->out.file); + + for (size_t cnt = 0; cnt < asmscn->pattern->len; ++cnt) + fprintf (asmscn->ctx->out.file, "\\x%02hhx", + asmscn->pattern->bytes[cnt]); + + fputs_unlocked ("\"\n", asmscn->ctx->out.file); + } + return 0; + } + + rwlock_wrlock (asmscn->ctx->lock); + + int result = 0; + + /* Fillbytes necessary? */ + if ((asmscn->offset & (value - 1)) != 0) + { + /* Add fillbytes. */ + size_t cnt = value - (asmscn->offset & (value - 1)); + + /* Ensure there is enough room to add the fill bytes. */ + result = __libasm_ensure_section_space (asmscn, cnt); + if (result != 0) + goto out; + + /* Fill in the bytes. We align the pattern according to the + current offset. */ + size_t byteptr = asmscn->offset % asmscn->pattern->len; + + /* Update the total size. */ + asmscn->offset += cnt; + + do + { + asmscn->content->data[asmscn->content->len++] + = asmscn->pattern->bytes[byteptr++]; + + if (byteptr == asmscn->pattern->len) + byteptr = 0; + } + while (--cnt > 0); + } + + /* Remember the maximum alignment for this subsection. */ + if (asmscn->max_align < value) + { + asmscn->max_align = value; + + /* Update the parent as well (if it exists). */ + if (asmscn->subsection_id != 0) + { + rwlock_wrlock (asmscn->data.up->ctx->lock); + + if (asmscn->data.up->max_align < value) + asmscn->data.up->max_align = value; + + rwlock_unlock (asmscn->data.up->ctx->lock); + } + } + + out: + rwlock_unlock (asmscn->ctx->lock); + + return result; +} + + +/* Ensure there are at least LEN bytes available in the output buffer + for ASMSCN. */ +int +internal_function +__libasm_ensure_section_space (AsmScn_t *asmscn, size_t len) +{ + /* The blocks with the section content are kept in a circular + single-linked list. */ + size_t size; + + if (asmscn->content == NULL) + { + /* This is the first block. */ + size = MAX (2 * len, 960); + + asmscn->content = (struct AsmData *) calloc (1, sizeof (struct AsmData) + + size); + if (asmscn->content == NULL) + return -1; + + asmscn->content->next = asmscn->content; + } + else + { + struct AsmData *newp; + + if (asmscn->content->maxlen - asmscn->content->len >= len) + /* Nothing to do, there is enough space. */ + return 0; + + size = MAX (2 *len, MIN (32768, 2 * asmscn->offset)); + + newp = (struct AsmData *) calloc (1, sizeof (struct AsmData) + size); + if (newp == NULL) + return -1; + + newp->next = asmscn->content->next; + asmscn->content = asmscn->content->next = newp; + } + + asmscn->content->len = 0; + asmscn->content->maxlen = size; + + return 0; +} diff --git a/libasm/asm_begin.c b/libasm/asm_begin.c new file mode 100644 index 00000000..1df2d4ea --- /dev/null +++ b/libasm/asm_begin.c @@ -0,0 +1,181 @@ +/* Create descriptor for assembling. + Copyright (C) 2002, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "libasmP.h" +#include + + +static AsmCtx_t * +prepare_text_output (AsmCtx_t *result) +{ + if (result->fd == -1) + result->out.file = stdout; + else + { + result->out.file = fdopen (result->fd, "a"); + if (result->out.file == NULL) + { + close (result->fd); + free (result); + result = NULL; + } + else + __fsetlocking (result->out.file, FSETLOCKING_BYCALLER); + } + + return result; +} + + +static AsmCtx_t * +prepare_binary_output (AsmCtx_t *result, Ebl *ebl) +{ + GElf_Ehdr *ehdr; + GElf_Ehdr ehdr_mem; + + /* Create the ELF descriptor for the file. */ + result->out.elf = elf_begin (result->fd, ELF_C_WRITE_MMAP, NULL); + if (result->out.elf == NULL) + { + err_libelf: + unlink (result->tmp_fname); + close (result->fd); + free (result); + __libasm_seterrno (ASM_E_LIBELF); + return NULL; + } + + /* Create the ELF header for the output file. */ + int class = ebl_get_elfclass (ebl); + if (gelf_newehdr (result->out.elf, class) == 0) + goto err_libelf; + + ehdr = gelf_getehdr (result->out.elf, &ehdr_mem); + /* If this failed we are in trouble. */ + assert (ehdr != NULL); + + /* We create an object file. */ + ehdr->e_type = ET_REL; + /* Set the ELF version. */ + ehdr->e_version = EV_CURRENT; + + /* Use the machine, class, and endianness values from the Ebl descriptor. */ + ehdr->e_machine = ebl_get_elfmachine (ebl); + ehdr->e_ident[EI_CLASS] = class; + ehdr->e_ident[EI_DATA] = ebl_get_elfdata (ebl); + + memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG); + + /* Write the ELF header information back. */ + (void) gelf_update_ehdr (result->out.elf, ehdr); + + /* No section so far. */ + result->section_list = NULL; + + /* Initialize the hash table. */ + asm_symbol_tab_init (&result->symbol_tab, 67); + result->nsymbol_tab = 0; + /* And the string tables. */ + result->section_strtab = dwelf_strtab_init (true); + result->symbol_strtab = dwelf_strtab_init (true); + + /* We have no section groups so far. */ + result->groups = NULL; + result->ngroups = 0; + + return result; +} + + +AsmCtx_t * +asm_begin (const char *fname, Ebl *ebl, bool textp) +{ + if (fname == NULL && ! textp) + return NULL; + + size_t fname_len = fname != NULL ? strlen (fname) : 0; + + /* Create the file descriptor. We do not generate the output file + right away. Instead we create a temporary file in the same + directory which, if everything goes alright, will replace a + possibly existing file with the given name. */ + AsmCtx_t *result + = (AsmCtx_t *) malloc (sizeof (AsmCtx_t) + 2 * fname_len + 9); + if (result == NULL) + return NULL; + + /* Initialize the lock. */ + rwlock_init (result->lock); + + if (fname != NULL) + { + /* Create the name of the temporary file. */ + result->fname = stpcpy (mempcpy (result->tmp_fname, fname, fname_len), + ".XXXXXX") + 1; + memcpy (result->fname, fname, fname_len + 1); + + /* Create the temporary file. */ + result->fd = mkstemp (result->tmp_fname); + if (result->fd == -1) + { + int save_errno = errno; + free (result); + __libasm_seterrno (ASM_E_CANNOT_CREATE); + errno = save_errno; + return NULL; + } + } + else + result->fd = -1; + + /* Initialize the counter for temporary symbols. */ + result->tempsym_count = 0; + + /* Now we differentiate between textual and binary output. */ + result->textp = textp; + if (textp) + result = prepare_text_output (result); + else + result = prepare_binary_output (result, ebl); + + return result; +} diff --git a/libasm/asm_end.c b/libasm/asm_end.c new file mode 100644 index 00000000..077d2aa5 --- /dev/null +++ b/libasm/asm_end.c @@ -0,0 +1,617 @@ +/* Finalize operations on the assembler context, free all resources. + Copyright (C) 2002, 2003, 2005, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +static int +text_end (AsmCtx_t *ctx __attribute__ ((unused))) +{ + if (fflush (ctx->out.file) != 0) + { + __libasm_seterrno (ASM_E_IOERROR); + return -1; + } + + return 0; +} + + +static int +binary_end (AsmCtx_t *ctx) +{ + void *symtab = NULL; + Dwelf_Strent *symscn_strent = NULL; + Dwelf_Strent *strscn_strent = NULL; + Dwelf_Strent *xndxscn_strent = NULL; + Elf_Scn *shstrscn; + Dwelf_Strent *shstrscn_strent; + size_t shstrscnndx; + size_t symscnndx = 0; + size_t strscnndx = 0; + size_t xndxscnndx = 0; + Elf_Data *data; + Elf_Data *shstrtabdata; + Elf_Data *strtabdata = NULL; + Elf_Data *xndxdata = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + AsmScn_t *asmscn; + int result = 0; + + /* Iterate over the created sections and compute the offsets of the + various subsections and fill in the content. */ + for (asmscn = ctx->section_list; asmscn != NULL; asmscn = asmscn->allnext) + { +#if 0 + Elf_Scn *scn = elf_getscn (ctx->out.elf, asmscn->data.main.scnndx); +#else + Elf_Scn *scn = asmscn->data.main.scn; +#endif + off_t offset = 0; + AsmScn_t *asmsubscn = asmscn; + + do + { + struct AsmData *content = asmsubscn->content; + bool first = true; + + offset = ((offset + asmsubscn->max_align - 1) + & ~(asmsubscn->max_align - 1)); + + /* Update the offset for this subsection. This field now + stores the offset of the first by in this subsection. */ + asmsubscn->offset = offset; + + /* Note that the content list is circular. */ + if (content != NULL) + do + { + Elf_Data *newdata = elf_newdata (scn); + + if (newdata == NULL) + { + __libasm_seterrno (ASM_E_LIBELF); + return -1; + } + + newdata->d_buf = content->data; + newdata->d_type = ELF_T_BYTE; + newdata->d_size = content->len; + newdata->d_off = offset; + newdata->d_align = first ? asmsubscn->max_align : 1; + + offset += content->len; + } + while ((content = content->next) != asmsubscn->content); + } + while ((asmsubscn = asmsubscn->subnext) != NULL); + } + + + /* Create the symbol table if necessary. */ + if (ctx->nsymbol_tab > 0) + { + /* Create the symbol table and string table section names. */ + symscn_strent = dwelf_strtab_add_len (ctx->section_strtab, ".symtab", 8); + strscn_strent = dwelf_strtab_add_len (ctx->section_strtab, ".strtab", 8); + + /* Create the symbol string table section. */ + Elf_Scn *strscn = elf_newscn (ctx->out.elf); + strtabdata = elf_newdata (strscn); + shdr = gelf_getshdr (strscn, &shdr_mem); + if (strtabdata == NULL || shdr == NULL) + { + __libasm_seterrno (ASM_E_LIBELF); + return -1; + } + strscnndx = elf_ndxscn (strscn); + + dwelf_strtab_finalize (ctx->symbol_strtab, strtabdata); + + shdr->sh_type = SHT_STRTAB; + assert (shdr->sh_entsize == 0); + + (void) gelf_update_shdr (strscn, shdr); + + /* Create the symbol table section. */ + Elf_Scn *symscn = elf_newscn (ctx->out.elf); + data = elf_newdata (symscn); + shdr = gelf_getshdr (symscn, &shdr_mem); + if (data == NULL || shdr == NULL) + { + __libasm_seterrno (ASM_E_LIBELF); + return -1; + } + symscnndx = elf_ndxscn (symscn); + + /* We know how many symbols there will be in the symbol table. */ + data->d_size = gelf_fsize (ctx->out.elf, ELF_T_SYM, + ctx->nsymbol_tab + 1, EV_CURRENT); + symtab = malloc (data->d_size); + if (symtab == NULL) + return -1; + data->d_buf = symtab; + data->d_type = ELF_T_SYM; + data->d_off = 0; + + /* Clear the first entry. */ + GElf_Sym syment; + memset (&syment, '\0', sizeof (syment)); + (void) gelf_update_sym (data, 0, &syment); + + /* Iterate over the symbol table. */ + void *runp = NULL; + int ptr_local = 1; /* Start with index 1; zero remains unused. */ + int ptr_nonlocal = ctx->nsymbol_tab; + uint32_t *xshndx = NULL; + AsmSym_t *sym; + while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL) + if (asm_emit_symbol_p (dwelf_strent_str (sym->strent))) + { + assert (ptr_local <= ptr_nonlocal); + + syment.st_name = dwelf_strent_off (sym->strent); + syment.st_info = GELF_ST_INFO (sym->binding, sym->type); + syment.st_other = 0; + syment.st_value = sym->scn->offset + sym->offset; + syment.st_size = sym->size; + + /* Add local symbols at the beginning, the other from + the end. */ + int ptr = sym->binding == STB_LOCAL ? ptr_local++ : ptr_nonlocal--; + + /* Determine the section index. We have to handle the + overflow correctly. */ + Elf_Scn *scn = (sym->scn->subsection_id == 0 + ? sym->scn->data.main.scn + : sym->scn->data.up->data.main.scn); + + Elf32_Word ndx; + if (unlikely (scn == ASM_ABS_SCN)) + ndx = SHN_ABS; + else if (unlikely (scn == ASM_COM_SCN)) + ndx = SHN_COMMON; + else if (unlikely ((ndx = elf_ndxscn (scn)) >= SHN_LORESERVE)) + { + if (unlikely (xshndx == NULL)) + { + /* The extended section index section does not yet + exist. */ + Elf_Scn *xndxscn; + + xndxscn = elf_newscn (ctx->out.elf); + xndxdata = elf_newdata (xndxscn); + shdr = gelf_getshdr (xndxscn, &shdr_mem); + if (xndxdata == NULL || shdr == NULL) + { + __libasm_seterrno (ASM_E_LIBELF); + return -1; + } + xndxscnndx = elf_ndxscn (xndxscn); + + shdr->sh_type = SHT_SYMTAB_SHNDX; + shdr->sh_entsize = sizeof (Elf32_Word); + shdr->sh_addralign = sizeof (Elf32_Word); + shdr->sh_link = symscnndx; + + (void) gelf_update_shdr (xndxscn, shdr); + + xndxscn_strent = dwelf_strtab_add_len (ctx->section_strtab, + ".symtab_shndx", + 14); + + /* Note that using 'elf32_fsize' instead of + 'gelf_fsize' here is correct. */ + xndxdata->d_size = elf32_fsize (ELF_T_WORD, + ctx->nsymbol_tab + 1, + EV_CURRENT); + xshndx = xndxdata->d_buf = calloc (1, xndxdata->d_size); + if (xshndx == NULL) + return -1; + /* Using ELF_T_WORD here relies on the fact that the + 32- and 64-bit types are the same size. */ + xndxdata->d_type = ELF_T_WORD; + xndxdata->d_off = 0; + } + + /* Store the real section index in the extended section + index table. */ + assert ((size_t) ptr < ctx->nsymbol_tab + 1); + xshndx[ptr] = ndx; + + /* And signal that this happened. */ + ndx = SHN_XINDEX; + } + syment.st_shndx = ndx; + + /* Remember where we put the symbol. */ + sym->symidx = ptr; + + (void) gelf_update_sym (data, ptr, &syment); + } + + assert (ptr_local == ptr_nonlocal + 1); + + shdr->sh_type = SHT_SYMTAB; + shdr->sh_link = strscnndx; + shdr->sh_info = ptr_local; + shdr->sh_entsize = gelf_fsize (ctx->out.elf, ELF_T_SYM, 1, EV_CURRENT); + shdr->sh_addralign = gelf_fsize (ctx->out.elf, ELF_T_ADDR, 1, + EV_CURRENT); + + (void) gelf_update_shdr (symscn, shdr); + } + + + /* Create the section header string table section and fill in the + references in the section headers. */ + shstrscn = elf_newscn (ctx->out.elf); + shstrtabdata = elf_newdata (shstrscn); + shdr = gelf_getshdr (shstrscn, &shdr_mem); + if (shstrscn == NULL || shstrtabdata == NULL || shdr == NULL) + { + __libasm_seterrno (ASM_E_LIBELF); + return -1; + } + + + /* Add the name of the section header string table. */ + shstrscn_strent = dwelf_strtab_add_len (ctx->section_strtab, + ".shstrtab", 10); + + dwelf_strtab_finalize (ctx->section_strtab, shstrtabdata); + + shdr->sh_type = SHT_STRTAB; + assert (shdr->sh_entsize == 0); + shdr->sh_name = dwelf_strent_off (shstrscn_strent); + + (void) gelf_update_shdr (shstrscn, shdr); + + + /* Create the section groups. */ + if (ctx->groups != NULL) + { + AsmScnGrp_t *runp = ctx->groups->next; + + do + { + Elf_Scn *scn; + Elf32_Word *grpdata; + + scn = runp->scn; + assert (scn != NULL); + shdr = gelf_getshdr (scn, &shdr_mem); + assert (shdr != NULL); + + data = elf_newdata (scn); + if (data == NULL) + { + __libasm_seterrno (ASM_E_LIBELF); + return -1; + } + + /* It is correct to use 'elf32_fsize' instead of 'gelf_fsize' + here. */ + data->d_size = elf32_fsize (ELF_T_WORD, runp->nmembers + 1, + EV_CURRENT); + grpdata = data->d_buf = malloc (data->d_size); + if (grpdata == NULL) + return -1; + data->d_type = ELF_T_WORD; + data->d_off = 0; + data->d_align = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); + + /* The first word of the section is filled with the flag word. */ + *grpdata++ = runp->flags; + + if (runp->members != NULL) + { + AsmScn_t *member = runp->members->data.main.next_in_group; + + do + { + /* Only sections, not subsections, can be registered + as member of a group. The subsections get + automatically included. */ + assert (member->subsection_id == 0); + + *grpdata++ = elf_ndxscn (member->data.main.scn); + } + while ((member = member->data.main.next_in_group) + != runp->members->data.main.next_in_group); + } + + /* Construct the section header. */ + shdr->sh_name = dwelf_strent_off (runp->strent); + shdr->sh_type = SHT_GROUP; + shdr->sh_flags = 0; + shdr->sh_link = symscnndx; + /* If the user did not specify a signature we use the initial + empty symbol in the symbol table as the signature. */ + shdr->sh_info = (runp->signature != NULL + ? runp->signature->symidx : 0); + + (void) gelf_update_shdr (scn, shdr); + } + while ((runp = runp->next) != ctx->groups->next); + } + + + /* Add the name to the symbol section. */ + if (likely (symscnndx != 0)) + { + Elf_Scn *scn = elf_getscn (ctx->out.elf, symscnndx); + + shdr = gelf_getshdr (scn, &shdr_mem); + + shdr->sh_name = dwelf_strent_off (symscn_strent); + + (void) gelf_update_shdr (scn, shdr); + + + /* Add the name to the string section. */ + assert (strscnndx != 0); + scn = elf_getscn (ctx->out.elf, strscnndx); + + shdr = gelf_getshdr (scn, &shdr_mem); + + shdr->sh_name = dwelf_strent_off (strscn_strent); + + (void) gelf_update_shdr (scn, shdr); + + + /* Add the name to the extended symbol index section. */ + if (xndxscnndx != 0) + { + scn = elf_getscn (ctx->out.elf, xndxscnndx); + + shdr = gelf_getshdr (scn, &shdr_mem); + + shdr->sh_name = dwelf_strent_off (xndxscn_strent); + + (void) gelf_update_shdr (scn, shdr); + } + } + + + /* Iterate over the created sections and fill in the names. */ + for (asmscn = ctx->section_list; asmscn != NULL; asmscn = asmscn->allnext) + { + shdr = gelf_getshdr (asmscn->data.main.scn, &shdr_mem); + /* This better should not fail. */ + assert (shdr != NULL); + + shdr->sh_name = dwelf_strent_off (asmscn->data.main.strent); + + /* We now know the maximum alignment. */ + shdr->sh_addralign = asmscn->max_align; + + (void) gelf_update_shdr (asmscn->data.main.scn, shdr); + } + + /* Put the reference to the section header string table in the ELF + header. */ + ehdr = gelf_getehdr (ctx->out.elf, &ehdr_mem); + assert (ehdr != NULL); + + shstrscnndx = elf_ndxscn (shstrscn); + if (unlikely (shstrscnndx > SHN_HIRESERVE) + || unlikely (shstrscnndx == SHN_XINDEX)) + { + /* The index of the section header string sectio is too large. */ + Elf_Scn *scn = elf_getscn (ctx->out.elf, 0); + + /* Get the header for the zeroth section. */ + shdr = gelf_getshdr (scn, &shdr_mem); + /* This better does not fail. */ + assert (shdr != NULL); + + /* The sh_link field of the zeroth section header contains the value. */ + shdr->sh_link = shstrscnndx; + + (void) gelf_update_shdr (scn, shdr); + + /* This is the sign for the overflow. */ + ehdr->e_shstrndx = SHN_XINDEX; + } + else + ehdr->e_shstrndx = elf_ndxscn (shstrscn); + + if (unlikely (gelf_update_ehdr (ctx->out.elf, ehdr) == 0)) + { + __libasm_seterrno (ASM_E_LIBELF); + result = -1; + } + + /* Write out the ELF file. */ + if (unlikely (elf_update (ctx->out.elf, ELF_C_WRITE_MMAP) < 0)) + { + __libasm_seterrno (ASM_E_LIBELF); + result = -1; + } + + /* We do not need the section header and symbol string tables anymore. */ + free (shstrtabdata->d_buf); + if (strtabdata != NULL) + free (strtabdata->d_buf); + /* We might have allocated the extended symbol table index. */ + if (xndxdata != NULL) + free (xndxdata->d_buf); + + /* Free section groups memory. */ + AsmScnGrp_t *scngrp = ctx->groups; + if (scngrp != NULL) + do + free (elf_getdata (scngrp->scn, NULL)->d_buf); + while ((scngrp = scngrp->next) != ctx->groups); + + /* Finalize the ELF handling. */ + if (unlikely (elf_end (ctx->out.elf)) != 0) + { + __libasm_seterrno (ASM_E_LIBELF); + result = -1; + } + + /* Free the temporary resources. */ + free (symtab); + + return result; +} + + +int +asm_end (AsmCtx_t *ctx) +{ + int result; + + if (ctx == NULL) + /* Something went wrong earlier. */ + return -1; + + result = unlikely (ctx->textp) ? text_end (ctx) : binary_end (ctx); + if (result != 0) + return result; + + /* Make the new file globally readable and user/group-writable. */ + if (fchmod (ctx->fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) != 0) + { + __libasm_seterrno (ASM_E_CANNOT_CHMOD); + return -1; + } + + /* Rename output file. */ + if (rename (ctx->tmp_fname, ctx->fname) != 0) + { + __libasm_seterrno (ASM_E_CANNOT_RENAME); + return -1; + } + + /* Free the resources. */ + __libasm_finictx (ctx); + + return 0; +} + + +static void +free_section (AsmScn_t *scnp) +{ + void *oldp; + + if (scnp->subnext != NULL) + free_section (scnp->subnext); + + struct AsmData *data = scnp->content; + if (data != NULL) + do + { + oldp = data; + data = data->next; + free (oldp); + } + while (oldp != scnp->content); + + free (scnp); +} + + +void +internal_function +__libasm_finictx (AsmCtx_t *ctx) +{ + /* Iterate through section table and free individual entries. */ + AsmScn_t *scn = ctx->section_list; + while (scn != NULL) + { + AsmScn_t *oldp = scn; + scn = scn->allnext; + free_section (oldp); + } + + /* Free the resources of the symbol table. */ + void *runp = NULL; + AsmSym_t *sym; + while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL) + free (sym); + asm_symbol_tab_free (&ctx->symbol_tab); + + + /* Free section groups. */ + AsmScnGrp_t *scngrp = ctx->groups; + if (scngrp != NULL) + do + { + AsmScnGrp_t *oldp = scngrp; + + scngrp = scngrp->next; + free (oldp); + } + while (scngrp != ctx->groups); + + + if (unlikely (ctx->textp)) + { + /* Close the stream. */ + fclose (ctx->out.file); + } + else + { + /* Close the output file. */ + /* XXX We should test for errors here but what would we do if we'd + find any. */ + (void) close (ctx->fd); + + /* And the string tables. */ + dwelf_strtab_free (ctx->section_strtab); + dwelf_strtab_free (ctx->symbol_strtab); + } + + /* Initialize the lock. */ + rwlock_fini (ctx->lock); + + /* Finally free the data structure. */ + free (ctx); +} diff --git a/libasm/asm_error.c b/libasm/asm_error.c new file mode 100644 index 00000000..cc3e660b --- /dev/null +++ b/libasm/asm_error.c @@ -0,0 +1,95 @@ +/* Error handling in libasm. + Copyright (C) 2002, 2004, 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libasmP.h" + + +/* This is the key for the thread specific memory. */ +static __thread int global_error; + + +int +asm_errno (void) +{ + int result = global_error; + global_error = ASM_E_NOERROR; + return result; +} + + +void +internal_function +__libasm_seterrno (int value) +{ + global_error = value; +} + + +/* Return the appropriate message for the error. */ +static const char *msgs[ASM_E_NUM] = +{ + [ASM_E_NOERROR] = N_("no error"), + [ASM_E_NOMEM] = N_("out of memory"), + [ASM_E_CANNOT_CREATE] = N_("cannot create output file"), + [ASM_E_INVALID] = N_("invalid parameter"), + [ASM_E_CANNOT_CHMOD] = N_("cannot change mode of output file"), + [ASM_E_CANNOT_RENAME] = N_("cannot rename output file"), + [ASM_E_DUPLSYM] = N_("duplicate symbol"), + [ASM_E_TYPE] = N_("invalid section type for operation"), + [ASM_E_IOERROR] = N_("error during output of data"), + [ASM_E_ENOSUP] = N_("no backend support available"), +}; + +const char * +asm_errmsg (int error) +{ + int last_error = global_error; + + if (error < -1) + return _("unknown error"); + if (error == 0 && last_error == 0) + /* No error. */ + return NULL; + + if (error != -1) + last_error = error; + + if (last_error == ASM_E_LIBELF) + return elf_errmsg (-1); + + return _(msgs[last_error]); +} diff --git a/libasm/asm_fill.c b/libasm/asm_fill.c new file mode 100644 index 00000000..62d9d732 --- /dev/null +++ b/libasm/asm_fill.c @@ -0,0 +1,74 @@ +/* Determine fill pattern for a section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include + + +int +asm_fill (AsmScn_t *asmscn, void *bytes, size_t len) +{ + struct FillPattern *pattern; + struct FillPattern *old_pattern; + + if (asmscn == NULL) + /* Some earlier error. */ + return -1; + + if (bytes == NULL) + /* Use the default pattern. */ + pattern = (struct FillPattern *) __libasm_default_pattern; + else + { + /* Allocate appropriate memory. */ + pattern = (struct FillPattern *) malloc (sizeof (struct FillPattern) + + len); + if (pattern == NULL) + return -1; + + pattern->len = len; + memcpy (pattern->bytes, bytes, len); + } + + old_pattern = asmscn->pattern; + asmscn->pattern = pattern; + + /* Free the old data structure if we have allocated it. */ + if (old_pattern != __libasm_default_pattern) + free (old_pattern); + + return 0; +} diff --git a/libasm/asm_getelf.c b/libasm/asm_getelf.c new file mode 100644 index 00000000..2a5c37bb --- /dev/null +++ b/libasm/asm_getelf.c @@ -0,0 +1,43 @@ +/* Return ELF descriptor associated with the assembler context. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + + +Elf * +asm_getelf (AsmCtx_t *ctx) +{ + return ctx != NULL ? ctx->out.elf : NULL; +} diff --git a/libasm/asm_newabssym.c b/libasm/asm_newabssym.c new file mode 100644 index 00000000..34fef3e3 --- /dev/null +++ b/libasm/asm_newabssym.c @@ -0,0 +1,131 @@ +/* Create new ABS symbol. + Copyright (C) 2002, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include + + +/* Object for special COMMON section. */ +static const AsmScn_t __libasm_abs_scn = + { + .data = { + .main = { + .scn = ASM_ABS_SCN + } + } + }; + + +AsmSym_t * +asm_newabssym (AsmCtx_t *ctx, const char *name, GElf_Xword size, + GElf_Addr value, int type, int binding) +{ + AsmSym_t *result; + + if (ctx == NULL) + /* Something went wrong before. */ + return NULL; + + /* Common symbols are public. Therefore the user must provide a + name. */ + if (name == NULL) + { + __libasm_seterrno (ASM_E_INVALID); + return NULL; + } + + rwlock_wrlock (ctx->lock); + + result = (AsmSym_t *) malloc (sizeof (AsmSym_t)); + if (result == NULL) + return NULL; + + result->scn = (AsmScn_t *) &__libasm_abs_scn; + result->size = size; + result->type = type; + result->binding = binding; + result->symidx = 0; + result->strent = dwelf_strtab_add (ctx->symbol_strtab, name); + + /* The value of an ABS symbol must not be modified. Since there are + no subsection and the initial offset of the section is 0 we can + get the alignment recorded by storing it into the offset + field. */ + result->offset = value; + + if (unlikely (ctx->textp)) + { + /* An absolute symbol can be defined by giving a symbol a + specific value. */ + if (binding == STB_GLOBAL) + fprintf (ctx->out.file, "\t.globl %s\n", name); + else if (binding == STB_WEAK) + fprintf (ctx->out.file, "\t.weak %s\n", name); + + if (type == STT_OBJECT) + fprintf (ctx->out.file, "\t.type %s,@object\n", name); + else if (type == STT_FUNC) + fprintf (ctx->out.file, "\t.type %s,@function\n", name); + + fprintf (ctx->out.file, "%s = %llu\n", + name, (unsigned long long int) value); + + if (size != 0) + fprintf (ctx->out.file, "\t.size %s, %llu\n", + name, (unsigned long long int) size); + } + else + { + /* Put the symbol in the hash table so that we can later find it. */ + if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result) + != 0) + { + /* The symbol already exists. */ + __libasm_seterrno (ASM_E_DUPLSYM); + free (result); + result = NULL; + } + else if (name != NULL && asm_emit_symbol_p (name)) + /* Only count non-private symbols. */ + ++ctx->nsymbol_tab; + } + + rwlock_unlock (ctx->lock); + + return result; +} diff --git a/libasm/asm_newcomsym.c b/libasm/asm_newcomsym.c new file mode 100644 index 00000000..ee3b6966 --- /dev/null +++ b/libasm/asm_newcomsym.c @@ -0,0 +1,114 @@ +/* Create new COMMON symbol. + Copyright (C) 2002, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include + + +/* Object for special COMMON section. */ +static const AsmScn_t __libasm_com_scn = + { + .data = { + .main = { + .scn = ASM_COM_SCN + } + } + }; + + +AsmSym_t * +asm_newcomsym (AsmCtx_t *ctx, const char *name, GElf_Xword size, + GElf_Addr align) +{ + AsmSym_t *result; + + if (ctx == NULL) + /* Something went wrong before. */ + return NULL; + + /* Common symbols are public. Therefore the user must provide a + name. */ + if (name == NULL) + { + __libasm_seterrno (ASM_E_INVALID); + return NULL; + } + + rwlock_wrlock (ctx->lock); + + result = (AsmSym_t *) malloc (sizeof (AsmSym_t)); + if (result == NULL) + return NULL; + + result->scn = (AsmScn_t *) &__libasm_com_scn; + result->size = size; + /* XXX Do we have to allow a different type? */ + result->type = STT_OBJECT; + /* XXX Do we have to allow a different binding? */ + result->binding = STB_GLOBAL; + result->symidx = 0; + result->strent = dwelf_strtab_add (ctx->symbol_strtab, name); + + /* The value of a COM symbol is the alignment. Since there are no + subsection and the initial offset of the section is 0 we can get + the alignment recorded by storing it into the offset field. */ + result->offset = align; + + if (unlikely (ctx->textp)) + fprintf (ctx->out.file, "\t.comm %s, %" PRIuMAX ", %" PRIuMAX "\n", + name, (uintmax_t) size, (uintmax_t) align); + else + { + /* Put the symbol in the hash table so that we can later find it. */ + if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result) + != 0) + { + /* The symbol already exists. */ + __libasm_seterrno (ASM_E_DUPLSYM); + free (result); + result = NULL; + } + else if (name != NULL && asm_emit_symbol_p (name)) + /* Only count non-private symbols. */ + ++ctx->nsymbol_tab; + } + + rwlock_unlock (ctx->lock); + + return result; +} diff --git a/libasm/asm_newscn.c b/libasm/asm_newscn.c new file mode 100644 index 00000000..7cdf484f --- /dev/null +++ b/libasm/asm_newscn.c @@ -0,0 +1,211 @@ +/* Create new section in output file. + Copyright (C) 2002-2011, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include +#include + + +/* Memory for the default pattern. The type uses a flexible array + which does work well with a static initializer. So we play some + dirty tricks here. */ +static const struct +{ + struct FillPattern pattern; + char zero; +} xdefault_pattern = + { + .pattern = + { + .len = 1 + }, + .zero = '\0' + }; +const struct FillPattern *__libasm_default_pattern = &xdefault_pattern.pattern; + + +static AsmScn_t * +text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags) +{ + /* Buffer where we construct the flag string. */ + char flagstr[sizeof (GElf_Xword) * 8 + 5]; + char *wp = flagstr; + const char *typestr = ""; + + /* Only write out the flag string if this is the first time the + section is selected. Some assemblers cannot cope with the + .section pseudo-op otherwise. */ + wp = stpcpy (wp, ", \""); + + if (flags & SHF_WRITE) + *wp++ = 'w'; + if (flags & SHF_ALLOC) + *wp++ = 'a'; + if (flags & SHF_EXECINSTR) + *wp++ = 'x'; + if (flags & SHF_MERGE) + *wp++ = 'M'; + if (flags & SHF_STRINGS) + *wp++ = 'S'; + if (flags & SHF_LINK_ORDER) + *wp++ = 'L'; + + *wp++ = '"'; + + if (type == SHT_PROGBITS) + typestr = ",@progbits"; + else if (type == SHT_NOBITS) + typestr = ",@nobits"; + + /* Terminate the string. */ + *wp = '\0'; + + fprintf (result->ctx->out.file, "\t.section \"%s\"%s%s\n", + result->name, flagstr, typestr); + + return result; +} + + +static AsmScn_t * +binary_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags, + size_t scnname_len) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + Elf_Scn *scn; + + /* The initial subsection has the number zero. */ + result->subsection_id = 0; + + /* We start at offset zero. */ + result->offset = 0; + /* And generic alignment. */ + result->max_align = 1; + + /* No output yet. */ + result->content = NULL; + + /* Put the default fill pattern in place. */ + result->pattern = (struct FillPattern *) __libasm_default_pattern; + + /* There are no subsections so far. */ + result->subnext = NULL; + + /* Add the name to the section header string table. */ + result->data.main.strent = dwelf_strtab_add_len (result->ctx->section_strtab, + result->name, scnname_len); + assert (result->data.main.strent != NULL); + + /* Create the new ELF section. */ + result->data.main.scn = scn = elf_newscn (result->ctx->out.elf); + if (scn == NULL) + { + free (result); + __libasm_seterrno (ASM_E_LIBELF); + return NULL; + } + + /* Not part of a section group (yet). */ + result->data.main.next_in_group = NULL; + + /* Remember the flags. */ + shdr = gelf_getshdr (scn, &shdr_mem); + + shdr->sh_flags = flags; + result->type = shdr->sh_type = type; + + (void) gelf_update_shdr (scn, shdr); + + return result; +} + + +AsmScn_t * +asm_newscn (AsmCtx_t *ctx, const char *scnname, GElf_Word type, + GElf_Xword flags) +{ + size_t scnname_len = strlen (scnname) + 1; + AsmScn_t *result; + + /* If no context is given there might be an earlier error. */ + if (ctx == NULL) + return NULL; + + /* Check whether only flags are set which areselectable by the user. */ + if (unlikely ((flags & ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE + | SHF_STRINGS | SHF_LINK_ORDER)) != 0) + /* We allow only two section types: data and data without file + representation. */ + || (type != SHT_PROGBITS && unlikely (type != SHT_NOBITS))) + { + __libasm_seterrno (ASM_E_INVALID); + return NULL; + } + + rwlock_wrlock (ctx->lock); + + /* This is a new section. */ + result = (AsmScn_t *) malloc (sizeof (AsmScn_t) + scnname_len); + if (result != NULL) + { + /* Add the name. */ + memcpy (result->name, scnname, scnname_len); + + /* Add the reference to the context. */ + result->ctx = ctx; + + /* Perform operations according to output mode. */ + result = (unlikely (ctx->textp) + ? text_newscn (result, type, flags) + : binary_newscn (result, type, flags, scnname_len)); + + /* If everything went well finally add the new section to the hash + table. */ + if (result != NULL) + { + result->allnext = ctx->section_list; + ctx->section_list = result; + } + } + + rwlock_unlock (ctx->lock); + + return result; +} +INTDEF(asm_newscn) diff --git a/libasm/asm_newscn_ingrp.c b/libasm/asm_newscn_ingrp.c new file mode 100644 index 00000000..fd45be62 --- /dev/null +++ b/libasm/asm_newscn_ingrp.c @@ -0,0 +1,77 @@ +/* Create new section, which is member of a group, in output file. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libasmP.h" + + +AsmScn_t * +asm_newscn_ingrp (AsmCtx_t *ctx, const char *scnname, GElf_Word type, + GElf_Xword flags, AsmScnGrp_t *grp) +{ + AsmScn_t *result = INTUSE (asm_newscn) (ctx, scnname, type, flags); + + if (likely (result != NULL)) + { + /* We managed to create a section group. Add it to the section + group. */ + if (grp->nmembers == 0) + { + assert (grp->members == NULL); + grp->members = result->data.main.next_in_group = result; + } + else + { + result->data.main.next_in_group + = grp->members->data.main.next_in_group; + grp->members = grp->members->data.main.next_in_group = result; + } + + ++grp->nmembers; + + /* Set the SHF_GROUP flag. */ + if (likely (! ctx->textp)) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (result->data.main.scn, &shdr_mem); + + assert (shdr != NULL); + shdr->sh_flags |= SHF_GROUP; + + (void) gelf_update_shdr (result->data.main.scn, shdr); + } + } + + return result; +} diff --git a/libasm/asm_newscngrp.c b/libasm/asm_newscngrp.c new file mode 100644 index 00000000..80757a9a --- /dev/null +++ b/libasm/asm_newscngrp.c @@ -0,0 +1,102 @@ +/* Create new section group. + Copyright (C) 2002, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libasmP.h" +#include + + + +AsmScnGrp_t * +asm_newscngrp (AsmCtx_t *ctx, const char *grpname, AsmSym_t *signature, + Elf32_Word flags) +{ + AsmScnGrp_t *result; + size_t grpname_len = strlen (grpname) + 1; + + if (ctx == NULL) + return NULL; + + if ((flags & ~GRP_COMDAT) != 0) + { + /* This is not a supported flag. */ + __libasm_seterrno (ASM_E_INVALID); + return NULL; + } + + result = (AsmScnGrp_t *) malloc (sizeof (AsmScnGrp_t) + grpname_len); + if (result == NULL) + return NULL; + + result->signature = signature; + result->members = NULL; + result->nmembers = 0; + result->flags = flags; + + memcpy (result->name, grpname, grpname_len); + result->strent = dwelf_strtab_add_len (ctx->section_strtab, result->name, + grpname_len); + + if (unlikely (ctx->textp)) + // XXX TBI. What is the format? + abort (); + else + { + result->scn = elf_newscn (ctx->out.elf); + if (result->scn == NULL) + { + /* Couldn't allocate a new section. */ + __libasm_seterrno (ASM_E_LIBELF); + free (result); + return NULL; + } + } + + /* Enqueue is the context data structure. */ + if (ctx->ngroups == 0) + { + assert (ctx->groups == NULL); + ctx->groups = result->next = result; + } + else + { + result->next = ctx->groups->next; + ctx->groups = ctx->groups->next = result; + } + ++ctx->ngroups; + + return result; +} diff --git a/libasm/asm_newsubscn.c b/libasm/asm_newsubscn.c new file mode 100644 index 00000000..906240ac --- /dev/null +++ b/libasm/asm_newsubscn.c @@ -0,0 +1,97 @@ +/* Create new subsection section in given section. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include + + +AsmScn_t * +asm_newsubscn (AsmScn_t *asmscn, unsigned int nr) +{ + AsmScn_t *runp; + AsmScn_t *newp; + + /* Just return if no section is given. The error must have been + somewhere else. */ + if (asmscn == NULL) + return NULL; + + /* Determine whether there is already a subsection with this number. */ + runp = asmscn->subsection_id == 0 ? asmscn : asmscn->data.up; + while (1) + { + if (runp->subsection_id == nr) + /* Found it. */ + return runp; + + if (runp->subnext == NULL || runp->subnext->subsection_id > nr) + break; + + runp = runp->subnext; + } + + newp = (AsmScn_t *) malloc (sizeof (AsmScn_t)); + if (newp == NULL) + return NULL; + + /* Same assembler context than the original section. */ + newp->ctx = runp->ctx; + + /* User provided the subsectio nID. */ + newp->subsection_id = nr; + + /* Inherit the parent's type. */ + newp->type = runp->type; + + /* Pointer to the zeroth subsection. */ + newp->data.up = runp->subsection_id == 0 ? runp : runp->data.up; + + /* We start at offset zero. */ + newp->offset = 0; + /* And generic alignment. */ + newp->max_align = 1; + + /* No output yet. */ + newp->content = NULL; + + /* Inherit the fill pattern from the section this one is derived from. */ + newp->pattern = asmscn->pattern; + + /* Enqueue at the right position in the list. */ + newp->subnext = runp->subnext; + runp->subnext = newp; + + return newp; +} diff --git a/libasm/asm_newsym.c b/libasm/asm_newsym.c new file mode 100644 index 00000000..53891668 --- /dev/null +++ b/libasm/asm_newsym.c @@ -0,0 +1,136 @@ +/* Define new symbol for current position in given section. + Copyright (C) 2002, 2005, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include + + +AsmSym_t * +asm_newsym (AsmScn_t *asmscn, const char *name, GElf_Xword size, + int type, int binding) +{ +/* We don't really expect labels with many digits, but in theory it could + be 10 digits (plus ".L" and a zero terminator). */ +#define TEMPSYMLEN 13 + char tempsym[TEMPSYMLEN]; + AsmSym_t *result; + + if (asmscn == NULL) + /* Something went wrong before. */ + return NULL; + + /* Generate a temporary symbol if necessary. */ + if (name == NULL) + { + /* If a local symbol name is created the symbol better have + local binding. */ + if (binding != STB_LOCAL) + { + __libasm_seterrno (ASM_E_INVALID); + return NULL; + } + + // XXX This requires getting the format from the machine backend. */ + snprintf (tempsym, TEMPSYMLEN, ".L%07u", asmscn->ctx->tempsym_count++); + + name = tempsym; + } + + size_t name_len = strlen (name) + 1; + + result = (AsmSym_t *) malloc (sizeof (AsmSym_t) + name_len); + if (result == NULL) + return NULL; + + rwlock_wrlock (asmscn->ctx->lock); + + result->scn = asmscn; + result->offset = asmscn->offset; + result->size = size; + result->type = type; + result->binding = binding; + result->symidx = 0; + result->strent = dwelf_strtab_add (asmscn->ctx->symbol_strtab, + memcpy (result + 1, name, name_len)); + + if (unlikely (asmscn->ctx->textp)) + { + /* We are only interested in the name and don't need to know whether + it is a local name or not. */ + /* First print the binding pseudo-op. */ + if (binding == STB_GLOBAL) + fprintf (asmscn->ctx->out.file, "\t.globl\t%s\n", name); + else if (binding == STB_WEAK) + fprintf (asmscn->ctx->out.file, "\t.weak\t%s\n", name); + + /* Next the symbol type. */ + if (type == STT_OBJECT) + fprintf (asmscn->ctx->out.file, "\t.type\t%s,@object\n", name); + else if (type == STT_FUNC) + fprintf (asmscn->ctx->out.file, "\t.type\t%s,@function\n", name); + + /* Finally the size and the label. */ + fprintf (asmscn->ctx->out.file, "\t.size\t%s,%" PRIuMAX "\n%s:\n", + name, (uintmax_t) size, name); + } + else + { + /* Put the symbol in the hash table so that we can later find it. */ + if (asm_symbol_tab_insert (&asmscn->ctx->symbol_tab, elf_hash (name), + result) != 0) + { + /* The symbol already exists. */ + __libasm_seterrno (ASM_E_DUPLSYM); + /* Note that we can free the entry since there must be no + reference in the string table to the string. We can only + fail to insert the symbol into the symbol table if there + is already a symbol with this name. In this case the + dwelf_strtab_add function would use the previously provided + name. */ + free (result); + result = NULL; + } + else if (name != tempsym && asm_emit_symbol_p (name)) + /* Only count non-private symbols. */ + ++asmscn->ctx->nsymbol_tab; + } + + rwlock_unlock (asmscn->ctx->lock); + + return result; +} diff --git a/libasm/asm_scngrp_newsignature.c b/libasm/asm_scngrp_newsignature.c new file mode 100644 index 00000000..2fbb3346 --- /dev/null +++ b/libasm/asm_scngrp_newsignature.c @@ -0,0 +1,46 @@ +/* Update signature of section group. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libasmP.h" + + +int +asm_scngrp_newsignature (AsmScnGrp_t *grp, AsmSym_t *signature) +{ + if (grp == NULL || signature == NULL) + return 1; + + grp->signature = signature; + + return 0; +} diff --git a/libasm/disasm_begin.c b/libasm/disasm_begin.c new file mode 100644 index 00000000..d00852b7 --- /dev/null +++ b/libasm/disasm_begin.c @@ -0,0 +1,64 @@ +/* Create context descriptor for disassembler. + Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libasmP.h" +#include "../libebl/libeblP.h" + + +DisasmCtx_t * +disasm_begin (Ebl *ebl, Elf *elf, DisasmGetSymCB_t symcb) +{ + if (ebl == NULL) + return NULL; + + if (ebl->disasm == NULL) + { + __libasm_seterrno (ASM_E_ENOSUP); + return NULL; + } + + DisasmCtx_t *ctx = (DisasmCtx_t *) malloc (sizeof (DisasmCtx_t)); + if (ctx == NULL) + { + __libasm_seterrno (ASM_E_NOMEM); + return NULL; + } + + ctx->ebl = ebl; + ctx->elf = elf; + ctx->symcb = symcb; + + return ctx; +} diff --git a/libasm/disasm_cb.c b/libasm/disasm_cb.c new file mode 100644 index 00000000..80f8b25b --- /dev/null +++ b/libasm/disasm_cb.c @@ -0,0 +1,181 @@ +/* Copyright (C) 2005, 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libasmP.h" +#include "../libebl/libeblP.h" + + +struct symtoken +{ + DisasmCtx_t *ctx; + void *symcbarg; +}; + + +static int +default_elf_getsym (GElf_Addr addr, Elf32_Word scnndx, GElf_Addr value, + char **buf, size_t *buflen, void *arg) +{ + struct symtoken *symtoken = (struct symtoken *) arg; + + /* First try the user provided function. */ + if (symtoken->ctx->symcb != NULL) + { + int res = symtoken->ctx->symcb (addr, scnndx, value, buf, buflen, + symtoken->symcbarg); + if (res >= 0) + return res; + } + + // XXX Look up in ELF file. + + return -1; +} + + +struct symaddrpair +{ + GElf_Addr addr; + const char *name; +}; + + +static void +read_symtab_exec (DisasmCtx_t *ctx) +{ + /* We simply use all we can get our hands on. This will produce + some duplicate information but this is no problem, we simply + ignore the latter definitions. */ + Elf_Scn *scn= NULL; + while ((scn = elf_nextscn (ctx->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + Elf_Data *data; + if (shdr == NULL || shdr->sh_type != SHT_SYMTAB + || (data = elf_getdata (scn, NULL)) == NULL) + continue; + + int xndxscnidx = elf_scnshndx (scn); + Elf_Data *xndxdata = NULL; + if (xndxscnidx > 0) + xndxdata = elf_getdata (elf_getscn (ctx->elf, xndxscnidx), NULL); + + /* Iterate over all symbols. Add all defined symbols. */ + if (shdr->sh_entsize == 0) + continue; + int nsyms = shdr->sh_size / shdr->sh_entsize; + for (int cnt = 1; cnt < nsyms; ++cnt) + { + Elf32_Word xshndx; + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, + &xshndx); + if (sym == NULL) + continue; + + /* Undefined symbols are useless here. */ + if (sym->st_shndx == SHN_UNDEF) + continue; + + + } + } +} + + +static void +read_symtab (DisasmCtx_t *ctx) +{ + /* Find the symbol table(s). */ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (ctx->elf, &ehdr_mem); + if (ehdr == NULL) + return; + + switch (ehdr->e_type) + { + case ET_EXEC: + case ET_DYN: + read_symtab_exec (ctx); + break; + + case ET_REL: + // XXX Handle + break; + + default: + break; + } +} + + +static int +null_elf_getsym (GElf_Addr addr __attribute__ ((unused)), + Elf32_Word scnndx __attribute__ ((unused)), + GElf_Addr value __attribute__ ((unused)), + char **buf __attribute__ ((unused)), + size_t *buflen __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ + return -1; +} + + +int +disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end, + GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb, + void *outcbarg, void *symcbarg) +{ + struct symtoken symtoken; + DisasmGetSymCB_t getsym = ctx->symcb ?: null_elf_getsym; + + if (ctx->elf != NULL) + { + /* Read all symbols of the ELF file and stuff them into a hash + table. The key is the address and the section index. */ + read_symtab (ctx); + + symtoken.ctx = ctx; + symtoken.symcbarg = symcbarg; + + symcbarg = &symtoken; + + getsym = default_elf_getsym; + } + + return ctx->ebl->disasm (ctx->ebl, startp, end, addr, fmt, outcb, + getsym, outcbarg, symcbarg); +} +INTDEF (disasm_cb) diff --git a/libasm/disasm_end.c b/libasm/disasm_end.c new file mode 100644 index 00000000..68780308 --- /dev/null +++ b/libasm/disasm_end.c @@ -0,0 +1,45 @@ +/* Release descriptor for disassembler. + Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libasmP.h" + + +int +disasm_end (DisasmCtx_t *ctx) +{ + free (ctx); + + return 0; +} diff --git a/libasm/disasm_str.c b/libasm/disasm_str.c new file mode 100644 index 00000000..c14e6d5b --- /dev/null +++ b/libasm/disasm_str.c @@ -0,0 +1,72 @@ +/* Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libasmP.h" + + +struct buffer +{ + char *buf; + size_t len; +}; + + +static int +buffer_cb (char *str, size_t len, void *arg) +{ + struct buffer *buffer = (struct buffer *) arg; + + if (len > buffer->len) + /* Return additional needed space. */ + return len - buffer->len; + + buffer->buf = mempcpy (buffer->buf, str, len); + buffer->len = len; + + return 0; +} + + +int +disasm_str (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end, + GElf_Addr addr, const char *fmt, char **bufp, size_t len, + void *symcbarg) +{ + struct buffer buffer = { .buf = *bufp, .len = len }; + + int res = INTUSE(disasm_cb) (ctx, startp, end, addr, fmt, buffer_cb, &buffer, + symcbarg); + *bufp = buffer.buf; + return res; +} diff --git a/libasm/libasm.h b/libasm/libasm.h new file mode 100644 index 00000000..b67b77dc --- /dev/null +++ b/libasm/libasm.h @@ -0,0 +1,203 @@ +/* Interface for libasm. + Copyright (C) 2002, 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBASM_H +#define _LIBASM_H 1 + +#include +#include +#include + +typedef struct ebl Ebl; + + +/* Opaque type for the assembler context descriptor. */ +typedef struct AsmCtx AsmCtx_t; + +/* Opaque type for a section. */ +typedef struct AsmScn AsmScn_t; + +/* Opaque type for a section group. */ +typedef struct AsmScnGrp AsmScnGrp_t; + +/* Opaque type for a symbol. */ +typedef struct AsmSym AsmSym_t; + + +/* Opaque type for the disassembler context descriptor. */ +typedef struct DisasmCtx DisasmCtx_t; + +/* Type used for callback functions to retrieve symbol name. The + symbol reference is in the section designated by the second parameter + at an offset described by the first parameter. The value is the + third parameter. */ +typedef int (*DisasmGetSymCB_t) (GElf_Addr, Elf32_Word, GElf_Addr, char **, + size_t *, void *); + +/* Output function callback. */ +typedef int (*DisasmOutputCB_t) (char *, size_t, void *); + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create output file and return descriptor for assembler context. If + TEXTP is true the output is an assembler format text file. + Otherwise an object file is created. The MACHINE parameter + corresponds to an EM_ constant from , KLASS specifies the + class (32- or 64-bit), and DATA specifies the byte order (little or + big endian). */ +extern AsmCtx_t *asm_begin (const char *fname, Ebl *ebl, bool textp); + +/* Abort the operation on the assembler context and free all resources. */ +extern int asm_abort (AsmCtx_t *ctx); + +/* Finalize output file and free all resources. */ +extern int asm_end (AsmCtx_t *ctx); + + +/* Return handle for the named section. If it was not used before + create it. */ +extern AsmScn_t *asm_newscn (AsmCtx_t *ctx, const char *scnname, + GElf_Word type, GElf_Xword flags); + + +/* Similar to 'asm_newscn', but make it part of section group GRP. */ +extern AsmScn_t *asm_newscn_ingrp (AsmCtx_t *ctx, const char *scnname, + GElf_Word type, GElf_Xword flags, + AsmScnGrp_t *grp); + +/* Create new subsection NR in the given section. */ +extern AsmScn_t *asm_newsubscn (AsmScn_t *asmscn, unsigned int nr); + + +/* Return handle for new section group. The signature symbol can be + set later. */ +extern AsmScnGrp_t *asm_newscngrp (AsmCtx_t *ctx, const char *grpname, + AsmSym_t *signature, Elf32_Word flags); + +/* Set or overwrite signature symbol for group. */ +extern int asm_scngrp_newsignature (AsmScnGrp_t *grp, AsmSym_t *signature); + + +/* Add zero terminated string STR of size LEN to (sub)section ASMSCN. */ +extern int asm_addstrz (AsmScn_t *asmscn, const char *str, size_t len); + +/* Add 8-bit signed integer NUM to (sub)section ASMSCN. */ +extern int asm_addint8 (AsmScn_t *asmscn, int8_t num); + +/* Add 8-bit unsigned integer NUM to (sub)section ASMSCN. */ +extern int asm_adduint8 (AsmScn_t *asmscn, uint8_t num); + +/* Add 16-bit signed integer NUM to (sub)section ASMSCN. */ +extern int asm_addint16 (AsmScn_t *asmscn, int16_t num); + +/* Add 16-bit unsigned integer NUM to (sub)section ASMSCN. */ +extern int asm_adduint16 (AsmScn_t *asmscn, uint16_t num); + +/* Add 32-bit signed integer NUM to (sub)section ASMSCN. */ +extern int asm_addint32 (AsmScn_t *asmscn, int32_t num); + +/* Add 32-bit unsigned integer NUM to (sub)section ASMSCN. */ +extern int asm_adduint32 (AsmScn_t *asmscn, uint32_t num); + +/* Add 64-bit signed integer NUM to (sub)section ASMSCN. */ +extern int asm_addint64 (AsmScn_t *asmscn, int64_t num); + +/* Add 64-bit unsigned integer NUM to (sub)section ASMSCN. */ +extern int asm_adduint64 (AsmScn_t *asmscn, uint64_t num); + + +/* Add signed little endian base 128 integer NUM to (sub)section ASMSCN. */ +extern int asm_addsleb128 (AsmScn_t *asmscn, int32_t num); + +/* Add unsigned little endian base 128 integer NUM to (sub)section ASMSCN. */ +extern int asm_adduleb128 (AsmScn_t *asmscn, uint32_t num); + + +/* Define new symbol NAME for current position in given section ASMSCN. */ +extern AsmSym_t *asm_newsym (AsmScn_t *asmscn, const char *name, + GElf_Xword size, int type, int binding); + + +/* Define new common symbol NAME with given SIZE and alignment. */ +extern AsmSym_t *asm_newcomsym (AsmCtx_t *ctx, const char *name, + GElf_Xword size, GElf_Addr align); + +/* Define new common symbol NAME with given SIZE, VALUE, TYPE, and BINDING. */ +extern AsmSym_t *asm_newabssym (AsmCtx_t *ctx, const char *name, + GElf_Xword size, GElf_Addr value, + int type, int binding); + + +/* Align (sub)section offset according to VALUE. */ +extern int asm_align (AsmScn_t *asmscn, GElf_Word value); + +/* Set the byte pattern used to fill gaps created by alignment. */ +extern int asm_fill (AsmScn_t *asmscn, void *bytes, size_t len); + + +/* Return ELF descriptor created for the output file of the given context. */ +extern Elf *asm_getelf (AsmCtx_t *ctx); + + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int asm_errno (void); + +/* Return error string for ERROR. If ERROR is zero, return error string + for most recent error or NULL is none occurred. If ERROR is -1 the + behaviour is similar to the last case except that not NULL but a legal + string is returned. */ +extern const char *asm_errmsg (int __error); + + +/* Create context descriptor for disassembler. */ +extern DisasmCtx_t *disasm_begin (Ebl *ebl, Elf *elf, DisasmGetSymCB_t symcb); + +/* Release descriptor for disassembler. */ +extern int disasm_end (DisasmCtx_t *ctx); + +/* Produce of disassembly output for given memory, store text in + provided buffer. */ +extern int disasm_str (DisasmCtx_t *ctx, const uint8_t **startp, + const uint8_t *end, GElf_Addr addr, const char *fmt, + char **bufp, size_t len, void *symcbarg); + +/* Produce disassembly output for given memory and output it using the + given callback functions. */ +extern int disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp, + const uint8_t *end, GElf_Addr addr, const char *fmt, + DisasmOutputCB_t outcb, void *outcbarg, void *symcbarg); + +#ifdef __cplusplus +} +#endif + +#endif /* libasm.h */ diff --git a/libasm/libasm.map b/libasm/libasm.map new file mode 100644 index 00000000..a36cdbfe --- /dev/null +++ b/libasm/libasm.map @@ -0,0 +1,38 @@ +ELFUTILS_1.0 { + global: + asm_abort; + asm_addint16; + asm_addint32; + asm_addint64; + asm_addint8; + asm_addsleb128; + asm_addstrz; + asm_adduint16; + asm_adduint32; + asm_adduint64; + asm_adduint8; + asm_adduleb128; + asm_align; + asm_begin; + asm_end; + asm_errmsg; + asm_errno; + asm_fill; + asm_getelf; + asm_newabssym; + asm_newcomsym; + asm_newscn; + asm_newscn_ingrp; + asm_newscngrp; + asm_newsubscn; + asm_newsym; + asm_scngrp_newsignature; + + disasm_begin; + disasm_cb; + disasm_end; + disasm_str; + + local: + *; +}; diff --git a/libasm/libasmP.h b/libasm/libasmP.h new file mode 100644 index 00000000..5b5fb776 --- /dev/null +++ b/libasm/libasmP.h @@ -0,0 +1,307 @@ +/* Internal definitions for libasm. + Copyright (C) 2002, 2004, 2005, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBASMP_H +#define _LIBASMP_H 1 + +#include + +#include +#include "libebl.h" + +#include "libdwelf.h" + + +/* Known error codes. */ +enum + { + ASM_E_NOERROR, + ASM_E_NOMEM, /* No more memory. */ + ASM_E_CANNOT_CREATE, /* Output file cannot be created. */ + ASM_E_INVALID, /* Invalid parameters. */ + ASM_E_CANNOT_CHMOD, /* Cannot change mode of output file. */ + ASM_E_CANNOT_RENAME, /* Cannot rename output file. */ + ASM_E_DUPLSYM, /* Duplicate symbol definition. */ + ASM_E_LIBELF, /* Refer to error in libelf. */ + ASM_E_TYPE, /* Invalid section type for operation. */ + ASM_E_IOERROR, /* Error during output of data. */ + ASM_E_ENOSUP, /* No backend support. */ + ASM_E_NUM /* Keep this entry as the last. */ + }; + + +/* Special sections. */ +#define ASM_ABS_SCN ((Elf_Scn *) 1) +#define ASM_COM_SCN ((Elf_Scn *) 2) + + +/* And the hash table for symbols. */ +#include + + +/* Descriptor for a section. */ +struct AsmScn +{ + /* The underlying assembler context. */ + AsmCtx_t *ctx; + + /* Subsection ID. */ + unsigned int subsection_id; + + /* Section type. */ + GElf_Word type; + + union + { + /* Data only stored in the record for subsection zero. */ + struct + { + /* The ELF section. */ + Elf_Scn *scn; + + /* Entry in the section header string table. */ + Dwelf_Strent *strent; + + /* Next member of group. */ + struct AsmScn *next_in_group; + } main; + + /* Pointer to the record for subsection zero. */ + AsmScn_t *up; + } data; + + /* Current offset in the (sub)section. */ + GElf_Off offset; + /* Maximum alignment of the section so far. */ + GElf_Word max_align; + + /* Section content. */ + struct AsmData + { + /* Currently used number of bytes in the block. */ + size_t len; + + /* Number of bytes allocated. */ + size_t maxlen; + + /* Pointer to the next block. */ + struct AsmData *next; + + /* The actual data. */ + char data[flexarr_size]; + } *content; + + /* Fill pattern. */ + struct FillPattern + { + size_t len; + char bytes[flexarr_size]; + } *pattern; + + /* Next subsection. */ + AsmScn_t *subnext; + + /* List of all allocated sections. */ + AsmScn_t *allnext; + + /* Name of the section. */ + char name[flexarr_size]; +}; + + +/* Descriptor used for the assembling session. */ +struct AsmCtx +{ + /* File descriptor of the temporary file. */ + int fd; + + /* True if text output is wanted. */ + bool textp; + + /* Output file handle. */ + union + { + /* ELF descriptor of the temporary file. */ + Elf *elf; + /* I/O stream for text output. */ + FILE *file; + } out; + + + /* List with defined sections. */ + AsmScn_t *section_list; + /* Section header string table. */ + Dwelf_Strtab *section_strtab; + + /* Table with defined symbols. */ + asm_symbol_tab symbol_tab; + /* Number of symbols in the table. */ + unsigned int nsymbol_tab; + /* Symbol string table. */ + Dwelf_Strtab *symbol_strtab; + + /* List of section groups. */ + struct AsmScnGrp *groups; + /* Number of section groups. */ + size_t ngroups; + + /* Current required alignment for common symbols. */ + GElf_Word common_align; + + /* Lock to handle multithreaded programs. */ + rwlock_define (,lock); + + /* Counter for temporary symbols. */ + unsigned int tempsym_count; + + /* Name of the output file. */ + char *fname; + /* The name of the temporary file. */ + char tmp_fname[flexarr_size]; +}; + + +/* Descriptor for a symbol. */ +struct AsmSym +{ + /* Reference to the section which contains the symbol. */ + AsmScn_t *scn; + + /* Type of the symbol. */ + int8_t type; + /* Binding of the symbol. */ + int8_t binding; + + /* Size of the symbol. */ + GElf_Xword size; + + /* Offset in the section. */ + GElf_Off offset; + + /* Symbol table index of the symbol in the symbol table. */ + size_t symidx; + + /* Reference to name of the symbol. */ + Dwelf_Strent *strent; +}; + + +/* Descriptor for section group. */ +struct AsmScnGrp +{ + /* Entry in the section header string table. */ + Dwelf_Strent *strent; + + /* The ELF section. */ + Elf_Scn *scn; + + /* The signature. */ + struct AsmSym *signature; + + /* First member. */ + struct AsmScn *members; + /* Number of members. */ + size_t nmembers; + + /* Flags. */ + Elf32_Word flags; + + /* Next group. */ + struct AsmScnGrp *next; + + /* Name of the section group. */ + char name[flexarr_size]; +}; + + +/* Descriptor for disassembler. */ +struct DisasmCtx +{ + /* Handle for the backend library with the disassembler routine. */ + Ebl *ebl; + + /* ELF file containing all the data passed to the function. This + allows to look up symbols. */ + Elf *elf; + + /* Callback function to determine symbol names. */ + DisasmGetSymCB_t symcb; +}; + + +/* The default fill pattern: one zero byte. */ +extern const struct FillPattern *__libasm_default_pattern + attribute_hidden; + + +/* Ensure there are at least LEN bytes available in the output buffer + for ASMSCN. */ +extern int __libasm_ensure_section_space (AsmScn_t *asmscn, size_t len) + internal_function; + +/* Free all resources associated with the assembler context. */ +extern void __libasm_finictx (AsmCtx_t *ctx) internal_function; + +/* Set error code. */ +extern void __libasm_seterrno (int err) internal_function; + +/* Return handle for the named section. If it was not used before + create it. */ +extern AsmScn_t *__asm_newscn_internal (AsmCtx_t *ctx, const char *scnname, + GElf_Word type, GElf_Xword flags) + attribute_hidden; + + +/* Internal aliases of the asm_addintXX functions. */ +extern int __asm_addint8_internal (AsmScn_t *asmscn, int8_t num) + attribute_hidden; +extern int __asm_addint16_internal (AsmScn_t *asmscn, int16_t num) + attribute_hidden; +extern int __asm_addint32_internal (AsmScn_t *asmscn, int32_t num) + attribute_hidden; +extern int __asm_addint64_internal (AsmScn_t *asmscn, int64_t num) + attribute_hidden; + + +/* Produce disassembly output for given memory and output it using the + given callback functions. */ +extern int __disasm_cb_internal (DisasmCtx_t *ctx, const uint8_t **startp, + const uint8_t *end, GElf_Addr addr, + const char *fmt, DisasmOutputCB_t outcb, + void *outcbarp, void *symcbarg) + attribute_hidden; + + +/* Test whether given symbol is an internal symbol and if yes, whether + we should nevertheless emit it in the symbol table. */ +// XXX The second part should probably be controlled by an option which +// isn't implemented yet +// XXX Also, the format will change with the backend. +#define asm_emit_symbol_p(name) (!startswith (name, ".L")) + +#endif /* libasmP.h */ diff --git a/libasm/symbolhash.c b/libasm/symbolhash.c new file mode 100644 index 00000000..57c9e76d --- /dev/null +++ b/libasm/symbolhash.c @@ -0,0 +1,54 @@ +/* Symbol hash table implementation. + Copyright (C) 2001, 2002, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include + +/* Definitions for the symbol hash table. */ +#define TYPE AsmSym_t * +#define NAME asm_symbol_tab +#define ITERATE 1 +#define REVERSE 1 +#define COMPARE(a, b) \ + strcmp (dwelf_strent_str ((a)->strent), dwelf_strent_str ((b)->strent)) + +#define next_prime __libasm_next_prime +extern size_t next_prime (size_t) attribute_hidden; + +#include "../lib/dynamicsizehash.c" + +#undef next_prime +#define next_prime attribute_hidden __libasm_next_prime +#include "../lib/next_prime.c" diff --git a/libasm/symbolhash.h b/libasm/symbolhash.h new file mode 100644 index 00000000..d05a40a5 --- /dev/null +++ b/libasm/symbolhash.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef SYMBOLHASH_H +#define SYMBOLHASH_H 1 + +/* Definitions for the symbol hash table. */ +#define TYPE AsmSym_t * +#define NAME asm_symbol_tab +#define ITERATE 1 +#define COMPARE(a, b) \ + strcmp (dwelf_strent_str ((a)->strent), dwelf_strent_str ((b)->strent)) +#include + +#endif /* symbolhash.h */ diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog new file mode 100644 index 00000000..7cca9419 --- /dev/null +++ b/libcpu/ChangeLog @@ -0,0 +1,512 @@ +2020-12-20 Dmitry V. Levin + + * .gitignore: New file. + +2020-12-16 Érico Nogueira + + * Makefile.am (i386_gendis_LDADD): Add obstack_LIBS. + +2020-12-16 Dmitry V. Levin + + * i386_lex.l (invalid_char): Replace gettext(...) with _(...). + * i386_parse.y (yyerror): Likewise. + +2020-12-12 Dmitry V. Levin + + * bpf_disasm.c (bswap_bpf_insn): Fix spelling typo in comment. + * i386_disasm.c (i386_disasm): Likewise. + +2020-05-09 Mark Wielaard + + * i386_parse.y (new_bitfield): Call free newp on error. + +2020-04-16 Mark Wielaard + + * i386_disasm.c (i386_disasm): Replace assert with goto invalid_op + for bad prefix. + +2019-12-11 Omar Sandoval + + * Makefile.am (i386_lex_CFLAGS): Add -Wno-implicit-fallthrough. + +2019-10-17 Mark Wielaard + + * i386_data.h (FCT_sel): Check for param_start + 2 >= end instead + of just >. + * i386_disasm.c (i386_disasm): Check param_start < end. Don't + assert, but assign INVALID to str. Make sure we get past any + unrecognized opcode. + +2019-09-07 Mark Wielaard + + * riscv_disasm.c (riscv_disasm): Use UINT64_C to make calculation + unsigned. + +2019-07-05 Omar Sandoval + + * Makefile.am: Combine libcpu_{i386,x86_64,bpf}.a into libcpu.a. + Make libcpu.a non-PIC by default. + Add libcpu_pic.a. + +2018-11-04 Mark Wielaard + + * bpf_disasm.c (bpf_disasm): Recognize BPF_JLT, BPF_JLE, BPF_JSLT + and BPF_JSLE. + +2018-02-09 Joshua Watt + + * i386_disasm.c (i386_disasm): Use FALLTHOUGH macro instead of + comment. + +2017-08-18 Ulf Hermann + + * memory-access.h: Use attribute_packed. + +2017-02-27 Ulf Hermann + + * Makefile.am: Use fpic_CFLAGS. + +2017-07-18 Mark Wielaard + + * Makefile.am: Don't check HAVE_LINUX_BPF_H, just define libcpu_bpf. + * bpf_disasm.c: Include bpf.h instead of linux/bpf.h. Don't define + BPF_PSEUDO_MAP_FD. + +2017-04-20 Ulf Hermann + + * Makefile.am: Add EXEEXT to gendis. + +2017-04-20 Ulf Hermann + + * i386_parse.y: Eliminate comparison_fn_t. + +2016-11-02 Mark Wielaard + + * i386_disasm.c (i386_disasm): Add fallthrough comment. + +2016-10-11 Akihiko Odaki + + * i386_lex.l: Remove system.h include, add libeu.h include. + * i386_parse.y: Remove sys/param.h include, add libeu.h include. + * i386_disasm.c: Remove sys/param.h. + +2016-09-05 Mark Wielaard + + * bpf_disasm.c: Define BPF_PSEUDO_MAP_FD if undefined. + +2016-08-10 Richard Henderson + + * bpf_disasm.c (bpf_disasm): Rearrange the printing of instructions + to use exactly the operands required. + +2016-06-28 Richard Henderson + + * Makefile.am (noinst_LIBRARIES): Add libcpu_bpf.a. + (libcpu_bpf_a_SOURCES, libcpu_bpf_a_CFLAGS): New. + * bpf_disasm.c: New file. + * i386_disasm.c (i386_disasm): Add ebl parameter. + +2015-10-05 Josh Stone + + * Makefile.am (%_defs): Add AM_V_GEN and AM_V_at silencers. + ($(srcdir)/%_dis.h): Ditto. + (%.mnemonics): Add AM_V_GEN silencer. + +2014-10-29 Jose E. Marchesi + + * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid + relocation overflows in some platforms. + +2014-04-13 Mark Wielaard + + * Makefile.am (i386_gendis_LDADD): Remove libmudflap. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2012-10-10 Roland McGrath + + * Makefile.am (%_defs, $(srcdir)/%_dis.h): Redirect to temp file, + mv into place with separate command. + +2012-06-26 Roland McGrath + + * Makefile.am [!MAINTAINER_MODE] ($(srcdir)/%_dis.h): New rule. + +2012-02-24 Mark Wielaard + + * Makefile.am (CLEANFILES): Move %_dis.h to... + (MAINTAINERCLEANFILES): here. + +2012-01-21 Ulrich Drepper + + * i386_disasm.c (ADD_NSTRING): Define. + (i386_disasm): Print color codes in the appropriate places. + +2011-10-16 Roland McGrath + + * Makefile.am (libcpu_i386_a_SOURCES): Add i386_dis.h. + (libcpu_x86_64_a_SOURCES): Add x86_64_dis.h. + (i386_disasm.o, x86_64_disasm.o): Depend on those in $(srcdir). + (%_dis.h): Renamed target pattern to ... + ($(srcdir)/%_dis.h): ... this. + (noinst_HEADERS, noinst_PROGRAMS): Put under [MAINTAINER_MODE]. + +2010-08-16 Roland McGrath + + * Makefile.am (%_defs): New pattern rule. + (%_dis.h, %.mnemonics): Define as pattern rules using %_defs input. + (CLEANFILES): Include all those files. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2009-04-14 Roland McGrath + + * Makefile.am (AM_CFLAGS): Add -fdollars-in-identifiers; it is not the + default on every machine. + +2009-01-23 Roland McGrath + + * Makefile.am (i386_parse_CFLAGS): Use quotes around command + substitution that can produce leading whitespace. + +2009-01-01 Ulrich Drepper + + * i386_parse.y (instrtable_out): Optimize match_data table by not + emitting 0xff masks for leading bytes. + * i386_disasm.c (i386_disasm): Adjust reader of match_data. + + * i386_disasm.c (i386_disasm): Reset bufcnt when not matched. We + don't expect snprintf to fail. + +2008-12-31 Ulrich Drepper + + * defs/i386: Add dppd, dpps, insertps, movntdqa, mpsadbw, packusdw, + pblendvb, pblendw, pcmpeqq, pcmpestri, pcmpestrm, pcmpistri, pcmpistrm, + pcmpgtq, phminposuw, pinsrb, pinsrd, pmaxsb, pmaxsd, pmaxud, pmaxuw, + pminsb, pminsd, pminud, pminuw, pmovsxbw, pmovsxbd, pmovsxbq, pmovsxwd, + pmovsxwq, pmovsxdq, pmovzxbw, pmovzxbd, pmovzxbq, pmovzxwd, pmovzxwq, + pmovzxdq, pmuldq, pmulld, popcnt, ptest, roundss, roundps, roundpd, + and roundsd opcodes. + + * i386_disasm.c (i386_disasm): Correct resizing of buffer. + + * i386_parse.y (struct argstring): Add off element. + (off_op_str): New global variable. + (print_op_str): Print strings as concatenated strings. Keep track + of index and length. Update ->off element. + (print_op_str_idx): New function. + (instrtable_out): Mark op%d_fct as const. + Emit two tables for the strings: the string itself (op%d_str) and the + index table (op%d_str_idx). + * i386_disasm.c (i386_disasm): Adjust for new op%d_str definition. + + * i386_disasm.c [X86_64] (i386_disasm): Handle rex prefix when + printing only prefix. + + * i386_disasm.c (i386_disasm): Minor optimizations. + + * i386_parse.y (instrtable_out): No need to emit index, the reader can + keep track. + * i386_disasm.c (i386_disasm): The index is not emitted anymore, no + need to skip it. + + * i386_disasm.c (amd3dnow): Mark as const. + + * defs/i386: Add blendvpd and blendvps opcodes. + +2008-12-30 Ulrich Drepper + + * defs/i386: Add blendpd and blendps opcodes. + +2008-12-19 Ulrich Drepper + + * defs/i386: Add entry for AMD 3DNOW. + * i386_disasm.c: Implement AMD 3DNOW disassembly. + +2008-12-17 Ulrich Drepper + + * i386_disasm.c (i386_disasm): If instruction matches prefix, + undoing the prefix match finishes the instruction. + +2008-01-21 Roland McGrath + + * defs/i386: Fix typo in comment. + * i386_disasm.c (i386_disasm): Handle cltq, cqto. + + * i386_parse.y: Add sanity check for NMNES macro value. + * Makefile.am (i386_parse.o): Fix target in dependency rule. + (i386_parse.h): New target with empty commands. + (i386_lex.o): Depend on it in place of i386_parse.c. + +2008-01-21 Ulrich Drepper + + * Makefile.am (EXTRA_DIST): Remove defs/x86_64. + +2008-01-14 Ulrich Drepper + + * defs/i386: Add fixes for opcodes with register number in opcode, + 64-bit immediate forms, nop with rex.B. + * i386_data.h [X86_64] (FCT_imm64$w): New function. + (FCT_oreg): New function. + (FCT_oreg$w): New function. + * i386_disasm.c (i386_disasm): Reinitialize fmt always before + starting the loop to process the string. Handle 0x90 special for + x86-64. + * i386_parse.y (fillin_arg): Expand synonyms before concatening to + form the function name. + +2008-01-11 Ulrich Drepper + + * i386_disasm.c (struct output_buffer): Remove symcb and symcbarg. + (i386_disasm): Remove appropriate initializers. + Use symcb to lookup symbol strings. + + * i386_disasm.c (struct output_buffer): Add labelbuf, labelbufsize, + symaddr_use, and symaddr fields. + (i386_disasm): Remove labelbuf and labelbufsize variables. + Add back %e format. Implement %a and %l formats. + + * i386_data.h (general_mod$r_m): Set symaddr_use and symaddr for %rip + base addressing. + + * i386_disasm.c (i386_disasm): Resize output buffer if necessary. + Optimize output_data initialization. Free buffers before return. + (struct output_data): Remove op1str field. Adjust code. + (i386_disasm): Store final NUL btye at end of functions. + +2008-01-10 Ulrich Drepper + + * i386_data.h (FCT_crdb): New function. + (FCT_ccc): Use FCT_crdb. + (FCT_ddd): Likewise. + + * defs/i386: Fix a few instructions with immediate arguments. + + * i386_disasm.c: Rewrite interface to callback functions for operands + to take a single pointer to a structure. + * i386_data.h: Adjust all functions. + +2008-01-08 Ulrich Drepper + + * Makefile.am: Enable x86-64 again. + * defs/i386: Lots of changes for x86-64. + * i386_data.h: Add support for use in x86-64 disassembler. + * i386_disasm.c: Likewise. + * i386_parse.y: Likewise. + * defs/x86_64: Removed. + +2008-01-04 Ulrich Drepper + + * defs/i386: Cleanups, remove masks which are not needed. + Add remaining Intel opcodes. + * i386_data.h (FCT_imm8): Check for input buffer overrun. + * i386_disasm.c (i386_disasm): Likewise. + * i386_parse.y: Remove suffixes which are not needed anymore. + +2008-01-03 Ulrich Drepper + + * defs/i386: Add yet more SSE instructions. + +2008-01-02 Ulrich Drepper + + * i386_disasm.c (i386_disasm): Extend matcher to allow tables to + contain instructions with prefixes. + * defs/i386: Use for many SSE operations. + * i386_data.h (FCT_mmxreg2): Removed. + +2008-01-01 Ulrich Drepper + + * defs/i386: More 0f prefix support. + * i386_data.h (FCT_mmxreg): Implement. + (FCT_mmxreg2): Implement. + (FCT_mmreg): Remove. + * i386_disasm.c (i386_disasm): More special instructions. + Fix tttn suffix for cmov. + * i386_parse.y: Simplify test for mod/r_m mode. + +2007-12-31 Ulrich Drepper + + * defs/i386: Fix order or arguments for mov of control/debug registers. + * i386_data.h (FCT_ccc): Implement + (FCT_ddd): Implement + +2007-12-30 Ulrich Drepper + + * defs/i386: Fix 0f groups 6 and 7. + * i386_data.c (FCT_mod$16r_m): Implement. + * i386_disasm.c (i386_disasm): Third parameter can also have string. + +2007-12-29 Ulrich Drepper + + * defs/i386: Add lots of floating point ops. + * i386_data.h (FCT_fmod$fr_m): Removed. + (FCT_freg): Implement. + * i386_disasm.c (i386_disasm): Implement suffix_D. + * i386_parse.y: Emit suffix_D. + + * defs/i386: Use rel instead of dispA. + Fix lcall, dec, div, idiv, imul, inc, jmp, ljmp, mul, neg, not, push, + test. + + * i386_data.h (FCT_dispA): Removed. + (FCT_ds_xx): Add test for end of input buffer. + * i386_disasm.c (ABORT_ENTRY): Removed. + (i386_disasm): Fix handling of SIB. Pass correct address value to + operand callbacks. + + * Makefile.am (*.mnemonics): Filter out INVALID entry. + * defs/i386: Define imms8 and use in appropriate places. + Add INVALID entries for special opcodes with special mnemonics. + Fix int3. Fix typo in shl. Correct xlat. + * i386_data.h (FCT_ds_xx): New function. + (FCT_ds_si): Use it. + (FCT_ds_bx): New function. + (FCT_imms8): New function. + * i386_disasm.c (MNE_INVALID): Define. + (i386_disasm): Handle invalid opcodes in mnemonics printing, not + separately. Fix address value passed to operand handlers. + * i386_parse.y (bx_reg): Define. + (instrtable_out): Handle INVALID entries differently, just use + MNE_INVALID value for .mnemonic. + +2007-12-28 Ulrich Drepper + + * defs/i386: Fix shift and mov immediate instructions. + * i386_data.h (FCT_imm16): Implement. + + * defs/i386: Use absval instead of abs of lcall and ljmp. + Add parameters for cmps. Fix test and mov immediate. + * i386_data.h: Implement FCT_absval. + * i386_disasm.c: Handle data16 for suffix_w and FCT_imm. + + * defs/i386: Move entries with 0x9b prefix together. + * i386_disasm.c (i386_disasm): Fix recognizing insufficient bytes in + input. Handle data16 with suffix_W. + + * i386_data.h (FCT_*): Add end parameter to all functions. Check + before using more bytes. + (FCT_sel): Implement. + * i386_disasm.c (i386_disasm): Better handle end of input buffer. + Specal opcode 0x99. + + * Makefile.am: Use m4 to preprocess defs/* files. + * defs/i386: Adjust appropriately. + * i386_data.c (FCT_ax): Implement. + (FCT_ax$w): Use FCT_ax. + * i386_disasm.c (ADD_STRING): Use _len instead of len. + (i386_disasm): If no instruction can be matched because of lack of + input and prefixes have been matched, print prefixes. + Recognize abort entries. + Handle special cases. + * i386_gendis.c: Recognize - input file name. + * i386_lex.c: Recognize INVALID token. + * i386_parse.y: Handle INVALID token input. + + * defs/i386: Fix mov, pop. + * i386_data.h (FCT_sreg3): Implement. + +2007-12-27 Ulrich Drepper + + * defs/i386: Fix adc, add, cmp, or, sbb, sub, xchg, xor. + * i386_data.h (FCT_imms): New function. + (FCT_imm$s): Use FCT_imms for handling of signed values. + (FCT_imm8): Sign extend values. + * i386_disasm.c (i386_disasm): Implement suffix_w0. + * i386_parse.y: Emit suffix w0. + + * i386_data.h (FCT_disp8): Add 0x prefix. + (FCT_ds_si): Implement. + * i386_disasm.c (i386_disasm): Increment addr for invalid prefixes. + Implement tttn suffix. + * i386_parse.y: Emit tttn suffix definition. + +2007-12-26 Ulrich Drepper + + * i386_data.h (struct instr_enc): Use suffix field. + (FCT_dx): Fill in body. + (FCT_es_di): Likewise. + (FCT_imm$s): Sign-extended byte values. + * i386_disasm.c: Protect ADD_CHAR and ADD_STRING macros. Adjust uses. + (i386_disasm): Handle suffix. + * i386_parse.y: Emit suffix information. + * defs/i386: Remove unnecessary suffixes. + + * Makefile.am: Disable building x86-64 version for now. + + * defs/i386: Fix and, bound, cmp, or, pop, sbb, sub, xor. + * i386_data.h: Pass pointer to prefix to functions. If not prefixes + are consumed this means invalid input. + * i386_disasm.c: Fix prefix printing. Adjust function calls for + parameter change. + * i386_parse.y: Recognize moda prefix. + +2007-12-21 Ulrich Drepper + + * i386_data.h: Fix SIB handling. + * i386_disasm.c: Likewise. + +2007-12-19 Ulrich Drepper + + * defs/i386: Fix up 'and' opcode. + +2007-10-31 Ulrich Drepper + + * Makefile.am: Add dependencies of the generated files on the source + files. + (i386_lex_CFLAGS): Add -Wno-sign-compare. + + * defs/i386: A lot more data. + * defs/x86_64: Likewise. + * i386_data.h (struct instr_enc): Add off1_3, off2_3, and off3_3 + fields. + (opfct_t): Add parameter for third operand. + (FCT_*): Likewise. + (data_prefix): New function. + (FCT_abs): Implement. + (FCT_ax): Renamed to FCT_ax$w amd implement. + (FCT_disp8): Implement. + (FCT_dispA): Implement. + (FCT_imm): Implement. + (FCT_imm$w): Implement. + (FCT_imm$s): Don't zero-pad numbers. + (FCT_imm8): Likewise. + (FCT_rel): Likewise. + (general_mod$r_m): New function. + (FCT_mod$r_m): Use it. + (FCT_mod$r_m$w): New function. + (FCT_mod$8r_m): New function. + (FCT_reg): Correctly handle 16-bit registers. + (FCT_reg$w): New function. + * i386_disasm.c (i386_disasm): Handle prefixes better. + Pass third parameter to operand functions. + * i386_parse.y (struct instruction): Add off3 field. + Handle third operand throughout. + +2007-02-05 Ulrich Drepper + + * i386_disasm.c: New file. + * i386_data.h: New file. + * i386_gendis.c: New file. + * i386_lex.l: New file. + * i386_parse.y: New file. + * memory-access.h: New file. + * x86_64_disasm.c: New file. + * defs/i386: New file. + * defs/i386.doc: New file. + * defs/x86_64: New file. + +2005-02-15 Ulrich Drepper + + * Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2. + +2005-02-05 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Define, instead of adding things to DEFS. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am new file mode 100644 index 00000000..43844ecf --- /dev/null +++ b/libcpu/Makefile.am @@ -0,0 +1,99 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2002-2012 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libasm +if BUILD_STATIC +AM_CFLAGS += $(fpic_CFLAGS) +endif +AM_CFLAGS += -fdollars-in-identifiers +LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$( $@T + $(AM_V_at)mv -f $@T $@ + +if MAINTAINER_MODE +noinst_HEADERS += memory-access.h i386_parse.h i386_data.h + +noinst_PROGRAMS = i386_gendis$(EXEEXT) + +$(srcdir)/%_dis.h: %_defs i386_gendis$(EXEEXT) + $(AM_V_GEN)./i386_gendis$(EXEEXT) $< > $@T + $(AM_V_at)mv -f $@T $@ + +else + +$(srcdir)/%_dis.h: + @echo '*** missing $@; configure with --enable-maintainer-mode' + @false + +endif + +%.mnemonics: %_defs + $(AM_V_GEN)sed '1,/^%%/d;/^#/d;/^[[:space:]]*$$/d;s/[^:]*:\([^[:space:]]*\).*/MNE(\1)/;s/{[^}]*}//g;/INVALID/d' \ + $< | sort -u > $@ + +i386_lex_no_Werror = yes + +libeu = ../lib/libeu.a + +i386_lex_CFLAGS = -Wno-unused-label -Wno-unused-function -Wno-sign-compare \ + -Wno-implicit-fallthrough +i386_parse.o: i386_parse.c i386.mnemonics +i386_parse_CFLAGS = -DNMNES="`wc -l < i386.mnemonics`" +i386_lex.o: i386_parse.h +i386_gendis_LDADD = $(libeu) -lm $(obstack_LIBS) + +i386_parse.h: i386_parse.c ; + +bpf_disasm_CFLAGS = -Wno-format-nonliteral + +EXTRA_DIST = defs/i386 + +MOSTLYCLEANFILES = $(am_libcpu_pic_a_OBJECTS) +CLEANFILES += $(foreach P,i386 x86_64,$P_defs $P.mnemonics) +MAINTAINERCLEANFILES = $(foreach P,i386 x86_64, $P_dis.h) diff --git a/libcpu/Makefile.in b/libcpu/Makefile.in new file mode 100644 index 00000000..53d6b5bd --- /dev/null +++ b/libcpu/Makefile.in @@ -0,0 +1,811 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@BUILD_STATIC_TRUE@am__append_2 = $(fpic_CFLAGS) +@MAINTAINER_MODE_TRUE@am__append_3 = memory-access.h i386_parse.h i386_data.h +subdir = libcpu +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__noinst_HEADERS_DIST) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libcpu_a_AR = $(AR) $(ARFLAGS) +libcpu_a_LIBADD = +am_libcpu_a_OBJECTS = i386_disasm.$(OBJEXT) x86_64_disasm.$(OBJEXT) \ + bpf_disasm.$(OBJEXT) riscv_disasm.$(OBJEXT) +libcpu_a_OBJECTS = $(am_libcpu_a_OBJECTS) +libcpu_pic_a_AR = $(AR) $(ARFLAGS) +libcpu_pic_a_LIBADD = +libcpu_pic_a_OBJECTS = $(am_libcpu_pic_a_OBJECTS) +am_i386_gendis_OBJECTS = i386_gendis.$(OBJEXT) i386_lex.$(OBJEXT) \ + i386_parse.$(OBJEXT) +i386_gendis_OBJECTS = $(am_i386_gendis_OBJECTS) +am__DEPENDENCIES_1 = +i386_gendis_DEPENDENCIES = $(libeu) $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/bpf_disasm.Po \ + ./$(DEPDIR)/i386_disasm.Po ./$(DEPDIR)/i386_gendis.Po \ + ./$(DEPDIR)/i386_lex.Po ./$(DEPDIR)/i386_parse.Po \ + ./$(DEPDIR)/riscv_disasm.Po ./$(DEPDIR)/x86_64_disasm.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +@MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || +AM_V_LEX = $(am__v_LEX_@AM_V@) +am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) +am__v_LEX_0 = @echo " LEX " $@; +am__v_LEX_1 = +YLWRAP = $(top_srcdir)/config/ylwrap +@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || +am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ + -e s/c++$$/h++/ -e s/c$$/h/ +YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) +AM_V_YACC = $(am__v_YACC_@AM_V@) +am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) +am__v_YACC_0 = @echo " YACC " $@; +am__v_YACC_1 = +SOURCES = $(libcpu_a_SOURCES) $(libcpu_pic_a_SOURCES) \ + $(i386_gendis_SOURCES) +DIST_SOURCES = $(libcpu_a_SOURCES) $(libcpu_pic_a_SOURCES) \ + $(i386_gendis_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__noinst_HEADERS_DIST = i386_dis.h x86_64_dis.h memory-access.h \ + i386_parse.h i386_data.h +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am $(top_srcdir)/config/ylwrap \ + ChangeLog i386_lex.c i386_parse.c +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = lex.$($@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.l.c: + $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) + +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f i386_lex.c + -rm -f i386_parse.c + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/bpf_disasm.Po + -rm -f ./$(DEPDIR)/i386_disasm.Po + -rm -f ./$(DEPDIR)/i386_gendis.Po + -rm -f ./$(DEPDIR)/i386_lex.Po + -rm -f ./$(DEPDIR)/i386_parse.Po + -rm -f ./$(DEPDIR)/riscv_disasm.Po + -rm -f ./$(DEPDIR)/x86_64_disasm.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/bpf_disasm.Po + -rm -f ./$(DEPDIR)/i386_disasm.Po + -rm -f ./$(DEPDIR)/i386_gendis.Po + -rm -f ./$(DEPDIR)/i386_lex.Po + -rm -f ./$(DEPDIR)/i386_parse.Po + -rm -f ./$(DEPDIR)/riscv_disasm.Po + -rm -f ./$(DEPDIR)/x86_64_disasm.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +i386_disasm.o: i386.mnemonics $(srcdir)/i386_dis.h +x86_64_disasm.o: x86_64.mnemonics $(srcdir)/x86_64_dis.h + +%_defs: $(srcdir)/defs/i386 + $(AM_V_GEN)m4 -D$* -DDISASSEMBLER $< > $@T + $(AM_V_at)mv -f $@T $@ + +@MAINTAINER_MODE_TRUE@$(srcdir)/%_dis.h: %_defs i386_gendis$(EXEEXT) +@MAINTAINER_MODE_TRUE@ $(AM_V_GEN)./i386_gendis$(EXEEXT) $< > $@T +@MAINTAINER_MODE_TRUE@ $(AM_V_at)mv -f $@T $@ + +@MAINTAINER_MODE_FALSE@$(srcdir)/%_dis.h: +@MAINTAINER_MODE_FALSE@ @echo '*** missing $@; configure with --enable-maintainer-mode' +@MAINTAINER_MODE_FALSE@ @false + +%.mnemonics: %_defs + $(AM_V_GEN)sed '1,/^%%/d;/^#/d;/^[[:space:]]*$$/d;s/[^:]*:\([^[:space:]]*\).*/MNE(\1)/;s/{[^}]*}//g;/INVALID/d' \ + $< | sort -u > $@ +i386_parse.o: i386_parse.c i386.mnemonics +i386_lex.o: i386_parse.h + +i386_parse.h: i386_parse.c ; + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libcpu/bpf_disasm.c b/libcpu/bpf_disasm.c new file mode 100644 index 00000000..62643c81 --- /dev/null +++ b/libcpu/bpf_disasm.c @@ -0,0 +1,504 @@ +/* Disassembler for BPF. + Copyright (C) 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include "bpf.h" + +#include "../libelf/common.h" +#include "../libebl/libeblP.h" + +static const char class_string[8][8] = { + [BPF_LD] = "ld", + [BPF_LDX] = "ldx", + [BPF_ST] = "st", + [BPF_STX] = "stx", + [BPF_ALU] = "alu", + [BPF_JMP] = "jmp", + [BPF_RET] = "6", /* completely unused in ebpf */ + [BPF_ALU64] = "alu64", +}; + + +#define REG(N) "r%" #N "$d" +#define REGU(N) "(u32)" REG(N) +#define REGS(N) "(s64)" REG(N) + +#define IMMS(N) "%" #N "$d" +#define IMMX(N) "%" #N "$#x" + +#define OFF(N) "%" #N "$+d" +#define JMP(N) "%" #N "$#x" + +#define A32(O, S) REG(1) " = " REGU(1) " " #O " " S +#define A64(O, S) REG(1) " " #O "= " S +#define J64(D, O, S) "if " D " " #O " " S " goto " JMP(3) +#define LOAD(T) REG(1) " = *(" #T " *)(" REG(2) OFF(3) ")" +#define STORE(T, S) "*(" #T " *)(" REG(1) OFF(3) ") = " S +#define XADD(T, S) "lock *(" #T " *)(" REG(1) OFF(3) ") += " S +#define LDSKB(T, S) "r0 = *(" #T " *)skb[" S "]" + +static void +bswap_bpf_insn (struct bpf_insn *p) +{ + /* Note that the dst_reg and src_reg fields are 4-bit bitfields. + That means these two nibbles are (typically) laid out in the + opposite order between big- and little-endian hosts. This is + not required by any standard, but does happen to be true for + at least ppc, s390, arm and mips as big-endian hosts. */ + int t = p->dst_reg; + p->dst_reg = p->src_reg; + p->src_reg = t; + + /* The other 2 and 4 byte fields are trivially converted. */ + CONVERT (p->off); + CONVERT (p->imm); +} + +int +bpf_disasm (Ebl *ebl, const uint8_t **startp, const uint8_t *end, + GElf_Addr addr, const char *fmt __attribute__((unused)), + DisasmOutputCB_t outcb, + DisasmGetSymCB_t symcb __attribute__((unused)), + void *outcbarg, + void *symcbarg __attribute__((unused))) +{ + const bool need_bswap = MY_ELFDATA != ebl->data; + const uint8_t *start = *startp; + char buf[128]; + int len, retval = 0; + + while (start + sizeof(struct bpf_insn) <= end) + { + struct bpf_insn i; + unsigned code, class, jmp; + const char *code_fmt; + + memcpy(&i, start, sizeof(struct bpf_insn)); + if (need_bswap) + bswap_bpf_insn (&i); + + start += sizeof(struct bpf_insn); + addr += sizeof(struct bpf_insn); + jmp = addr + i.off * sizeof(struct bpf_insn); + + code = i.code; + switch (code) + { + case BPF_LD | BPF_IMM | BPF_DW: + { + struct bpf_insn i2; + uint64_t imm64; + + if (start + sizeof(struct bpf_insn) > end) + { + start -= sizeof(struct bpf_insn); + *startp = start; + goto done; + } + memcpy(&i2, start, sizeof(struct bpf_insn)); + if (need_bswap) + bswap_bpf_insn (&i2); + start += sizeof(struct bpf_insn); + addr += sizeof(struct bpf_insn); + + imm64 = (uint32_t)i.imm | ((uint64_t)i2.imm << 32); + switch (i.src_reg) + { + case 0: + code_fmt = REG(1) " = %2$#" PRIx64; + break; + case BPF_PSEUDO_MAP_FD: + code_fmt = REG(1) " = map_fd(%2$#" PRIx64 ")"; + break; + default: + code_fmt = REG(1) " = ld_pseudo(%3$d, %2$#" PRIx64 ")"; + break; + } + len = snprintf(buf, sizeof(buf), code_fmt, + i.dst_reg, imm64, i.src_reg); + } + break; + + case BPF_JMP | BPF_EXIT: + len = snprintf(buf, sizeof(buf), "exit"); + break; + case BPF_JMP | BPF_JA: + len = snprintf(buf, sizeof(buf), "goto " JMP(1), jmp); + break; + case BPF_JMP | BPF_CALL: + code_fmt = "call " IMMS(1); + goto do_imm; + + case BPF_ALU | BPF_END | BPF_TO_LE: + /* The imm field contains {16,32,64}. */ + code_fmt = REG(1) " = le" IMMS(2) "(" REG(1) ")"; + goto do_dst_imm; + case BPF_ALU | BPF_END | BPF_TO_BE: + code_fmt = REG(1) " = be" IMMS(2) "(" REG(1) ")"; + goto do_dst_imm; + + case BPF_ALU | BPF_ADD | BPF_K: + code_fmt = A32(+, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_SUB | BPF_K: + code_fmt = A32(-, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_MUL | BPF_K: + code_fmt = A32(*, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_DIV | BPF_K: + code_fmt = A32(/, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_OR | BPF_K: + code_fmt = A32(|, IMMX(2)); + goto do_dst_imm; + case BPF_ALU | BPF_AND | BPF_K: + code_fmt = A32(&, IMMX(2)); + goto do_dst_imm; + case BPF_ALU | BPF_LSH | BPF_K: + code_fmt = A32(<<, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_RSH | BPF_K: + code_fmt = A32(>>, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_MOD | BPF_K: + code_fmt = A32(%%, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_XOR | BPF_K: + code_fmt = A32(^, IMMX(2)); + goto do_dst_imm; + case BPF_ALU | BPF_MOV | BPF_K: + code_fmt = REG(1) " = " IMMX(2); + goto do_dst_imm; + case BPF_ALU | BPF_ARSH | BPF_K: + code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " IMMS(2) ")"; + goto do_dst_imm; + + case BPF_ALU | BPF_ADD | BPF_X: + code_fmt = A32(+, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_SUB | BPF_X: + code_fmt = A32(-, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_MUL | BPF_X: + code_fmt = A32(*, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_DIV | BPF_X: + code_fmt = A32(/, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_OR | BPF_X: + code_fmt = A32(|, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_AND | BPF_X: + code_fmt = A32(&, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_LSH | BPF_X: + code_fmt = A32(<<, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_RSH | BPF_X: + code_fmt = A32(>>, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_MOD | BPF_X: + code_fmt = A32(%%, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_XOR | BPF_X: + code_fmt = A32(^, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_MOV | BPF_X: + code_fmt = REG(1) " = " REGU(2); + goto do_dst_src; + case BPF_ALU | BPF_ARSH | BPF_X: + code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " REG(2) ")"; + goto do_dst_src; + + case BPF_ALU64 | BPF_ADD | BPF_K: + code_fmt = A64(+, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_SUB | BPF_K: + code_fmt = A64(-, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_MUL | BPF_K: + code_fmt = A64(*, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_DIV | BPF_K: + code_fmt = A64(/, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_OR | BPF_K: + code_fmt = A64(|, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_AND | BPF_K: + code_fmt = A64(&, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_LSH | BPF_K: + code_fmt = A64(<<, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_RSH | BPF_K: + code_fmt = A64(>>, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_MOD | BPF_K: + code_fmt = A64(%%, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_XOR | BPF_K: + code_fmt = A64(^, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_MOV | BPF_K: + code_fmt = REG(1) " = " IMMS(2); + goto do_dst_imm; + case BPF_ALU64 | BPF_ARSH | BPF_K: + code_fmt = REG(1) " = (s64)" REG(1) " >> " IMMS(2); + goto do_dst_imm; + + case BPF_ALU64 | BPF_ADD | BPF_X: + code_fmt = A64(+, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_SUB | BPF_X: + code_fmt = A64(-, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_MUL | BPF_X: + code_fmt = A64(*, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_DIV | BPF_X: + code_fmt = A64(/, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_OR | BPF_X: + code_fmt = A64(|, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_AND | BPF_X: + code_fmt = A64(&, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_LSH | BPF_X: + code_fmt = A64(<<, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_RSH | BPF_X: + code_fmt = A64(>>, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_MOD | BPF_X: + code_fmt = A64(%%, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_XOR | BPF_X: + code_fmt = A64(^, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_MOV | BPF_X: + code_fmt = REG(1) " = " REG(2); + goto do_dst_src; + case BPF_ALU64 | BPF_ARSH | BPF_X: + code_fmt = REG(1) " = (s64)" REG(1) " >> " REG(2); + goto do_dst_src; + + case BPF_ALU | BPF_NEG: + code_fmt = REG(1) " = (u32)-" REG(1); + goto do_dst_src; + case BPF_ALU64 | BPF_NEG: + code_fmt = REG(1) " = -" REG(1); + goto do_dst_src; + + case BPF_JMP | BPF_JEQ | BPF_K: + code_fmt = J64(REG(1), ==, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JGT | BPF_K: + code_fmt = J64(REG(1), >, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JGE | BPF_K: + code_fmt = J64(REG(1), >=, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSET | BPF_K: + code_fmt = J64(REG(1), &, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JNE | BPF_K: + code_fmt = J64(REG(1), !=, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSGT | BPF_K: + code_fmt = J64(REGS(1), >, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSGE | BPF_K: + code_fmt = J64(REGS(1), >=, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JLT | BPF_K: + code_fmt = J64(REG(1), <, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JLE | BPF_K: + code_fmt = J64(REG(1), <=, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSLT | BPF_K: + code_fmt = J64(REGS(1), <, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSLE | BPF_K: + code_fmt = J64(REGS(1), <=, IMMS(2)); + goto do_dst_imm_jmp; + + case BPF_JMP | BPF_JEQ | BPF_X: + code_fmt = J64(REG(1), ==, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JGT | BPF_X: + code_fmt = J64(REG(1), >, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JGE | BPF_X: + code_fmt = J64(REG(1), >=, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSET | BPF_X: + code_fmt = J64(REG(1), &, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JNE | BPF_X: + code_fmt = J64(REG(1), !=, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSGT | BPF_X: + code_fmt = J64(REGS(1), >, REGS(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSGE | BPF_X: + code_fmt = J64(REGS(1), >=, REGS(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JLT | BPF_X: + code_fmt = J64(REG(1), <, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JLE | BPF_X: + code_fmt = J64(REG(1), <=, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSLT | BPF_X: + code_fmt = J64(REGS(1), <, REGS(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSLE | BPF_X: + code_fmt = J64(REGS(1), <=, REGS(2)); + goto do_dst_src_jmp; + + case BPF_LDX | BPF_MEM | BPF_B: + code_fmt = LOAD(u8); + goto do_dst_src_off; + case BPF_LDX | BPF_MEM | BPF_H: + code_fmt = LOAD(u16); + goto do_dst_src_off; + case BPF_LDX | BPF_MEM | BPF_W: + code_fmt = LOAD(u32); + goto do_dst_src_off; + case BPF_LDX | BPF_MEM | BPF_DW: + code_fmt = LOAD(u64); + goto do_dst_src_off; + + case BPF_STX | BPF_MEM | BPF_B: + code_fmt = STORE(u8, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_MEM | BPF_H: + code_fmt = STORE(u16, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_MEM | BPF_W: + code_fmt = STORE(u32, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_MEM | BPF_DW: + code_fmt = STORE(u64, REG(2)); + goto do_dst_src_off; + + case BPF_STX | BPF_XADD | BPF_W: + code_fmt = XADD(u32, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_XADD | BPF_DW: + code_fmt = XADD(u64, REG(2)); + goto do_dst_src_off; + + case BPF_ST | BPF_MEM | BPF_B: + code_fmt = STORE(u8, IMMS(2)); + goto do_dst_imm_off; + case BPF_ST | BPF_MEM | BPF_H: + code_fmt = STORE(u16, IMMS(2)); + goto do_dst_imm_off; + case BPF_ST | BPF_MEM | BPF_W: + code_fmt = STORE(u32, IMMS(2)); + goto do_dst_imm_off; + case BPF_ST | BPF_MEM | BPF_DW: + code_fmt = STORE(u64, IMMS(2)); + goto do_dst_imm_off; + + case BPF_LD | BPF_ABS | BPF_B: + code_fmt = LDSKB(u8, IMMS(1)); + goto do_imm; + case BPF_LD | BPF_ABS | BPF_H: + code_fmt = LDSKB(u16, IMMS(1)); + goto do_imm; + case BPF_LD | BPF_ABS | BPF_W: + code_fmt = LDSKB(u32, IMMS(1)); + goto do_imm; + + case BPF_LD | BPF_IND | BPF_B: + code_fmt = LDSKB(u8, REG(1) "+" IMMS(2)); + goto do_src_imm; + case BPF_LD | BPF_IND | BPF_H: + code_fmt = LDSKB(u16, REG(1) "+" IMMS(2)); + goto do_src_imm; + case BPF_LD | BPF_IND | BPF_W: + code_fmt = LDSKB(u32, REG(1) "+" IMMS(2)); + goto do_src_imm; + + do_imm: + len = snprintf(buf, sizeof(buf), code_fmt, i.imm); + break; + do_dst_imm: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm); + break; + do_src_imm: + len = snprintf(buf, sizeof(buf), code_fmt, i.src_reg, i.imm); + break; + do_dst_src: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.src_reg); + break; + do_dst_imm_jmp: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, jmp); + break; + do_dst_src_jmp: + len = snprintf(buf, sizeof(buf), code_fmt, + i.dst_reg, i.src_reg, jmp); + break; + do_dst_imm_off: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, i.off); + break; + do_dst_src_off: + len = snprintf(buf, sizeof(buf), code_fmt, + i.dst_reg, i.src_reg, i.off); + break; + + default: + class = BPF_CLASS(code); + len = snprintf(buf, sizeof(buf), "invalid class %s", + class_string[class]); + break; + } + + *startp = start; + retval = outcb (buf, len, outcbarg); + if (retval != 0) + goto done; + } + + done: + return retval; +} diff --git a/libcpu/defs/i386 b/libcpu/defs/i386 new file mode 100644 index 00000000..e0db28dc --- /dev/null +++ b/libcpu/defs/i386 @@ -0,0 +1,970 @@ +%mask {s} 1 +%mask {w} 1 +%mask {w1} 1 +%mask {W1} 1 +%mask {W2} 1 +dnl floating point reg suffix +%mask {D} 1 +%mask {imm8} 8 +%mask {imms8} 8 +%mask {imm16} 16 +%mask {reg} 3 +%mask {oreg} 3 +%mask {reg16} 3 +%mask {reg64} 3 +%mask {tttn} 4 +%mask {mod} 2 +%mask {moda} 2 +%mask {MOD} 2 +%mask {r_m} 3 +dnl like {r_m} but referencing byte register +%mask {8r_m} 3 +dnl like {r_m} but referencing 16-bit register +%mask {16r_m} 3 +dnl like {r_m} but referencing 32- or 64-bit register +%mask {64r_m} 3 +%mask {disp8} 8 +dnl imm really is 8/16/32 bit depending on the situation. +%mask {imm} 8 +%mask {imm64} 8 +%mask {imms} 8 +%mask {rel} 32 +%mask {abs} 32 +%mask {absval} 32 +%mask {sel} 16 +%mask {imm32} 32 +%mask {ccc} 3 +%mask {ddd} 3 +%mask {sreg3} 3 +%mask {sreg2} 2 +%mask {mmxreg} 3 +%mask {R_M} 3 +%mask {Mod} 2 +%mask {xmmreg} 3 +%mask {R_m} 3 +%mask {xmmreg1} 3 +%mask {xmmreg2} 3 +%mask {mmxreg1} 3 +%mask {mmxreg2} 3 +%mask {predps} 8 +%mask {freg} 3 +%mask {fmod} 2 +%mask {fr_m} 3 +%prefix {R} +%prefix {RE} +%suffix {W} +%suffix {w0} +%synonym {xmmreg1} {xmmreg} +%synonym {xmmreg2} {xmmreg} +%synonym {mmxreg1} {mmxreg} +%synonym {mmxreg2} {mmxreg} +ifdef(`i386', +`%synonym {oreg} {reg} +%synonym {imm64} {imm} +')dnl + +%% +ifdef(`i386', +`00110111:aaa +11010101,00001010:aad +11010100,00001010:aam +00111111:aas +')dnl +0001010{w},{imm}:adc {imm}{w},{ax}{w} +1000000{w},{mod}010{r_m},{imm}:adc{w} {imm}{w},{mod}{r_m}{w} +1000001{w},{mod}010{r_m},{imms8}:adc{w} {imms8},{mod}{r_m} +0001000{w},{mod}{reg}{r_m}:adc {reg}{w},{mod}{r_m}{w} +0001001{w},{mod}{reg}{r_m}:adc {mod}{r_m}{w},{reg}{w} +0000010{w},{imm}:add {imm}{w},{ax}{w} +1000000{w},{mod}000{r_m},{imm}:add{w} {imm}{w},{mod}{r_m}{w} +10000011,{mod}000{r_m},{imms8}:add{w} {imms8},{mod}{r_m} +0000000{w},{mod}{reg}{r_m}:add {reg}{w},{mod}{r_m}{w} +0000001{w},{mod}{reg}{r_m}:add {mod}{r_m}{w},{reg}{w} +01100110,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubpd {Mod}{R_m},{xmmreg} +11110010,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubps {Mod}{R_m},{xmmreg} +0010010{w},{imm}:and {imm}{w},{ax}{w} +1000000{w},{mod}100{r_m},{imm}:and{w} {imm}{w},{mod}{r_m}{w} +1000001{w},{mod}100{r_m},{imms8}:and{w} {imms8},{mod}{r_m} +0010000{w},{mod}{reg}{r_m}:and {reg}{w},{mod}{r_m}{w} +0010001{w},{mod}{reg}{r_m}:and {mod}{r_m}{w},{reg}{w} +01100110,00001111,01010100,{Mod}{xmmreg}{R_m}:andpd {Mod}{R_m},{xmmreg} +00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg} +01100110,00001111,01010101,{Mod}{xmmreg}{R_m}:andnpd {Mod}{R_m},{xmmreg} +00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg} +ifdef(`i386', +`01100011,{mod}{reg16}{r_m}:arpl {reg16},{mod}{r_m} +01100010,{moda}{reg}{r_m}:bound {reg},{moda}{r_m} +', +`01100011,{mod}{reg64}{r_m}:movslq {mod}{r_m},{reg64} +')dnl +00001111,10111100,{mod}{reg}{r_m}:bsf {mod}{r_m},{reg} +00001111,10111101,{mod}{reg}{r_m}:bsr {mod}{r_m},{reg} +00001111,11001{reg}:bswap {reg} +00001111,10100011,{mod}{reg}{r_m}:bt {reg},{mod}{r_m} +00001111,10111010,{mod}100{r_m},{imm8}:bt{w} {imm8},{mod}{r_m} +00001111,10111011,{mod}{reg}{r_m}:btc {reg},{mod}{r_m} +00001111,10111010,{mod}111{r_m},{imm8}:btc{w} {imm8},{mod}{r_m} +00001111,10110011,{mod}{reg}{r_m}:btr {reg},{mod}{r_m} +00001111,10111010,{mod}110{r_m},{imm8}:btr{w} {imm8},{mod}{r_m} +00001111,10101011,{mod}{reg}{r_m}:bts {reg},{mod}{r_m} +00001111,10111010,{mod}101{r_m},{imm8}:bts{w} {imm8},{mod}{r_m} +11101000,{rel}:call{W} {rel} +11111111,{mod}010{64r_m}:call{W} *{mod}{64r_m} +ifdef(`i386', +`10011010,{absval},{sel}:lcall {sel},{absval} +')dnl +11111111,{mod}011{64r_m}:lcall{W} *{mod}{64r_m} +# SPECIAL 10011000:[{rex.w}?cltq:{dpfx}?cbtw:cwtl] +10011000:INVALID +# SPECIAL 10011001:[{rex.w}?cqto:{dpfx}?cltd:cwtd] +10011001:INVALID +11111000:clc +11111100:cld +11111010:cli +00001111,00000101:syscall +00001111,00000110:clts +00001111,00000111:sysret +00001111,00110100:sysenter +00001111,00110101:sysexit +11110101:cmc +00001111,0100{tttn},{mod}{reg}{r_m}:cmov{tttn} {mod}{r_m},{reg} +0011110{w},{imm}:cmp {imm}{w},{ax}{w} +1000000{w},{mod}111{r_m},{imm}:cmp{w} {imm}{w},{mod}{r_m}{w} +10000011,{mod}111{r_m},{imms8}:cmp{w} {imms8},{mod}{r_m} +0011100{w},{mod}{reg}{r_m}:cmp {reg}{w},{mod}{r_m}{w} +0011101{w},{mod}{reg}{r_m}:cmp {mod}{r_m}{w},{reg}{w} +ifdef(`ASSEMBLER', +`11110010,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpsd {imm8},{Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpss {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmppd {imm8},{Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpps {imm8},{Mod}{R_m},{xmmreg} +', +`11110010,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg} +01100110,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg} +')dnl +1010011{w}:{RE}cmps{w} {es_di},{ds_si} +00001111,1011000{w},{mod}{reg}{r_m}:cmpxchg {reg}{w},{mod}{r_m}{w} +ifdef(`i386', +`00001111,11000111,{mod}001{r_m}:cmpxchg8b {mod}{r_m} +', +`# SPECIAL 00001111,11000111,{mod}001{r_m}:[{rex.w}?cmpxchg16b:cmpxchg8b] {reg},{mod}{r_m} +00001111,11000111,{mod}001{r_m}:INVALID {mod}{r_m} +')dnl +00001111,10100010:cpuid +11110011,00001111,11100110,{Mod}{xmmreg}{R_m}:cvtdq2pd {Mod}{R_m},{xmmreg} +11110010,00001111,11100110,{Mod}{xmmreg}{R_m}:cvtpd2dq {Mod}{R_m},{xmmreg} +01100110,00001111,11100110,{Mod}{xmmreg}{R_m}:cvttpd2dq {Mod}{R_m},{xmmreg} +ifdef(`i386', +`00100111:daa +00101111:das +')dnl +1111111{w},{mod}001{r_m}:dec{w} {mod}{r_m}{w} +ifdef(`i386', +`01001{reg}:dec {reg} +')dnl +1111011{w},{mod}110{r_m}:div{w} {mod}{r_m}{w} +00001111,01110111:emms +11001000,{imm16},{imm8}:enter{W} {imm16},{imm8} +11011001,11010000:fnop +11011001,11100000:fchs +11011001,11100001:fabs +11011001,11100100:ftst +11011001,11100101:fxam +11011001,11101000:fld1 +11011001,11101001:fldl2t +11011001,11101010:fldl2e +11011001,11101011:fldpi +11011001,11101100:fldlg2 +11011001,11101101:fldln2 +11011001,11101110:fldz +11011001,11110000:f2xm1 +11011001,11110001:fyl2x +11011001,11110010:fptan +11011001,11110011:fpatan +11011001,11110100:fxtract +11011001,11110101:fprem1 +11011001,11110110:fdecstp +11011001,11110111:fincstp +11011001,11111000:fprem +11011001,11111001:fyl2xp1 +11011001,11111010:fsqrt +11011001,11111011:fsincos +11011001,11111100:frndint +11011001,11111101:fscale +11011001,11111110:fsin +11011001,11111111:fcos +# ORDER +11011000,11000{freg}:fadd {freg},%st +11011100,11000{freg}:fadd %st,{freg} +11011{D}00,{mod}000{r_m}:fadd{D} {mod}{r_m} +# ORDER END +# ORDER +11011000,11001{freg}:fmul {freg},%st +11011100,11001{freg}:fmul %st,{freg} +11011{D}00,{mod}001{r_m}:fmul{D} {mod}{r_m} +# ORDER END +# ORDER +11011000,11100{freg}:fsub {freg},%st +11011100,11100{freg}:fsub %st,{freg} +11011{D}00,{mod}100{r_m}:fsub{D} {mod}{r_m} +# ORDER END +# ORDER +11011000,11101{freg}:fsubr {freg},%st +11011100,11101{freg}:fsubr %st,{freg} +11011{D}00,{mod}101{r_m}:fsubr{D} {mod}{r_m} +# ORDER END +# ORDER +11011101,11010{freg}:fst {freg} +11011{D}01,{mod}010{r_m}:fst{D} {mod}{r_m} +# ORDER END +# ORDER +11011101,11011{freg}:fstp {freg} +11011{D}01,{mod}011{r_m}:fstp{D} {mod}{r_m} +# ORDER END +11011001,{mod}100{r_m}:fldenv {mod}{r_m} +11011001,{mod}101{r_m}:fldcw {mod}{r_m} +11011001,{mod}110{r_m}:fnstenv {mod}{r_m} +11011001,{mod}111{r_m}:fnstcw {mod}{r_m} +11011001,11001{freg}:fxch {freg} +# ORDER +11011110,11000{freg}:faddp %st,{freg} +ifdef(`ASSEMBLER', +`11011110,11000001:faddp +')dnl +# ORDER +11011010,11000{freg}:fcmovb {freg},%st +11011{w1}10,{mod}000{r_m}:fiadd{w1} {mod}{r_m} +# ORDER END +# ORDER +11011010,11001{freg}:fcmove {freg},%st +11011110,11001{freg}:fmulp %st,{freg} +11011{w1}10,{mod}001{r_m}:fimul{w1} {mod}{r_m} +# ORDER END +# ORDER +11011110,11100{freg}:fsubp %st,{freg} +11011{w1}10,{mod}100{r_m}:fisub{w1} {mod}{r_m} +# ORDER END +# ORDER +11011110,11101{freg}:fsubrp %st,{freg} +11011{w1}10,{mod}101{r_m}:fisubr{w1} {mod}{r_m} +# ORDER END +# ORDER +11011111,11100000:fnstsw %ax +11011111,{mod}100{r_m}:fbld {mod}{r_m} +# ORDER END +# ORDER +11011111,11110{freg}:fcomip {freg},%st +11011111,{mod}110{r_m}:fbstp {mod}{r_m} +# ORDER END +11011001,11100000:fchs +# ORDER +10011011,11011011,11100010:fclex +10011011,11011011,11100011:finit +10011011:fwait +# END ORDER +11011011,11100010:fnclex +11011010,11000{freg}:fcmovb {freg},%st +11011010,11001{freg}:fcmove {freg},%st +11011010,11010{freg}:fcmovbe {freg},%st +11011010,11011{freg}:fcmovu {freg},%st +11011011,11000{freg}:fcmovnb {freg},%st +11011011,11001{freg}:fcmovne {freg},%st +11011011,11010{freg}:fcmovnbe {freg},%st +11011011,11011{freg}:fcmovnu {freg},%st +# ORDER +11011000,11010{freg}:fcom {freg} +ifdef(`ASSEMBLER', +`11011000,11010001:fcom +')dnl +11011{D}00,{mod}010{r_m}:fcom{D} {mod}{r_m} +# END ORDER +# ORDER +11011000,11011{freg}:fcomp {freg} +ifdef(`ASSEMBLER', +`11011000,11011001:fcomp +')dnl +11011{D}00,{mod}011{r_m}:fcomp{D} {mod}{r_m} +# END ORDER +11011110,11011001:fcompp +11011011,11110{freg}:fcomi {freg},%st +11011111,11110{freg}:fcomip {freg},%st +11011011,11101{freg}:fucomi {freg},%st +11011111,11101{freg}:fucomip {freg},%st +11011001,11111111:fcos +11011001,11110110:fdecstp +# ORDER +11011000,11110{freg}:fdiv {freg},%st +11011100,11110{freg}:fdiv %st,{freg} +11011{D}00,{mod}110{r_m}:fdiv{D} {mod}{r_m} +# END ORDER +11011010,{mod}110{r_m}:fidivl {mod}{r_m} +# ORDER +11011110,11110{freg}:fdivp %st,{freg} +11011110,{mod}110{r_m}:fidiv {mod}{r_m} +# END ORDER +11011110,11111{freg}:fdivrp %st,{freg} +ifdef(`ASSEMBLER', +`11011110,11111001:fdivp +')dnl +# ORDER +11011000,11111{freg}:fdivr {freg},%st +11011100,11111{freg}:fdivr %st,{freg} +11011{D}00,{mod}111{r_m}:fdivr{D} {mod}{r_m} +# END ORDER +11011010,{mod}111{r_m}:fidivrl {mod}{r_m} +11011110,{mod}111{r_m}:fidivr {mod}{r_m} +11011110,11110{freg}:fdivrp %st,{freg} +ifdef(`ASSEMBLER', +`11011110,11110001:fdivrp +')dnl +11011101,11000{freg}:ffree {freg} +11011010,11010{freg}:fcmovbe {freg} +11011{w1}10,{mod}010{r_m}:ficom{w1} {mod}{r_m} +11011010,11011{freg}:fcmovu {freg} +11011{w1}10,{mod}011{r_m}:ficomp{w1} {mod}{r_m} +11011111,{mod}000{r_m}:fild {mod}{r_m} +11011011,{mod}000{r_m}:fildl {mod}{r_m} +11011111,{mod}101{r_m}:fildll {mod}{r_m} +11011001,11110111:fincstp +11011011,11100011:fninit +11011{w1}11,{mod}010{r_m}:fist{w1} {mod}{r_m} +11011{w1}11,{mod}011{r_m}:fistp{w1} {mod}{r_m} +11011111,{mod}111{r_m}:fistpll {mod}{r_m} +11011{w1}11,{mod}001{r_m}:fisttp{w1} {mod}{r_m} +11011101,{mod}001{r_m}:fisttpll {mod}{r_m} +11011011,{mod}101{r_m}:fldt {mod}{r_m} +11011011,{mod}111{r_m}:fstpt {mod}{r_m} +# ORDER +11011001,11000{freg}:fld {freg} +11011{D}01,{mod}000{r_m}:fld{D} {mod}{r_m} +# ORDER END +# ORDER +11011101,11100{freg}:fucom {freg} +11011101,{mod}100{r_m}:frstor {mod}{r_m} +# ORDER END +11011101,11101{freg}:fucomp {freg} +11011101,{mod}110{r_m}:fnsave {mod}{r_m} +11011101,{mod}111{r_m}:fnstsw {mod}{r_m} +# +# +# +11110100:hlt +1111011{w},{mod}111{r_m}:idiv{w} {mod}{r_m}{w} +1111011{w},{mod}101{r_m}:imul{w} {mod}{r_m}{w} +00001111,10101111,{mod}{reg}{r_m}:imul {mod}{r_m},{reg} +011010{s}1,{mod}{reg}{r_m},{imm}:imul {imm}{s},{mod}{r_m},{reg} +1110010{w},{imm8}:in {imm8},{ax}{w} +1110110{w}:in {dx},{ax}{w} +1111111{w},{mod}000{r_m}:inc{w} {mod}{r_m}{w} +ifdef(`i386', +`01000{reg}:inc {reg} +')dnl +0110110{w}:{R}ins{w} {dx},{es_di} +11001101,{imm8}:int {imm8} +11001100:int3 +ifdef(`i386', +`11001110:into +')dnl +00001111,00001000:invd +# ORDER +00001111,00000001,11111000:swapgs +00001111,00000001,{mod}111{r_m}:invlpg {mod}{r_m} +# ORDER END +11001111:iret{W1} +0111{tttn},{disp8}:j{tttn} {disp8} +00001111,1000{tttn},{rel}:j{tttn} {rel} +00001111,1001{tttn},{mod}000{8r_m}:set{tttn} {mod}{8r_m} +# SPECIAL 11100011,{disp8}:[{dpfx}?jcxz:jecxz] {disp8} +11100011,{disp8}:INVALID {disp8} +11101011,{disp8}:jmp {disp8} +11101001,{rel}:jmp{W} {rel} +11111111,{mod}100{64r_m}:jmp{W} *{mod}{64r_m} +11101010,{absval},{sel}:ljmp {sel},{absval} +11111111,{mod}101{64r_m}:ljmp{W} *{mod}{64r_m} +10011111:lahf +00001111,00000010,{mod}{reg}{16r_m}:lar {mod}{16r_m},{reg} +ifdef(`i386', +`11000101,{mod}{reg}{r_m}:lds {mod}{r_m},{reg} +')dnl +10001101,{mod}{reg}{r_m}:lea {mod}{r_m},{reg} +11001001:leave{W} +ifdef(`i386', +`11000100,{mod}{reg}{r_m}:les {mod}{r_m},{reg} +')dnl +00001111,10110100,{mod}{reg}{r_m}:lfs {mod}{r_m},{reg} +00001111,10110101,{mod}{reg}{r_m}:lgs {mod}{r_m},{reg} +ifdef(`i386', +`00001111,00000001,{mod}010{r_m}:lgdt{w0} {mod}{r_m} +00001111,00000001,{mod}011{r_m}:lidt{w0} {mod}{r_m} +', +`00001111,00000001,{mod}010{r_m}:lgdt {mod}{r_m} +00001111,00000001,{mod}011{r_m}:lidt {mod}{r_m} +')dnl +00001111,00000000,{mod}010{16r_m}:lldt {mod}{16r_m} +00001111,00000001,{mod}110{16r_m}:lmsw {mod}{16r_m} +11110000:lock +1010110{w}:{R}lods {ds_si},{ax}{w} +11100010,{disp8}:loop {disp8} +11100001,{disp8}:loope {disp8} +11100000,{disp8}:loopne {disp8} +00001111,00000011,{mod}{reg}{16r_m}:lsl {mod}{16r_m},{reg} +00001111,10110010,{mod}{reg}{r_m}:lss {mod}{r_m},{reg} +00001111,00000000,{mod}011{16r_m}:ltr {mod}{16r_m} +1000100{w},{mod}{reg}{r_m}:mov {reg}{w},{mod}{r_m}{w} +1000101{w},{mod}{reg}{r_m}:mov {mod}{r_m}{w},{reg}{w} +1100011{w},{mod}000{r_m},{imm}:mov{w} {imm}{w},{mod}{r_m}{w} +1011{w}{oreg},{imm64}:mov {imm64}{w},{oreg}{w} +1010000{w},{abs}:mov {abs},{ax}{w} +1010001{w},{abs}:mov {ax}{w},{abs} +00001111,00100000,11{ccc}{reg64}:mov {ccc},{reg64} +00001111,00100010,11{ccc}{reg64}:mov {reg64},{ccc} +00001111,00100001,11{ddd}{reg64}:mov {ddd},{reg64} +00001111,00100011,11{ddd}{reg64}:mov {reg64},{ddd} +10001100,{mod}{sreg3}{r_m}:mov {sreg3},{mod}{r_m} +10001110,{mod}{sreg3}{r_m}:mov {mod}{r_m},{sreg3} +1010010{w}:{R}movs{w} {ds_si},{es_di} +00001111,10111110,{mod}{reg}{8r_m}:movsbl {mod}{8r_m},{reg} +00001111,10111111,{mod}{reg}{16r_m}:movswl {mod}{16r_m},{reg} +00001111,10110110,{mod}{reg}{8r_m}:movzbl {mod}{8r_m},{reg} +00001111,10110111,{mod}{reg}{16r_m}:movzwl {mod}{16r_m},{reg} +1111011{w},{mod}100{r_m}:mul{w} {mod}{r_m}{w} +1111011{w},{mod}011{r_m}:neg{w} {mod}{r_m}{w} +11110011,10010000:pause +ifdef(`i386', +`10010000:nop +', +`10010000:INVALID +')dnl +# ORDER before out +11110011,00001111,10111000,{mod}{reg}{r_m}:popcnt {mod}{r_m},{reg} +# END ORDER +1111011{w},{mod}010{r_m}:not{w} {mod}{r_m}{w} +0000100{w},{mod}{reg}{r_m}:or {reg}{w},{mod}{r_m}{w} +0000101{w},{mod}{reg}{r_m}:or {mod}{r_m}{w},{reg}{w} +1000000{w},{mod}001{r_m},{imm}:or{w} {imm}{w},{mod}{r_m}{w} +1000001{w},{mod}001{r_m},{imms8}:or{w} {imms8},{mod}{r_m}{w} +0000110{w},{imm}:or {imm}{w},{ax}{w} +1110011{w},{imm8}:out {ax}{w},{imm8} +1110111{w}:out {ax}{w},{dx} +0110111{w}:{R}outs{w} {ds_si},{dx} +ifdef(`i386', +`10001111,{mod}000{r_m}:pop{w} {mod}{r_m} +', +# XXX This is not the cleanest way... +`10001111,11000{reg64}:pop {reg64} +10001111,{mod}000{r_m}:pop{W} {mod}{r_m} +')dnl +00001111,10{sreg3}001:pop{W} {sreg3} +10011101:popf{W} +# XXX This is not the cleanest way... +ifdef(`i386', +`11111111,{mod}110{r_m}:push{w} {mod}{r_m} +', +`11111111,11110{reg64}:push {reg64} +11111111,{mod}110{r_m}:pushq {mod}{r_m} +')dnl +ifdef(`i386', +`01010{reg}:push {reg} +01011{reg}:pop {reg} +', +`01010{reg64}:push {reg64} +01011{reg64}:pop {reg64} +')dnl +011010{s}0,{imm}:push{W} {imm}{s} +000{sreg2}110:push {sreg2} +00001111,10{sreg3}000:push{W} {sreg3} +ifdef(`i386', +`01100000:pusha{W} +01100001:popa{W} +')dnl +10011100:pushf{W} +1101000{w},{mod}010{r_m}:rcl{w} {mod}{r_m}{w} +1101001{w},{mod}010{r_m}:rcl{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}010{r_m},{imm8}:rcl{w} {imm8},{mod}{r_m}{w} +1101000{w},{mod}011{r_m}:rcr{w} {mod}{r_m}{w} +1101001{w},{mod}011{r_m}:rcr{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}011{r_m},{imm8}:rcr{w} {imm8},{mod}{r_m}{w} +00001111,00110010:rdmsr +00001111,00110011:rdpmc +00001111,00110001:rdtsc +11000011:ret{W} +11000010,{imm16}:ret{W} {imm16} +11001011:lret +11001010,{imm16}:lret {imm16} +1101000{w},{mod}000{r_m}:rol{w} {mod}{r_m}{w} +1101001{w},{mod}000{r_m}:rol{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}000{r_m},{imm8}:rol{w} {imm8},{mod}{r_m}{w} +1101000{w},{mod}001{r_m}:ror{w} {mod}{r_m}{w} +1101001{w},{mod}001{r_m}:ror{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}001{r_m},{imm8}:ror{w} {imm8},{mod}{r_m}{w} +00001111,10101010:rsm +10011110:sahf +1101000{w},{mod}111{r_m}:sar{w} {mod}{r_m}{w} +1101001{w},{mod}111{r_m}:sar{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}111{r_m},{imm8}:sar{w} {imm8},{mod}{r_m}{w} +0001100{w},{mod}{reg}{r_m}:sbb {reg}{w},{mod}{r_m}{w} +0001101{w},{mod}{reg}{r_m}:sbb {mod}{r_m}{w},{reg}{w} +0001110{w},{imm}:sbb {imm}{w},{ax}{w} +1000000{w},{mod}011{r_m},{imm}:sbb{w} {imm}{w},{mod}{r_m}{w} +1000001{w},{mod}011{r_m},{imms8}:sbb{w} {imms8},{mod}{r_m} +1010111{w}:{RE}scas {es_di},{ax}{w} +00001111,1001{tttn},{mod}000{r_m}:set{tttn} {mod}{r_m} +1101000{w},{mod}100{r_m}:shl{w} {mod}{r_m}{w} +1101001{w},{mod}100{r_m}:shl{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}100{r_m},{imm8}:shl{w} {imm8},{mod}{r_m}{w} +1101000{w},{mod}101{r_m}:shr{w} {mod}{r_m}{w} +00001111,10100100,{mod}{reg}{r_m},{imm8}:shld {imm8},{reg},{mod}{r_m} +00001111,10100101,{mod}{reg}{r_m}:shld %cl,{reg},{mod}{r_m} +1101001{w},{mod}101{r_m}:shr{w} %cl,{mod}{r_m}{w} +1100000{w},{mod}101{r_m},{imm8}:shr{w} {imm8},{mod}{r_m}{w} +00001111,10101100,{mod}{reg}{r_m},{imm8}:shrd {imm8},{reg},{mod}{r_m} +00001111,10101101,{mod}{reg}{r_m}:shrd %cl,{reg},{mod}{r_m} +# ORDER +00001111,00000001,11000001:vmcall +00001111,00000001,11000010:vmlaunch +00001111,00000001,11000011:vmresume +00001111,00000001,11000100:vmxoff +00001111,01111000,{mod}{reg64}{64r_m}:vmread {reg64},{mod}{64r_m} +00001111,01111001,{mod}{reg64}{64r_m}:vmwrite {mod}{64r_m},{reg64} +ifdef(`i386', +`00001111,00000001,{mod}000{r_m}:sgdtl {mod}{r_m} +', +`00001111,00000001,{mod}000{r_m}:sgdt {mod}{r_m} +')dnl +# ORDER END +# ORDER +ifdef(`i386', +`00001111,00000001,11001000:monitor %eax,%ecx,%edx +00001111,00000001,11001001:mwait %eax,%ecx +', +`00001111,00000001,11001000:monitor %rax,%rcx,%rdx +00001111,00000001,11001001:mwait %rax,%rcx +')dnl +ifdef(`i386', +`00001111,00000001,{mod}001{r_m}:sidtl {mod}{r_m} +', +`00001111,00000001,{mod}001{r_m}:sidt {mod}{r_m} +')dnl +# ORDER END +00001111,00000000,{mod}000{r_m}:sldt {mod}{r_m} +00001111,00000001,{mod}100{r_m}:smsw {mod}{r_m} +11111001:stc +11111101:std +11111011:sti +1010101{w}:{R}stos {ax}{w},{es_di} +00001111,00000000,{mod}001{r_m}:str {mod}{r_m} +0010100{w},{mod}{reg}{r_m}:sub {reg}{w},{mod}{r_m}{w} +0010101{w},{mod}{reg}{r_m}:sub {mod}{r_m}{w},{reg}{w} +0010110{w},{imm}:sub {imm}{w},{ax}{w} +1000000{w},{mod}101{r_m},{imm}:sub{w} {imm}{w},{mod}{r_m}{w} +1000001{w},{mod}101{r_m},{imms8}:sub{w} {imms8},{mod}{r_m} +1000010{w},{mod}{reg}{r_m}:test {reg}{w},{mod}{r_m}{w} +1010100{w},{imm}:test {imm}{w},{ax}{w} +1111011{w},{mod}000{r_m},{imm}:test{w} {imm}{w},{mod}{r_m}{w} +00001111,00001011:ud2a +00001111,00000000,{mod}100{16r_m}:verr {mod}{16r_m} +00001111,00000000,{mod}101{16r_m}:verw {mod}{16r_m} +00001111,00001001:wbinvd +00001111,00001101,{mod}000{8r_m}:prefetch {mod}{8r_m} +00001111,00001101,{mod}001{8r_m}:prefetchw {mod}{8r_m} +00001111,00011000,{mod}000{r_m}:prefetchnta {mod}{r_m} +00001111,00011000,{mod}001{r_m}:prefetcht0 {mod}{r_m} +00001111,00011000,{mod}010{r_m}:prefetcht1 {mod}{r_m} +00001111,00011000,{mod}011{r_m}:prefetcht2 {mod}{r_m} +00001111,00011111,{mod}{reg}{r_m}:nop{w} {mod}{r_m} +00001111,00110000:wrmsr +00001111,1100000{w},{mod}{reg}{r_m}:xadd {reg}{w},{mod}{r_m}{w} +1000011{w},{mod}{reg}{r_m}:xchg {reg}{w},{mod}{r_m}{w} +10010{oreg}:xchg {ax},{oreg} +11010111:xlat {ds_bx} +0011000{w},{mod}{reg}{r_m}:xor {reg}{w},{mod}{r_m}{w} +0011001{w},{mod}{reg}{r_m}:xor {mod}{r_m}{w},{reg}{w} +0011010{w},{imm}:xor {imm}{w},{ax}{w} +1000000{w},{mod}110{r_m},{imm}:xor{w} {imm}{w},{mod}{r_m}{w} +1000001{w},{mod}110{r_m},{imms8}:xor{w} {imms8},{mod}{r_m} +00001111,01110111:emms +01100110,00001111,11011011,{Mod}{xmmreg}{R_m}:pand {Mod}{R_m},{xmmreg} +00001111,11011011,{MOD}{mmxreg}{R_M}:pand {MOD}{R_M},{mmxreg} +01100110,00001111,11011111,{Mod}{xmmreg}{R_m}:pandn {Mod}{R_m},{xmmreg} +00001111,11011111,{MOD}{mmxreg}{R_M}:pandn {MOD}{R_M},{mmxreg} +01100110,00001111,11110101,{Mod}{xmmreg}{R_m}:pmaddwd {Mod}{R_m},{xmmreg} +00001111,11110101,{MOD}{mmxreg}{R_M}:pmaddwd {MOD}{R_M},{mmxreg} +01100110,00001111,11101011,{Mod}{xmmreg}{R_m}:por {Mod}{R_m},{xmmreg} +00001111,11101011,{MOD}{mmxreg}{R_M}:por {MOD}{R_M},{mmxreg} +01100110,00001111,11101111,{Mod}{xmmreg}{R_m}:pxor {Mod}{R_m},{xmmreg} +00001111,11101111,{MOD}{mmxreg}{R_M}:pxor {MOD}{R_M},{mmxreg} +00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg} +00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpleps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnleps {Mod}{R_m},{xmmreg} +00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordps {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqss {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltss {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpless {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordss {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqss {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltss {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnless {Mod}{R_m},{xmmreg} +11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordss {Mod}{R_m},{xmmreg} +00001111,10101110,{mod}001{r_m}:fxrstor {mod}{r_m} +00001111,10101110,{mod}000{r_m}:fxsave {mod}{r_m} +00001111,10101110,{mod}010{r_m}:ldmxcsr {mod}{r_m} +00001111,10101110,{mod}011{r_m}:stmxcsr {mod}{r_m} +11110010,00001111,00010000,{Mod}{xmmreg}{R_m}:movsd {Mod}{R_m},{xmmreg} +11110011,00001111,00010000,{Mod}{xmmreg}{R_m}:movss {Mod}{R_m},{xmmreg} +01100110,00001111,00010000,{Mod}{xmmreg}{R_m}:movupd {Mod}{R_m},{xmmreg} +00001111,00010000,{Mod}{xmmreg}{R_m}:movups {Mod}{R_m},{xmmreg} +11110010,00001111,00010001,{Mod}{xmmreg}{R_m}:movsd {xmmreg},{Mod}{R_m} +11110011,00001111,00010001,{Mod}{xmmreg}{R_m}:movss {xmmreg},{Mod}{R_m} +01100110,00001111,00010001,{Mod}{xmmreg}{R_m}:movupd {xmmreg},{Mod}{R_m} +00001111,00010001,{Mod}{xmmreg}{R_m}:movups {xmmreg},{Mod}{R_m} +11110010,00001111,00010010,{Mod}{xmmreg}{R_m}:movddup {Mod}{R_m},{xmmreg} +11110011,00001111,00010010,{Mod}{xmmreg}{R_m}:movsldup {Mod}{R_m},{xmmreg} +01100110,00001111,00010010,{Mod}{xmmreg}{R_m}:movlpd {Mod}{R_m},{xmmreg} +00001111,00010010,11{xmmreg1}{xmmreg2}:movhlps {xmmreg2},{xmmreg1} +00001111,00010010,{Mod}{xmmreg}{R_m}:movlps {Mod}{R_m},{xmmreg} +01100110,00001111,00010011,11{xmmreg1}{xmmreg2}:movhlpd {xmmreg1},{xmmreg2} +00001111,00010011,11{xmmreg1}{xmmreg2}:movhlps {xmmreg1},{xmmreg2} +01100110,00001111,00010011,{Mod}{xmmreg}{R_m}:movlpd {xmmreg},{Mod}{R_m} +00001111,00010011,{Mod}{xmmreg}{R_m}:movlps {xmmreg},{Mod}{R_m} +01100110,00001111,00010100,{Mod}{xmmreg}{R_m}:unpcklpd {Mod}{R_m},{xmmreg} +00001111,00010100,{Mod}{xmmreg}{R_m}:unpcklps {Mod}{R_m},{xmmreg} +01100110,00001111,00010101,{Mod}{xmmreg}{R_m}:unpckhpd {Mod}{R_m},{xmmreg} +00001111,00010101,{Mod}{xmmreg}{R_m}:unpckhps {Mod}{R_m},{xmmreg} +11110011,00001111,00010110,{Mod}{xmmreg}{R_m}:movshdup {Mod}{R_m},{xmmreg} +01100110,00001111,00010110,{Mod}{xmmreg}{R_m}:movhpd {Mod}{R_m},{xmmreg} +00001111,00010110,11{xmmreg1}{xmmreg2}:movlhps {xmmreg2},{xmmreg1} +00001111,00010110,{Mod}{xmmreg}{R_m}:movhps {Mod}{R_m},{xmmreg} +01100110,00001111,00010111,11{xmmreg1}{xmmreg2}:movlhpd {xmmreg1},{xmmreg2} +00001111,00010111,11{xmmreg1}{xmmreg2}:movlhps {xmmreg1},{xmmreg2} +01100110,00001111,00010111,{Mod}{xmmreg}{R_m}:movhpd {xmmreg},{Mod}{R_m} +00001111,00010111,{Mod}{xmmreg}{R_m}:movhps {xmmreg},{Mod}{R_m} +01100110,00001111,00101000,{Mod}{xmmreg}{R_m}:movapd {Mod}{R_m},{xmmreg} +00001111,00101000,{Mod}{xmmreg}{R_m}:movaps {Mod}{R_m},{xmmreg} +01100110,00001111,00101001,{Mod}{xmmreg}{R_m}:movapd {xmmreg},{Mod}{R_m} +00001111,00101001,{Mod}{xmmreg}{R_m}:movaps {xmmreg},{Mod}{R_m} +11110010,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2sd {mod}{r_m},{xmmreg} +11110011,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2ss {mod}{r_m},{xmmreg} +01100110,00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2pd {MOD}{R_M},{xmmreg} +00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2ps {MOD}{R_M},{xmmreg} +01100110,00001111,00101011,{mod}{xmmreg}{r_m}:movntpd {xmmreg},{mod}{r_m} +00001111,00101011,{mod}{xmmreg}{r_m}:movntps {xmmreg},{mod}{r_m} +11110010,00001111,00101100,{Mod}{reg}{R_m}:cvttsd2si {Mod}{R_m},{reg} +11110011,00001111,00101100,{Mod}{reg}{R_m}:cvttss2si {Mod}{R_m},{reg} +01100110,00001111,00101100,{Mod}{mmxreg}{R_m}:cvttpd2pi {Mod}{R_m},{mmxreg} +00001111,00101100,{Mod}{mmxreg}{R_m}:cvttps2pi {Mod}{R_m},{mmxreg} +01100110,00001111,00101101,{Mod}{mmxreg}{R_m}:cvtpd2pi {Mod}{R_m},{mmxreg} +11110010,00001111,00101101,{Mod}{reg}{R_m}:cvtsd2si {Mod}{R_m},{reg} +11110011,00001111,00101101,{Mod}{reg}{R_m}:cvtss2si {Mod}{R_m},{reg} +00001111,00101101,{Mod}{mmxreg}{R_m}:cvtps2pi {Mod}{R_m},{mmxreg} +01100110,00001111,00101110,{Mod}{xmmreg}{R_m}:ucomisd {Mod}{R_m},{xmmreg} +00001111,00101110,{Mod}{xmmreg}{R_m}:ucomiss {Mod}{R_m},{xmmreg} +01100110,00001111,00101111,{Mod}{xmmreg}{R_m}:comisd {Mod}{R_m},{xmmreg} +00001111,00101111,{Mod}{xmmreg}{R_m}:comiss {Mod}{R_m},{xmmreg} +00001111,00110111:getsec +01100110,00001111,01010000,11{reg}{xmmreg}:movmskpd {xmmreg},{reg} +00001111,01010000,11{reg}{xmmreg}:movmskps {xmmreg},{reg} +01100110,00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtpd {Mod}{R_m},{xmmreg} +11110010,00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtsd {Mod}{R_m},{xmmreg} +11110011,00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtss {Mod}{R_m},{xmmreg} +00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtps {Mod}{R_m},{xmmreg} +11110011,00001111,01010010,{Mod}{xmmreg}{R_m}:rsqrtss {Mod}{R_m},{xmmreg} +00001111,01010010,{Mod}{xmmreg}{R_m}:rsqrtps {Mod}{R_m},{xmmreg} +11110011,00001111,01010011,{Mod}{xmmreg}{R_m}:rcpss {Mod}{R_m},{xmmreg} +00001111,01010011,{Mod}{xmmreg}{R_m}:rcpps {Mod}{R_m},{xmmreg} +01100110,00001111,01010100,{Mod}{xmmreg}{R_m}:andpd {Mod}{R_m},{xmmreg} +00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg} +01100110,00001111,01010101,{Mod}{xmmreg}{R_m}:andnpd {Mod}{R_m},{xmmreg} +00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg} +01100110,00001111,01010110,{Mod}{xmmreg}{R_m}:orpd {Mod}{R_m},{xmmreg} +00001111,01010110,{Mod}{xmmreg}{R_m}:orps {Mod}{R_m},{xmmreg} +01100110,00001111,01010111,{Mod}{xmmreg}{R_m}:xorpd {Mod}{R_m},{xmmreg} +00001111,01010111,{Mod}{xmmreg}{R_m}:xorps {Mod}{R_m},{xmmreg} +11110010,00001111,01011000,{Mod}{xmmreg}{R_m}:addsd {Mod}{R_m},{xmmreg} +11110011,00001111,01011000,{Mod}{xmmreg}{R_m}:addss {Mod}{R_m},{xmmreg} +01100110,00001111,01011000,{Mod}{xmmreg}{R_m}:addpd {Mod}{R_m},{xmmreg} +00001111,01011000,{Mod}{xmmreg}{R_m}:addps {Mod}{R_m},{xmmreg} +11110010,00001111,01011001,{Mod}{xmmreg}{R_m}:mulsd {Mod}{R_m},{xmmreg} +11110011,00001111,01011001,{Mod}{xmmreg}{R_m}:mulss {Mod}{R_m},{xmmreg} +01100110,00001111,01011001,{Mod}{xmmreg}{R_m}:mulpd {Mod}{R_m},{xmmreg} +00001111,01011001,{Mod}{xmmreg}{R_m}:mulps {Mod}{R_m},{xmmreg} +11110010,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtsd2ss {Mod}{R_m},{xmmreg} +11110011,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtss2sd {Mod}{R_m},{xmmreg} +01100110,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtpd2ps {Mod}{R_m},{xmmreg} +00001111,01011010,{Mod}{xmmreg}{R_m}:cvtps2pd {Mod}{R_m},{xmmreg} +01100110,00001111,01011011,{Mod}{xmmreg}{R_m}:cvtps2dq {Mod}{R_m},{xmmreg} +11110011,00001111,01011011,{Mod}{xmmreg}{R_m}:cvttps2dq {Mod}{R_m},{xmmreg} +00001111,01011011,{Mod}{xmmreg}{R_m}:cvtdq2ps {Mod}{R_m},{xmmreg} +11110010,00001111,01011100,{Mod}{xmmreg}{R_m}:subsd {Mod}{R_m},{xmmreg} +11110011,00001111,01011100,{Mod}{xmmreg}{R_m}:subss {Mod}{R_m},{xmmreg} +01100110,00001111,01011100,{Mod}{xmmreg}{R_m}:subpd {Mod}{R_m},{xmmreg} +00001111,01011100,{Mod}{xmmreg}{R_m}:subps {Mod}{R_m},{xmmreg} +11110010,00001111,01011101,{Mod}{xmmreg}{R_m}:minsd {Mod}{R_m},{xmmreg} +11110011,00001111,01011101,{Mod}{xmmreg}{R_m}:minss {Mod}{R_m},{xmmreg} +01100110,00001111,01011101,{Mod}{xmmreg}{R_m}:minpd {Mod}{R_m},{xmmreg} +00001111,01011101,{Mod}{xmmreg}{R_m}:minps {Mod}{R_m},{xmmreg} +11110010,00001111,01011110,{Mod}{xmmreg}{R_m}:divsd {Mod}{R_m},{xmmreg} +11110011,00001111,01011110,{Mod}{xmmreg}{R_m}:divss {Mod}{R_m},{xmmreg} +01100110,00001111,01011110,{Mod}{xmmreg}{R_m}:divpd {Mod}{R_m},{xmmreg} +00001111,01011110,{Mod}{xmmreg}{R_m}:divps {Mod}{R_m},{xmmreg} +11110010,00001111,01011111,{Mod}{xmmreg}{R_m}:maxsd {Mod}{R_m},{xmmreg} +11110011,00001111,01011111,{Mod}{xmmreg}{R_m}:maxss {Mod}{R_m},{xmmreg} +01100110,00001111,01011111,{Mod}{xmmreg}{R_m}:maxpd {Mod}{R_m},{xmmreg} +00001111,01011111,{Mod}{xmmreg}{R_m}:maxps {Mod}{R_m},{xmmreg} +01100110,00001111,01100000,{Mod}{xmmreg}{R_m}:punpcklbw {Mod}{R_m},{xmmreg} +00001111,01100000,{MOD}{mmxreg}{R_M}:punpcklbw {MOD}{R_M},{mmxreg} +01100110,00001111,01100001,{Mod}{xmmreg}{R_m}:punpcklwd {Mod}{R_m},{xmmreg} +00001111,01100001,{MOD}{mmxreg}{R_M}:punpcklwd {MOD}{R_M},{mmxreg} +01100110,00001111,01100010,{Mod}{xmmreg}{R_m}:punpckldq {Mod}{R_m},{xmmreg} +00001111,01100010,{MOD}{mmxreg}{R_M}:punpckldq {MOD}{R_M},{mmxreg} +01100110,00001111,01100011,{Mod}{xmmreg}{R_m}:packsswb {Mod}{R_m},{xmmreg} +00001111,01100011,{MOD}{mmxreg}{R_M}:packsswb {MOD}{R_M},{mmxreg} +01100110,00001111,01100100,{Mod}{xmmreg}{R_m}:pcmpgtb {Mod}{R_m},{xmmreg} +00001111,01100100,{MOD}{mmxreg}{R_M}:pcmpgtb {MOD}{R_M},{mmxreg} +01100110,00001111,01100101,{Mod}{xmmreg}{R_m}:pcmpgtw {Mod}{R_m},{xmmreg} +00001111,01100101,{MOD}{mmxreg}{R_M}:pcmpgtw {MOD}{R_M},{mmxreg} +01100110,00001111,01100110,{Mod}{xmmreg}{R_m}:pcmpgtd {Mod}{R_m},{xmmreg} +00001111,01100110,{MOD}{mmxreg}{R_M}:pcmpgtd {MOD}{R_M},{mmxreg} +01100110,00001111,01100111,{Mod}{xmmreg}{R_m}:packuswb {Mod}{R_m},{xmmreg} +00001111,01100111,{MOD}{mmxreg}{R_M}:packuswb {MOD}{R_M},{mmxreg} +01100110,00001111,01101000,{Mod}{xmmreg}{R_m}:punpckhbw {Mod}{R_m},{xmmreg} +00001111,01101000,{MOD}{mmxreg}{R_M}:punpckhbw {MOD}{R_M},{mmxreg} +01100110,00001111,01101001,{Mod}{xmmreg}{R_m}:punpckhwd {Mod}{R_m},{xmmreg} +00001111,01101001,{MOD}{mmxreg}{R_M}:punpckhwd {MOD}{R_M},{mmxreg} +01100110,00001111,01101010,{Mod}{xmmreg}{R_m}:punpckhdq {Mod}{R_m},{xmmreg} +00001111,01101010,{MOD}{mmxreg}{R_M}:punpckhdq {MOD}{R_M},{mmxreg} +01100110,00001111,01101011,{Mod}{xmmreg}{R_m}:packssdw {Mod}{R_m},{xmmreg} +00001111,01101011,{MOD}{mmxreg}{R_M}:packssdw {MOD}{R_M},{mmxreg} +01100110,00001111,01101100,{Mod}{xmmreg}{R_m}:punpcklqdq {Mod}{R_m},{xmmreg} +01100110,00001111,01101101,{Mod}{xmmreg}{R_m}:punpckhqdq {Mod}{R_m},{xmmreg} +01100110,00001111,01101110,{mod}{xmmreg}{r_m}:movd {mod}{r_m},{xmmreg} +00001111,01101110,{mod}{mmxreg}{r_m}:movd {mod}{r_m},{mmxreg} +01100110,00001111,01101111,{Mod}{xmmreg}{R_m}:movdqa {Mod}{R_m},{xmmreg} +11110011,00001111,01101111,{Mod}{xmmreg}{R_m}:movdqu {Mod}{R_m},{xmmreg} +00001111,01101111,{MOD}{mmxreg}{R_M}:movq {MOD}{R_M},{mmxreg} +01100110,00001111,01110000,{Mod}{xmmreg}{R_m},{imm8}:pshufd {imm8},{Mod}{R_m},{xmmreg} +11110010,00001111,01110000,{Mod}{xmmreg}{R_m},{imm8}:pshuflw {imm8},{Mod}{R_m},{xmmreg} +11110011,00001111,01110000,{Mod}{xmmreg}{R_m},{imm8}:pshufhw {imm8},{Mod}{R_m},{xmmreg} +00001111,01110000,{MOD}{mmxreg}{R_M},{imm8}:pshufw {imm8},{MOD}{R_M},{mmxreg} +01100110,00001111,01110100,{Mod}{xmmreg}{R_m}:pcmpeqb {Mod}{R_m},{xmmreg} +00001111,01110100,{MOD}{mmxreg}{R_M}:pcmpeqb {MOD}{R_M},{mmxreg} +01100110,00001111,01110101,{Mod}{xmmreg}{R_m}:pcmpeqw {Mod}{R_m},{xmmreg} +00001111,01110101,{MOD}{mmxreg}{R_M}:pcmpeqw {MOD}{R_M},{mmxreg} +01100110,00001111,01110110,{Mod}{xmmreg}{R_m}:pcmpeqd {Mod}{R_m},{xmmreg} +00001111,01110110,{MOD}{mmxreg}{R_M}:pcmpeqd {MOD}{R_M},{mmxreg} +01100110,00001111,01111100,{Mod}{xmmreg}{R_m}:haddpd {Mod}{R_m},{xmmreg} +11110010,00001111,01111100,{Mod}{xmmreg}{R_m}:haddps {Mod}{R_m},{xmmreg} +01100110,00001111,01111101,{Mod}{xmmreg}{R_m}:hsubpd {Mod}{R_m},{xmmreg} +11110010,00001111,01111101,{Mod}{xmmreg}{R_m}:hsubps {Mod}{R_m},{xmmreg} +01100110,00001111,01111110,{mod}{xmmreg}{r_m}:movd {xmmreg},{mod}{r_m} +11110011,00001111,01111110,{Mod}{xmmreg}{R_m}:movq {Mod}{R_m},{xmmreg} +00001111,01111110,{mod}{mmxreg}{r_m}:movd {mmxreg},{mod}{r_m} +01100110,00001111,01111111,{Mod}{xmmreg}{R_m}:movdqa {xmmreg},{Mod}{R_m} +11110011,00001111,01111111,{Mod}{xmmreg}{R_m}:movdqu {xmmreg},{Mod}{R_m} +00001111,01111111,{MOD}{mmxreg}{R_M}:movq {mmxreg},{MOD}{R_M} +00001111,11000011,{mod}{reg}{r_m}:movnti {reg},{mod}{r_m} +01100110,00001111,11000100,{mod}{xmmreg}{r_m},{imm8}:pinsrw {imm8},{mod}{r_m},{xmmreg} +00001111,11000100,{mod}{mmxreg}{r_m},{imm8}:pinsrw {imm8},{mod}{r_m},{mmxreg} +01100110,00001111,11000101,11{reg}{xmmreg},{imm8}:pextrw {imm8},{xmmreg},{reg} +00001111,11000101,11{reg}{mmxreg},{imm8}:pextrw {imm8},{mmxreg},{reg} +01100110,00001111,11000110,{Mod}{xmmreg}{R_m},{imm8}:shufpd {imm8},{Mod}{R_m},{xmmreg} +00001111,11000110,{Mod}{xmmreg}{R_m},{imm8}:shufps {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,11010001,{Mod}{xmmreg}{R_m}:psrlw {Mod}{R_m},{xmmreg} +00001111,11010001,{MOD}{mmxreg}{R_M}:psrlw {MOD}{R_M},{mmxreg} +01100110,00001111,11010010,{Mod}{xmmreg}{R_m}:psrld {Mod}{R_m},{xmmreg} +00001111,11010010,{MOD}{mmxreg}{R_M}:psrld {MOD}{R_M},{mmxreg} +01100110,00001111,11010011,{Mod}{xmmreg}{R_m}:psrlq {Mod}{R_m},{xmmreg} +00001111,11010011,{MOD}{mmxreg}{R_M}:psrlq {MOD}{R_M},{mmxreg} +01100110,00001111,11010100,{Mod}{xmmreg}{R_m}:paddq {Mod}{R_m},{xmmreg} +00001111,11010100,{MOD}{mmxreg}{R_M}:paddq {MOD}{R_M},{mmxreg} +01100110,00001111,11010101,{Mod}{xmmreg}{R_m}:pmullw {Mod}{R_m},{xmmreg} +00001111,11010101,{MOD}{mmxreg}{R_M}:pmullw {MOD}{R_M},{mmxreg} +01100110,00001111,11010110,{Mod}{xmmreg}{R_m}:movq {xmmreg},{Mod}{R_m} +11110010,00001111,11010110,11{mmxreg}{xmmreg}:movdq2q {xmmreg},{mmxreg} +11110011,00001111,11010110,11{xmmreg}{mmxreg}:movq2dq {mmxreg},{xmmreg} +01100110,00001111,11010111,11{reg}{xmmreg}:pmovmskb {xmmreg},{reg} +00001111,11010111,11{reg}{mmxreg}:pmovmskb {mmxreg},{reg} +01100110,00001111,11011000,{Mod}{xmmreg}{R_m}:psubusb {Mod}{R_m},{xmmreg} +00001111,11011000,{MOD}{mmxreg}{R_M}:psubusb {MOD}{R_M},{mmxreg} +01100110,00001111,11011001,{Mod}{xmmreg}{R_m}:psubusw {Mod}{R_m},{xmmreg} +00001111,11011001,{MOD}{mmxreg}{R_M}:psubusw {MOD}{R_M},{mmxreg} +01100110,00001111,11011010,{Mod}{xmmreg}{R_m}:pminub {Mod}{R_m},{xmmreg} +00001111,11011010,{MOD}{mmxreg}{R_M}:pminub {MOD}{R_M},{mmxreg} +01100110,00001111,11011100,{Mod}{xmmreg}{R_m}:paddusb {Mod}{R_m},{xmmreg} +00001111,11011100,{MOD}{mmxreg}{R_M}:paddusb {MOD}{R_M},{mmxreg} +01100110,00001111,11011101,{Mod}{xmmreg}{R_m}:paddusw {Mod}{R_m},{xmmreg} +00001111,11011101,{MOD}{mmxreg}{R_M}:paddusw {MOD}{R_M},{mmxreg} +01100110,00001111,11011110,{Mod}{xmmreg}{R_m}:pmaxub {Mod}{R_m},{xmmreg} +00001111,11011110,{MOD}{mmxreg}{R_M}:pmaxub {MOD}{R_M},{mmxreg} +01100110,00001111,11100000,{Mod}{xmmreg}{R_m}:pavgb {Mod}{R_m},{xmmreg} +00001111,11100000,{MOD}{mmxreg}{R_M}:pavgb {MOD}{R_M},{mmxreg} +01100110,00001111,11100001,{Mod}{xmmreg}{R_m}:psraw {Mod}{R_m},{xmmreg} +00001111,11100001,{MOD}{mmxreg}{R_M}:psraw {MOD}{R_M},{mmxreg} +01100110,00001111,11100010,{Mod}{xmmreg}{R_m}:psrad {Mod}{R_m},{xmmreg} +00001111,11100010,{MOD}{mmxreg}{R_M}:psrad {MOD}{R_M},{mmxreg} +01100110,00001111,11100011,{Mod}{xmmreg}{R_m}:pavgw {Mod}{R_m},{xmmreg} +00001111,11100011,{MOD}{mmxreg}{R_M}:pavgw {MOD}{R_M},{mmxreg} +01100110,00001111,11100100,{Mod}{xmmreg}{R_m}:pmulhuw {Mod}{R_m},{xmmreg} +00001111,11100100,{MOD}{mmxreg}{R_M}:pmulhuw {MOD}{R_M},{mmxreg} +01100110,00001111,11100101,{Mod}{xmmreg}{R_m}:pmulhw {Mod}{R_m},{xmmreg} +00001111,11100101,{MOD}{mmxreg}{R_M}:pmulhw {MOD}{R_M},{mmxreg} +01100110,00001111,11100111,{Mod}{xmmreg}{R_m}:movntdq {xmmreg},{Mod}{R_m} +00001111,11100111,{MOD}{mmxreg}{R_M}:movntq {mmxreg},{MOD}{R_M} +01100110,00001111,11101000,{Mod}{xmmreg}{R_m}:psubsb {Mod}{R_m},{xmmreg} +00001111,11101000,{MOD}{mmxreg}{R_M}:psubsb {MOD}{R_M},{mmxreg} +01100110,00001111,11101001,{Mod}{xmmreg}{R_m}:psubsw {Mod}{R_m},{xmmreg} +00001111,11101001,{MOD}{mmxreg}{R_M}:psubsw {MOD}{R_M},{mmxreg} +01100110,00001111,11101010,{Mod}{xmmreg}{R_m}:pminsw {Mod}{R_m},{xmmreg} +00001111,11101010,{MOD}{mmxreg}{R_M}:pminsw {MOD}{R_M},{mmxreg} +01100110,00001111,11101100,{Mod}{xmmreg}{R_m}:paddsb {Mod}{R_m},{xmmreg} +00001111,11101100,{MOD}{mmxreg}{R_M}:paddsb {MOD}{R_M},{mmxreg} +01100110,00001111,11101101,{Mod}{xmmreg}{R_m}:paddsw {Mod}{R_m},{xmmreg} +00001111,11101101,{MOD}{mmxreg}{R_M}:paddsw {MOD}{R_M},{mmxreg} +01100110,00001111,11101110,{Mod}{xmmreg}{R_m}:pmaxsw {Mod}{R_m},{xmmreg} +00001111,11101110,{MOD}{mmxreg}{R_M}:pmaxsw {MOD}{R_M},{mmxreg} +11110010,00001111,11110000,{mod}{xmmreg}{r_m}:lddqu {mod}{r_m},{xmmreg} +01100110,00001111,11110001,{Mod}{xmmreg}{R_m}:psllw {Mod}{R_m},{xmmreg} +00001111,11110001,{MOD}{mmxreg}{R_M}:psllw {MOD}{R_M},{mmxreg} +01100110,00001111,11110010,{Mod}{xmmreg}{R_m}:pslld {Mod}{R_m},{xmmreg} +00001111,11110010,{MOD}{mmxreg}{R_M}:pslld {MOD}{R_M},{mmxreg} +01100110,00001111,11110011,{Mod}{xmmreg}{R_m}:psllq {Mod}{R_m},{xmmreg} +00001111,11110011,{MOD}{mmxreg}{R_M}:psllq {MOD}{R_M},{mmxreg} +01100110,00001111,11110100,{Mod}{xmmreg}{R_m}:pmuludq {Mod}{R_m},{xmmreg} +00001111,11110100,{MOD}{mmxreg}{R_M}:pmuludq {MOD}{R_M},{mmxreg} +01100110,00001111,11110110,{Mod}{xmmreg}{R_m}:psadbw {Mod}{R_m},{xmmreg} +00001111,11110110,{MOD}{mmxreg}{R_M}:psadbw {MOD}{R_M},{mmxreg} +01100110,00001111,11110111,11{xmmreg1}{xmmreg2}:maskmovdqu {xmmreg2},{xmmreg1} +00001111,11110111,11{mmxreg1}{mmxreg2}:maskmovq {mmxreg2},{mmxreg1} +01100110,00001111,11111000,{Mod}{xmmreg}{R_m}:psubb {Mod}{R_m},{xmmreg} +00001111,11111000,{MOD}{mmxreg}{R_M}:psubb {MOD}{R_M},{mmxreg} +01100110,00001111,11111001,{Mod}{xmmreg}{R_m}:psubw {Mod}{R_m},{xmmreg} +00001111,11111001,{MOD}{mmxreg}{R_M}:psubw {MOD}{R_M},{mmxreg} +01100110,00001111,11111010,{Mod}{xmmreg}{R_m}:psubd {Mod}{R_m},{xmmreg} +00001111,11111010,{MOD}{mmxreg}{R_M}:psubd {MOD}{R_M},{mmxreg} +01100110,00001111,11111011,{Mod}{xmmreg}{R_m}:psubq {Mod}{R_m},{xmmreg} +00001111,11111011,{MOD}{mmxreg}{R_M}:psubq {MOD}{R_M},{mmxreg} +01100110,00001111,11111100,{Mod}{xmmreg}{R_m}:paddb {Mod}{R_m},{xmmreg} +00001111,11111100,{MOD}{mmxreg}{R_M}:paddb {MOD}{R_M},{mmxreg} +01100110,00001111,11111101,{Mod}{xmmreg}{R_m}:paddw {Mod}{R_m},{xmmreg} +00001111,11111101,{MOD}{mmxreg}{R_M}:paddw {MOD}{R_M},{mmxreg} +01100110,00001111,11111110,{Mod}{xmmreg}{R_m}:paddd {Mod}{R_m},{xmmreg} +00001111,11111110,{MOD}{mmxreg}{R_M}:paddd {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000000,{Mod}{xmmreg}{R_m}:pshufb {Mod}{R_m},{xmmreg} +00001111,00111000,00000000,{MOD}{mmxreg}{R_M}:pshufb {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000001,{Mod}{xmmreg}{R_m}:phaddw {Mod}{R_m},{xmmreg} +00001111,00111000,00000001,{MOD}{mmxreg}{R_M}:phaddw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000010,{Mod}{xmmreg}{R_m}:phaddd {Mod}{R_m},{xmmreg} +00001111,00111000,00000010,{MOD}{mmxreg}{R_M}:phaddd {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000011,{Mod}{xmmreg}{R_m}:phaddsw {Mod}{R_m},{xmmreg} +00001111,00111000,00000011,{MOD}{mmxreg}{R_M}:phaddsw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000100,{Mod}{xmmreg}{R_m}:pmaddubsw {Mod}{R_m},{xmmreg} +00001111,00111000,00000100,{MOD}{mmxreg}{R_M}:pmaddubsw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000101,{Mod}{xmmreg}{R_m}:phsubw {Mod}{R_m},{xmmreg} +00001111,00111000,00000101,{MOD}{mmxreg}{R_M}:phsubw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000110,{Mod}{xmmreg}{R_m}:phsubd {Mod}{R_m},{xmmreg} +00001111,00111000,00000110,{MOD}{mmxreg}{R_M}:phsubd {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00000111,{Mod}{xmmreg}{R_m}:phsubsw {Mod}{R_m},{xmmreg} +00001111,00111000,00000111,{MOD}{mmxreg}{R_M}:phsubsw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00001000,{Mod}{xmmreg}{R_m}:psignb {Mod}{R_m},{xmmreg} +00001111,00111000,00001000,{MOD}{mmxreg}{R_M}:psignb {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00001001,{Mod}{xmmreg}{R_m}:psignw {Mod}{R_m},{xmmreg} +00001111,00111000,00001001,{MOD}{mmxreg}{R_M}:psignw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00001010,{Mod}{xmmreg}{R_m}:psignd {Mod}{R_m},{xmmreg} +00001111,00111000,00001010,{MOD}{mmxreg}{R_M}:psignd {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00001011,{Mod}{xmmreg}{R_m}:pmulhrsw {Mod}{R_m},{xmmreg} +00001111,00111000,00001011,{MOD}{mmxreg}{R_M}:pmulhrsw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00011100,{Mod}{xmmreg}{R_m}:pabsb {Mod}{R_m},{xmmreg} +00001111,00111000,00011100,{MOD}{mmxreg}{R_M}:pabsb {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00011101,{Mod}{xmmreg}{R_m}:pabsw {Mod}{R_m},{xmmreg} +00001111,00111000,00011101,{MOD}{mmxreg}{R_M}:pabsw {MOD}{R_M},{mmxreg} +01100110,00001111,00111000,00011110,{Mod}{xmmreg}{R_m}:pabsd {Mod}{R_m},{xmmreg} +00001111,00111000,00011110,{MOD}{mmxreg}{R_M}:pabsd {MOD}{R_M},{mmxreg} +01100110,00001111,00111010,00001111,{Mod}{xmmreg}{R_m},{imm8}:palignr {imm8},{Mod}{R_m},{xmmreg} +00001111,00111010,00001111,{MOD}{mmxreg}{R_M},{imm8}:palignr {imm8},{MOD}{R_M},{mmxreg} +01100110,00001111,11000111,{mod}110{r_m}:vmclear {mod}{r_m} +11110011,00001111,11000111,{mod}110{r_m}:vmxon {mod}{r_m} +00001111,11000111,{mod}110{r_m}:vmptrld {mod}{r_m} +00001111,11000111,{mod}111{r_m}:vmptrst {mod}{r_m} +01100110,00001111,01110001,11010{xmmreg},{imm8}:psrlw {imm8},{xmmreg} +00001111,01110001,11010{mmxreg},{imm8}:psrlw {imm8},{mmxreg} +01100110,00001111,01110001,11100{xmmreg},{imm8}:psraw {imm8},{xmmreg} +00001111,01110001,11100{mmxreg},{imm8}:psraw {imm8},{mmxreg} +01100110,00001111,01110001,11110{xmmreg},{imm8}:psllw {imm8},{xmmreg} +00001111,01110001,11110{mmxreg},{imm8}:psllw {imm8},{mmxreg} +01100110,00001111,01110010,11010{xmmreg},{imm8}:psrld {imm8},{xmmreg} +00001111,01110010,11010{mmxreg},{imm8}:psrld {imm8},{mmxreg} +01100110,00001111,01110010,11100{xmmreg},{imm8}:psrad {imm8},{xmmreg} +00001111,01110010,11100{mmxreg},{imm8}:psrad {imm8},{mmxreg} +01100110,00001111,01110010,11110{xmmreg},{imm8}:pslld {imm8},{xmmreg} +00001111,01110010,11110{mmxreg},{imm8}:pslld {imm8},{mmxreg} +01100110,00001111,01110011,11010{xmmreg},{imm8}:psrlq {imm8},{xmmreg} +00001111,01110011,11010{mmxreg},{imm8}:psrlq {imm8},{mmxreg} +01100110,00001111,01110011,11011{xmmreg},{imm8}:psrldq {imm8},{xmmreg} +01100110,00001111,01110011,11110{xmmreg},{imm8}:psllq {imm8},{xmmreg} +00001111,01110011,11110{mmxreg},{imm8}:psllq {imm8},{mmxreg} +01100110,00001111,01110011,11111{xmmreg},{imm8}:pslldq {imm8},{xmmreg} +00001111,10101110,11101000:lfence +00001111,10101110,11110000:mfence +00001111,10101110,11111000:sfence +00001111,10101110,{mod}111{r_m}:clflush {mod}{r_m} +00001111,00001111,{MOD}{mmxreg}{R_M}:INVALID {MOD}{R_M},{mmxreg} +01100110,00001111,00111010,00001100,{Mod}{xmmreg}{R_m},{imm8}:blendps {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00001101,{Mod}{xmmreg}{R_m},{imm8}:blendpd {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00010100,{Mod}{xmmreg}{R_m}:blendvps %xmm0,{Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00010101,{Mod}{xmmreg}{R_m}:blendvpd %xmm0,{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01000000,{Mod}{xmmreg}{R_m},{imm8}:dpps {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01000001,{Mod}{xmmreg}{R_m},{imm8}:dppd {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00100001,{Mod}{xmmreg}{R_m},{imm8}:insertps {imm8},{Mod}{R_m},{xmmreg} +# Mod == 11 is not valid +01100110,00001111,00111000,00101010,{Mod}{xmmreg}{R_m}:movntdqa {Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01000010,{Mod}{xmmreg}{R_m},{imm8}:mpsadbw {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00101011,{Mod}{xmmreg}{R_m}:packusdw {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00010000,{Mod}{xmmreg}{R_m}:pblendvb %xmm0,{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00001110,{Mod}{xmmreg}{R_m},{imm8}:pblendw {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00101001,{Mod}{xmmreg}{R_m}:pcmpeqq {Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01100001,{Mod}{xmmreg}{R_m},{imm8}:pcmpestri {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01100000,{Mod}{xmmreg}{R_m},{imm8}:pcmpestrm {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01100011,{Mod}{xmmreg}{R_m},{imm8}:pcmpistri {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,01100010,{Mod}{xmmreg}{R_m},{imm8}:pcmpistrm {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110111,{Mod}{xmmreg}{R_m}:pcmpgtq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,01000001,{Mod}{xmmreg}{R_m}:phminposuw {Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00100000,{mod}{xmmreg}{r_m},{imm8}:pinsrb {imm8},{mod}{r_m},{xmmreg} +01100110,00001111,00111010,00100010,{mod}{xmmreg}{r_m},{imm8}:pinsrd {imm8},{mod}{r_m},{xmmreg} +01100110,00001111,00111000,00111100,{Mod}{xmmreg}{R_m}:pmaxsb {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111101,{Mod}{xmmreg}{R_m}:pmaxsd {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111111,{Mod}{xmmreg}{R_m}:pmaxud {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111110,{Mod}{xmmreg}{R_m}:pmaxuw {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111000,{Mod}{xmmreg}{R_m}:pminsb {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111001,{Mod}{xmmreg}{R_m}:pminsd {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111011,{Mod}{xmmreg}{R_m}:pminud {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00111010,{Mod}{xmmreg}{R_m}:pminuw {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00100000,{Mod}{xmmreg}{R_m}:pmovsxbw {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00100001,{Mod}{xmmreg}{R_m}:pmovsxbd {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00100010,{Mod}{xmmreg}{R_m}:pmovsxbq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00100011,{Mod}{xmmreg}{R_m}:pmovsxwd {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00100100,{Mod}{xmmreg}{R_m}:pmovsxwq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00100101,{Mod}{xmmreg}{R_m}:pmovsxdq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110000,{Mod}{xmmreg}{R_m}:pmovzxbw {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110001,{Mod}{xmmreg}{R_m}:pmovzxbd {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110010,{Mod}{xmmreg}{R_m}:pmovzxbq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110011,{Mod}{xmmreg}{R_m}:pmovzxwd {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110100,{Mod}{xmmreg}{R_m}:pmovzxwq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00110101,{Mod}{xmmreg}{R_m}:pmovzxdq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00101000,{Mod}{xmmreg}{R_m}:pmuldq {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,01000000,{Mod}{xmmreg}{R_m}:pmulld {Mod}{R_m},{xmmreg} +01100110,00001111,00111000,00010111,{Mod}{xmmreg}{R_m}:ptest {Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00001000,{Mod}{xmmreg}{R_m},{imm8}:roundps {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00001001,{Mod}{xmmreg}{R_m},{imm8}:roundpd {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00001010,{Mod}{xmmreg}{R_m},{imm8}:roundss {imm8},{Mod}{R_m},{xmmreg} +01100110,00001111,00111010,00001011,{Mod}{xmmreg}{R_m},{imm8}:roundsd {imm8},{Mod}{R_m},{xmmreg} +# ORDER: +dnl Many previous entries depend on this being last. +000{sreg2}111:pop {sreg2} +# ORDER END: diff --git a/libcpu/i386_data.h b/libcpu/i386_data.h new file mode 100644 index 00000000..06356b8a --- /dev/null +++ b/libcpu/i386_data.h @@ -0,0 +1,1418 @@ +/* Helper routines for disassembler for x86/x86-64. + Copyright (C) 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include +#include +#include +#include + +struct instr_enc +{ + /* The mnemonic. Especially encoded for the optimized table. */ + unsigned int mnemonic : MNEMONIC_BITS; + + /* The rep/repe prefixes. */ + unsigned int rep : 1; + unsigned int repe : 1; + + /* Mnemonic suffix. */ + unsigned int suffix : SUFFIX_BITS; + + /* Nonzero if the instruction uses modr/m. */ + unsigned int modrm : 1; + + /* 1st parameter. */ + unsigned int fct1 : FCT1_BITS; +#ifdef STR1_BITS + unsigned int str1 : STR1_BITS; +#endif + unsigned int off1_1 : OFF1_1_BITS; + unsigned int off1_2 : OFF1_2_BITS; + unsigned int off1_3 : OFF1_3_BITS; + + /* 2nd parameter. */ + unsigned int fct2 : FCT2_BITS; +#ifdef STR2_BITS + unsigned int str2 : STR2_BITS; +#endif + unsigned int off2_1 : OFF2_1_BITS; + unsigned int off2_2 : OFF2_2_BITS; + unsigned int off2_3 : OFF2_3_BITS; + + /* 3rd parameter. */ + unsigned int fct3 : FCT3_BITS; +#ifdef STR3_BITS + unsigned int str3 : STR3_BITS; +#endif + unsigned int off3_1 : OFF3_1_BITS; +#ifdef OFF3_2_BITS + unsigned int off3_2 : OFF3_2_BITS; +#endif +#ifdef OFF3_3_BITS + unsigned int off3_3 : OFF3_3_BITS; +#endif +}; + + +typedef int (*opfct_t) (struct output_data *); + + +static int +data_prefix (struct output_data *d) +{ + char ch = '\0'; + if (*d->prefixes & has_cs) + { + ch = 'c'; + *d->prefixes &= ~has_cs; + } + else if (*d->prefixes & has_ds) + { + ch = 'd'; + *d->prefixes &= ~has_ds; + } + else if (*d->prefixes & has_es) + { + ch = 'e'; + *d->prefixes &= ~has_es; + } + else if (*d->prefixes & has_fs) + { + ch = 'f'; + *d->prefixes &= ~has_fs; + } + else if (*d->prefixes & has_gs) + { + ch = 'g'; + *d->prefixes &= ~has_gs; + } + else if (*d->prefixes & has_ss) + { + ch = 's'; + *d->prefixes &= ~has_ss; + } + else + return 0; + + if (*d->bufcntp + 4 > d->bufsize) + return *d->bufcntp + 4 - d->bufsize; + + d->bufp[(*d->bufcntp)++] = '%'; + d->bufp[(*d->bufcntp)++] = ch; + d->bufp[(*d->bufcntp)++] = 's'; + d->bufp[(*d->bufcntp)++] = ':'; + + return 0; +} + +#ifdef X86_64 +static const char hiregs[8][4] = + { + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" + }; +static const char aregs[8][4] = + { + "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi" + }; +static const char dregs[8][4] = + { + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" + }; +#else +static const char aregs[8][4] = + { + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" + }; +# define dregs aregs +#endif + +static int +general_mod$r_m (struct output_data *d) +{ + int r = data_prefix (d); + if (r != 0) + return r; + + int prefixes = *d->prefixes; + const uint8_t *data = &d->data[d->opoff1 / 8]; + char *bufp = d->bufp; + size_t *bufcntp = d->bufcntp; + size_t bufsize = d->bufsize; + + uint_fast8_t modrm = data[0]; +#ifndef X86_64 + if (unlikely ((prefixes & has_addr16) != 0)) + { + int16_t disp = 0; + bool nodisp = false; + + if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80) + /* 16 bit displacement. */ + disp = read_2sbyte_unaligned (&data[1]); + else if ((modrm & 0xc0) == 0x40) + /* 8 bit displacement. */ + disp = *(const int8_t *) &data[1]; + else if ((modrm & 0xc0) == 0) + nodisp = true; + + char tmpbuf[sizeof ("-0x1234(%rr,%rr)")]; + int n; + if ((modrm & 0xc7) == 6) + n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx16, disp); + else + { + n = 0; + if (!nodisp) + n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx16, + disp < 0 ? "-" : "", disp < 0 ? -disp : disp); + + if ((modrm & 0x4) == 0) + n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%b%c,%%%ci)", + "xp"[(modrm >> 1) & 1], "sd"[modrm & 1]); + else + n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%%s)", + ((const char [4][3]) { "si", "di", "bp", "bx" })[modrm & 3]); + } + + if (*bufcntp + n + 1 > bufsize) + return *bufcntp + n + 1 - bufsize; + + memcpy (&bufp[*bufcntp], tmpbuf, n + 1); + *bufcntp += n; + } + else +#endif + { + if ((modrm & 7) != 4) + { + int32_t disp = 0; + bool nodisp = false; + + if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80) + /* 32 bit displacement. */ + disp = read_4sbyte_unaligned (&data[1]); + else if ((modrm & 0xc0) == 0x40) + /* 8 bit displacement. */ + disp = *(const int8_t *) &data[1]; + else if ((modrm & 0xc0) == 0) + nodisp = true; + + char tmpbuf[sizeof ("-0x12345678(%rrrr)")]; + int n; + if (nodisp) + { + n = snprintf (tmpbuf, sizeof (tmpbuf), "(%%%s)", +#ifdef X86_64 + (prefixes & has_rex_b) ? hiregs[modrm & 7] : +#endif + aregs[modrm & 7]); +#ifdef X86_64 + if (prefixes & has_addr16) + { + if (prefixes & has_rex_b) + tmpbuf[n++] = 'd'; + else + tmpbuf[2] = 'e'; + } +#endif + } + else if ((modrm & 0xc7) != 5) + { + int p; + n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%%n%s)", + disp < 0 ? "-" : "", disp < 0 ? -disp : disp, &p, +#ifdef X86_64 + (prefixes & has_rex_b) ? hiregs[modrm & 7] : +#endif + aregs[modrm & 7]); +#ifdef X86_64 + if (prefixes & has_addr16) + { + if (prefixes & has_rex_b) + tmpbuf[n++] = 'd'; + else + tmpbuf[p] = 'e'; + } +#endif + } + else + { +#ifdef X86_64 + n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%rip)", + disp < 0 ? "-" : "", disp < 0 ? -disp : disp); + + d->symaddr_use = addr_rel_always; + d->symaddr = disp; +#else + n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx32, disp); +#endif + } + + if (*bufcntp + n + 1 > bufsize) + return *bufcntp + n + 1 - bufsize; + + memcpy (&bufp[*bufcntp], tmpbuf, n + 1); + *bufcntp += n; + } + else + { + /* SIB */ + uint_fast8_t sib = data[1]; + int32_t disp = 0; + bool nodisp = false; + + if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80 + || ((modrm & 0xc7) == 0x4 && (sib & 0x7) == 0x5)) + /* 32 bit displacement. */ + disp = read_4sbyte_unaligned (&data[2]); + else if ((modrm & 0xc0) == 0x40) + /* 8 bit displacement. */ + disp = *(const int8_t *) &data[2]; + else + nodisp = true; + + char tmpbuf[sizeof ("-0x12345678(%rrrr,%rrrr,N)")]; + char *cp = tmpbuf; + int n; + if ((modrm & 0xc0) != 0 || (sib & 0x3f) != 0x25 +#ifdef X86_64 + || (prefixes & has_rex_x) != 0 +#endif + ) + { + if (!nodisp) + { + n = snprintf (cp, sizeof (tmpbuf), "%s0x%" PRIx32, + disp < 0 ? "-" : "", disp < 0 ? -disp : disp); + cp += n; + } + + *cp++ = '('; + + if ((modrm & 0xc7) != 0x4 || (sib & 0x7) != 0x5) + { + *cp++ = '%'; + cp = stpcpy (cp, +#ifdef X86_64 + (prefixes & has_rex_b) ? hiregs[sib & 7] : + (prefixes & has_addr16) ? dregs[sib & 7] : +#endif + aregs[sib & 7]); +#ifdef X86_64 + if ((prefixes & (has_rex_b | has_addr16)) + == (has_rex_b | has_addr16)) + *cp++ = 'd'; +#endif + } + + if ((sib & 0x38) != 0x20 +#ifdef X86_64 + || (prefixes & has_rex_x) != 0 +#endif + ) + { + *cp++ = ','; + *cp++ = '%'; + cp = stpcpy (cp, +#ifdef X86_64 + (prefixes & has_rex_x) + ? hiregs[(sib >> 3) & 7] : + (prefixes & has_addr16) + ? dregs[(sib >> 3) & 7] : +#endif + aregs[(sib >> 3) & 7]); +#ifdef X86_64 + if ((prefixes & (has_rex_b | has_addr16)) + == (has_rex_b | has_addr16)) + *cp++ = 'd'; +#endif + + *cp++ = ','; + *cp++ = '0' + (1 << (sib >> 6)); + } + + *cp++ = ')'; + } + else + { + assert (! nodisp); +#ifdef X86_64 + if ((prefixes & has_addr16) == 0) + n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx64, + (int64_t) disp); + else +#endif + n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx32, disp); + cp += n; + } + + if (*bufcntp + (cp - tmpbuf) > bufsize) + return *bufcntp + (cp - tmpbuf) - bufsize; + + memcpy (&bufp[*bufcntp], tmpbuf, cp - tmpbuf); + *bufcntp += cp - tmpbuf; + } + } + return 0; +} + + +static int +FCT_MOD$R_M (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + assert (d->opoff1 / 8 == d->opoff2 / 8); + assert (d->opoff2 % 8 == 5); + //uint_fast8_t byte = d->data[d->opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + char *buf = d->bufp + *bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed; + if (*d->prefixes & (has_rep | has_repne)) + needed = snprintf (buf, avail, "%%%s", dregs[byte]); + else + needed = snprintf (buf, avail, "%%mm%" PRIxFAST8, byte); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; + } + + return general_mod$r_m (d); +} + + +static int +FCT_Mod$R_m (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + assert (d->opoff1 / 8 == d->opoff2 / 8); + assert (d->opoff2 % 8 == 5); + //uint_fast8_t byte = data[opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, + byte); + if ((size_t) needed > avail) + return needed - avail; + *d->bufcntp += needed; + return 0; + } + + return general_mod$r_m (d); +} + +static int +generic_abs (struct output_data *d, const char *absstring +#ifdef X86_64 + , int abslen +#else +# define abslen 4 +#endif + ) +{ + int r = data_prefix (d); + if (r != 0) + return r; + + assert (d->opoff1 % 8 == 0); + assert (d->opoff1 / 8 == 1); + if (*d->param_start + abslen > d->end) + return -1; + *d->param_start += abslen; +#ifndef X86_64 + uint32_t absval; +# define ABSPRIFMT PRIx32 +#else + uint64_t absval; +# define ABSPRIFMT PRIx64 + if (abslen == 8) + absval = read_8ubyte_unaligned (&d->data[1]); + else +#endif + absval = read_4ubyte_unaligned (&d->data[1]); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT, + absstring, absval); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_absval (struct output_data *d) +{ + return generic_abs (d, "$" +#ifdef X86_64 + , 4 +#endif + ); +} + +static int +FCT_abs (struct output_data *d) +{ + return generic_abs (d, "" +#ifdef X86_64 + , 8 +#endif + ); +} + +static int +FCT_ax (struct output_data *d) +{ + int is_16bit = (*d->prefixes & has_data16) != 0; + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + size_t bufsize = d->bufsize; + + if (*bufcntp + 4 - is_16bit > bufsize) + return *bufcntp + 4 - is_16bit - bufsize; + + bufp[(*bufcntp)++] = '%'; + if (! is_16bit) + bufp[(*bufcntp)++] = ( +#ifdef X86_64 + (*d->prefixes & has_rex_w) ? 'r' : +#endif + 'e'); + bufp[(*bufcntp)++] = 'a'; + bufp[(*bufcntp)++] = 'x'; + + return 0; +} + + +static int +FCT_ax$w (struct output_data *d) +{ + if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0) + return FCT_ax (d); + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + size_t bufsize = d->bufsize; + + if (*bufcntp + 3 > bufsize) + return *bufcntp + 3 - bufsize; + + bufp[(*bufcntp)++] = '%'; + bufp[(*bufcntp)++] = 'a'; + bufp[(*bufcntp)++] = 'l'; + + return 0; +} + + +static int +__attribute__ ((noinline)) +FCT_crdb (struct output_data *d, const char *regstr) +{ + if (*d->prefixes & has_data16) + return -1; + + size_t *bufcntp = d->bufcntp; + + // XXX If this assert is true, use absolute offset below + assert (d->opoff1 / 8 == 2); + assert (d->opoff1 % 8 == 2); + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%%s%" PRIx32, + regstr, (uint32_t) (d->data[d->opoff1 / 8] >> 3) & 7); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_ccc (struct output_data *d) +{ + return FCT_crdb (d, "cr"); +} + + +static int +FCT_ddd (struct output_data *d) +{ + return FCT_crdb (d, "db"); +} + + +static int +FCT_disp8 (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + if (*d->param_start >= d->end) + return -1; + int32_t offset = *(const int8_t *) (*d->param_start)++; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32, + (uint32_t) (d->addr + (*d->param_start - d->data) + + offset)); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +__attribute__ ((noinline)) +FCT_ds_xx (struct output_data *d, const char *reg) +{ + int prefix = *d->prefixes & SEGMENT_PREFIXES; + + if (prefix == 0) + *d->prefixes |= prefix = has_ds; + /* Make sure only one bit is set. */ + else if ((prefix - 1) & prefix) + return -1; + + int r = data_prefix (d); + + assert ((*d->prefixes & prefix) == 0); + + if (r != 0) + return r; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "(%%%s%s)", +#ifdef X86_64 + *d->prefixes & idx_addr16 ? "e" : "r", +#else + *d->prefixes & idx_addr16 ? "" : "e", +#endif + reg); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + + return 0; +} + + +static int +FCT_ds_bx (struct output_data *d) +{ + return FCT_ds_xx (d, "bx"); +} + + +static int +FCT_ds_si (struct output_data *d) +{ + return FCT_ds_xx (d, "si"); +} + + +static int +FCT_dx (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + + if (*bufcntp + 7 > d->bufsize) + return *bufcntp + 7 - d->bufsize; + + memcpy (&d->bufp[*bufcntp], "(%dx)", 5); + *bufcntp += 5; + + return 0; +} + + +static int +FCT_es_di (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%es:(%%%sdi)", +#ifdef X86_64 + *d->prefixes & idx_addr16 ? "e" : "r" +#else + *d->prefixes & idx_addr16 ? "" : "e" +#endif + ); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + + return 0; +} + + +static int +FCT_imm (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed; + if (*d->prefixes & has_data16) + { + if (*d->param_start + 2 > d->end) + return -1; + uint16_t word = read_2ubyte_unaligned_inc (*d->param_start); + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word); + } + else + { + if (*d->param_start + 4 > d->end) + return -1; + int32_t word = read_4sbyte_unaligned_inc (*d->param_start); +#ifdef X86_64 + if (*d->prefixes & has_rex_w) + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, + (int64_t) word); + else +#endif + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word); + } + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_imm$w (struct output_data *d) +{ + if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0) + return FCT_imm (d); + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start>= d->end) + return -1; + uint_fast8_t word = *(*d->param_start)++; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +#ifdef X86_64 +static int +FCT_imm64$w (struct output_data *d) +{ + if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) == 0 + || (*d->prefixes & has_data16) != 0) + return FCT_imm$w (d); + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed; + if (*d->prefixes & has_rex_w) + { + if (*d->param_start + 8 > d->end) + return -1; + uint64_t word = read_8ubyte_unaligned_inc (*d->param_start); + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, word); + } + else + { + if (*d->param_start + 4 > d->end) + return -1; + int32_t word = read_4sbyte_unaligned_inc (*d->param_start); + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word); + } + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} +#endif + + +static int +FCT_imms (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start>= d->end) + return -1; + int8_t byte = *(*d->param_start)++; +#ifdef X86_64 + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, + (int64_t) byte); +#else + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, + (int32_t) byte); +#endif + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_imm$s (struct output_data *d) +{ + uint_fast8_t opcode = d->data[d->opoff2 / 8]; + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if ((opcode & 2) != 0) + return FCT_imms (d); + + if ((*d->prefixes & has_data16) == 0) + { + if (*d->param_start + 4 > d->end) + return -1; + int32_t word = read_4sbyte_unaligned_inc (*d->param_start); +#ifdef X86_64 + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, + (int64_t) word); +#else + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word); +#endif + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + } + else + { + if (*d->param_start + 2 > d->end) + return -1; + uint16_t word = read_2ubyte_unaligned_inc (*d->param_start); + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + } + return 0; +} + + +static int +FCT_imm16 (struct output_data *d) +{ + if (*d->param_start + 2 > d->end) + return -1; + uint16_t word = read_2ubyte_unaligned_inc (*d->param_start); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_imms8 (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start >= d->end) + return -1; + int_fast8_t byte = *(*d->param_start)++; + int needed; +#ifdef X86_64 + if (*d->prefixes & has_rex_w) + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, + (int64_t) byte); + else +#endif + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, + (int32_t) byte); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_imm8 (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start >= d->end) + return -1; + uint_fast8_t byte = *(*d->param_start)++; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, + (uint32_t) byte); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_rel (struct output_data *d) +{ + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start + 4 > d->end) + return -1; + int32_t rel = read_4sbyte_unaligned_inc (*d->param_start); +#ifdef X86_64 + int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx64, + (uint64_t) (d->addr + rel + + (*d->param_start - d->data))); +#else + int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32, + (uint32_t) (d->addr + rel + + (*d->param_start - d->data))); +#endif + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_mmxreg (struct output_data *d) +{ + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5); + byte = (byte >> (5 - d->opoff1 % 8)) & 7; + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_mod$r_m (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + int prefixes = *d->prefixes; + if (prefixes & has_addr16) + return -1; + + int is_16bit = (prefixes & has_data16) != 0; + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 5 - is_16bit > d->bufsize) + return *bufcntp + 5 - is_16bit - d->bufsize; + bufp[(*bufcntp)++] = '%'; + + char *cp; +#ifdef X86_64 + if ((prefixes & has_rex_b) != 0 && !is_16bit) + { + cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]); + if ((prefixes & has_rex_w) == 0) + *cp++ = 'd'; + } + else +#endif + { + cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit); +#ifdef X86_64 + if ((prefixes & has_rex_w) != 0) + bufp[*bufcntp] = 'r'; +#endif + } + *bufcntp = cp - bufp; + return 0; + } + + return general_mod$r_m (d); +} + + +#ifndef X86_64 +static int +FCT_moda$r_m (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + if (*d->prefixes & has_addr16) + return -1; + + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; + + memcpy (&d->bufp[*bufcntp], "???", 3); + *bufcntp += 3; + + return 0; + } + + return general_mod$r_m (d); +} +#endif + + +#ifdef X86_64 +static const char rex_8bit[8][3] = + { + [0] = "a", [1] = "c", [2] = "d", [3] = "b", + [4] = "sp", [5] = "bp", [6] = "si", [7] = "di" + }; +#endif + + +static int +FCT_mod$r_m$w (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + const uint8_t *data = d->data; + uint_fast8_t modrm = data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + int prefixes = *d->prefixes; + + if (prefixes & has_addr16) + return -1; + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 5 > d->bufsize) + return *bufcntp + 5 - d->bufsize; + + if ((data[d->opoff3 / 8] & (1 << (7 - (d->opoff3 & 7)))) == 0) + { + bufp[(*bufcntp)++] = '%'; + +#ifdef X86_64 + if (prefixes & has_rex) + { + if (prefixes & has_rex_r) + *bufcntp += snprintf (bufp + *bufcntp, d->bufsize - *bufcntp, + "r%db", 8 + (modrm & 7)); + else + { + char *cp = stpcpy (bufp + *bufcntp, hiregs[modrm & 7]); + *cp++ = 'l'; + *bufcntp = cp - bufp; + } + } + else +#endif + { + bufp[(*bufcntp)++] = "acdb"[modrm & 3]; + bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2]; + } + } + else + { + int is_16bit = (prefixes & has_data16) != 0; + + bufp[(*bufcntp)++] = '%'; + + char *cp; +#ifdef X86_64 + if ((prefixes & has_rex_b) != 0 && !is_16bit) + { + cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]); + if ((prefixes & has_rex_w) == 0) + *cp++ = 'd'; + } + else +#endif + { + cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit); +#ifdef X86_64 + if ((prefixes & has_rex_w) != 0) + bufp[*bufcntp] = 'r'; +#endif + } + *bufcntp = cp - bufp; + } + return 0; + } + + return general_mod$r_m (d); +} + + +static int +FCT_mod$8r_m (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; + bufp[(*bufcntp)++] = '%'; + bufp[(*bufcntp)++] = "acdb"[modrm & 3]; + bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2]; + return 0; + } + + return general_mod$r_m (d); +} + + +static int +FCT_mod$16r_m (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + assert (d->opoff1 / 8 == d->opoff2 / 8); + //uint_fast8_t byte = data[opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; + d->bufp[(*bufcntp)++] = '%'; + memcpy (&d->bufp[*bufcntp], dregs[byte] + 1, sizeof (dregs[0]) - 1); + *bufcntp += 2; + return 0; + } + + return general_mod$r_m (d); +} + + +#ifdef X86_64 +static int +FCT_mod$64r_m (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; + if ((modrm & 0xc0) == 0xc0) + { + assert (d->opoff1 / 8 == d->opoff2 / 8); + //uint_fast8_t byte = data[opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 4 > d->bufsize) + return *bufcntp + 4 - d->bufsize; + char *cp = &d->bufp[*bufcntp]; + *cp++ = '%'; + cp = stpcpy (cp, + (*d->prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]); + *bufcntp = cp - d->bufp; + return 0; + } + + return general_mod$r_m (d); +} +#else +static typeof (FCT_mod$r_m) FCT_mod$64r_m __attribute__ ((alias ("FCT_mod$r_m"))); +#endif + + +static int +FCT_reg (struct output_data *d) +{ + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); + byte &= 7; + int is_16bit = (*d->prefixes & has_data16) != 0; + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 5 > d->bufsize) + return *bufcntp + 5 - d->bufsize; + d->bufp[(*bufcntp)++] = '%'; +#ifdef X86_64 + if ((*d->prefixes & has_rex_r) != 0 && !is_16bit) + { + *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d", + 8 + byte); + if ((*d->prefixes & has_rex_w) == 0) + d->bufp[(*bufcntp)++] = 'd'; + } + else +#endif + { + memcpy (&d->bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit); +#ifdef X86_64 + if ((*d->prefixes & has_rex_w) != 0 && !is_16bit) + d->bufp[*bufcntp] = 'r'; +#endif + *bufcntp += 3 - is_16bit; + } + return 0; +} + + +#ifdef X86_64 +static int +FCT_oreg (struct output_data *d) +{ + /* Special form where register comes from opcode. The rex.B bit is used, + rex.R and rex.X are ignored. */ + int save_prefixes = *d->prefixes; + + *d->prefixes = ((save_prefixes & ~has_rex_r) + | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b))); + + int r = FCT_reg (d); + + *d->prefixes = save_prefixes; + + return r; +} +#endif + + +static int +FCT_reg64 (struct output_data *d) +{ + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); + byte &= 7; + if ((*d->prefixes & has_data16) != 0) + return -1; + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 5 > d->bufsize) + return *bufcntp + 5 - d->bufsize; + d->bufp[(*bufcntp)++] = '%'; +#ifdef X86_64 + if ((*d->prefixes & has_rex_r) != 0) + { + *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d", + 8 + byte); + if ((*d->prefixes & has_rex_w) == 0) + d->bufp[(*bufcntp)++] = 'd'; + } + else +#endif + { + memcpy (&d->bufp[*bufcntp], aregs[byte], 3); + *bufcntp += 3; + } + return 0; +} + + +static int +FCT_reg$w (struct output_data *d) +{ + if (d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) + return FCT_reg (d); + + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); + byte &= 7; + + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 4 > d->bufsize) + return *bufcntp + 4 - d->bufsize; + + d->bufp[(*bufcntp)++] = '%'; + +#ifdef X86_64 + if (*d->prefixes & has_rex) + { + if (*d->prefixes & has_rex_r) + *bufcntp += snprintf (d->bufp + *bufcntp, d->bufsize - *bufcntp, + "r%db", 8 + byte); + else + { + char* cp = stpcpy (d->bufp + *bufcntp, rex_8bit[byte]); + *cp++ = 'l'; + *bufcntp = cp - d->bufp; + } + } + else +#endif + { + d->bufp[(*bufcntp)++] = "acdb"[byte & 3]; + d->bufp[(*bufcntp)++] = "lh"[byte >> 2]; + } + return 0; +} + + +#ifdef X86_64 +static int +FCT_oreg$w (struct output_data *d) +{ + /* Special form where register comes from opcode. The rex.B bit is used, + rex.R and rex.X are ignored. */ + int save_prefixes = *d->prefixes; + + *d->prefixes = ((save_prefixes & ~has_rex_r) + | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b))); + + int r = FCT_reg$w (d); + + *d->prefixes = save_prefixes; + + return r; +} +#endif + + +static int +FCT_freg (struct output_data *d) +{ + assert (d->opoff1 / 8 == 1); + assert (d->opoff1 % 8 == 5); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%st(%" PRIx32 ")", + (uint32_t) (d->data[1] & 7)); + if ((size_t) needed > avail) + return (size_t) needed - avail; + *bufcntp += needed; + return 0; +} + + +#ifndef X86_64 +static int +FCT_reg16 (struct output_data *d) +{ + if (*d->prefixes & has_data16) + return -1; + + *d->prefixes |= has_data16; + return FCT_reg (d); +} +#endif + + +static int +FCT_sel (struct output_data *d) +{ + assert (d->opoff1 % 8 == 0); + assert (d->opoff1 / 8 == 5); + if (*d->param_start + 2 >= d->end) + return -1; + *d->param_start += 2; + uint16_t absval = read_2ubyte_unaligned (&d->data[5]); + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, absval); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; +} + + +static int +FCT_sreg2 (struct output_data *d) +{ + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 2); + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; + + bufp[(*bufcntp)++] = '%'; + bufp[(*bufcntp)++] = "ecsd"[byte & 3]; + bufp[(*bufcntp)++] = 's'; + + return 0; +} + + +static int +FCT_sreg3 (struct output_data *d) +{ + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 4 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); + + if ((byte & 7) >= 6) + return -1; + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; + + bufp[(*bufcntp)++] = '%'; + bufp[(*bufcntp)++] = "ecsdfg"[byte & 7]; + bufp[(*bufcntp)++] = 's'; + + return 0; +} + + +static int +FCT_string (struct output_data *d __attribute__ ((unused))) +{ + return 0; +} + + +static int +FCT_xmmreg (struct output_data *d) +{ + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5); + byte = (byte >> (5 - d->opoff1 % 8)) & 7; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte); + if ((size_t) needed > avail) + return needed - avail; + *bufcntp += needed; + return 0; +} diff --git a/libcpu/i386_dis.h b/libcpu/i386_dis.h new file mode 100644 index 00000000..a5cc01f9 --- /dev/null +++ b/libcpu/i386_dis.h @@ -0,0 +1,1657 @@ +#define MNEMONIC_BITS 10 +#define SUFFIX_BITS 3 +#define FCT1_BITS 7 +#define STR1_BITS 4 +#define OFF1_1_BITS 7 +#define OFF1_1_BIAS 3 +#define OFF1_2_BITS 7 +#define OFF1_2_BIAS 4 +#define OFF1_3_BITS 1 +#define OFF1_3_BIAS 7 +#define FCT2_BITS 6 +#define STR2_BITS 2 +#define OFF2_1_BITS 7 +#define OFF2_1_BIAS 5 +#define OFF2_2_BITS 7 +#define OFF2_2_BIAS 4 +#define OFF2_3_BITS 4 +#define OFF2_3_BIAS 7 +#define FCT3_BITS 4 +#define STR3_BITS 1 +#define OFF3_1_BITS 6 +#define OFF3_1_BIAS 10 +#define OFF3_2_BITS 1 +#define OFF3_2_BIAS 21 + +#include + +#define suffix_none 0 +#define suffix_w 1 +#define suffix_w0 2 +#define suffix_W 3 +#define suffix_tttn 4 +#define suffix_D 7 +#define suffix_w1 5 +#define suffix_W1 6 + +static const opfct_t op1_fct[] = +{ + NULL, + FCT_MOD$R_M, + FCT_Mod$R_m, + FCT_abs, + FCT_ax, + FCT_ax$w, + FCT_ccc, + FCT_ddd, + FCT_disp8, + FCT_ds_bx, + FCT_ds_si, + FCT_dx, + FCT_es_di, + FCT_freg, + FCT_imm$s, + FCT_imm$w, + FCT_imm16, + FCT_imm8, + FCT_imms8, + FCT_mmxreg, + FCT_mod$16r_m, + FCT_mod$64r_m, + FCT_mod$8r_m, + FCT_mod$r_m, + FCT_mod$r_m$w, + FCT_reg, + FCT_reg$w, + FCT_reg16, + FCT_reg64, + FCT_rel, + FCT_sel, + FCT_sreg2, + FCT_sreg3, + FCT_string, + FCT_xmmreg, +}; +static const char op1_str[] = + "%ax\0" + "%cl\0" + "%eax\0" + "%st\0" + "%xmm0\0" + "*"; +static const uint8_t op1_str_idx[] = { + 0, + 4, + 8, + 13, + 17, + 23, +}; +static const opfct_t op2_fct[] = +{ + NULL, + FCT_MOD$R_M, + FCT_Mod$R_m, + FCT_abs, + FCT_absval, + FCT_ax$w, + FCT_ccc, + FCT_ddd, + FCT_ds_si, + FCT_dx, + FCT_es_di, + FCT_freg, + FCT_imm8, + FCT_mmxreg, + FCT_mod$64r_m, + FCT_mod$r_m, + FCT_mod$r_m$w, + FCT_moda$r_m, + FCT_reg, + FCT_reg$w, + FCT_reg64, + FCT_sreg3, + FCT_string, + FCT_xmmreg, +}; +static const char op2_str[] = + "%ecx\0" + "%st"; +static const uint8_t op2_str_idx[] = { + 0, + 5, +}; +static const opfct_t op3_fct[] = +{ + NULL, + FCT_mmxreg, + FCT_mod$r_m, + FCT_reg, + FCT_string, + FCT_xmmreg, +}; +static const char op3_str[] = + "%edx"; +static const uint8_t op3_str_idx[] = { + 0, +}; +static const struct instr_enc instrtab[] = +{ + { .mnemonic = MNE_aaa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_aad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_aam, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_aas, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addsubpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addsubps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_arpl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bound, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 17, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bsf, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bswap, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 25, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bt, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bts, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bts, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_call, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 29, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_call, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 21, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lcall, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 30, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 4, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lcall, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 21, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_clc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cli, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_syscall, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_clts, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sysret, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sysenter, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sysexit, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmov, .rep = 0, .repe = 0, .suffix = 4, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmps, .rep = 0, .repe = 1, .suffix = 1, .modrm = 0, .fct1 = 12, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 8, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpxchg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 11, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 8, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpxchg8b, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cpuid, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtdq2pd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpd2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttpd2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_daa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_das, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_dec, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_dec, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 25, .str1 = 0, .off1_1 = 2, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_div, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_emms, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_enter, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 16, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 12, .str2 = 0, .off2_1 = 19, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fchs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fabs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ftst, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxam, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fld1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldl2t, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldl2e, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldpi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldlg2, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldln2, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldz, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_f2xm1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fyl2x, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fptan, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fpatan, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxtract, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fprem1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdecstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fincstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fprem, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fyl2xp1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsqrt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsincos, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_frndint, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fscale, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsin, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcos, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fadd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fadd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fadd, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmul, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsub, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubr, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fst, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fst, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fstp, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldenv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldcw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstenv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstcw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxch, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_faddp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fiadd, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmove, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmulp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fimul, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisub, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubrp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisubr, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 1, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fbld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomip, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fbstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fchs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fclex, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_finit, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fwait, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnclex, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmove, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovbe, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovnb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovne, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovnbe, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovnu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcom, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcom, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomp, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcompp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomip, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucomi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucomip, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcos, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdecstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdiv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdiv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdiv, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidivl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidiv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivrp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivr, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidivrl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidivr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivrp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ffree, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovbe, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ficom, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ficomp, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fild, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fildl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fildll, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fincstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fninit, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fist, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fistp, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fistpll, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisttp, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisttpll, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fstpt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fld, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucom, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_frstor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucomp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnsave, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_hlt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_idiv, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_imul, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_imul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_imul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 14, .str1 = 0, .off1_1 = 13, .off1_2 = 2, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 3, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_in, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_in, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 11, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 3, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_inc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_inc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 25, .str1 = 0, .off1_1 = 2, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ins, .rep = 1, .repe = 0, .suffix = 1, .modrm = 0, .fct1 = 11, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 10, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_int, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_int3, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_into, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_invd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_swapgs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_invlpg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_iret, .rep = 0, .repe = 0, .suffix = 6, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_j, .rep = 0, .repe = 0, .suffix = 4, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_j, .rep = 0, .repe = 0, .suffix = 4, .modrm = 0, .fct1 = 29, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_set, .rep = 0, .repe = 0, .suffix = 4, .modrm = 1, .fct1 = 22, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_jmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_jmp, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 29, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_jmp, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 21, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ljmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 30, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 4, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ljmp, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 21, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lahf, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lar, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lds, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lea, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_leave, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_les, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lfs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lgs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lgdt, .rep = 0, .repe = 0, .suffix = 2, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lidt, .rep = 0, .repe = 0, .suffix = 2, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lldt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lmsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lock, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lods, .rep = 1, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 10, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 3, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_loop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_loope, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_loopne, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lsl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ltr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 3, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 35, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 37, .off1_2 = 3, .off1_3 = 0, .fct2 = 3, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 6, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 6, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 7, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 7, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 32, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 21, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movs, .rep = 1, .repe = 0, .suffix = 1, .modrm = 0, .fct1 = 10, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 10, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsbl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 22, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movswl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movzbl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 22, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movzwl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mul, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_neg, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pause, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_nop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_popcnt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_not, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_out, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 12, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_out, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 9, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_outs, .rep = 1, .repe = 0, .suffix = 1, .modrm = 0, .fct1 = 10, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 9, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 32, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_popf, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 25, .str1 = 0, .off1_1 = 2, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 25, .str1 = 0, .off1_1 = 2, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 14, .str1 = 0, .off1_1 = 5, .off1_2 = 2, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 31, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 32, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pusha, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_popa, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pushf, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rdmsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rdpmc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rdtsc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ret, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ret, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 16, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lret, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lret, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 16, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rol, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rol, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rol, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ror, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ror, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ror, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rsm, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sahf, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sar, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sar, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sar, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_scas, .rep = 0, .repe = 1, .suffix = 0, .modrm = 0, .fct1 = 12, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 3, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_set, .rep = 0, .repe = 0, .suffix = 4, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_shld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_shr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shrd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_shrd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_vmcall, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmlaunch, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmresume, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmxoff, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmread, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 28, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 14, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmwrite, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sgdtl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_monitor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 3, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 1, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 4, .str3 = 1, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mwait, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 3, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 22, .str2 = 1, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sidtl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sldt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_smsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_stc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_std, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sti, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_stos, .rep = 1, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 10, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_str, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_test, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_test, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_test, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ud2a, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_verr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_verw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_wbinvd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetch, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 22, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetchw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 22, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetchnta, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetcht0, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetcht1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetcht2, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_nop, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_wrmsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xadd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 11, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 8, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xchg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xchg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 4, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xlat, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 9, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_emms, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pand, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pand, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pandn, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pandn, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_por, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_por, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pxor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pxor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpeqps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpltps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpleps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpunordps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpneqps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnltps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnleps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpordps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpeqss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpltss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpless, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpunordss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpneqss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnltss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnless, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpordss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxrstor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxsave, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ldmxcsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_stmxcsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movupd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movups, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movupd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movups, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movddup, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsldup, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhlpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpcklpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpcklps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpckhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpckhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movshdup, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movapd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movaps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movapd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movaps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsi2sd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsi2ss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpi2pd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpi2ps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttsd2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttss2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttpd2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttps2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpd2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsd2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtss2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtps2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ucomisd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ucomiss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_comisd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_comiss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_getsec, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movmskpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movmskps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rsqrtss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rsqrtps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcpss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcpps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_orpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_orps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xorpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xorps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsd2ss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtss2sd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpd2ps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtps2pd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtps2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttps2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtdq2ps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packsswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packsswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packuswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packuswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packssdw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packssdw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklqdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhqdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pshufd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pshuflw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pshufhw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pshufw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 1, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_haddpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_haddps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_hsubpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_hsubps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movnti, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 1, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_pextrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 3, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pextrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 3, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_shufpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_shufps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmullw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmullw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdq2q, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 19, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovmskb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovmskb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 19, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lddqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmuludq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmuludq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psadbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psadbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maskmovdqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maskmovq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 19, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pshufb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pshufb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhrsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhrsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_palignr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_palignr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 1, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_vmclear, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmxon, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmptrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmptrst, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lfence, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mfence, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sfence, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_clflush, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_blendps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_blendpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_blendvps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 5, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_blendvpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 5, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_dpps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_dppd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_insertps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_movntdqa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mpsadbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_packusdw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pblendvb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 5, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pblendw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpestri, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpestrm, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpistri, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpistrm, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phminposuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxud, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminud, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxbd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxbq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxwq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxbd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxbq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxwq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmuldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ptest, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 23, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_roundps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_roundpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_roundss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_roundsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 17, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 31, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, +}; +static const uint8_t match_data[] = +{ + 0x11, 0x37, + 0x22, 0xd5, 0xa, + 0x22, 0xd4, 0xa, + 0x11, 0x3f, + 0x1, 0xfe, 0x14, + 0x2, 0xfe, 0x80, 0x38, 0x10, + 0x2, 0xfe, 0x82, 0x38, 0x10, + 0x2, 0xfe, 0x10, 0, 0, + 0x2, 0xfe, 0x12, 0, 0, + 0x1, 0xfe, 0x4, + 0x2, 0xfe, 0x80, 0x38, 0, + 0x12, 0x83, 0x38, 0, + 0x2, 0xfe, 0, 0, 0, + 0x2, 0xfe, 0x2, 0, 0, + 0x34, 0x66, 0xf, 0xd0, 0, 0, + 0x34, 0xf2, 0xf, 0xd0, 0, 0, + 0x1, 0xfe, 0x24, + 0x2, 0xfe, 0x80, 0x38, 0x20, + 0x2, 0xfe, 0x82, 0x38, 0x20, + 0x2, 0xfe, 0x20, 0, 0, + 0x2, 0xfe, 0x22, 0, 0, + 0x34, 0x66, 0xf, 0x54, 0, 0, + 0x23, 0xf, 0x54, 0, 0, + 0x34, 0x66, 0xf, 0x55, 0, 0, + 0x23, 0xf, 0x55, 0, 0, + 0x12, 0x63, 0, 0, + 0x12, 0x62, 0, 0, + 0x23, 0xf, 0xbc, 0, 0, + 0x23, 0xf, 0xbd, 0, 0, + 0x12, 0xf, 0xf8, 0xc8, + 0x23, 0xf, 0xa3, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x20, + 0x23, 0xf, 0xbb, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x38, + 0x23, 0xf, 0xb3, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x30, + 0x23, 0xf, 0xab, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x28, + 0x11, 0xe8, + 0x12, 0xff, 0x38, 0x10, + 0x11, 0x9a, + 0x12, 0xff, 0x38, 0x18, + 0x11, 0x98, + 0x11, 0x99, + 0x11, 0xf8, + 0x11, 0xfc, + 0x11, 0xfa, + 0x22, 0xf, 0x5, + 0x22, 0xf, 0x6, + 0x22, 0xf, 0x7, + 0x22, 0xf, 0x34, + 0x22, 0xf, 0x35, + 0x11, 0xf5, + 0x13, 0xf, 0xf0, 0x40, 0, 0, + 0x1, 0xfe, 0x3c, + 0x2, 0xfe, 0x80, 0x38, 0x38, + 0x12, 0x83, 0x38, 0x38, + 0x2, 0xfe, 0x38, 0, 0, + 0x2, 0xfe, 0x3a, 0, 0, + 0x34, 0xf2, 0xf, 0xc2, 0, 0, + 0x34, 0xf3, 0xf, 0xc2, 0, 0, + 0x34, 0x66, 0xf, 0xc2, 0, 0, + 0x23, 0xf, 0xc2, 0, 0, + 0x1, 0xfe, 0xa6, + 0x13, 0xf, 0xfe, 0xb0, 0, 0, + 0x23, 0xf, 0xc7, 0x38, 0x8, + 0x22, 0xf, 0xa2, + 0x34, 0xf3, 0xf, 0xe6, 0, 0, + 0x34, 0xf2, 0xf, 0xe6, 0, 0, + 0x34, 0x66, 0xf, 0xe6, 0, 0, + 0x11, 0x27, + 0x11, 0x2f, + 0x2, 0xfe, 0xfe, 0x38, 0x8, + 0x1, 0xf8, 0x48, + 0x2, 0xfe, 0xf6, 0x38, 0x30, + 0x22, 0xf, 0x77, + 0x11, 0xc8, + 0x22, 0xd9, 0xd0, + 0x22, 0xd9, 0xe0, + 0x22, 0xd9, 0xe1, + 0x22, 0xd9, 0xe4, + 0x22, 0xd9, 0xe5, + 0x22, 0xd9, 0xe8, + 0x22, 0xd9, 0xe9, + 0x22, 0xd9, 0xea, + 0x22, 0xd9, 0xeb, + 0x22, 0xd9, 0xec, + 0x22, 0xd9, 0xed, + 0x22, 0xd9, 0xee, + 0x22, 0xd9, 0xf0, + 0x22, 0xd9, 0xf1, + 0x22, 0xd9, 0xf2, + 0x22, 0xd9, 0xf3, + 0x22, 0xd9, 0xf4, + 0x22, 0xd9, 0xf5, + 0x22, 0xd9, 0xf6, + 0x22, 0xd9, 0xf7, + 0x22, 0xd9, 0xf8, + 0x22, 0xd9, 0xf9, + 0x22, 0xd9, 0xfa, + 0x22, 0xd9, 0xfb, + 0x22, 0xd9, 0xfc, + 0x22, 0xd9, 0xfd, + 0x22, 0xd9, 0xfe, + 0x22, 0xd9, 0xff, + 0x12, 0xd8, 0xf8, 0xc0, + 0x12, 0xdc, 0xf8, 0xc0, + 0x2, 0xfb, 0xd8, 0x38, 0, + 0x12, 0xd8, 0xf8, 0xc8, + 0x12, 0xdc, 0xf8, 0xc8, + 0x2, 0xfb, 0xd8, 0x38, 0x8, + 0x12, 0xd8, 0xf8, 0xe0, + 0x12, 0xdc, 0xf8, 0xe0, + 0x2, 0xfb, 0xd8, 0x38, 0x20, + 0x12, 0xd8, 0xf8, 0xe8, + 0x12, 0xdc, 0xf8, 0xe8, + 0x2, 0xfb, 0xd8, 0x38, 0x28, + 0x12, 0xdd, 0xf8, 0xd0, + 0x2, 0xfb, 0xd9, 0x38, 0x10, + 0x12, 0xdd, 0xf8, 0xd8, + 0x2, 0xfb, 0xd9, 0x38, 0x18, + 0x12, 0xd9, 0x38, 0x20, + 0x12, 0xd9, 0x38, 0x28, + 0x12, 0xd9, 0x38, 0x30, + 0x12, 0xd9, 0x38, 0x38, + 0x12, 0xd9, 0xf8, 0xc8, + 0x12, 0xde, 0xf8, 0xc0, + 0x12, 0xda, 0xf8, 0xc0, + 0x2, 0xfb, 0xda, 0x38, 0, + 0x12, 0xda, 0xf8, 0xc8, + 0x12, 0xde, 0xf8, 0xc8, + 0x2, 0xfb, 0xda, 0x38, 0x8, + 0x12, 0xde, 0xf8, 0xe0, + 0x2, 0xfb, 0xda, 0x38, 0x20, + 0x12, 0xde, 0xf8, 0xe8, + 0x2, 0xfb, 0xda, 0x38, 0x28, + 0x22, 0xdf, 0xe0, + 0x12, 0xdf, 0x38, 0x20, + 0x12, 0xdf, 0xf8, 0xf0, + 0x12, 0xdf, 0x38, 0x30, + 0x22, 0xd9, 0xe0, + 0x33, 0x9b, 0xdb, 0xe2, + 0x33, 0x9b, 0xdb, 0xe3, + 0x11, 0x9b, + 0x22, 0xdb, 0xe2, + 0x12, 0xda, 0xf8, 0xc0, + 0x12, 0xda, 0xf8, 0xc8, + 0x12, 0xda, 0xf8, 0xd0, + 0x12, 0xda, 0xf8, 0xd8, + 0x12, 0xdb, 0xf8, 0xc0, + 0x12, 0xdb, 0xf8, 0xc8, + 0x12, 0xdb, 0xf8, 0xd0, + 0x12, 0xdb, 0xf8, 0xd8, + 0x12, 0xd8, 0xf8, 0xd0, + 0x2, 0xfb, 0xd8, 0x38, 0x10, + 0x12, 0xd8, 0xf8, 0xd8, + 0x2, 0xfb, 0xd8, 0x38, 0x18, + 0x22, 0xde, 0xd9, + 0x12, 0xdb, 0xf8, 0xf0, + 0x12, 0xdf, 0xf8, 0xf0, + 0x12, 0xdb, 0xf8, 0xe8, + 0x12, 0xdf, 0xf8, 0xe8, + 0x22, 0xd9, 0xff, + 0x22, 0xd9, 0xf6, + 0x12, 0xd8, 0xf8, 0xf0, + 0x12, 0xdc, 0xf8, 0xf0, + 0x2, 0xfb, 0xd8, 0x38, 0x30, + 0x12, 0xda, 0x38, 0x30, + 0x12, 0xde, 0xf8, 0xf0, + 0x12, 0xde, 0x38, 0x30, + 0x12, 0xde, 0xf8, 0xf8, + 0x12, 0xd8, 0xf8, 0xf8, + 0x12, 0xdc, 0xf8, 0xf8, + 0x2, 0xfb, 0xd8, 0x38, 0x38, + 0x12, 0xda, 0x38, 0x38, + 0x12, 0xde, 0x38, 0x38, + 0x12, 0xde, 0xf8, 0xf0, + 0x12, 0xdd, 0xf8, 0xc0, + 0x12, 0xda, 0xf8, 0xd0, + 0x2, 0xfb, 0xda, 0x38, 0x10, + 0x12, 0xda, 0xf8, 0xd8, + 0x2, 0xfb, 0xda, 0x38, 0x18, + 0x12, 0xdf, 0x38, 0, + 0x12, 0xdb, 0x38, 0, + 0x12, 0xdf, 0x38, 0x28, + 0x22, 0xd9, 0xf7, + 0x22, 0xdb, 0xe3, + 0x2, 0xfb, 0xdb, 0x38, 0x10, + 0x2, 0xfb, 0xdb, 0x38, 0x18, + 0x12, 0xdf, 0x38, 0x38, + 0x2, 0xfb, 0xdb, 0x38, 0x8, + 0x12, 0xdd, 0x38, 0x8, + 0x12, 0xdb, 0x38, 0x28, + 0x12, 0xdb, 0x38, 0x38, + 0x12, 0xd9, 0xf8, 0xc0, + 0x2, 0xfb, 0xd9, 0x38, 0, + 0x12, 0xdd, 0xf8, 0xe0, + 0x12, 0xdd, 0x38, 0x20, + 0x12, 0xdd, 0xf8, 0xe8, + 0x12, 0xdd, 0x38, 0x30, + 0x12, 0xdd, 0x38, 0x38, + 0x11, 0xf4, + 0x2, 0xfe, 0xf6, 0x38, 0x38, + 0x2, 0xfe, 0xf6, 0x38, 0x28, + 0x23, 0xf, 0xaf, 0, 0, + 0x2, 0xfd, 0x69, 0, 0, + 0x1, 0xfe, 0xe4, + 0x1, 0xfe, 0xec, + 0x2, 0xfe, 0xfe, 0x38, 0, + 0x1, 0xf8, 0x40, + 0x1, 0xfe, 0x6c, + 0x11, 0xcd, + 0x11, 0xcc, + 0x11, 0xce, + 0x22, 0xf, 0x8, + 0x33, 0xf, 0x1, 0xf8, + 0x23, 0xf, 0x1, 0x38, 0x38, + 0x11, 0xcf, + 0x1, 0xf0, 0x70, + 0x12, 0xf, 0xf0, 0x80, + 0x13, 0xf, 0xf0, 0x90, 0x38, 0, + 0x11, 0xe3, + 0x11, 0xeb, + 0x11, 0xe9, + 0x12, 0xff, 0x38, 0x20, + 0x11, 0xea, + 0x12, 0xff, 0x38, 0x28, + 0x11, 0x9f, + 0x23, 0xf, 0x2, 0, 0, + 0x12, 0xc5, 0, 0, + 0x12, 0x8d, 0, 0, + 0x11, 0xc9, + 0x12, 0xc4, 0, 0, + 0x23, 0xf, 0xb4, 0, 0, + 0x23, 0xf, 0xb5, 0, 0, + 0x23, 0xf, 0x1, 0x38, 0x10, + 0x23, 0xf, 0x1, 0x38, 0x18, + 0x23, 0xf, 0, 0x38, 0x10, + 0x23, 0xf, 0x1, 0x38, 0x30, + 0x11, 0xf0, + 0x1, 0xfe, 0xac, + 0x11, 0xe2, + 0x11, 0xe1, + 0x11, 0xe0, + 0x23, 0xf, 0x3, 0, 0, + 0x23, 0xf, 0xb2, 0, 0, + 0x23, 0xf, 0, 0x38, 0x18, + 0x2, 0xfe, 0x88, 0, 0, + 0x2, 0xfe, 0x8a, 0, 0, + 0x2, 0xfe, 0xc6, 0x38, 0, + 0x1, 0xf0, 0xb0, + 0x1, 0xfe, 0xa0, + 0x1, 0xfe, 0xa2, + 0x23, 0xf, 0x20, 0xc0, 0xc0, + 0x23, 0xf, 0x22, 0xc0, 0xc0, + 0x23, 0xf, 0x21, 0xc0, 0xc0, + 0x23, 0xf, 0x23, 0xc0, 0xc0, + 0x12, 0x8c, 0, 0, + 0x12, 0x8e, 0, 0, + 0x1, 0xfe, 0xa4, + 0x23, 0xf, 0xbe, 0, 0, + 0x23, 0xf, 0xbf, 0, 0, + 0x23, 0xf, 0xb6, 0, 0, + 0x23, 0xf, 0xb7, 0, 0, + 0x2, 0xfe, 0xf6, 0x38, 0x20, + 0x2, 0xfe, 0xf6, 0x38, 0x18, + 0x22, 0xf3, 0x90, + 0x11, 0x90, + 0x34, 0xf3, 0xf, 0xb8, 0, 0, + 0x2, 0xfe, 0xf6, 0x38, 0x10, + 0x2, 0xfe, 0x8, 0, 0, + 0x2, 0xfe, 0xa, 0, 0, + 0x2, 0xfe, 0x80, 0x38, 0x8, + 0x2, 0xfe, 0x82, 0x38, 0x8, + 0x1, 0xfe, 0xc, + 0x1, 0xfe, 0xe6, + 0x1, 0xfe, 0xee, + 0x1, 0xfe, 0x6e, + 0x12, 0x8f, 0x38, 0, + 0x12, 0xf, 0xc7, 0x81, + 0x11, 0x9d, + 0x12, 0xff, 0x38, 0x30, + 0x1, 0xf8, 0x50, + 0x1, 0xf8, 0x58, + 0x1, 0xfd, 0x68, + 0x1, 0xe7, 0x6, + 0x12, 0xf, 0xc7, 0x80, + 0x11, 0x60, + 0x11, 0x61, + 0x11, 0x9c, + 0x2, 0xfe, 0xd0, 0x38, 0x10, + 0x2, 0xfe, 0xd2, 0x38, 0x10, + 0x2, 0xfe, 0xc0, 0x38, 0x10, + 0x2, 0xfe, 0xd0, 0x38, 0x18, + 0x2, 0xfe, 0xd2, 0x38, 0x18, + 0x2, 0xfe, 0xc0, 0x38, 0x18, + 0x22, 0xf, 0x32, + 0x22, 0xf, 0x33, + 0x22, 0xf, 0x31, + 0x11, 0xc3, + 0x11, 0xc2, + 0x11, 0xcb, + 0x11, 0xca, + 0x2, 0xfe, 0xd0, 0x38, 0, + 0x2, 0xfe, 0xd2, 0x38, 0, + 0x2, 0xfe, 0xc0, 0x38, 0, + 0x2, 0xfe, 0xd0, 0x38, 0x8, + 0x2, 0xfe, 0xd2, 0x38, 0x8, + 0x2, 0xfe, 0xc0, 0x38, 0x8, + 0x22, 0xf, 0xaa, + 0x11, 0x9e, + 0x2, 0xfe, 0xd0, 0x38, 0x38, + 0x2, 0xfe, 0xd2, 0x38, 0x38, + 0x2, 0xfe, 0xc0, 0x38, 0x38, + 0x2, 0xfe, 0x18, 0, 0, + 0x2, 0xfe, 0x1a, 0, 0, + 0x1, 0xfe, 0x1c, + 0x2, 0xfe, 0x80, 0x38, 0x18, + 0x2, 0xfe, 0x82, 0x38, 0x18, + 0x1, 0xfe, 0xae, + 0x13, 0xf, 0xf0, 0x90, 0x38, 0, + 0x2, 0xfe, 0xd0, 0x38, 0x20, + 0x2, 0xfe, 0xd2, 0x38, 0x20, + 0x2, 0xfe, 0xc0, 0x38, 0x20, + 0x2, 0xfe, 0xd0, 0x38, 0x28, + 0x23, 0xf, 0xa4, 0, 0, + 0x23, 0xf, 0xa5, 0, 0, + 0x2, 0xfe, 0xd2, 0x38, 0x28, + 0x2, 0xfe, 0xc0, 0x38, 0x28, + 0x23, 0xf, 0xac, 0, 0, + 0x23, 0xf, 0xad, 0, 0, + 0x33, 0xf, 0x1, 0xc1, + 0x33, 0xf, 0x1, 0xc2, + 0x33, 0xf, 0x1, 0xc3, + 0x33, 0xf, 0x1, 0xc4, + 0x23, 0xf, 0x78, 0, 0, + 0x23, 0xf, 0x79, 0, 0, + 0x23, 0xf, 0x1, 0x38, 0, + 0x33, 0xf, 0x1, 0xc8, + 0x33, 0xf, 0x1, 0xc9, + 0x23, 0xf, 0x1, 0x38, 0x8, + 0x23, 0xf, 0, 0x38, 0, + 0x23, 0xf, 0x1, 0x38, 0x20, + 0x11, 0xf9, + 0x11, 0xfd, + 0x11, 0xfb, + 0x1, 0xfe, 0xaa, + 0x23, 0xf, 0, 0x38, 0x8, + 0x2, 0xfe, 0x28, 0, 0, + 0x2, 0xfe, 0x2a, 0, 0, + 0x1, 0xfe, 0x2c, + 0x2, 0xfe, 0x80, 0x38, 0x28, + 0x2, 0xfe, 0x82, 0x38, 0x28, + 0x2, 0xfe, 0x84, 0, 0, + 0x1, 0xfe, 0xa8, + 0x2, 0xfe, 0xf6, 0x38, 0, + 0x22, 0xf, 0xb, + 0x23, 0xf, 0, 0x38, 0x20, + 0x23, 0xf, 0, 0x38, 0x28, + 0x22, 0xf, 0x9, + 0x23, 0xf, 0xd, 0x38, 0, + 0x23, 0xf, 0xd, 0x38, 0x8, + 0x23, 0xf, 0x18, 0x38, 0, + 0x23, 0xf, 0x18, 0x38, 0x8, + 0x23, 0xf, 0x18, 0x38, 0x10, + 0x23, 0xf, 0x18, 0x38, 0x18, + 0x23, 0xf, 0x1f, 0, 0, + 0x22, 0xf, 0x30, + 0x13, 0xf, 0xfe, 0xc0, 0, 0, + 0x2, 0xfe, 0x86, 0, 0, + 0x1, 0xf8, 0x90, + 0x11, 0xd7, + 0x2, 0xfe, 0x30, 0, 0, + 0x2, 0xfe, 0x32, 0, 0, + 0x1, 0xfe, 0x34, + 0x2, 0xfe, 0x80, 0x38, 0x30, + 0x2, 0xfe, 0x82, 0x38, 0x30, + 0x22, 0xf, 0x77, + 0x34, 0x66, 0xf, 0xdb, 0, 0, + 0x23, 0xf, 0xdb, 0, 0, + 0x34, 0x66, 0xf, 0xdf, 0, 0, + 0x23, 0xf, 0xdf, 0, 0, + 0x34, 0x66, 0xf, 0xf5, 0, 0, + 0x23, 0xf, 0xf5, 0, 0, + 0x34, 0x66, 0xf, 0xeb, 0, 0, + 0x23, 0xf, 0xeb, 0, 0, + 0x34, 0x66, 0xf, 0xef, 0, 0, + 0x23, 0xf, 0xef, 0, 0, + 0x23, 0xf, 0x55, 0, 0, + 0x23, 0xf, 0x54, 0, 0, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x1, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x2, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x3, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x4, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x5, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x6, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x7, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x1, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x2, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x3, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x4, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x5, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x6, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x7, + 0x23, 0xf, 0xae, 0x38, 0x8, + 0x23, 0xf, 0xae, 0x38, 0, + 0x23, 0xf, 0xae, 0x38, 0x10, + 0x23, 0xf, 0xae, 0x38, 0x18, + 0x34, 0xf2, 0xf, 0x10, 0, 0, + 0x34, 0xf3, 0xf, 0x10, 0, 0, + 0x34, 0x66, 0xf, 0x10, 0, 0, + 0x23, 0xf, 0x10, 0, 0, + 0x34, 0xf2, 0xf, 0x11, 0, 0, + 0x34, 0xf3, 0xf, 0x11, 0, 0, + 0x34, 0x66, 0xf, 0x11, 0, 0, + 0x23, 0xf, 0x11, 0, 0, + 0x34, 0xf2, 0xf, 0x12, 0, 0, + 0x34, 0xf3, 0xf, 0x12, 0, 0, + 0x34, 0x66, 0xf, 0x12, 0, 0, + 0x23, 0xf, 0x12, 0xc0, 0xc0, + 0x23, 0xf, 0x12, 0, 0, + 0x34, 0x66, 0xf, 0x13, 0xc0, 0xc0, + 0x23, 0xf, 0x13, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0x13, 0, 0, + 0x23, 0xf, 0x13, 0, 0, + 0x34, 0x66, 0xf, 0x14, 0, 0, + 0x23, 0xf, 0x14, 0, 0, + 0x34, 0x66, 0xf, 0x15, 0, 0, + 0x23, 0xf, 0x15, 0, 0, + 0x34, 0xf3, 0xf, 0x16, 0, 0, + 0x34, 0x66, 0xf, 0x16, 0, 0, + 0x23, 0xf, 0x16, 0xc0, 0xc0, + 0x23, 0xf, 0x16, 0, 0, + 0x34, 0x66, 0xf, 0x17, 0xc0, 0xc0, + 0x23, 0xf, 0x17, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0x17, 0, 0, + 0x23, 0xf, 0x17, 0, 0, + 0x34, 0x66, 0xf, 0x28, 0, 0, + 0x23, 0xf, 0x28, 0, 0, + 0x34, 0x66, 0xf, 0x29, 0, 0, + 0x23, 0xf, 0x29, 0, 0, + 0x34, 0xf2, 0xf, 0x2a, 0, 0, + 0x34, 0xf3, 0xf, 0x2a, 0, 0, + 0x34, 0x66, 0xf, 0x2a, 0, 0, + 0x23, 0xf, 0x2a, 0, 0, + 0x34, 0x66, 0xf, 0x2b, 0, 0, + 0x23, 0xf, 0x2b, 0, 0, + 0x34, 0xf2, 0xf, 0x2c, 0, 0, + 0x34, 0xf3, 0xf, 0x2c, 0, 0, + 0x34, 0x66, 0xf, 0x2c, 0, 0, + 0x23, 0xf, 0x2c, 0, 0, + 0x34, 0x66, 0xf, 0x2d, 0, 0, + 0x34, 0xf2, 0xf, 0x2d, 0, 0, + 0x34, 0xf3, 0xf, 0x2d, 0, 0, + 0x23, 0xf, 0x2d, 0, 0, + 0x34, 0x66, 0xf, 0x2e, 0, 0, + 0x23, 0xf, 0x2e, 0, 0, + 0x34, 0x66, 0xf, 0x2f, 0, 0, + 0x23, 0xf, 0x2f, 0, 0, + 0x22, 0xf, 0x37, + 0x34, 0x66, 0xf, 0x50, 0xc0, 0xc0, + 0x23, 0xf, 0x50, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0x51, 0, 0, + 0x34, 0xf2, 0xf, 0x51, 0, 0, + 0x34, 0xf3, 0xf, 0x51, 0, 0, + 0x23, 0xf, 0x51, 0, 0, + 0x34, 0xf3, 0xf, 0x52, 0, 0, + 0x23, 0xf, 0x52, 0, 0, + 0x34, 0xf3, 0xf, 0x53, 0, 0, + 0x23, 0xf, 0x53, 0, 0, + 0x34, 0x66, 0xf, 0x54, 0, 0, + 0x23, 0xf, 0x54, 0, 0, + 0x34, 0x66, 0xf, 0x55, 0, 0, + 0x23, 0xf, 0x55, 0, 0, + 0x34, 0x66, 0xf, 0x56, 0, 0, + 0x23, 0xf, 0x56, 0, 0, + 0x34, 0x66, 0xf, 0x57, 0, 0, + 0x23, 0xf, 0x57, 0, 0, + 0x34, 0xf2, 0xf, 0x58, 0, 0, + 0x34, 0xf3, 0xf, 0x58, 0, 0, + 0x34, 0x66, 0xf, 0x58, 0, 0, + 0x23, 0xf, 0x58, 0, 0, + 0x34, 0xf2, 0xf, 0x59, 0, 0, + 0x34, 0xf3, 0xf, 0x59, 0, 0, + 0x34, 0x66, 0xf, 0x59, 0, 0, + 0x23, 0xf, 0x59, 0, 0, + 0x34, 0xf2, 0xf, 0x5a, 0, 0, + 0x34, 0xf3, 0xf, 0x5a, 0, 0, + 0x34, 0x66, 0xf, 0x5a, 0, 0, + 0x23, 0xf, 0x5a, 0, 0, + 0x34, 0x66, 0xf, 0x5b, 0, 0, + 0x34, 0xf3, 0xf, 0x5b, 0, 0, + 0x23, 0xf, 0x5b, 0, 0, + 0x34, 0xf2, 0xf, 0x5c, 0, 0, + 0x34, 0xf3, 0xf, 0x5c, 0, 0, + 0x34, 0x66, 0xf, 0x5c, 0, 0, + 0x23, 0xf, 0x5c, 0, 0, + 0x34, 0xf2, 0xf, 0x5d, 0, 0, + 0x34, 0xf3, 0xf, 0x5d, 0, 0, + 0x34, 0x66, 0xf, 0x5d, 0, 0, + 0x23, 0xf, 0x5d, 0, 0, + 0x34, 0xf2, 0xf, 0x5e, 0, 0, + 0x34, 0xf3, 0xf, 0x5e, 0, 0, + 0x34, 0x66, 0xf, 0x5e, 0, 0, + 0x23, 0xf, 0x5e, 0, 0, + 0x34, 0xf2, 0xf, 0x5f, 0, 0, + 0x34, 0xf3, 0xf, 0x5f, 0, 0, + 0x34, 0x66, 0xf, 0x5f, 0, 0, + 0x23, 0xf, 0x5f, 0, 0, + 0x34, 0x66, 0xf, 0x60, 0, 0, + 0x23, 0xf, 0x60, 0, 0, + 0x34, 0x66, 0xf, 0x61, 0, 0, + 0x23, 0xf, 0x61, 0, 0, + 0x34, 0x66, 0xf, 0x62, 0, 0, + 0x23, 0xf, 0x62, 0, 0, + 0x34, 0x66, 0xf, 0x63, 0, 0, + 0x23, 0xf, 0x63, 0, 0, + 0x34, 0x66, 0xf, 0x64, 0, 0, + 0x23, 0xf, 0x64, 0, 0, + 0x34, 0x66, 0xf, 0x65, 0, 0, + 0x23, 0xf, 0x65, 0, 0, + 0x34, 0x66, 0xf, 0x66, 0, 0, + 0x23, 0xf, 0x66, 0, 0, + 0x34, 0x66, 0xf, 0x67, 0, 0, + 0x23, 0xf, 0x67, 0, 0, + 0x34, 0x66, 0xf, 0x68, 0, 0, + 0x23, 0xf, 0x68, 0, 0, + 0x34, 0x66, 0xf, 0x69, 0, 0, + 0x23, 0xf, 0x69, 0, 0, + 0x34, 0x66, 0xf, 0x6a, 0, 0, + 0x23, 0xf, 0x6a, 0, 0, + 0x34, 0x66, 0xf, 0x6b, 0, 0, + 0x23, 0xf, 0x6b, 0, 0, + 0x34, 0x66, 0xf, 0x6c, 0, 0, + 0x34, 0x66, 0xf, 0x6d, 0, 0, + 0x34, 0x66, 0xf, 0x6e, 0, 0, + 0x23, 0xf, 0x6e, 0, 0, + 0x34, 0x66, 0xf, 0x6f, 0, 0, + 0x34, 0xf3, 0xf, 0x6f, 0, 0, + 0x23, 0xf, 0x6f, 0, 0, + 0x34, 0x66, 0xf, 0x70, 0, 0, + 0x34, 0xf2, 0xf, 0x70, 0, 0, + 0x34, 0xf3, 0xf, 0x70, 0, 0, + 0x23, 0xf, 0x70, 0, 0, + 0x34, 0x66, 0xf, 0x74, 0, 0, + 0x23, 0xf, 0x74, 0, 0, + 0x34, 0x66, 0xf, 0x75, 0, 0, + 0x23, 0xf, 0x75, 0, 0, + 0x34, 0x66, 0xf, 0x76, 0, 0, + 0x23, 0xf, 0x76, 0, 0, + 0x34, 0x66, 0xf, 0x7c, 0, 0, + 0x34, 0xf2, 0xf, 0x7c, 0, 0, + 0x34, 0x66, 0xf, 0x7d, 0, 0, + 0x34, 0xf2, 0xf, 0x7d, 0, 0, + 0x34, 0x66, 0xf, 0x7e, 0, 0, + 0x34, 0xf3, 0xf, 0x7e, 0, 0, + 0x23, 0xf, 0x7e, 0, 0, + 0x34, 0x66, 0xf, 0x7f, 0, 0, + 0x34, 0xf3, 0xf, 0x7f, 0, 0, + 0x23, 0xf, 0x7f, 0, 0, + 0x23, 0xf, 0xc3, 0, 0, + 0x34, 0x66, 0xf, 0xc4, 0, 0, + 0x23, 0xf, 0xc4, 0, 0, + 0x34, 0x66, 0xf, 0xc5, 0xc0, 0xc0, + 0x23, 0xf, 0xc5, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xc6, 0, 0, + 0x23, 0xf, 0xc6, 0, 0, + 0x34, 0x66, 0xf, 0xd1, 0, 0, + 0x23, 0xf, 0xd1, 0, 0, + 0x34, 0x66, 0xf, 0xd2, 0, 0, + 0x23, 0xf, 0xd2, 0, 0, + 0x34, 0x66, 0xf, 0xd3, 0, 0, + 0x23, 0xf, 0xd3, 0, 0, + 0x34, 0x66, 0xf, 0xd4, 0, 0, + 0x23, 0xf, 0xd4, 0, 0, + 0x34, 0x66, 0xf, 0xd5, 0, 0, + 0x23, 0xf, 0xd5, 0, 0, + 0x34, 0x66, 0xf, 0xd6, 0, 0, + 0x34, 0xf2, 0xf, 0xd6, 0xc0, 0xc0, + 0x34, 0xf3, 0xf, 0xd6, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xd7, 0xc0, 0xc0, + 0x23, 0xf, 0xd7, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xd8, 0, 0, + 0x23, 0xf, 0xd8, 0, 0, + 0x34, 0x66, 0xf, 0xd9, 0, 0, + 0x23, 0xf, 0xd9, 0, 0, + 0x34, 0x66, 0xf, 0xda, 0, 0, + 0x23, 0xf, 0xda, 0, 0, + 0x34, 0x66, 0xf, 0xdc, 0, 0, + 0x23, 0xf, 0xdc, 0, 0, + 0x34, 0x66, 0xf, 0xdd, 0, 0, + 0x23, 0xf, 0xdd, 0, 0, + 0x34, 0x66, 0xf, 0xde, 0, 0, + 0x23, 0xf, 0xde, 0, 0, + 0x34, 0x66, 0xf, 0xe0, 0, 0, + 0x23, 0xf, 0xe0, 0, 0, + 0x34, 0x66, 0xf, 0xe1, 0, 0, + 0x23, 0xf, 0xe1, 0, 0, + 0x34, 0x66, 0xf, 0xe2, 0, 0, + 0x23, 0xf, 0xe2, 0, 0, + 0x34, 0x66, 0xf, 0xe3, 0, 0, + 0x23, 0xf, 0xe3, 0, 0, + 0x34, 0x66, 0xf, 0xe4, 0, 0, + 0x23, 0xf, 0xe4, 0, 0, + 0x34, 0x66, 0xf, 0xe5, 0, 0, + 0x23, 0xf, 0xe5, 0, 0, + 0x34, 0x66, 0xf, 0xe7, 0, 0, + 0x23, 0xf, 0xe7, 0, 0, + 0x34, 0x66, 0xf, 0xe8, 0, 0, + 0x23, 0xf, 0xe8, 0, 0, + 0x34, 0x66, 0xf, 0xe9, 0, 0, + 0x23, 0xf, 0xe9, 0, 0, + 0x34, 0x66, 0xf, 0xea, 0, 0, + 0x23, 0xf, 0xea, 0, 0, + 0x34, 0x66, 0xf, 0xec, 0, 0, + 0x23, 0xf, 0xec, 0, 0, + 0x34, 0x66, 0xf, 0xed, 0, 0, + 0x23, 0xf, 0xed, 0, 0, + 0x34, 0x66, 0xf, 0xee, 0, 0, + 0x23, 0xf, 0xee, 0, 0, + 0x34, 0xf2, 0xf, 0xf0, 0, 0, + 0x34, 0x66, 0xf, 0xf1, 0, 0, + 0x23, 0xf, 0xf1, 0, 0, + 0x34, 0x66, 0xf, 0xf2, 0, 0, + 0x23, 0xf, 0xf2, 0, 0, + 0x34, 0x66, 0xf, 0xf3, 0, 0, + 0x23, 0xf, 0xf3, 0, 0, + 0x34, 0x66, 0xf, 0xf4, 0, 0, + 0x23, 0xf, 0xf4, 0, 0, + 0x34, 0x66, 0xf, 0xf6, 0, 0, + 0x23, 0xf, 0xf6, 0, 0, + 0x34, 0x66, 0xf, 0xf7, 0xc0, 0xc0, + 0x23, 0xf, 0xf7, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xf8, 0, 0, + 0x23, 0xf, 0xf8, 0, 0, + 0x34, 0x66, 0xf, 0xf9, 0, 0, + 0x23, 0xf, 0xf9, 0, 0, + 0x34, 0x66, 0xf, 0xfa, 0, 0, + 0x23, 0xf, 0xfa, 0, 0, + 0x34, 0x66, 0xf, 0xfb, 0, 0, + 0x23, 0xf, 0xfb, 0, 0, + 0x34, 0x66, 0xf, 0xfc, 0, 0, + 0x23, 0xf, 0xfc, 0, 0, + 0x34, 0x66, 0xf, 0xfd, 0, 0, + 0x23, 0xf, 0xfd, 0, 0, + 0x34, 0x66, 0xf, 0xfe, 0, 0, + 0x23, 0xf, 0xfe, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0, 0, 0, + 0x34, 0xf, 0x38, 0, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1, 0, 0, + 0x34, 0xf, 0x38, 0x1, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x2, 0, 0, + 0x34, 0xf, 0x38, 0x2, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3, 0, 0, + 0x34, 0xf, 0x38, 0x3, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x4, 0, 0, + 0x34, 0xf, 0x38, 0x4, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x5, 0, 0, + 0x34, 0xf, 0x38, 0x5, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x6, 0, 0, + 0x34, 0xf, 0x38, 0x6, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x7, 0, 0, + 0x34, 0xf, 0x38, 0x7, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x8, 0, 0, + 0x34, 0xf, 0x38, 0x8, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x9, 0, 0, + 0x34, 0xf, 0x38, 0x9, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0xa, 0, 0, + 0x34, 0xf, 0x38, 0xa, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0xb, 0, 0, + 0x34, 0xf, 0x38, 0xb, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1c, 0, 0, + 0x34, 0xf, 0x38, 0x1c, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1d, 0, 0, + 0x34, 0xf, 0x38, 0x1d, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1e, 0, 0, + 0x34, 0xf, 0x38, 0x1e, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xf, 0, 0, + 0x34, 0xf, 0x3a, 0xf, 0, 0, + 0x34, 0x66, 0xf, 0xc7, 0x38, 0x30, + 0x34, 0xf3, 0xf, 0xc7, 0x38, 0x30, + 0x23, 0xf, 0xc7, 0x38, 0x30, + 0x23, 0xf, 0xc7, 0x38, 0x38, + 0x34, 0x66, 0xf, 0x71, 0xf8, 0xd0, + 0x23, 0xf, 0x71, 0xf8, 0xd0, + 0x34, 0x66, 0xf, 0x71, 0xf8, 0xe0, + 0x23, 0xf, 0x71, 0xf8, 0xe0, + 0x34, 0x66, 0xf, 0x71, 0xf8, 0xf0, + 0x23, 0xf, 0x71, 0xf8, 0xf0, + 0x34, 0x66, 0xf, 0x72, 0xf8, 0xd0, + 0x23, 0xf, 0x72, 0xf8, 0xd0, + 0x34, 0x66, 0xf, 0x72, 0xf8, 0xe0, + 0x23, 0xf, 0x72, 0xf8, 0xe0, + 0x34, 0x66, 0xf, 0x72, 0xf8, 0xf0, + 0x23, 0xf, 0x72, 0xf8, 0xf0, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xd0, + 0x23, 0xf, 0x73, 0xf8, 0xd0, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xd8, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xf0, + 0x23, 0xf, 0x73, 0xf8, 0xf0, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xf8, + 0x33, 0xf, 0xae, 0xe8, + 0x33, 0xf, 0xae, 0xf0, + 0x33, 0xf, 0xae, 0xf8, + 0x23, 0xf, 0xae, 0x38, 0x38, + 0x23, 0xf, 0xf, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xc, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xd, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x14, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x15, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x40, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x41, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x21, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x2a, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x42, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x2b, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x10, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xe, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x29, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x61, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x60, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x63, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x62, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x37, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x41, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x20, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x22, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3c, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3d, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3f, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3e, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x38, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x39, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3b, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3a, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x20, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x21, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x22, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x23, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x24, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x25, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x30, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x31, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x32, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x33, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x34, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x35, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x28, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x40, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x17, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x8, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x9, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xa, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xb, 0, 0, + 0x1, 0xe7, 0x7, +}; diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c new file mode 100644 index 00000000..fd7340cc --- /dev/null +++ b/libcpu/i386_disasm.c @@ -0,0 +1,1156 @@ +/* Disassembler for x86. + Copyright (C) 2007, 2008, 2009, 2011 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../libebl/libeblP.h" + +#define MACHINE_ENCODING __LITTLE_ENDIAN +#include "memory-access.h" + + +#ifndef MNEFILE +# define MNEFILE "i386.mnemonics" +#endif + +#define MNESTRFIELD(line) MNESTRFIELD1 (line) +#define MNESTRFIELD1(line) str##line +static const union mnestr_t +{ + struct + { +#define MNE(name) char MNESTRFIELD (__LINE__)[sizeof (#name)]; +#include MNEFILE +#undef MNE + }; + char str[0]; +} mnestr = + { + { +#define MNE(name) #name, +#include MNEFILE +#undef MNE + } + }; + +/* The index can be stored in the instrtab. */ +enum + { +#define MNE(name) MNE_##name, +#include MNEFILE +#undef MNE + MNE_INVALID + }; + +static const unsigned short int mneidx[] = + { +#define MNE(name) \ + [MNE_##name] = offsetof (union mnestr_t, MNESTRFIELD (__LINE__)), +#include MNEFILE +#undef MNE + }; + + +enum + { + idx_rex_b = 0, + idx_rex_x, + idx_rex_r, + idx_rex_w, + idx_rex, + idx_cs, + idx_ds, + idx_es, + idx_fs, + idx_gs, + idx_ss, + idx_data16, + idx_addr16, + idx_rep, + idx_repne, + idx_lock + }; + +enum + { +#define prefbit(pref) has_##pref = 1 << idx_##pref + prefbit (rex_b), + prefbit (rex_x), + prefbit (rex_r), + prefbit (rex_w), + prefbit (rex), + prefbit (cs), + prefbit (ds), + prefbit (es), + prefbit (fs), + prefbit (gs), + prefbit (ss), + prefbit (data16), + prefbit (addr16), + prefbit (rep), + prefbit (repne), + prefbit (lock) +#undef prefbit + }; +#define SEGMENT_PREFIXES \ + (has_cs | has_ds | has_es | has_fs | has_gs | has_ss) + +#define prefix_cs 0x2e +#define prefix_ds 0x3e +#define prefix_es 0x26 +#define prefix_fs 0x64 +#define prefix_gs 0x65 +#define prefix_ss 0x36 +#define prefix_data16 0x66 +#define prefix_addr16 0x67 +#define prefix_rep 0xf3 +#define prefix_repne 0xf2 +#define prefix_lock 0xf0 + + +static const uint8_t known_prefixes[] = + { +#define newpref(pref) [idx_##pref] = prefix_##pref + newpref (cs), + newpref (ds), + newpref (es), + newpref (fs), + newpref (gs), + newpref (ss), + newpref (data16), + newpref (addr16), + newpref (rep), + newpref (repne), + newpref (lock) +#undef newpref + }; +#define nknown_prefixes (sizeof (known_prefixes) / sizeof (known_prefixes[0])) + + +#if 0 +static const char *prefix_str[] = + { +#define newpref(pref) [idx_##pref] = #pref + newpref (cs), + newpref (ds), + newpref (es), + newpref (fs), + newpref (gs), + newpref (ss), + newpref (data16), + newpref (addr16), + newpref (rep), + newpref (repne), + newpref (lock) +#undef newpref + }; +#endif + + +static const char amd3dnowstr[] = +#define MNE_3DNOW_PAVGUSB 1 + "pavgusb\0" +#define MNE_3DNOW_PFADD (MNE_3DNOW_PAVGUSB + 8) + "pfadd\0" +#define MNE_3DNOW_PFSUB (MNE_3DNOW_PFADD + 6) + "pfsub\0" +#define MNE_3DNOW_PFSUBR (MNE_3DNOW_PFSUB + 6) + "pfsubr\0" +#define MNE_3DNOW_PFACC (MNE_3DNOW_PFSUBR + 7) + "pfacc\0" +#define MNE_3DNOW_PFCMPGE (MNE_3DNOW_PFACC + 6) + "pfcmpge\0" +#define MNE_3DNOW_PFCMPGT (MNE_3DNOW_PFCMPGE + 8) + "pfcmpgt\0" +#define MNE_3DNOW_PFCMPEQ (MNE_3DNOW_PFCMPGT + 8) + "pfcmpeq\0" +#define MNE_3DNOW_PFMIN (MNE_3DNOW_PFCMPEQ + 8) + "pfmin\0" +#define MNE_3DNOW_PFMAX (MNE_3DNOW_PFMIN + 6) + "pfmax\0" +#define MNE_3DNOW_PI2FD (MNE_3DNOW_PFMAX + 6) + "pi2fd\0" +#define MNE_3DNOW_PF2ID (MNE_3DNOW_PI2FD + 6) + "pf2id\0" +#define MNE_3DNOW_PFRCP (MNE_3DNOW_PF2ID + 6) + "pfrcp\0" +#define MNE_3DNOW_PFRSQRT (MNE_3DNOW_PFRCP + 6) + "pfrsqrt\0" +#define MNE_3DNOW_PFMUL (MNE_3DNOW_PFRSQRT + 8) + "pfmul\0" +#define MNE_3DNOW_PFRCPIT1 (MNE_3DNOW_PFMUL + 6) + "pfrcpit1\0" +#define MNE_3DNOW_PFRSQIT1 (MNE_3DNOW_PFRCPIT1 + 9) + "pfrsqit1\0" +#define MNE_3DNOW_PFRCPIT2 (MNE_3DNOW_PFRSQIT1 + 9) + "pfrcpit2\0" +#define MNE_3DNOW_PMULHRW (MNE_3DNOW_PFRCPIT2 + 9) + "pmulhrw"; + +#define AMD3DNOW_LOW_IDX 0x0d +#define AMD3DNOW_HIGH_IDX (sizeof (amd3dnow) + AMD3DNOW_LOW_IDX - 1) +#define AMD3DNOW_IDX(val) ((val) - AMD3DNOW_LOW_IDX) +static const unsigned char amd3dnow[] = + { + [AMD3DNOW_IDX (0xbf)] = MNE_3DNOW_PAVGUSB, + [AMD3DNOW_IDX (0x9e)] = MNE_3DNOW_PFADD, + [AMD3DNOW_IDX (0x9a)] = MNE_3DNOW_PFSUB, + [AMD3DNOW_IDX (0xaa)] = MNE_3DNOW_PFSUBR, + [AMD3DNOW_IDX (0xae)] = MNE_3DNOW_PFACC, + [AMD3DNOW_IDX (0x90)] = MNE_3DNOW_PFCMPGE, + [AMD3DNOW_IDX (0xa0)] = MNE_3DNOW_PFCMPGT, + [AMD3DNOW_IDX (0xb0)] = MNE_3DNOW_PFCMPEQ, + [AMD3DNOW_IDX (0x94)] = MNE_3DNOW_PFMIN, + [AMD3DNOW_IDX (0xa4)] = MNE_3DNOW_PFMAX, + [AMD3DNOW_IDX (0x0d)] = MNE_3DNOW_PI2FD, + [AMD3DNOW_IDX (0x1d)] = MNE_3DNOW_PF2ID, + [AMD3DNOW_IDX (0x96)] = MNE_3DNOW_PFRCP, + [AMD3DNOW_IDX (0x97)] = MNE_3DNOW_PFRSQRT, + [AMD3DNOW_IDX (0xb4)] = MNE_3DNOW_PFMUL, + [AMD3DNOW_IDX (0xa6)] = MNE_3DNOW_PFRCPIT1, + [AMD3DNOW_IDX (0xa7)] = MNE_3DNOW_PFRSQIT1, + [AMD3DNOW_IDX (0xb6)] = MNE_3DNOW_PFRCPIT2, + [AMD3DNOW_IDX (0xb7)] = MNE_3DNOW_PMULHRW + }; + + +struct output_data +{ + GElf_Addr addr; + int *prefixes; + size_t opoff1; + size_t opoff2; + size_t opoff3; + char *bufp; + size_t *bufcntp; + size_t bufsize; + const uint8_t *data; + const uint8_t **param_start; + const uint8_t *end; + char *labelbuf; + size_t labelbufsize; + enum + { + addr_none = 0, + addr_abs_symbolic, + addr_abs_always, + addr_rel_symbolic, + addr_rel_always + } symaddr_use; + GElf_Addr symaddr; +}; + + +#ifndef DISFILE +# define DISFILE "i386_dis.h" +#endif +#include DISFILE + + +#define ADD_CHAR(ch) \ + do { \ + if (unlikely (bufcnt == bufsize)) \ + goto enomem; \ + buf[bufcnt++] = (ch); \ + } while (0) + +#define ADD_STRING(str) \ + do { \ + const char *_str0 = (str); \ + size_t _len0 = strlen (_str0); \ + ADD_NSTRING (_str0, _len0); \ + } while (0) + +#define ADD_NSTRING(str, len) \ + do { \ + const char *_str = (str); \ + size_t _len = (len); \ + if (unlikely (bufcnt + _len > bufsize)) \ + goto enomem; \ + memcpy (buf + bufcnt, _str, _len); \ + bufcnt += _len; \ + } while (0) + + +int +i386_disasm (Ebl *ebl __attribute__((unused)), + const uint8_t **startp, const uint8_t *end, GElf_Addr addr, + const char *fmt, DisasmOutputCB_t outcb, DisasmGetSymCB_t symcb, + void *outcbarg, void *symcbarg) +{ + const char *save_fmt = fmt; + +#define BUFSIZE 512 + char initbuf[BUFSIZE]; + int prefixes; + size_t bufcnt; + size_t bufsize = BUFSIZE; + char *buf = initbuf; + const uint8_t *param_start; + + struct output_data output_data = + { + .prefixes = &prefixes, + .bufp = buf, + .bufsize = bufsize, + .bufcntp = &bufcnt, + .param_start = ¶m_start, + .end = end + }; + + int retval = 0; + while (1) + { + prefixes = 0; + + const uint8_t *data = *startp; + const uint8_t *begin = data; + + /* Recognize all prefixes. */ + int last_prefix_bit = 0; + while (data < end) + { + unsigned int i; + for (i = idx_cs; i < nknown_prefixes; ++i) + if (known_prefixes[i] == *data) + break; + if (i == nknown_prefixes) + break; + + prefixes |= last_prefix_bit = 1 << i; + + ++data; + } + +#ifdef X86_64 + if (data < end && (*data & 0xf0) == 0x40) + prefixes |= ((*data++) & 0xf) | has_rex; +#endif + + bufcnt = 0; + size_t cnt = 0; + + const uint8_t *curr = match_data; + const uint8_t *const match_end = match_data + sizeof (match_data); + + assert (data <= end); + if (data == end) + { + if (prefixes != 0) + goto print_prefix; + + retval = -1; + goto do_ret; + } + + next_match: + while (curr < match_end) + { + uint_fast8_t len = *curr++; + uint_fast8_t clen = len >> 4; + len &= 0xf; + const uint8_t *next_curr = curr + clen + (len - clen) * 2; + + assert (len > 0); + assert (curr + clen + 2 * (len - clen) <= match_end); + + const uint8_t *codep = data; + int correct_prefix = 0; + int opoff = 0; + + if (data > begin && codep[-1] == *curr && clen > 0) + { + /* We match a prefix byte. This is exactly one byte and + is matched exactly, without a mask. */ + --len; + --clen; + opoff = 8; + + ++curr; + + if (last_prefix_bit == 0) + goto invalid_op; + correct_prefix = last_prefix_bit; + } + + size_t avail = len; + while (clen > 0) + { + if (*codep++ != *curr++) + goto not; + --avail; + --clen; + if (codep == end && avail > 0) + goto do_ret; + } + + while (avail > 0) + { + uint_fast8_t masked = *codep++ & *curr++; + if (masked != *curr++) + { + not: + curr = next_curr; + ++cnt; + bufcnt = 0; + goto next_match; + } + + --avail; + if (codep == end && avail > 0) + goto do_ret; + } + + if (len > end - data) + /* There is not enough data for the entire instruction. The + caller can figure this out by looking at the pointer into + the input data. */ + goto do_ret; + + if (correct_prefix != 0 && (prefixes & correct_prefix) == 0) + goto invalid_op; + prefixes ^= correct_prefix; + + if (0) + { + /* Resize the buffer. */ + char *oldbuf; + enomem: + oldbuf = buf; + if (buf == initbuf) + buf = malloc (2 * bufsize); + else + buf = realloc (buf, 2 * bufsize); + if (buf == NULL) + { + buf = oldbuf; + retval = ENOMEM; + goto do_ret; + } + bufsize *= 2; + + output_data.bufp = buf; + output_data.bufsize = bufsize; + bufcnt = 0; + + if (data == end) + { + if (prefixes == 0) + goto invalid_op; + goto print_prefix; + } + + /* gcc is not clever enough to see the following variables + are not used uninitialized. */ + asm ("" + : "=mr" (opoff), "=mr" (correct_prefix), "=mr" (codep), + "=mr" (next_curr), "=mr" (len)); + } + + size_t prefix_size = 0; + + // XXXonly print as prefix if valid? + if ((prefixes & has_lock) != 0) + { + ADD_STRING ("lock "); + prefix_size += 5; + } + + if (instrtab[cnt].rep) + { + if ((prefixes & has_rep) != 0) + { + ADD_STRING ("rep "); + prefix_size += 4; + } + } + else if (instrtab[cnt].repe + && (prefixes & (has_rep | has_repne)) != 0) + { + if ((prefixes & has_repne) != 0) + { + ADD_STRING ("repne "); + prefix_size += 6; + } + else if ((prefixes & has_rep) != 0) + { + ADD_STRING ("repe "); + prefix_size += 5; + } + } + else if ((prefixes & (has_rep | has_repne)) != 0) + { + uint_fast8_t byte; + print_prefix: + bufcnt = 0; + byte = *begin; + /* This is a prefix byte. Print it. */ + switch (byte) + { + case prefix_rep: + ADD_STRING ("rep"); + break; + case prefix_repne: + ADD_STRING ("repne"); + break; + case prefix_cs: + ADD_STRING ("cs"); + break; + case prefix_ds: + ADD_STRING ("ds"); + break; + case prefix_es: + ADD_STRING ("es"); + break; + case prefix_fs: + ADD_STRING ("fs"); + break; + case prefix_gs: + ADD_STRING ("gs"); + break; + case prefix_ss: + ADD_STRING ("ss"); + break; + case prefix_data16: + ADD_STRING ("data16"); + break; + case prefix_addr16: + ADD_STRING ("addr16"); + break; + case prefix_lock: + ADD_STRING ("lock"); + break; +#ifdef X86_64 + case 0x40 ... 0x4f: + ADD_STRING ("rex"); + if (byte != 0x40) + { + ADD_CHAR ('.'); + if (byte & 0x8) + ADD_CHAR ('w'); + if (byte & 0x4) + ADD_CHAR ('r'); + if (byte & 0x3) + ADD_CHAR ('x'); + if (byte & 0x1) + ADD_CHAR ('b'); + } + break; +#endif + default: + /* Cannot happen. */ + puts ("unknown prefix"); + abort (); + } + data = begin + 1; + ++addr; + + goto out; + } + + /* We have a match. First determine how many bytes are + needed for the addressing mode. */ + param_start = codep; + if (instrtab[cnt].modrm) + { + uint_fast8_t modrm = codep[-1]; + +#ifndef X86_64 + if (likely ((prefixes & has_addr16) != 0)) + { + /* Account for displacement. */ + if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80) + param_start += 2; + else if ((modrm & 0xc0) == 0x40) + param_start += 1; + } + else +#endif + { + /* Account for SIB. */ + if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 0x4) + param_start += 1; + + /* Account for displacement. */ + if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80 + || ((modrm & 0xc7) == 0x4 + && param_start < end + && (codep[0] & 0x7) == 0x5)) + param_start += 4; + else if ((modrm & 0xc0) == 0x40) + param_start += 1; + } + + if (unlikely (param_start > end)) + goto not; + } + + output_data.addr = addr + (data - begin); + output_data.data = data; + + unsigned long string_end_idx = 0; + fmt = save_fmt; + const char *deferred_start = NULL; + size_t deferred_len = 0; + // XXX Can we get this from color.c? + static const char color_off[] = "\e[0m"; + while (*fmt != '\0') + { + if (*fmt != '%') + { + char ch = *fmt++; + if (ch == '\\') + { + switch ((ch = *fmt++)) + { + case '0' ... '7': + { + int val = ch - '0'; + ch = *fmt; + if (ch >= '0' && ch <= '7') + { + val *= 8; + val += ch - '0'; + ch = *++fmt; + if (ch >= '0' && ch <= '7' && val < 32) + { + val *= 8; + val += ch - '0'; + ++fmt; + } + } + ch = val; + } + break; + + case 'n': + ch = '\n'; + break; + + case 't': + ch = '\t'; + break; + + default: + retval = EINVAL; + goto do_ret; + } + } + else if (ch == '\e' && *fmt == '[') + { + deferred_start = fmt - 1; + do + ++fmt; + while (*fmt != 'm' && *fmt != '\0'); + + if (*fmt == 'm') + { + deferred_len = ++fmt - deferred_start; + continue; + } + + fmt = deferred_start + 1; + deferred_start = NULL; + } + ADD_CHAR (ch); + continue; + } + ++fmt; + + int width = 0; + while (isdigit (*fmt)) + width = width * 10 + (*fmt++ - '0'); + + int prec = 0; + if (*fmt == '.') + while (isdigit (*++fmt)) + prec = prec * 10 + (*fmt - '0'); + + size_t start_idx = bufcnt; + size_t non_printing = 0; + switch (*fmt++) + { + char mnebuf[16]; + const char *str; + + case 'm': + /* Mnemonic. */ + + if (unlikely (instrtab[cnt].mnemonic == MNE_INVALID)) + { + switch (*data) + { +#ifdef X86_64 + case 0x90: + if (prefixes & has_rex_b) + goto not; + str = "nop"; + break; +#endif + + case 0x98: +#ifdef X86_64 + if (prefixes == (has_rex_w | has_rex)) + { + str = "cltq"; + break; + } +#endif + if (prefixes & ~has_data16) + goto print_prefix; + str = prefixes & has_data16 ? "cbtw" : "cwtl"; + break; + + case 0x99: +#ifdef X86_64 + if (prefixes == (has_rex_w | has_rex)) + { + str = "cqto"; + break; + } +#endif + if (prefixes & ~has_data16) + goto print_prefix; + str = prefixes & has_data16 ? "cwtd" : "cltd"; + break; + + case 0xe3: + if (prefixes & ~has_addr16) + goto print_prefix; +#ifdef X86_64 + str = prefixes & has_addr16 ? "jecxz" : "jrcxz"; +#else + str = prefixes & has_addr16 ? "jcxz" : "jecxz"; +#endif + break; + + case 0x0f: + if (data[1] == 0x0f) + { + /* AMD 3DNOW. We need one more byte. */ + if (param_start >= end) + goto not; + if (*param_start < AMD3DNOW_LOW_IDX + || *param_start > AMD3DNOW_HIGH_IDX) + goto not; + unsigned int idx + = amd3dnow[AMD3DNOW_IDX (*param_start)]; + if (idx == 0) + goto not; + str = amd3dnowstr + idx - 1; + /* Eat the immediate byte indicating the + operation. */ + ++param_start; + break; + } +#ifdef X86_64 + if (data[1] == 0xc7) + { + str = ((prefixes & has_rex_w) + ? "cmpxchg16b" : "cmpxchg8b"); + break; + } +#endif + if (data[1] == 0xc2) + { + if (param_start >= end) + goto not; + if (*param_start > 7) + goto not; + static const char cmpops[][9] = + { + [0] = "cmpeq", + [1] = "cmplt", + [2] = "cmple", + [3] = "cmpunord", + [4] = "cmpneq", + [5] = "cmpnlt", + [6] = "cmpnle", + [7] = "cmpord" + }; + char *cp = stpcpy (mnebuf, cmpops[*param_start]); + if (correct_prefix & (has_rep | has_repne)) + *cp++ = 's'; + else + *cp++ = 'p'; + if (correct_prefix & (has_data16 | has_repne)) + *cp++ = 'd'; + else + *cp++ = 's'; + *cp = '\0'; + str = mnebuf; + /* Eat the immediate byte indicating the + operation. */ + ++param_start; + break; + } + FALLTHROUGH; + default: + str = "INVALID not handled"; + break; + } + } + else + str = mnestr.str + mneidx[instrtab[cnt].mnemonic]; + + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + ADD_STRING (str); + + switch (instrtab[cnt].suffix) + { + case suffix_none: + break; + + case suffix_w: + if ((codep[-1] & 0xc0) != 0xc0) + { + char ch; + + if (data[0] & 1) + { + if (prefixes & has_data16) + ch = 'w'; +#ifdef X86_64 + else if (prefixes & has_rex_w) + ch = 'q'; +#endif + else + ch = 'l'; + } + else + ch = 'b'; + + ADD_CHAR (ch); + } + break; + + case suffix_w0: + if ((codep[-1] & 0xc0) != 0xc0) + ADD_CHAR ('l'); + break; + + case suffix_w1: + if ((data[0] & 0x4) == 0) + ADD_CHAR ('l'); + break; + + case suffix_W: + if (prefixes & has_data16) + { + ADD_CHAR ('w'); + prefixes &= ~has_data16; + } +#ifdef X86_64 + else + ADD_CHAR ('q'); +#endif + break; + + case suffix_W1: + if (prefixes & has_data16) + { + ADD_CHAR ('w'); + prefixes &= ~has_data16; + } +#ifdef X86_64 + else if (prefixes & has_rex_w) + ADD_CHAR ('q'); +#endif + break; + + case suffix_tttn:; + static const char tttn[16][3] = + { + "o", "no", "b", "ae", "e", "ne", "be", "a", + "s", "ns", "p", "np", "l", "ge", "le", "g" + }; + ADD_STRING (tttn[codep[-1 - instrtab[cnt].modrm] & 0x0f]); + break; + + case suffix_D: + if ((codep[-1] & 0xc0) != 0xc0) + ADD_CHAR ((data[0] & 0x04) == 0 ? 's' : 'l'); + break; + + default: + printf("unknown suffix %d\n", instrtab[cnt].suffix); + abort (); + } + + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + + string_end_idx = bufcnt; + break; + + case 'o': + if (prec == 1 && instrtab[cnt].fct1 != 0) + { + /* First parameter. */ + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + if (instrtab[cnt].str1 != 0) + ADD_STRING (op1_str + + op1_str_idx[instrtab[cnt].str1 - 1]); + + output_data.opoff1 = (instrtab[cnt].off1_1 + + OFF1_1_BIAS - opoff); + output_data.opoff2 = (instrtab[cnt].off1_2 + + OFF1_2_BIAS - opoff); + output_data.opoff3 = (instrtab[cnt].off1_3 + + OFF1_3_BIAS - opoff); + int r = op1_fct[instrtab[cnt].fct1] (&output_data); + if (r < 0) + goto not; + if (r > 0) + goto enomem; + + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + + string_end_idx = bufcnt; + } + else if (prec == 2 && instrtab[cnt].fct2 != 0) + { + /* Second parameter. */ + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + if (instrtab[cnt].str2 != 0) + ADD_STRING (op2_str + + op2_str_idx[instrtab[cnt].str2 - 1]); + + output_data.opoff1 = (instrtab[cnt].off2_1 + + OFF2_1_BIAS - opoff); + output_data.opoff2 = (instrtab[cnt].off2_2 + + OFF2_2_BIAS - opoff); + output_data.opoff3 = (instrtab[cnt].off2_3 + + OFF2_3_BIAS - opoff); + int r = op2_fct[instrtab[cnt].fct2] (&output_data); + if (r < 0) + goto not; + if (r > 0) + goto enomem; + + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + + string_end_idx = bufcnt; + } + else if (prec == 3 && instrtab[cnt].fct3 != 0) + { + /* Third parameter. */ + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + if (instrtab[cnt].str3 != 0) + ADD_STRING (op3_str + + op3_str_idx[instrtab[cnt].str3 - 1]); + + output_data.opoff1 = (instrtab[cnt].off3_1 + + OFF3_1_BIAS - opoff); + output_data.opoff2 = (instrtab[cnt].off3_2 + + OFF3_2_BIAS - opoff); +#ifdef OFF3_3_BITS + output_data.opoff3 = (instrtab[cnt].off3_3 + + OFF3_3_BIAS - opoff); +#else + output_data.opoff3 = 0; +#endif + int r = op3_fct[instrtab[cnt].fct3] (&output_data); + if (r < 0) + goto not; + if (r > 0) + goto enomem; + + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + + string_end_idx = bufcnt; + } + else + start_idx = bufcnt = string_end_idx; + break; + + case 'e': + string_end_idx = bufcnt; + break; + + case 'a': + /* Pad to requested column. */ + while (bufcnt - non_printing < (size_t) width) + ADD_CHAR (' '); + width = 0; + break; + + case 'l': + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + if (output_data.labelbuf != NULL + && output_data.labelbuf[0] != '\0') + { + ADD_STRING (output_data.labelbuf); + output_data.labelbuf[0] = '\0'; + string_end_idx = bufcnt; + } + else if (output_data.symaddr_use != addr_none) + { + GElf_Addr symaddr = output_data.symaddr; + if (output_data.symaddr_use >= addr_rel_symbolic) + symaddr += addr + param_start - begin; + + // XXX Lookup symbol based on symaddr + const char *symstr = NULL; + if (symcb != NULL + && symcb (0 /* XXX */, 0 /* XXX */, symaddr, + &output_data.labelbuf, + &output_data.labelbufsize, symcbarg) == 0) + symstr = output_data.labelbuf; + + size_t bufavail = bufsize - bufcnt; + int r = 0; + if (symstr != NULL) + r = snprintf (&buf[bufcnt], bufavail, "# <%s>", + symstr); + else if (output_data.symaddr_use == addr_abs_always + || output_data.symaddr_use == addr_rel_always) + r = snprintf (&buf[bufcnt], bufavail, "# %#" PRIx64, + (uint64_t) symaddr); + + assert (r >= 0); + if ((size_t) r >= bufavail) + goto enomem; + bufcnt += r; + string_end_idx = bufcnt; + + output_data.symaddr_use = addr_none; + } + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + break; + + default: + abort (); + } + + deferred_start = NULL; + + /* Pad according to the specified width. */ + while (bufcnt + prefix_size - non_printing < start_idx + width) + ADD_CHAR (' '); + prefix_size = 0; + } + + if ((prefixes & SEGMENT_PREFIXES) != 0) + goto print_prefix; + + assert (string_end_idx != ~0ul); + bufcnt = string_end_idx; + + addr += param_start - begin; + data = param_start; + + goto out; + } + + /* Invalid (or at least unhandled) opcode. */ + invalid_op: + if (prefixes != 0) + goto print_prefix; + /* Make sure we get past the unrecognized opcode if we haven't yet. */ + if (*startp == data) + ++data; + ADD_STRING ("(bad)"); + addr += data - begin; + + out: + if (bufcnt == bufsize) + goto enomem; + buf[bufcnt] = '\0'; + + *startp = data; + retval = outcb (buf, bufcnt, outcbarg); + if (retval != 0) + goto do_ret; + } + + do_ret: + free (output_data.labelbuf); + if (buf != initbuf) + free (buf); + + return retval; +} diff --git a/libcpu/i386_gendis.c b/libcpu/i386_gendis.c new file mode 100644 index 00000000..37d2ecd6 --- /dev/null +++ b/libcpu/i386_gendis.c @@ -0,0 +1,71 @@ +/* Generate tables for x86 disassembler. + Copyright (C) 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include "system.h" + +extern int i386_parse (void); + + +extern FILE *i386_in; +extern int i386_debug; +char *infname; + +FILE *outfile; + +int +main (int argc, char *argv[argc]) +{ + outfile = stdout; + + if (argc == 1) + error (EXIT_FAILURE, 0, "usage: %s ", argv[0]); + + //i386_debug = 1; + infname = argv[1]; + if (strcmp (infname, "-") == 0) + i386_in = stdin; + else + { + i386_in = fopen (infname, "r"); + if (i386_in == NULL) + error (EXIT_FAILURE, errno, "cannot open %s", argv[1]); + } + + i386_parse (); + + return error_message_count != 0; +} diff --git a/libcpu/i386_lex.c b/libcpu/i386_lex.c new file mode 100644 index 00000000..88da750a --- /dev/null +++ b/libcpu/i386_lex.c @@ -0,0 +1,2272 @@ + +#line 3 "i386_lex.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer i386__create_buffer +#define yy_delete_buffer i386__delete_buffer +#define yy_scan_buffer i386__scan_buffer +#define yy_scan_string i386__scan_string +#define yy_scan_bytes i386__scan_bytes +#define yy_init_buffer i386__init_buffer +#define yy_flush_buffer i386__flush_buffer +#define yy_load_buffer_state i386__load_buffer_state +#define yy_switch_to_buffer i386__switch_to_buffer +#define yypush_buffer_state i386_push_buffer_state +#define yypop_buffer_state i386_pop_buffer_state +#define yyensure_buffer_stack i386_ensure_buffer_stack +#define yy_flex_debug i386__flex_debug +#define yyin i386_in +#define yyleng i386_leng +#define yylex i386_lex +#define yylineno i386_lineno +#define yyout i386_out +#define yyrestart i386_restart +#define yytext i386_text +#define yywrap i386_wrap +#define yyalloc i386_alloc +#define yyrealloc i386_realloc +#define yyfree i386_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define i386__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer i386__create_buffer +#endif + +#ifdef yy_delete_buffer +#define i386__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer i386__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define i386__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer i386__scan_buffer +#endif + +#ifdef yy_scan_string +#define i386__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string i386__scan_string +#endif + +#ifdef yy_scan_bytes +#define i386__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes i386__scan_bytes +#endif + +#ifdef yy_init_buffer +#define i386__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer i386__init_buffer +#endif + +#ifdef yy_flush_buffer +#define i386__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer i386__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define i386__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state i386__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define i386__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer i386__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define i386_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state i386_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define i386_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state i386_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define i386_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack i386_ensure_buffer_stack +#endif + +#ifdef yylex +#define i386_lex_ALREADY_DEFINED +#else +#define yylex i386_lex +#endif + +#ifdef yyrestart +#define i386_restart_ALREADY_DEFINED +#else +#define yyrestart i386_restart +#endif + +#ifdef yylex_init +#define i386_lex_init_ALREADY_DEFINED +#else +#define yylex_init i386_lex_init +#endif + +#ifdef yylex_init_extra +#define i386_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra i386_lex_init_extra +#endif + +#ifdef yylex_destroy +#define i386_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy i386_lex_destroy +#endif + +#ifdef yyget_debug +#define i386_get_debug_ALREADY_DEFINED +#else +#define yyget_debug i386_get_debug +#endif + +#ifdef yyset_debug +#define i386_set_debug_ALREADY_DEFINED +#else +#define yyset_debug i386_set_debug +#endif + +#ifdef yyget_extra +#define i386_get_extra_ALREADY_DEFINED +#else +#define yyget_extra i386_get_extra +#endif + +#ifdef yyset_extra +#define i386_set_extra_ALREADY_DEFINED +#else +#define yyset_extra i386_set_extra +#endif + +#ifdef yyget_in +#define i386_get_in_ALREADY_DEFINED +#else +#define yyget_in i386_get_in +#endif + +#ifdef yyset_in +#define i386_set_in_ALREADY_DEFINED +#else +#define yyset_in i386_set_in +#endif + +#ifdef yyget_out +#define i386_get_out_ALREADY_DEFINED +#else +#define yyget_out i386_get_out +#endif + +#ifdef yyset_out +#define i386_set_out_ALREADY_DEFINED +#else +#define yyset_out i386_set_out +#endif + +#ifdef yyget_leng +#define i386_get_leng_ALREADY_DEFINED +#else +#define yyget_leng i386_get_leng +#endif + +#ifdef yyget_text +#define i386_get_text_ALREADY_DEFINED +#else +#define yyget_text i386_get_text +#endif + +#ifdef yyget_lineno +#define i386_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno i386_get_lineno +#endif + +#ifdef yyset_lineno +#define i386_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno i386_set_lineno +#endif + +#ifdef yywrap +#define i386_wrap_ALREADY_DEFINED +#else +#define yywrap i386_wrap +#endif + +#ifdef yyalloc +#define i386_alloc_ALREADY_DEFINED +#else +#define yyalloc i386_alloc +#endif + +#ifdef yyrealloc +#define i386_realloc_ALREADY_DEFINED +#else +#define yyrealloc i386_realloc +#endif + +#ifdef yyfree +#define i386_free_ALREADY_DEFINED +#else +#define yyfree i386_free +#endif + +#ifdef yytext +#define i386_text_ALREADY_DEFINED +#else +#define yytext i386_text +#endif + +#ifdef yyleng +#define i386_leng_ALREADY_DEFINED +#else +#define yyleng i386_leng +#endif + +#ifdef yyin +#define i386_in_ALREADY_DEFINED +#else +#define yyin i386_in +#endif + +#ifdef yyout +#define i386_out_ALREADY_DEFINED +#else +#define yyout i386_out +#endif + +#ifdef yy_flex_debug +#define i386__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug i386__flex_debug +#endif + +#ifdef yylineno +#define i386_lineno_ALREADY_DEFINED +#else +#define yylineno i386_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define i386_wrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 21 +#define YY_END_OF_BUFFER 22 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[62] = + { 0, + 0, 0, 0, 0, 22, 20, 17, 15, 20, 5, + 20, 14, 16, 19, 18, 15, 12, 7, 8, 13, + 11, 11, 19, 14, 16, 17, 6, 0, 0, 0, + 5, 0, 9, 18, 11, 11, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 11, 1, 0, 0, 0, + 11, 0, 0, 0, 11, 2, 3, 0, 10, 4, + 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 4, 1, 5, 1, 1, 1, + 1, 1, 1, 6, 1, 1, 7, 8, 9, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 1, 1, + 1, 1, 1, 1, 12, 13, 13, 14, 13, 13, + 13, 13, 15, 13, 13, 16, 13, 17, 13, 13, + 13, 13, 13, 13, 13, 18, 13, 13, 13, 13, + 1, 1, 1, 1, 13, 1, 19, 13, 13, 13, + + 20, 21, 13, 13, 22, 13, 23, 13, 24, 25, + 26, 27, 13, 28, 29, 13, 30, 13, 13, 31, + 32, 13, 33, 1, 34, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[35] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 3 + } ; + +static const flex_int16_t yy_base[65] = + { 0, + 0, 32, 65, 3, 113, 114, 9, 11, 19, 7, + 78, 16, 114, 114, 18, 20, 114, 114, 114, 114, + 0, 94, 76, 23, 114, 25, 114, 90, 80, 0, + 41, 73, 114, 36, 0, 88, 76, 44, 42, 37, + 49, 37, 38, 37, 31, 40, 114, 33, 32, 28, + 37, 16, 14, 12, 17, 114, 114, 5, 0, 114, + 114, 99, 101, 2 + } ; + +static const flex_int16_t yy_def[65] = + { 0, + 62, 62, 61, 3, 61, 61, 61, 61, 61, 61, + 63, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 64, 64, 63, 61, 61, 61, 61, 61, 61, 61, + 61, 63, 61, 61, 64, 64, 61, 61, 61, 61, + 64, 61, 61, 61, 61, 64, 61, 61, 61, 61, + 64, 61, 61, 61, 64, 61, 61, 61, 64, 61, + 0, 61, 61, 61 + } ; + +static const flex_int16_t yy_nxt[149] = + { 0, + 61, 7, 8, 35, 9, 24, 25, 10, 10, 10, + 26, 26, 26, 26, 31, 31, 31, 26, 26, 34, + 34, 34, 34, 27, 34, 34, 26, 26, 60, 39, + 59, 40, 11, 7, 12, 13, 9, 34, 34, 10, + 10, 10, 28, 58, 57, 29, 56, 30, 31, 31, + 31, 55, 54, 53, 52, 51, 50, 49, 48, 47, + 46, 45, 44, 43, 11, 14, 15, 16, 14, 14, + 17, 14, 18, 19, 14, 20, 21, 21, 21, 22, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 23, 14, 6, + + 6, 6, 32, 32, 42, 41, 33, 38, 37, 33, + 36, 33, 61, 5, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61 + } ; + +static const flex_int16_t yy_chk[149] = + { 0, + 0, 1, 1, 64, 1, 4, 4, 1, 1, 1, + 7, 7, 8, 8, 10, 10, 10, 12, 12, 15, + 15, 16, 16, 9, 24, 24, 26, 26, 58, 30, + 55, 30, 1, 2, 2, 2, 2, 34, 34, 2, + 2, 2, 9, 54, 53, 9, 52, 9, 31, 31, + 31, 51, 50, 49, 48, 46, 45, 44, 43, 42, + 41, 40, 39, 38, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 62, + + 62, 62, 63, 63, 37, 36, 32, 29, 28, 23, + 22, 11, 5, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[22] = + { 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, }; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "i386_lex.l" +#line 2 "i386_lex.l" +/* Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include "system.h" +#include "i386_parse.h" + + +static void eat_to_eol (void); +static void invalid_char (int ch); +#line 821 "i386_lex.c" + +#line 823 "i386_lex.c" + +#define INITIAL 0 +#define MAIN 1 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 57 "i386_lex.l" + + +#line 1047 "i386_lex.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 62 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_current_state != 61 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 59 "i386_lex.l" +{ return kMASK; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 61 "i386_lex.l" +{ return kPREFIX; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 62 "i386_lex.l" +{ return kSUFFIX; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 64 "i386_lex.l" +{ return kSYNONYM; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 66 "i386_lex.l" +{ i386_lval.num = strtoul (yytext, NULL, 10); + return kNUMBER; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 69 "i386_lex.l" +{ BEGIN (MAIN); return kPERCPERC; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 72 "i386_lex.l" +{ return '0'; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 73 "i386_lex.l" +{ return '1'; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 75 "i386_lex.l" +{ i386_lval.str = xstrndup (yytext + 1, + yyleng - 2); + return kBITFIELD; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 79 "i386_lex.l" +{ i386_lval.str = (void *) -1l; + return kID; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 82 "i386_lex.l" +{ i386_lval.str = xstrndup (yytext, yyleng); + return kID; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 85 "i386_lex.l" +{ return ','; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 87 "i386_lex.l" +{ return ':'; } + YY_BREAK +case 14: +/* rule 14 can match eol */ +YY_RULE_SETUP +#line 89 "i386_lex.l" +{ /* IGNORE */ } + YY_BREAK +case 15: +/* rule 15 can match eol */ +YY_RULE_SETUP +#line 91 "i386_lex.l" +{ return '\n'; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 93 "i386_lex.l" +{ eat_to_eol (); } + YY_BREAK +case 17: +/* rule 17 can match eol */ +YY_RULE_SETUP +#line 95 "i386_lex.l" +{ /* IGNORE */ } + YY_BREAK +case 18: +/* rule 18 can match eol */ +YY_RULE_SETUP +#line 97 "i386_lex.l" +{ return kSPACE; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 99 "i386_lex.l" +{ i386_lval.ch = *yytext; return kCHAR; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 101 "i386_lex.l" +{ invalid_char (*yytext); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 104 "i386_lex.l" +ECHO; + YY_BREAK +#line 1225 "i386_lex.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(MAIN): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 62 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 62 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 61); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) + + yylineno++; +; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 104 "i386_lex.l" + + +static void +eat_to_eol (void) +{ + while (1) + { + int c = input (); + + if (c == EOF || c == '\n') + break; + } +} + +static void +invalid_char (int ch) +{ + error (0, 0, (isascii (ch) + ? _("invalid character '%c' at line %d; ignored") + : _("invalid character '\\%o' at line %d; ignored")), + ch, yylineno); +} + +// Local Variables: +// mode: C +// End: + diff --git a/libcpu/i386_lex.l b/libcpu/i386_lex.l new file mode 100644 index 00000000..b6ec0f87 --- /dev/null +++ b/libcpu/i386_lex.l @@ -0,0 +1,129 @@ +%{ +/* Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include "system.h" +#include "i386_parse.h" + + +static void eat_to_eol (void); +static void invalid_char (int ch); +%} + +ID [a-zA-Z_][a-zA-Z0-9_/]* +ID2 [a-zA-Z0-9_:/]* +NUMBER [0-9]+ +WHITE [[:space:]]+ + +%option yylineno +%option never-interactive +%option noyywrap + + +%x MAIN + +%% + +"%mask" { return kMASK; } + +"%prefix" { return kPREFIX; } +"%suffix" { return kSUFFIX; } + +"%synonym" { return kSYNONYM; } + +{NUMBER} { i386_lval.num = strtoul (yytext, NULL, 10); + return kNUMBER; } + +"%%" { BEGIN (MAIN); return kPERCPERC; } + + +
"0" { return '0'; } +
"1" { return '1'; } + +"{"{ID2}"}" { i386_lval.str = xstrndup (yytext + 1, + yyleng - 2); + return kBITFIELD; } + +
"INVALID" { i386_lval.str = (void *) -1l; + return kID; } + +
{ID} { i386_lval.str = xstrndup (yytext, yyleng); + return kID; } + +
"," { return ','; } + +
":" { return ':'; } + +^"\n" { /* IGNORE */ } + +"\n" { return '\n'; } + +^"#" { eat_to_eol (); } + +{WHITE} { /* IGNORE */ } + +
{WHITE} { return kSPACE; } + +
. { i386_lval.ch = *yytext; return kCHAR; } + +. { invalid_char (*yytext); } + + +%% + +static void +eat_to_eol (void) +{ + while (1) + { + int c = input (); + + if (c == EOF || c == '\n') + break; + } +} + +static void +invalid_char (int ch) +{ + error (0, 0, (isascii (ch) + ? _("invalid character '%c' at line %d; ignored") + : _("invalid character '\\%o' at line %d; ignored")), + ch, yylineno); +} + +// Local Variables: +// mode: C +// End: diff --git a/libcpu/i386_parse.c b/libcpu/i386_parse.c new file mode 100644 index 00000000..2434a172 --- /dev/null +++ b/libcpu/i386_parse.c @@ -0,0 +1,3117 @@ +/* A Bison parser, made by GNU Bison 3.7.6. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output, and Bison version. */ +#define YYBISON 30706 + +/* Bison version string. */ +#define YYBISON_VERSION "3.7.6" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse i386_parse +#define yylex i386_lex +#define yyerror i386_error +#define yydebug i386_debug +#define yynerrs i386_nerrs +#define yylval i386_lval +#define yychar i386_char + +/* First part of user prologue. */ +#line 1 "i386_parse.y" + +/* Parser for i386 CPU description. + Copyright (C) 2004, 2005, 2007, 2008, 2009 Red Hat, Inc. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + +/* The error handler. */ +static void yyerror (const char *s); + +extern int yylex (void); +extern int i386_lineno; +extern char *infname; + + +struct known_bitfield +{ + char *name; + unsigned long int bits; + int tmp; +}; + + +struct bitvalue +{ + enum bittype { zeroone, field, failure } type; + union + { + unsigned int value; + struct known_bitfield *field; + }; + struct bitvalue *next; +}; + + +struct argname +{ + enum nametype { string, nfield } type; + union + { + char *str; + struct known_bitfield *field; + }; + struct argname *next; +}; + + +struct argument +{ + struct argname *name; + struct argument *next; +}; + + +struct instruction +{ + /* The byte encoding. */ + struct bitvalue *bytes; + + /* Prefix possible. */ + int repe; + int rep; + + /* Mnemonic. */ + char *mnemonic; + + /* Suffix. */ + enum { suffix_none = 0, suffix_w, suffix_w0, suffix_W, suffix_tttn, + suffix_w1, suffix_W1, suffix_D } suffix; + + /* Flag set if modr/m is used. */ + int modrm; + + /* Operands. */ + struct operand + { + char *fct; + char *str; + int off1; + int off2; + int off3; + } operands[3]; + + struct instruction *next; +}; + + +struct synonym +{ + char *from; + char *to; +}; + + +struct suffix +{ + char *name; + int idx; +}; + + +struct argstring +{ + char *str; + int idx; + int off; +}; + + +static struct known_bitfield ax_reg = + { + .name = "ax", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield dx_reg = + { + .name = "dx", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield di_reg = + { + .name = "es_di", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield si_reg = + { + .name = "ds_si", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield bx_reg = + { + .name = "ds_bx", .bits = 0, .tmp = 0 + }; + + +static int bitfield_compare (const void *p1, const void *p2); +static void new_bitfield (char *name, unsigned long int num); +static void check_bits (struct bitvalue *value); +static int check_duplicates (struct bitvalue *val); +static int check_argsdef (struct bitvalue *bitval, struct argument *args); +static int check_bitsused (struct bitvalue *bitval, + struct known_bitfield *suffix, + struct argument *args); +static struct argname *combine (struct argname *name); +static void fillin_arg (struct bitvalue *bytes, struct argname *name, + struct instruction *instr, int n); +static void find_numbers (void); +static int compare_syn (const void *p1, const void *p2); +static int compare_suf (const void *p1, const void *p2); +static void instrtable_out (void); +#if 0 +static void create_mnemonic_table (void); +#endif + +static void *bitfields; +static struct instruction *instructions; +static size_t ninstructions; +static void *synonyms; +static void *suffixes; +static int nsuffixes; +static void *mnemonics; +size_t nmnemonics; +extern FILE *outfile; + +/* Number of bits used mnemonics. */ +#if 0 +static size_t best_mnemonic_bits; +#endif + +#line 293 "i386_parse.c" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Use api.header.include to #include this header + instead of duplicating it here. */ +#ifndef YY_I386_I_PARSE_H_INCLUDED +# define YY_I386_I_PARSE_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int i386_debug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + kMASK = 258, /* kMASK */ + kPREFIX = 259, /* kPREFIX */ + kSUFFIX = 260, /* kSUFFIX */ + kSYNONYM = 261, /* kSYNONYM */ + kID = 262, /* kID */ + kNUMBER = 263, /* kNUMBER */ + kPERCPERC = 264, /* kPERCPERC */ + kBITFIELD = 265, /* kBITFIELD */ + kCHAR = 266, /* kCHAR */ + kSPACE = 267 /* kSPACE */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 +#define kMASK 258 +#define kPREFIX 259 +#define kSUFFIX 260 +#define kSYNONYM 261 +#define kID 262 +#define kNUMBER 263 +#define kPERCPERC 264 +#define kBITFIELD 265 +#define kCHAR 266 +#define kSPACE 267 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 216 "i386_parse.y" + + unsigned long int num; + char *str; + char ch; + struct known_bitfield *field; + struct bitvalue *bit; + struct argname *name; + struct argument *arg; + +#line 380 "i386_parse.c" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE i386_lval; + +int i386_parse (void); + +#endif /* !YY_I386_I_PARSE_H_INCLUDED */ +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_kMASK = 3, /* kMASK */ + YYSYMBOL_kPREFIX = 4, /* kPREFIX */ + YYSYMBOL_kSUFFIX = 5, /* kSUFFIX */ + YYSYMBOL_kSYNONYM = 6, /* kSYNONYM */ + YYSYMBOL_kID = 7, /* kID */ + YYSYMBOL_kNUMBER = 8, /* kNUMBER */ + YYSYMBOL_kPERCPERC = 9, /* kPERCPERC */ + YYSYMBOL_kBITFIELD = 10, /* kBITFIELD */ + YYSYMBOL_kCHAR = 11, /* kCHAR */ + YYSYMBOL_kSPACE = 12, /* kSPACE */ + YYSYMBOL_13_n_ = 13, /* '\n' */ + YYSYMBOL_14_ = 14, /* ':' */ + YYSYMBOL_15_ = 15, /* ',' */ + YYSYMBOL_16_0_ = 16, /* '0' */ + YYSYMBOL_17_1_ = 17, /* '1' */ + YYSYMBOL_YYACCEPT = 18, /* $accept */ + YYSYMBOL_spec = 19, /* spec */ + YYSYMBOL_masks = 20, /* masks */ + YYSYMBOL_mask = 21, /* mask */ + YYSYMBOL_instrs = 22, /* instrs */ + YYSYMBOL_instr = 23, /* instr */ + YYSYMBOL_bitfieldopt = 24, /* bitfieldopt */ + YYSYMBOL_bytes = 25, /* bytes */ + YYSYMBOL_byte = 26, /* byte */ + YYSYMBOL_bit = 27, /* bit */ + YYSYMBOL_optargs = 28, /* optargs */ + YYSYMBOL_args = 29, /* args */ + YYSYMBOL_arg = 30, /* arg */ + YYSYMBOL_argcomp = 31 /* argcomp */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YY_USE(E) ((void) (E)) +#else +# define YY_USE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if !defined yyoverflow + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* !defined yyoverflow */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 12 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 37 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 18 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 14 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 32 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 49 + +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 267 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_int8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 15, 2, 2, 2, 16, 17, + 2, 2, 2, 2, 2, 2, 2, 2, 14, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = +{ + 0, 246, 246, 256, 257, 260, 262, 264, 266, 278, + 281, 282, 285, 368, 371, 387, 390, 400, 407, 415, + 419, 426, 433, 455, 458, 461, 471, 479, 487, 490, + 522, 531, 538 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if YYDEBUG || 0 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "\"end of file\"", "error", "\"invalid token\"", "kMASK", "kPREFIX", + "kSUFFIX", "kSYNONYM", "kID", "kNUMBER", "kPERCPERC", "kBITFIELD", + "kCHAR", "kSPACE", "'\\n'", "':'", "','", "'0'", "'1'", "$accept", + "spec", "masks", "mask", "instrs", "instr", "bitfieldopt", "bytes", + "byte", "bit", "optargs", "args", "arg", "argcomp", YY_NULLPTR +}; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} +#endif + +#ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_int16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 10, 58, 44, 48, 49 +}; +#endif + +#define YYPACT_NINF (-35) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-1) + +#define yytable_value_is_error(Yyn) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + 12, 9, 10, 11, 13, 22, -2, -35, 16, -35, + -35, 15, -35, 14, 12, -35, -35, -4, -35, -35, + -35, -35, 17, -35, -12, -4, -35, -4, 18, -4, + -35, -35, -35, 19, -4, 18, 20, -6, -35, -35, + -35, -35, -35, 21, -6, -35, -6, -35, -6 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int8 yydefact[] = +{ + 9, 0, 0, 0, 0, 0, 0, 4, 0, 6, + 7, 0, 1, 0, 9, 5, 8, 13, 3, 22, + 20, 21, 2, 11, 0, 17, 19, 13, 15, 0, + 18, 10, 14, 0, 16, 15, 24, 0, 12, 31, + 29, 30, 32, 23, 26, 28, 0, 27, 25 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -35, -35, -35, 23, -35, 2, -1, -35, 4, -25, + -35, -35, -15, -34 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + 0, 5, 6, 7, 22, 23, 33, 24, 25, 26, + 38, 43, 44, 45 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int8 yytable[] = +{ + 30, 39, 28, 29, 40, 41, 19, 13, 42, 30, + 47, 14, 20, 21, 47, 1, 2, 3, 4, 8, + 9, 10, 12, 11, 15, 16, 35, 17, 32, 31, + 27, 48, 37, 34, 36, 0, 46, 18 +}; + +static const yytype_int8 yycheck[] = +{ + 25, 7, 14, 15, 10, 11, 10, 9, 14, 34, + 44, 13, 16, 17, 48, 3, 4, 5, 6, 10, + 10, 10, 0, 10, 8, 10, 7, 13, 10, 27, + 13, 46, 12, 29, 35, -1, 15, 14 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_int8 yystos[] = +{ + 0, 3, 4, 5, 6, 19, 20, 21, 10, 10, + 10, 10, 0, 9, 13, 8, 10, 13, 21, 10, + 16, 17, 22, 23, 25, 26, 27, 13, 14, 15, + 27, 23, 10, 24, 26, 7, 24, 12, 28, 7, + 10, 11, 14, 29, 30, 31, 15, 31, 30 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_int8 yyr1[] = +{ + 0, 18, 19, 20, 20, 21, 21, 21, 21, 21, + 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, + 27, 27, 27, 28, 28, 29, 29, 30, 30, 31, + 31, 31, 31 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 4, 3, 1, 3, 2, 2, 3, 0, + 3, 1, 6, 0, 1, 0, 3, 1, 2, 1, + 1, 1, 1, 2, 0, 3, 1, 2, 1, 1, + 1, 1, 1 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +# ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YY_USE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yykind < YYNTOKENS) + YYPRINT (yyo, yytoknum[yykind], *yyvaluep); +# endif + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + + + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) +{ + YY_USE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* Lookahead token kind. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus = 0; + + /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; + + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: /* spec: masks kPERCPERC '\n' instrs */ +#line 247 "i386_parse.y" + { + if (error_message_count != 0) + error (EXIT_FAILURE, 0, + "terminated due to previous error"); + + instrtable_out (); + } +#line 1421 "i386_parse.c" + break; + + case 5: /* mask: kMASK kBITFIELD kNUMBER */ +#line 261 "i386_parse.y" + { new_bitfield ((yyvsp[-1].str), (yyvsp[0].num)); } +#line 1427 "i386_parse.c" + break; + + case 6: /* mask: kPREFIX kBITFIELD */ +#line 263 "i386_parse.y" + { new_bitfield ((yyvsp[0].str), -1); } +#line 1433 "i386_parse.c" + break; + + case 7: /* mask: kSUFFIX kBITFIELD */ +#line 265 "i386_parse.y" + { new_bitfield ((yyvsp[0].str), -2); } +#line 1439 "i386_parse.c" + break; + + case 8: /* mask: kSYNONYM kBITFIELD kBITFIELD */ +#line 267 "i386_parse.y" + { + struct synonym *newp = xmalloc (sizeof (*newp)); + newp->from = (yyvsp[-1].str); + newp->to = (yyvsp[0].str); + if (tfind (newp, &synonyms, compare_syn) != NULL) + error (0, 0, + "%d: duplicate definition for synonym '%s'", + i386_lineno, (yyvsp[-1].str)); + else if (tsearch ( newp, &synonyms, compare_syn) == NULL) + error (EXIT_FAILURE, 0, "tsearch"); + } +#line 1455 "i386_parse.c" + break; + + case 12: /* instr: bytes ':' bitfieldopt kID bitfieldopt optargs */ +#line 286 "i386_parse.y" + { + if ((yyvsp[-3].field) != NULL && strcmp ((yyvsp[-3].field)->name, "RE") != 0 + && strcmp ((yyvsp[-3].field)->name, "R") != 0) + { + error (0, 0, "%d: only 'R' and 'RE' prefix allowed", + i386_lineno - 1); + } + if (check_duplicates ((yyvsp[-5].bit)) == 0 + && check_argsdef ((yyvsp[-5].bit), (yyvsp[0].arg)) == 0 + && check_bitsused ((yyvsp[-5].bit), (yyvsp[-1].field), (yyvsp[0].arg)) == 0) + { + struct instruction *newp = xcalloc (sizeof (*newp), + 1); + if ((yyvsp[-3].field) != NULL) + { + if (strcmp ((yyvsp[-3].field)->name, "RE") == 0) + newp->repe = 1; + else if (strcmp ((yyvsp[-3].field)->name, "R") == 0) + newp->rep = 1; + } + + newp->bytes = (yyvsp[-5].bit); + newp->mnemonic = (yyvsp[-2].str); + if (newp->mnemonic != (void *) -1l + && tfind ((yyvsp[-2].str), &mnemonics, + (int (*)(const void *, const void *)) strcmp) == NULL) + { + if (tsearch ((yyvsp[-2].str), &mnemonics, + (int (*)(const void *, const void *)) strcmp) == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + ++nmnemonics; + } + + if ((yyvsp[-1].field) != NULL) + { + if (strcmp ((yyvsp[-1].field)->name, "w") == 0) + newp->suffix = suffix_w; + else if (strcmp ((yyvsp[-1].field)->name, "w0") == 0) + newp->suffix = suffix_w0; + else if (strcmp ((yyvsp[-1].field)->name, "tttn") == 0) + newp->suffix = suffix_tttn; + else if (strcmp ((yyvsp[-1].field)->name, "w1") == 0) + newp->suffix = suffix_w1; + else if (strcmp ((yyvsp[-1].field)->name, "W") == 0) + newp->suffix = suffix_W; + else if (strcmp ((yyvsp[-1].field)->name, "W1") == 0) + newp->suffix = suffix_W1; + else if (strcmp ((yyvsp[-1].field)->name, "D") == 0) + newp->suffix = suffix_D; + else + error (EXIT_FAILURE, 0, + "%s: %d: unknown suffix '%s'", + infname, i386_lineno - 1, (yyvsp[-1].field)->name); + + struct suffix search = { .name = (yyvsp[-1].field)->name }; + if (tfind (&search, &suffixes, compare_suf) + == NULL) + { + struct suffix *ns = xmalloc (sizeof (*ns)); + ns->name = (yyvsp[-1].field)->name; + ns->idx = ++nsuffixes; + if (tsearch (ns, &suffixes, compare_suf) + == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + } + } + + struct argument *args = (yyvsp[0].arg); + int n = 0; + while (args != NULL) + { + fillin_arg ((yyvsp[-5].bit), args->name, newp, n); + + args = args->next; + ++n; + } + + newp->next = instructions; + instructions = newp; + ++ninstructions; + } + } +#line 1542 "i386_parse.c" + break; + + case 14: /* bitfieldopt: kBITFIELD */ +#line 372 "i386_parse.y" + { + struct known_bitfield search; + search.name = (yyvsp[0].str); + struct known_bitfield **res; + res = tfind (&search, &bitfields, bitfield_compare); + if (res == NULL) + { + error (0, 0, "%d: unknown bitfield '%s'", + i386_lineno, search.name); + (yyval.field) = NULL; + } + else + (yyval.field) = *res; + } +#line 1561 "i386_parse.c" + break; + + case 15: /* bitfieldopt: %empty */ +#line 387 "i386_parse.y" + { (yyval.field) = NULL; } +#line 1567 "i386_parse.c" + break; + + case 16: /* bytes: bytes ',' byte */ +#line 391 "i386_parse.y" + { + check_bits ((yyvsp[0].bit)); + + struct bitvalue *runp = (yyvsp[-2].bit); + while (runp->next != NULL) + runp = runp->next; + runp->next = (yyvsp[0].bit); + (yyval.bit) = (yyvsp[-2].bit); + } +#line 1581 "i386_parse.c" + break; + + case 17: /* bytes: byte */ +#line 401 "i386_parse.y" + { + check_bits ((yyvsp[0].bit)); + (yyval.bit) = (yyvsp[0].bit); + } +#line 1590 "i386_parse.c" + break; + + case 18: /* byte: byte bit */ +#line 408 "i386_parse.y" + { + struct bitvalue *runp = (yyvsp[-1].bit); + while (runp->next != NULL) + runp = runp->next; + runp->next = (yyvsp[0].bit); + (yyval.bit) = (yyvsp[-1].bit); + } +#line 1602 "i386_parse.c" + break; + + case 19: /* byte: bit */ +#line 416 "i386_parse.y" + { (yyval.bit) = (yyvsp[0].bit); } +#line 1608 "i386_parse.c" + break; + + case 20: /* bit: '0' */ +#line 420 "i386_parse.y" + { + (yyval.bit) = xmalloc (sizeof (struct bitvalue)); + (yyval.bit)->type = zeroone; + (yyval.bit)->value = 0; + (yyval.bit)->next = NULL; + } +#line 1619 "i386_parse.c" + break; + + case 21: /* bit: '1' */ +#line 427 "i386_parse.y" + { + (yyval.bit) = xmalloc (sizeof (struct bitvalue)); + (yyval.bit)->type = zeroone; + (yyval.bit)->value = 1; + (yyval.bit)->next = NULL; + } +#line 1630 "i386_parse.c" + break; + + case 22: /* bit: kBITFIELD */ +#line 434 "i386_parse.y" + { + (yyval.bit) = xmalloc (sizeof (struct bitvalue)); + struct known_bitfield search; + search.name = (yyvsp[0].str); + struct known_bitfield **res; + res = tfind (&search, &bitfields, bitfield_compare); + if (res == NULL) + { + error (0, 0, "%d: unknown bitfield '%s'", + i386_lineno, search.name); + (yyval.bit)->type = failure; + } + else + { + (yyval.bit)->type = field; + (yyval.bit)->field = *res; + } + (yyval.bit)->next = NULL; + } +#line 1654 "i386_parse.c" + break; + + case 23: /* optargs: kSPACE args */ +#line 456 "i386_parse.y" + { (yyval.arg) = (yyvsp[0].arg); } +#line 1660 "i386_parse.c" + break; + + case 24: /* optargs: %empty */ +#line 458 "i386_parse.y" + { (yyval.arg) = NULL; } +#line 1666 "i386_parse.c" + break; + + case 25: /* args: args ',' arg */ +#line 462 "i386_parse.y" + { + struct argument *runp = (yyvsp[-2].arg); + while (runp->next != NULL) + runp = runp->next; + runp->next = xmalloc (sizeof (struct argument)); + runp->next->name = combine ((yyvsp[0].name)); + runp->next->next = NULL; + (yyval.arg) = (yyvsp[-2].arg); + } +#line 1680 "i386_parse.c" + break; + + case 26: /* args: arg */ +#line 472 "i386_parse.y" + { + (yyval.arg) = xmalloc (sizeof (struct argument)); + (yyval.arg)->name = combine ((yyvsp[0].name)); + (yyval.arg)->next = NULL; + } +#line 1690 "i386_parse.c" + break; + + case 27: /* arg: arg argcomp */ +#line 480 "i386_parse.y" + { + struct argname *runp = (yyvsp[-1].name); + while (runp->next != NULL) + runp = runp->next; + runp->next = (yyvsp[0].name); + (yyval.name) = (yyvsp[-1].name); + } +#line 1702 "i386_parse.c" + break; + + case 28: /* arg: argcomp */ +#line 488 "i386_parse.y" + { (yyval.name) = (yyvsp[0].name); } +#line 1708 "i386_parse.c" + break; + + case 29: /* argcomp: kBITFIELD */ +#line 491 "i386_parse.y" + { + (yyval.name) = xmalloc (sizeof (struct argname)); + (yyval.name)->type = nfield; + (yyval.name)->next = NULL; + + struct known_bitfield search; + search.name = (yyvsp[0].str); + struct known_bitfield **res; + res = tfind (&search, &bitfields, bitfield_compare); + if (res == NULL) + { + if (strcmp ((yyvsp[0].str), "ax") == 0) + (yyval.name)->field = &ax_reg; + else if (strcmp ((yyvsp[0].str), "dx") == 0) + (yyval.name)->field = &dx_reg; + else if (strcmp ((yyvsp[0].str), "es_di") == 0) + (yyval.name)->field = &di_reg; + else if (strcmp ((yyvsp[0].str), "ds_si") == 0) + (yyval.name)->field = &si_reg; + else if (strcmp ((yyvsp[0].str), "ds_bx") == 0) + (yyval.name)->field = &bx_reg; + else + { + error (0, 0, "%d: unknown bitfield '%s'", + i386_lineno, search.name); + (yyval.name)->field = NULL; + } + } + else + (yyval.name)->field = *res; + } +#line 1744 "i386_parse.c" + break; + + case 30: /* argcomp: kCHAR */ +#line 523 "i386_parse.y" + { + (yyval.name) = xmalloc (sizeof (struct argname)); + (yyval.name)->type = string; + (yyval.name)->next = NULL; + (yyval.name)->str = xmalloc (2); + (yyval.name)->str[0] = (yyvsp[0].ch); + (yyval.name)->str[1] = '\0'; + } +#line 1757 "i386_parse.c" + break; + + case 31: /* argcomp: kID */ +#line 532 "i386_parse.y" + { + (yyval.name) = xmalloc (sizeof (struct argname)); + (yyval.name)->type = string; + (yyval.name)->next = NULL; + (yyval.name)->str = (yyvsp[0].str); + } +#line 1768 "i386_parse.c" + break; + + case 32: /* argcomp: ':' */ +#line 539 "i386_parse.y" + { + (yyval.name) = xmalloc (sizeof (struct argname)); + (yyval.name)->type = string; + (yyval.name)->next = NULL; + (yyval.name)->str = xmalloc (2); + (yyval.name)->str[0] = ':'; + (yyval.name)->str[1] = '\0'; + } +#line 1781 "i386_parse.c" + break; + + +#line 1785 "i386_parse.c" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + yyerror (YY_("syntax error")); + } + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + goto yyreturn; +#endif + + +/*-------------------------------------------------------. +| yyreturn -- parsing is finished, clean up and return. | +`-------------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + + return yyresult; +} + +#line 549 "i386_parse.y" + + +static void +yyerror (const char *s) +{ + error (0, 0, _("while reading i386 CPU description: %s at line %d"), + _(s), i386_lineno); +} + + +static int +bitfield_compare (const void *p1, const void *p2) +{ + struct known_bitfield *f1 = (struct known_bitfield *) p1; + struct known_bitfield *f2 = (struct known_bitfield *) p2; + + return strcmp (f1->name, f2->name); +} + + +static void +new_bitfield (char *name, unsigned long int num) +{ + struct known_bitfield *newp = xmalloc (sizeof (struct known_bitfield)); + newp->name = name; + newp->bits = num; + newp->tmp = 0; + + if (tfind (newp, &bitfields, bitfield_compare) != NULL) + { + error (0, 0, "%d: duplicated definition of bitfield '%s'", + i386_lineno, name); + free (name); + free (newp); + return; + } + + if (tsearch (newp, &bitfields, bitfield_compare) == NULL) + error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'", + i386_lineno, name); +} + + +/* Check that the number of bits is a multiple of 8. */ +static void +check_bits (struct bitvalue *val) +{ + struct bitvalue *runp = val; + unsigned int total = 0; + + while (runp != NULL) + { + if (runp->type == zeroone) + ++total; + else if (runp->field == NULL) + /* No sense doing anything, the field is not known. */ + return; + else + total += runp->field->bits; + + runp = runp->next; + } + + if (total % 8 != 0) + { + struct obstack os; + obstack_init (&os); + + while (val != NULL) + { + if (val->type == zeroone) + obstack_printf (&os, "%u", val->value); + else + obstack_printf (&os, "{%s}", val->field->name); + val = val->next; + } + obstack_1grow (&os, '\0'); + + error (0, 0, "%d: field '%s' not a multiple of 8 bits in size", + i386_lineno, (char *) obstack_finish (&os)); + + obstack_free (&os, NULL); + } +} + + +static int +check_duplicates (struct bitvalue *val) +{ + static int testcnt; + ++testcnt; + + int result = 0; + while (val != NULL) + { + if (val->type == field && val->field != NULL) + { + if (val->field->tmp == testcnt) + { + error (0, 0, "%d: bitfield '%s' used more than once", + i386_lineno - 1, val->field->name); + result = 1; + } + val->field->tmp = testcnt; + } + + val = val->next; + } + + return result; +} + + +static int +check_argsdef (struct bitvalue *bitval, struct argument *args) +{ + int result = 0; + + while (args != NULL) + { + for (struct argname *name = args->name; name != NULL; name = name->next) + if (name->type == nfield && name->field != NULL + && name->field != &ax_reg && name->field != &dx_reg + && name->field != &di_reg && name->field != &si_reg + && name->field != &bx_reg) + { + struct bitvalue *runp = bitval; + + while (runp != NULL) + if (runp->type == field && runp->field == name->field) + break; + else + runp = runp->next; + + if (runp == NULL) + { + error (0, 0, "%d: unknown bitfield '%s' used in output format", + i386_lineno - 1, name->field->name); + result = 1; + } + } + + args = args->next; + } + + return result; +} + + +static int +check_bitsused (struct bitvalue *bitval, struct known_bitfield *suffix, + struct argument *args) +{ + int result = 0; + + while (bitval != NULL) + { + if (bitval->type == field && bitval->field != NULL + && bitval->field != suffix + /* {w} is handled special. */ + && strcmp (bitval->field->name, "w") != 0) + { + struct argument *runp; + for (runp = args; runp != NULL; runp = runp->next) + { + struct argname *name = runp->name; + + while (name != NULL) + if (name->type == nfield && name->field == bitval->field) + break; + else + name = name->next; + + if (name != NULL) + break; + } + +#if 0 + if (runp == NULL) + { + error (0, 0, "%d: bitfield '%s' not used", + i386_lineno - 1, bitval->field->name); + result = 1; + } +#endif + } + + bitval = bitval->next; + } + + return result; +} + + +static struct argname * +combine (struct argname *name) +{ + struct argname *last_str = NULL; + for (struct argname *runp = name; runp != NULL; runp = runp->next) + { + if (runp->type == string) + { + if (last_str == NULL) + last_str = runp; + else + { + last_str->str = xrealloc (last_str->str, + strlen (last_str->str) + + strlen (runp->str) + 1); + strcat (last_str->str, runp->str); + last_str->next = runp->next; + } + } + else + last_str = NULL; + } + return name; +} + + +#define obstack_grow_str(ob, str) obstack_grow (ob, str, strlen (str)) + + +static void +fillin_arg (struct bitvalue *bytes, struct argname *name, + struct instruction *instr, int n) +{ + static struct obstack ob; + static int initialized; + if (! initialized) + { + initialized = 1; + obstack_init (&ob); + } + + struct argname *runp = name; + int cnt = 0; + while (runp != NULL) + { + /* We ignore strings in the function name. */ + if (runp->type == string) + { + if (instr->operands[n].str != NULL) + error (EXIT_FAILURE, 0, + "%d: cannot have more than one string parameter", + i386_lineno - 1); + + instr->operands[n].str = runp->str; + } + else + { + assert (runp->type == nfield); + + /* Construct the function name. */ + if (cnt++ > 0) + obstack_1grow (&ob, '$'); + + if (runp->field == NULL) + /* Add some string which contains invalid characters. */ + obstack_grow_str (&ob, "!!!INVALID!!!"); + else + { + char *fieldname = runp->field->name; + + struct synonym search = { .from = fieldname }; + + struct synonym **res = tfind (&search, &synonyms, compare_syn); + if (res != NULL) + fieldname = (*res)->to; + + obstack_grow_str (&ob, fieldname); + } + + /* Now compute the bit offset of the field. */ + struct bitvalue *b = bytes; + int bitoff = 0; + if (runp->field != NULL) + while (b != NULL) + { + if (b->type == field && b->field != NULL) + { + if (strcmp (b->field->name, runp->field->name) == 0) + break; + bitoff += b->field->bits; + } + else + ++bitoff; + + b = b->next; + } + if (instr->operands[n].off1 == 0) + instr->operands[n].off1 = bitoff; + else if (instr->operands[n].off2 == 0) + instr->operands[n].off2 = bitoff; + else if (instr->operands[n].off3 == 0) + instr->operands[n].off3 = bitoff; + else + error (EXIT_FAILURE, 0, + "%d: cannot have more than three fields in parameter", + i386_lineno - 1); + + if (runp->field != NULL + && strncasecmp (runp->field->name, "mod", 3) == 0) + instr->modrm = 1; + } + + runp = runp->next; + } + if (obstack_object_size (&ob) == 0) + obstack_grow_str (&ob, "string"); + obstack_1grow (&ob, '\0'); + char *fct = obstack_finish (&ob); + + instr->operands[n].fct = fct; +} + + +#if 0 +static void +nameout (const void *nodep, VISIT value, int level) +{ + if (value == leaf || value == postorder) + printf (" %s\n", *(const char **) nodep); +} +#endif + + +static int +compare_argstring (const void *p1, const void *p2) +{ + const struct argstring *a1 = (const struct argstring *) p1; + const struct argstring *a2 = (const struct argstring *) p2; + + return strcmp (a1->str, a2->str); +} + + +static int maxoff[3][3]; +static int minoff[3][3] = { { 1000, 1000, 1000 }, + { 1000, 1000, 1000 }, + { 1000, 1000, 1000 } }; +static int nbitoff[3][3]; +static void *fct_names[3]; +static int nbitfct[3]; +static int nbitsuf; +static void *strs[3]; +static int nbitstr[3]; +static int total_bits = 2; // Already counted the rep/repe bits. + +static void +find_numbers (void) +{ + int nfct_names[3] = { 0, 0, 0 }; + int nstrs[3] = { 0, 0, 0 }; + + /* We reverse the order of the instruction list while processing it. + Later phases need it in the order in which the input file has + them. */ + struct instruction *reversed = NULL; + + struct instruction *runp = instructions; + while (runp != NULL) + { + for (int i = 0; i < 3; ++i) + if (runp->operands[i].fct != NULL) + { + struct argstring search = { .str = runp->operands[i].fct }; + if (tfind (&search, &fct_names[i], compare_argstring) == NULL) + { + struct argstring *newp = xmalloc (sizeof (*newp)); + newp->str = runp->operands[i].fct; + newp->idx = 0; + if (tsearch (newp, &fct_names[i], compare_argstring) == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + ++nfct_names[i]; + } + + if (runp->operands[i].str != NULL) + { + search.str = runp->operands[i].str; + if (tfind (&search, &strs[i], compare_argstring) == NULL) + { + struct argstring *newp = xmalloc (sizeof (*newp)); + newp->str = runp->operands[i].str; + newp->idx = 0; + if (tsearch (newp, &strs[i], compare_argstring) == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + ++nstrs[i]; + } + } + + maxoff[i][0] = MAX (maxoff[i][0], runp->operands[i].off1); + maxoff[i][1] = MAX (maxoff[i][1], runp->operands[i].off2); + maxoff[i][2] = MAX (maxoff[i][2], runp->operands[i].off3); + + if (runp->operands[i].off1 > 0) + minoff[i][0] = MIN (minoff[i][0], runp->operands[i].off1); + if (runp->operands[i].off2 > 0) + minoff[i][1] = MIN (minoff[i][1], runp->operands[i].off2); + if (runp->operands[i].off3 > 0) + minoff[i][2] = MIN (minoff[i][2], runp->operands[i].off3); + } + + struct instruction *old = runp; + runp = runp->next; + + old->next = reversed; + reversed = old; + } + instructions = reversed; + + int d; + int c; + for (int i = 0; i < 3; ++i) + { + // printf ("min1 = %d, min2 = %d, min3 = %d\n", minoff[i][0], minoff[i][1], minoff[i][2]); + // printf ("max1 = %d, max2 = %d, max3 = %d\n", maxoff[i][0], maxoff[i][1], maxoff[i][2]); + + if (minoff[i][0] == 1000) + nbitoff[i][0] = 0; + else + { + nbitoff[i][0] = 1; + d = maxoff[i][0] - minoff[i][0]; + c = 1; + while (c < d) + { + ++nbitoff[i][0]; + c *= 2; + } + total_bits += nbitoff[i][0]; + } + + if (minoff[i][1] == 1000) + nbitoff[i][1] = 0; + else + { + nbitoff[i][1] = 1; + d = maxoff[i][1] - minoff[i][1]; + c = 1; + while (c < d) + { + ++nbitoff[i][1]; + c *= 2; + } + total_bits += nbitoff[i][1]; + } + + if (minoff[i][2] == 1000) + nbitoff[i][2] = 0; + else + { + nbitoff[i][2] = 1; + d = maxoff[i][2] - minoff[i][2]; + c = 1; + while (c < d) + { + ++nbitoff[i][2]; + c *= 2; + } + total_bits += nbitoff[i][2]; + } + // printf ("off1 = %d, off2 = %d, off3 = %d\n", nbitoff[i][0], nbitoff[i][1], nbitoff[i][2]); + + nbitfct[i] = 1; + d = nfct_names[i]; + c = 1; + while (c < d) + { + ++nbitfct[i]; + c *= 2; + } + total_bits += nbitfct[i]; + // printf ("%d fct[%d], %d bits\n", nfct_names[i], i, nbitfct[i]); + + if (nstrs[i] != 0) + { + nbitstr[i] = 1; + d = nstrs[i]; + c = 1; + while (c < d) + { + ++nbitstr[i]; + c *= 2; + } + total_bits += nbitstr[i]; + } + + // twalk (fct_names[i], nameout); + } + + nbitsuf = 0; + d = nsuffixes; + c = 1; + while (c < d) + { + ++nbitsuf; + c *= 2; + } + total_bits += nbitsuf; + // printf ("%d suffixes, %d bits\n", nsuffixes, nbitsuf); +} + + +static int +compare_syn (const void *p1, const void *p2) +{ + const struct synonym *s1 = (const struct synonym *) p1; + const struct synonym *s2 = (const struct synonym *) p2; + + return strcmp (s1->from, s2->from); +} + + +static int +compare_suf (const void *p1, const void *p2) +{ + const struct suffix *s1 = (const struct suffix *) p1; + const struct suffix *s2 = (const struct suffix *) p2; + + return strcmp (s1->name, s2->name); +} + + +static int count_op_str; +static int off_op_str; +static void +print_op_str (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + { + const char *str = (*(struct argstring **) nodep)->str; + fprintf (outfile, "%s\n \"%s", + count_op_str == 0 ? "" : "\\0\"", str); + (*(struct argstring **) nodep)->idx = ++count_op_str; + (*(struct argstring **) nodep)->off = off_op_str; + off_op_str += strlen (str) + 1; + } +} + + +static void +print_op_str_idx (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + printf (" %d,\n", (*(struct argstring **) nodep)->off); +} + + +static void +print_op_fct (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + { + fprintf (outfile, " FCT_%s,\n", (*(struct argstring **) nodep)->str); + (*(struct argstring **) nodep)->idx = ++count_op_str; + } +} + + +#if NMNES < 2 +# error "bogus NMNES value" +#endif + +static void +instrtable_out (void) +{ + find_numbers (); + +#if 0 + create_mnemonic_table (); + + fprintf (outfile, "#define MNEMONIC_BITS %zu\n", best_mnemonic_bits); +#else + fprintf (outfile, "#define MNEMONIC_BITS %ld\n", + lrint (ceil (log2 (NMNES)))); +#endif + fprintf (outfile, "#define SUFFIX_BITS %d\n", nbitsuf); + for (int i = 0; i < 3; ++i) + { + fprintf (outfile, "#define FCT%d_BITS %d\n", i + 1, nbitfct[i]); + if (nbitstr[i] != 0) + fprintf (outfile, "#define STR%d_BITS %d\n", i + 1, nbitstr[i]); + fprintf (outfile, "#define OFF%d_1_BITS %d\n", i + 1, nbitoff[i][0]); + fprintf (outfile, "#define OFF%d_1_BIAS %d\n", i + 1, minoff[i][0]); + if (nbitoff[i][1] != 0) + { + fprintf (outfile, "#define OFF%d_2_BITS %d\n", i + 1, nbitoff[i][1]); + fprintf (outfile, "#define OFF%d_2_BIAS %d\n", i + 1, minoff[i][1]); + } + if (nbitoff[i][2] != 0) + { + fprintf (outfile, "#define OFF%d_3_BITS %d\n", i + 1, nbitoff[i][2]); + fprintf (outfile, "#define OFF%d_3_BIAS %d\n", i + 1, minoff[i][2]); + } + } + + fputs ("\n#include \n\n", outfile); + + +#define APPEND(a, b) APPEND_ (a, b) +#define APPEND_(a, b) a##b +#define EMIT_SUFFIX(suf) \ + fprintf (outfile, "#define suffix_%s %d\n", #suf, APPEND (suffix_, suf)) + EMIT_SUFFIX (none); + EMIT_SUFFIX (w); + EMIT_SUFFIX (w0); + EMIT_SUFFIX (W); + EMIT_SUFFIX (tttn); + EMIT_SUFFIX (D); + EMIT_SUFFIX (w1); + EMIT_SUFFIX (W1); + + fputc_unlocked ('\n', outfile); + + for (int i = 0; i < 3; ++i) + { + /* Functions. */ + count_op_str = 0; + fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n NULL,\n", + i + 1); + twalk (fct_names[i], print_op_fct); + fputs ("};\n", outfile); + + /* The operand strings. */ + if (nbitstr[i] != 0) + { + count_op_str = 0; + off_op_str = 0; + fprintf (outfile, "static const char op%d_str[] =", i + 1); + twalk (strs[i], print_op_str); + fputs ("\";\n", outfile); + + fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n", + i + 1); + twalk (strs[i], print_op_str_idx); + fputs ("};\n", outfile); + } + } + + + fputs ("static const struct instr_enc instrtab[] =\n{\n", outfile); + struct instruction *instr; + for (instr = instructions; instr != NULL; instr = instr->next) + { + fputs (" {", outfile); + if (instr->mnemonic == (void *) -1l) + fputs (" .mnemonic = MNE_INVALID,", outfile); + else + fprintf (outfile, " .mnemonic = MNE_%s,", instr->mnemonic); + fprintf (outfile, " .rep = %d,", instr->rep); + fprintf (outfile, " .repe = %d,", instr->repe); + fprintf (outfile, " .suffix = %d,", instr->suffix); + fprintf (outfile, " .modrm = %d,", instr->modrm); + + for (int i = 0; i < 3; ++i) + { + int idx = 0; + if (instr->operands[i].fct != NULL) + { + struct argstring search = { .str = instr->operands[i].fct }; + struct argstring **res = tfind (&search, &fct_names[i], + compare_argstring); + assert (res != NULL); + idx = (*res)->idx; + } + fprintf (outfile, " .fct%d = %d,", i + 1, idx); + + idx = 0; + if (instr->operands[i].str != NULL) + { + struct argstring search = { .str = instr->operands[i].str }; + struct argstring **res = tfind (&search, &strs[i], + compare_argstring); + assert (res != NULL); + idx = (*res)->idx; + } + if (nbitstr[i] != 0) + fprintf (outfile, " .str%d = %d,", i + 1, idx); + + fprintf (outfile, " .off%d_1 = %d,", i + 1, + MAX (0, instr->operands[i].off1 - minoff[i][0])); + + if (nbitoff[i][1] != 0) + fprintf (outfile, " .off%d_2 = %d,", i + 1, + MAX (0, instr->operands[i].off2 - minoff[i][1])); + + if (nbitoff[i][2] != 0) + fprintf (outfile, " .off%d_3 = %d,", i + 1, + MAX (0, instr->operands[i].off3 - minoff[i][2])); + } + + fputs (" },\n", outfile); + } + fputs ("};\n", outfile); + + fputs ("static const uint8_t match_data[] =\n{\n", outfile); + size_t cnt = 0; + for (instr = instructions; instr != NULL; instr = instr->next, ++cnt) + { + /* First count the number of bytes. */ + size_t totalbits = 0; + size_t zerobits = 0; + bool leading_p = true; + size_t leadingbits = 0; + struct bitvalue *b = instr->bytes; + while (b != NULL) + { + if (b->type == zeroone) + { + ++totalbits; + zerobits = 0; + if (leading_p) + ++leadingbits; + } + else + { + totalbits += b->field->bits; + /* We must always count the mod/rm byte. */ + if (strncasecmp (b->field->name, "mod", 3) == 0) + zerobits = 0; + else + zerobits += b->field->bits; + leading_p = false; + } + b = b->next; + } + size_t nbytes = (totalbits - zerobits + 7) / 8; + assert (nbytes > 0); + size_t leadingbytes = leadingbits / 8; + + fprintf (outfile, " %#zx,", nbytes | (leadingbytes << 4)); + + /* Now create the mask and byte values. */ + uint8_t byte = 0; + uint8_t mask = 0; + int nbits = 0; + b = instr->bytes; + while (b != NULL) + { + if (b->type == zeroone) + { + byte = (byte << 1) | b->value; + mask = (mask << 1) | 1; + if (++nbits == 8) + { + if (leadingbytes > 0) + { + assert (mask == 0xff); + fprintf (outfile, " %#" PRIx8 ",", byte); + --leadingbytes; + } + else + fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", + mask, byte); + byte = mask = nbits = 0; + if (--nbytes == 0) + break; + } + } + else + { + assert (leadingbytes == 0); + + unsigned long int remaining = b->field->bits; + while (nbits + remaining > 8) + { + fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", + mask << (8 - nbits), byte << (8 - nbits)); + remaining = nbits + remaining - 8; + byte = mask = nbits = 0; + if (--nbytes == 0) + break; + } + byte <<= remaining; + mask <<= remaining; + nbits += remaining; + if (nbits == 8) + { + fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte); + byte = mask = nbits = 0; + if (--nbytes == 0) + break; + } + } + b = b->next; + } + + fputc_unlocked ('\n', outfile); + } + fputs ("};\n", outfile); +} + + +#if 0 +static size_t mnemonic_maxlen; +static size_t mnemonic_minlen; +static size_t +which_chars (const char *str[], size_t nstr) +{ + char used_char[256]; + memset (used_char, '\0', sizeof (used_char)); + mnemonic_maxlen = 0; + mnemonic_minlen = 10000; + for (size_t cnt = 0; cnt < nstr; ++cnt) + { + const unsigned char *cp = (const unsigned char *) str[cnt]; + mnemonic_maxlen = MAX (mnemonic_maxlen, strlen ((char *) cp)); + mnemonic_minlen = MIN (mnemonic_minlen, strlen ((char *) cp)); + do + used_char[*cp++] = 1; + while (*cp != '\0'); + } + size_t nused_char = 0; + for (size_t cnt = 0; cnt < 256; ++cnt) + if (used_char[cnt] != 0) + ++nused_char; + return nused_char; +} + + +static const char **mnemonic_strs; +static size_t nmnemonic_strs; +static void +add_mnemonics (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + mnemonic_strs[nmnemonic_strs++] = *(const char **) nodep; +} + + +struct charfreq +{ + char ch; + int freq; +}; +static struct charfreq pfxfreq[256]; +static struct charfreq sfxfreq[256]; + + +static int +compare_freq (const void *p1, const void *p2) +{ + const struct charfreq *c1 = (const struct charfreq *) p1; + const struct charfreq *c2 = (const struct charfreq *) p2; + + if (c1->freq > c2->freq) + return -1; + if (c1->freq < c2->freq) + return 1; + return 0; +} + + +static size_t +compute_pfxfreq (const char *str[], size_t nstr) +{ + memset (pfxfreq, '\0', sizeof (pfxfreq)); + + for (size_t i = 0; i < nstr; ++i) + pfxfreq[i].ch = i; + + for (size_t i = 0; i < nstr; ++i) + ++pfxfreq[*((const unsigned char *) str[i])].freq; + + qsort (pfxfreq, 256, sizeof (struct charfreq), compare_freq); + + size_t n = 0; + while (n < 256 && pfxfreq[n].freq != 0) + ++n; + return n; +} + + +struct strsnlen +{ + const char *str; + size_t len; +}; + +static size_t +compute_sfxfreq (size_t nstr, struct strsnlen *strsnlen) +{ + memset (sfxfreq, '\0', sizeof (sfxfreq)); + + for (size_t i = 0; i < nstr; ++i) + sfxfreq[i].ch = i; + + for (size_t i = 0; i < nstr; ++i) + ++sfxfreq[((const unsigned char *) strchrnul (strsnlen[i].str, '\0'))[-1]].freq; + + qsort (sfxfreq, 256, sizeof (struct charfreq), compare_freq); + + size_t n = 0; + while (n < 256 && sfxfreq[n].freq != 0) + ++n; + return n; +} + + +static void +create_mnemonic_table (void) +{ + mnemonic_strs = xmalloc (nmnemonics * sizeof (char *)); + + twalk (mnemonics, add_mnemonics); + + (void) which_chars (mnemonic_strs, nmnemonic_strs); + + size_t best_so_far = 100000000; + char *best_prefix = NULL; + char *best_suffix = NULL; + char *best_table = NULL; + size_t best_table_size = 0; + size_t best_table_bits = 0; + size_t best_prefix_bits = 0; + + /* We can precompute the prefix characters. */ + size_t npfx_char = compute_pfxfreq (mnemonic_strs, nmnemonic_strs); + + /* Compute best size for string representation including explicit NUL. */ + for (size_t pfxbits = 0; (1u << pfxbits) < 2 * npfx_char; ++pfxbits) + { + char prefix[1 << pfxbits]; + size_t i; + for (i = 0; i < (1u << pfxbits) - 1; ++i) + prefix[i] = pfxfreq[i].ch; + prefix[i] = '\0'; + + struct strsnlen strsnlen[nmnemonic_strs]; + + for (i = 0; i < nmnemonic_strs; ++i) + { + if (strchr (prefix, *mnemonic_strs[i]) != NULL) + strsnlen[i].str = mnemonic_strs[i] + 1; + else + strsnlen[i].str = mnemonic_strs[i]; + strsnlen[i].len = strlen (strsnlen[i].str); + } + + /* With the prefixes gone, try to combine strings. */ + size_t nstrsnlen = 1; + for (i = 1; i < nmnemonic_strs; ++i) + { + size_t j; + for (j = 0; j < nstrsnlen; ++j) + if (strsnlen[i].len > strsnlen[j].len + && strcmp (strsnlen[j].str, + strsnlen[i].str + (strsnlen[i].len + - strsnlen[j].len)) == 0) + { + strsnlen[j] = strsnlen[i]; + break; + } + else if (strsnlen[i].len < strsnlen[j].len + && strcmp (strsnlen[i].str, + strsnlen[j].str + (strsnlen[j].len + - strsnlen[i].len)) == 0) + break; +; + if (j == nstrsnlen) + strsnlen[nstrsnlen++] = strsnlen[i]; + } + + size_t nsfx_char = compute_sfxfreq (nstrsnlen, strsnlen); + + for (size_t sfxbits = 0; (1u << sfxbits) < 2 * nsfx_char; ++sfxbits) + { + char suffix[1 << sfxbits]; + + for (i = 0; i < (1u << sfxbits) - 1; ++i) + suffix[i] = sfxfreq[i].ch; + suffix[i] = '\0'; + + size_t newlen[nstrsnlen]; + + for (i = 0; i < nstrsnlen; ++i) + if (strchr (suffix, strsnlen[i].str[strsnlen[i].len - 1]) != NULL) + newlen[i] = strsnlen[i].len - 1; + else + newlen[i] = strsnlen[i].len; + + char charused[256]; + memset (charused, '\0', sizeof (charused)); + size_t ncharused = 0; + + const char *tablestr[nstrsnlen]; + size_t ntablestr = 1; + tablestr[0] = strsnlen[0].str; + size_t table = newlen[0] + 1; + for (i = 1; i < nstrsnlen; ++i) + { + size_t j; + for (j = 0; j < ntablestr; ++j) + if (newlen[i] > newlen[j] + && memcmp (tablestr[j], + strsnlen[i].str + (newlen[i] - newlen[j]), + newlen[j]) == 0) + { + table += newlen[i] - newlen[j]; + tablestr[j] = strsnlen[i].str; + newlen[j] = newlen[i]; + break; + } + else if (newlen[i] < newlen[j] + && memcmp (strsnlen[i].str, + tablestr[j] + (newlen[j] - newlen[i]), + newlen[i]) == 0) + break; + + if (j == ntablestr) + { + table += newlen[i] + 1; + tablestr[ntablestr] = strsnlen[i].str; + newlen[ntablestr] = newlen[i]; + + ++ntablestr; + } + + for (size_t x = 0; x < newlen[j]; ++x) + if (charused[((const unsigned char *) tablestr[j])[x]]++ == 0) + ++ncharused; + } + + size_t ncharused_bits = 0; + i = 1; + while (i < ncharused) + { + i *= 2; + ++ncharused_bits; + } + + size_t table_bits = 0; + i = 1; + while (i < table) + { + i *= 2; + ++table_bits; + } + + size_t mnemonic_bits = table_bits + pfxbits + sfxbits; + size_t new_total = (((table + 7) / 8) * ncharused_bits + ncharused + + (pfxbits == 0 ? 0 : (1 << pfxbits) - 1) + + (sfxbits == 0 ? 0 : (1 << sfxbits) - 1) + + (((total_bits + mnemonic_bits + 7) / 8) + * ninstructions)); + + if (new_total < best_so_far) + { + best_so_far = new_total; + best_mnemonic_bits = mnemonic_bits; + + free (best_suffix); + best_suffix = xstrdup (suffix); + + free (best_prefix); + best_prefix = xstrdup (prefix); + best_prefix_bits = pfxbits; + + best_table_size = table; + best_table_bits = table_bits; + char *cp = best_table = xrealloc (best_table, table); + for (i = 0; i < ntablestr; ++i) + { + assert (cp + newlen[i] + 1 <= best_table + table); + cp = mempcpy (cp, tablestr[i], newlen[i]); + *cp++ = '\0'; + } + assert (cp == best_table + table); + } + } + } + + fputs ("static const char mnemonic_table[] =\n\"", outfile); + for (size_t i = 0; i < best_table_size; ++i) + { + if (((i + 1) % 60) == 0) + fputs ("\"\n\"", outfile); + if (!isascii (best_table[i]) || !isprint (best_table[i])) + fprintf (outfile, "\\%03o", best_table[i]); + else + fputc (best_table[i], outfile); + } + fputs ("\";\n", outfile); + + if (best_prefix[0] != '\0') + fprintf (outfile, + "static const char prefix[%zu] = \"%s\";\n" + "#define PREFIXCHAR_BITS %zu\n", + strlen (best_prefix), best_prefix, best_prefix_bits); + else + fputs ("#define NO_PREFIX\n", outfile); + + if (best_suffix[0] != '\0') + fprintf (outfile, "static const char suffix[%zu] = \"%s\";\n", + strlen (best_suffix), best_suffix); + else + fputs ("#define NO_SUFFIX\n", outfile); + + for (size_t i = 0; i < nmnemonic_strs; ++i) + { + const char *mne = mnemonic_strs[i]; + + size_t pfxval = 0; + char *cp = strchr (best_prefix, *mne); + if (cp != NULL) + { + pfxval = 1 + (cp - best_prefix); + ++mne; + } + + size_t l = strlen (mne); + + size_t sfxval = 0; + cp = strchr (best_suffix, mne[l - 1]); + if (cp != NULL) + { + sfxval = 1 + (cp - best_suffix); + --l; + } + + char *off = memmem (best_table, best_table_size, mne, l); + while (off[l] != '\0') + { + off = memmem (off + 1, best_table_size, mne, l); + assert (off != NULL); + } + + fprintf (outfile, "#define MNE_%s %#zx\n", + mnemonic_strs[i], + (off - best_table) + + ((pfxval + (sfxval << best_prefix_bits)) << best_table_bits)); + } +} +#endif diff --git a/libcpu/i386_parse.h b/libcpu/i386_parse.h new file mode 100644 index 00000000..66f6e350 --- /dev/null +++ b/libcpu/i386_parse.h @@ -0,0 +1,113 @@ +/* A Bison parser, made by GNU Bison 3.7.6. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_I386_I_PARSE_H_INCLUDED +# define YY_I386_I_PARSE_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int i386_debug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + kMASK = 258, /* kMASK */ + kPREFIX = 259, /* kPREFIX */ + kSUFFIX = 260, /* kSUFFIX */ + kSYNONYM = 261, /* kSYNONYM */ + kID = 262, /* kID */ + kNUMBER = 263, /* kNUMBER */ + kPERCPERC = 264, /* kPERCPERC */ + kBITFIELD = 265, /* kBITFIELD */ + kCHAR = 266, /* kCHAR */ + kSPACE = 267 /* kSPACE */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif +/* Token kinds. */ +#define YYEMPTY -2 +#define YYEOF 0 +#define YYerror 256 +#define YYUNDEF 257 +#define kMASK 258 +#define kPREFIX 259 +#define kSUFFIX 260 +#define kSYNONYM 261 +#define kID 262 +#define kNUMBER 263 +#define kPERCPERC 264 +#define kBITFIELD 265 +#define kCHAR 266 +#define kSPACE 267 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 216 "i386_parse.y" + + unsigned long int num; + char *str; + char ch; + struct known_bitfield *field; + struct bitvalue *bit; + struct argname *name; + struct argument *arg; + +#line 101 "i386_parse.h" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE i386_lval; + +int i386_parse (void); + +#endif /* !YY_I386_I_PARSE_H_INCLUDED */ diff --git a/libcpu/i386_parse.y b/libcpu/i386_parse.y new file mode 100644 index 00000000..9a92c2e0 --- /dev/null +++ b/libcpu/i386_parse.y @@ -0,0 +1,1687 @@ +%{ +/* Parser for i386 CPU description. + Copyright (C) 2004, 2005, 2007, 2008, 2009 Red Hat, Inc. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + +/* The error handler. */ +static void yyerror (const char *s); + +extern int yylex (void); +extern int i386_lineno; +extern char *infname; + + +struct known_bitfield +{ + char *name; + unsigned long int bits; + int tmp; +}; + + +struct bitvalue +{ + enum bittype { zeroone, field, failure } type; + union + { + unsigned int value; + struct known_bitfield *field; + }; + struct bitvalue *next; +}; + + +struct argname +{ + enum nametype { string, nfield } type; + union + { + char *str; + struct known_bitfield *field; + }; + struct argname *next; +}; + + +struct argument +{ + struct argname *name; + struct argument *next; +}; + + +struct instruction +{ + /* The byte encoding. */ + struct bitvalue *bytes; + + /* Prefix possible. */ + int repe; + int rep; + + /* Mnemonic. */ + char *mnemonic; + + /* Suffix. */ + enum { suffix_none = 0, suffix_w, suffix_w0, suffix_W, suffix_tttn, + suffix_w1, suffix_W1, suffix_D } suffix; + + /* Flag set if modr/m is used. */ + int modrm; + + /* Operands. */ + struct operand + { + char *fct; + char *str; + int off1; + int off2; + int off3; + } operands[3]; + + struct instruction *next; +}; + + +struct synonym +{ + char *from; + char *to; +}; + + +struct suffix +{ + char *name; + int idx; +}; + + +struct argstring +{ + char *str; + int idx; + int off; +}; + + +static struct known_bitfield ax_reg = + { + .name = "ax", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield dx_reg = + { + .name = "dx", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield di_reg = + { + .name = "es_di", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield si_reg = + { + .name = "ds_si", .bits = 0, .tmp = 0 + }; + +static struct known_bitfield bx_reg = + { + .name = "ds_bx", .bits = 0, .tmp = 0 + }; + + +static int bitfield_compare (const void *p1, const void *p2); +static void new_bitfield (char *name, unsigned long int num); +static void check_bits (struct bitvalue *value); +static int check_duplicates (struct bitvalue *val); +static int check_argsdef (struct bitvalue *bitval, struct argument *args); +static int check_bitsused (struct bitvalue *bitval, + struct known_bitfield *suffix, + struct argument *args); +static struct argname *combine (struct argname *name); +static void fillin_arg (struct bitvalue *bytes, struct argname *name, + struct instruction *instr, int n); +static void find_numbers (void); +static int compare_syn (const void *p1, const void *p2); +static int compare_suf (const void *p1, const void *p2); +static void instrtable_out (void); +#if 0 +static void create_mnemonic_table (void); +#endif + +static void *bitfields; +static struct instruction *instructions; +static size_t ninstructions; +static void *synonyms; +static void *suffixes; +static int nsuffixes; +static void *mnemonics; +size_t nmnemonics; +extern FILE *outfile; + +/* Number of bits used mnemonics. */ +#if 0 +static size_t best_mnemonic_bits; +#endif +%} + +%union { + unsigned long int num; + char *str; + char ch; + struct known_bitfield *field; + struct bitvalue *bit; + struct argname *name; + struct argument *arg; +} + +%token kMASK +%token kPREFIX +%token kSUFFIX +%token kSYNONYM +%token kID +%token kNUMBER +%token kPERCPERC +%token kBITFIELD +%token kCHAR +%token kSPACE + +%type bit byte bytes +%type bitfieldopt +%type argcomp arg +%type args optargs + +%defines + +%% + +spec: masks kPERCPERC '\n' instrs + { + if (error_message_count != 0) + error (EXIT_FAILURE, 0, + "terminated due to previous error"); + + instrtable_out (); + } + ; + +masks: masks '\n' mask + | mask + ; + +mask: kMASK kBITFIELD kNUMBER + { new_bitfield ($2, $3); } + | kPREFIX kBITFIELD + { new_bitfield ($2, -1); } + | kSUFFIX kBITFIELD + { new_bitfield ($2, -2); } + | kSYNONYM kBITFIELD kBITFIELD + { + struct synonym *newp = xmalloc (sizeof (*newp)); + newp->from = $2; + newp->to = $3; + if (tfind (newp, &synonyms, compare_syn) != NULL) + error (0, 0, + "%d: duplicate definition for synonym '%s'", + i386_lineno, $2); + else if (tsearch ( newp, &synonyms, compare_syn) == NULL) + error (EXIT_FAILURE, 0, "tsearch"); + } + | + ; + +instrs: instrs '\n' instr + | instr + ; + +instr: bytes ':' bitfieldopt kID bitfieldopt optargs + { + if ($3 != NULL && strcmp ($3->name, "RE") != 0 + && strcmp ($3->name, "R") != 0) + { + error (0, 0, "%d: only 'R' and 'RE' prefix allowed", + i386_lineno - 1); + } + if (check_duplicates ($1) == 0 + && check_argsdef ($1, $6) == 0 + && check_bitsused ($1, $5, $6) == 0) + { + struct instruction *newp = xcalloc (sizeof (*newp), + 1); + if ($3 != NULL) + { + if (strcmp ($3->name, "RE") == 0) + newp->repe = 1; + else if (strcmp ($3->name, "R") == 0) + newp->rep = 1; + } + + newp->bytes = $1; + newp->mnemonic = $4; + if (newp->mnemonic != (void *) -1l + && tfind ($4, &mnemonics, + (int (*)(const void *, const void *)) strcmp) == NULL) + { + if (tsearch ($4, &mnemonics, + (int (*)(const void *, const void *)) strcmp) == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + ++nmnemonics; + } + + if ($5 != NULL) + { + if (strcmp ($5->name, "w") == 0) + newp->suffix = suffix_w; + else if (strcmp ($5->name, "w0") == 0) + newp->suffix = suffix_w0; + else if (strcmp ($5->name, "tttn") == 0) + newp->suffix = suffix_tttn; + else if (strcmp ($5->name, "w1") == 0) + newp->suffix = suffix_w1; + else if (strcmp ($5->name, "W") == 0) + newp->suffix = suffix_W; + else if (strcmp ($5->name, "W1") == 0) + newp->suffix = suffix_W1; + else if (strcmp ($5->name, "D") == 0) + newp->suffix = suffix_D; + else + error (EXIT_FAILURE, 0, + "%s: %d: unknown suffix '%s'", + infname, i386_lineno - 1, $5->name); + + struct suffix search = { .name = $5->name }; + if (tfind (&search, &suffixes, compare_suf) + == NULL) + { + struct suffix *ns = xmalloc (sizeof (*ns)); + ns->name = $5->name; + ns->idx = ++nsuffixes; + if (tsearch (ns, &suffixes, compare_suf) + == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + } + } + + struct argument *args = $6; + int n = 0; + while (args != NULL) + { + fillin_arg ($1, args->name, newp, n); + + args = args->next; + ++n; + } + + newp->next = instructions; + instructions = newp; + ++ninstructions; + } + } + | + ; + +bitfieldopt: kBITFIELD + { + struct known_bitfield search; + search.name = $1; + struct known_bitfield **res; + res = tfind (&search, &bitfields, bitfield_compare); + if (res == NULL) + { + error (0, 0, "%d: unknown bitfield '%s'", + i386_lineno, search.name); + $$ = NULL; + } + else + $$ = *res; + } + | + { $$ = NULL; } + ; + +bytes: bytes ',' byte + { + check_bits ($3); + + struct bitvalue *runp = $1; + while (runp->next != NULL) + runp = runp->next; + runp->next = $3; + $$ = $1; + } + | byte + { + check_bits ($1); + $$ = $1; + } + ; + +byte: byte bit + { + struct bitvalue *runp = $1; + while (runp->next != NULL) + runp = runp->next; + runp->next = $2; + $$ = $1; + } + | bit + { $$ = $1; } + ; + +bit: '0' + { + $$ = xmalloc (sizeof (struct bitvalue)); + $$->type = zeroone; + $$->value = 0; + $$->next = NULL; + } + | '1' + { + $$ = xmalloc (sizeof (struct bitvalue)); + $$->type = zeroone; + $$->value = 1; + $$->next = NULL; + } + | kBITFIELD + { + $$ = xmalloc (sizeof (struct bitvalue)); + struct known_bitfield search; + search.name = $1; + struct known_bitfield **res; + res = tfind (&search, &bitfields, bitfield_compare); + if (res == NULL) + { + error (0, 0, "%d: unknown bitfield '%s'", + i386_lineno, search.name); + $$->type = failure; + } + else + { + $$->type = field; + $$->field = *res; + } + $$->next = NULL; + } + ; + +optargs: kSPACE args + { $$ = $2; } + | + { $$ = NULL; } + ; + +args: args ',' arg + { + struct argument *runp = $1; + while (runp->next != NULL) + runp = runp->next; + runp->next = xmalloc (sizeof (struct argument)); + runp->next->name = combine ($3); + runp->next->next = NULL; + $$ = $1; + } + | arg + { + $$ = xmalloc (sizeof (struct argument)); + $$->name = combine ($1); + $$->next = NULL; + } + ; + +arg: arg argcomp + { + struct argname *runp = $1; + while (runp->next != NULL) + runp = runp->next; + runp->next = $2; + $$ = $1; + } + | argcomp + { $$ = $1; } + ; +argcomp: kBITFIELD + { + $$ = xmalloc (sizeof (struct argname)); + $$->type = nfield; + $$->next = NULL; + + struct known_bitfield search; + search.name = $1; + struct known_bitfield **res; + res = tfind (&search, &bitfields, bitfield_compare); + if (res == NULL) + { + if (strcmp ($1, "ax") == 0) + $$->field = &ax_reg; + else if (strcmp ($1, "dx") == 0) + $$->field = &dx_reg; + else if (strcmp ($1, "es_di") == 0) + $$->field = &di_reg; + else if (strcmp ($1, "ds_si") == 0) + $$->field = &si_reg; + else if (strcmp ($1, "ds_bx") == 0) + $$->field = &bx_reg; + else + { + error (0, 0, "%d: unknown bitfield '%s'", + i386_lineno, search.name); + $$->field = NULL; + } + } + else + $$->field = *res; + } + | kCHAR + { + $$ = xmalloc (sizeof (struct argname)); + $$->type = string; + $$->next = NULL; + $$->str = xmalloc (2); + $$->str[0] = $1; + $$->str[1] = '\0'; + } + | kID + { + $$ = xmalloc (sizeof (struct argname)); + $$->type = string; + $$->next = NULL; + $$->str = $1; + } + | ':' + { + $$ = xmalloc (sizeof (struct argname)); + $$->type = string; + $$->next = NULL; + $$->str = xmalloc (2); + $$->str[0] = ':'; + $$->str[1] = '\0'; + } + ; + +%% + +static void +yyerror (const char *s) +{ + error (0, 0, _("while reading i386 CPU description: %s at line %d"), + _(s), i386_lineno); +} + + +static int +bitfield_compare (const void *p1, const void *p2) +{ + struct known_bitfield *f1 = (struct known_bitfield *) p1; + struct known_bitfield *f2 = (struct known_bitfield *) p2; + + return strcmp (f1->name, f2->name); +} + + +static void +new_bitfield (char *name, unsigned long int num) +{ + struct known_bitfield *newp = xmalloc (sizeof (struct known_bitfield)); + newp->name = name; + newp->bits = num; + newp->tmp = 0; + + if (tfind (newp, &bitfields, bitfield_compare) != NULL) + { + error (0, 0, "%d: duplicated definition of bitfield '%s'", + i386_lineno, name); + free (name); + free (newp); + return; + } + + if (tsearch (newp, &bitfields, bitfield_compare) == NULL) + error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'", + i386_lineno, name); +} + + +/* Check that the number of bits is a multiple of 8. */ +static void +check_bits (struct bitvalue *val) +{ + struct bitvalue *runp = val; + unsigned int total = 0; + + while (runp != NULL) + { + if (runp->type == zeroone) + ++total; + else if (runp->field == NULL) + /* No sense doing anything, the field is not known. */ + return; + else + total += runp->field->bits; + + runp = runp->next; + } + + if (total % 8 != 0) + { + struct obstack os; + obstack_init (&os); + + while (val != NULL) + { + if (val->type == zeroone) + obstack_printf (&os, "%u", val->value); + else + obstack_printf (&os, "{%s}", val->field->name); + val = val->next; + } + obstack_1grow (&os, '\0'); + + error (0, 0, "%d: field '%s' not a multiple of 8 bits in size", + i386_lineno, (char *) obstack_finish (&os)); + + obstack_free (&os, NULL); + } +} + + +static int +check_duplicates (struct bitvalue *val) +{ + static int testcnt; + ++testcnt; + + int result = 0; + while (val != NULL) + { + if (val->type == field && val->field != NULL) + { + if (val->field->tmp == testcnt) + { + error (0, 0, "%d: bitfield '%s' used more than once", + i386_lineno - 1, val->field->name); + result = 1; + } + val->field->tmp = testcnt; + } + + val = val->next; + } + + return result; +} + + +static int +check_argsdef (struct bitvalue *bitval, struct argument *args) +{ + int result = 0; + + while (args != NULL) + { + for (struct argname *name = args->name; name != NULL; name = name->next) + if (name->type == nfield && name->field != NULL + && name->field != &ax_reg && name->field != &dx_reg + && name->field != &di_reg && name->field != &si_reg + && name->field != &bx_reg) + { + struct bitvalue *runp = bitval; + + while (runp != NULL) + if (runp->type == field && runp->field == name->field) + break; + else + runp = runp->next; + + if (runp == NULL) + { + error (0, 0, "%d: unknown bitfield '%s' used in output format", + i386_lineno - 1, name->field->name); + result = 1; + } + } + + args = args->next; + } + + return result; +} + + +static int +check_bitsused (struct bitvalue *bitval, struct known_bitfield *suffix, + struct argument *args) +{ + int result = 0; + + while (bitval != NULL) + { + if (bitval->type == field && bitval->field != NULL + && bitval->field != suffix + /* {w} is handled special. */ + && strcmp (bitval->field->name, "w") != 0) + { + struct argument *runp; + for (runp = args; runp != NULL; runp = runp->next) + { + struct argname *name = runp->name; + + while (name != NULL) + if (name->type == nfield && name->field == bitval->field) + break; + else + name = name->next; + + if (name != NULL) + break; + } + +#if 0 + if (runp == NULL) + { + error (0, 0, "%d: bitfield '%s' not used", + i386_lineno - 1, bitval->field->name); + result = 1; + } +#endif + } + + bitval = bitval->next; + } + + return result; +} + + +static struct argname * +combine (struct argname *name) +{ + struct argname *last_str = NULL; + for (struct argname *runp = name; runp != NULL; runp = runp->next) + { + if (runp->type == string) + { + if (last_str == NULL) + last_str = runp; + else + { + last_str->str = xrealloc (last_str->str, + strlen (last_str->str) + + strlen (runp->str) + 1); + strcat (last_str->str, runp->str); + last_str->next = runp->next; + } + } + else + last_str = NULL; + } + return name; +} + + +#define obstack_grow_str(ob, str) obstack_grow (ob, str, strlen (str)) + + +static void +fillin_arg (struct bitvalue *bytes, struct argname *name, + struct instruction *instr, int n) +{ + static struct obstack ob; + static int initialized; + if (! initialized) + { + initialized = 1; + obstack_init (&ob); + } + + struct argname *runp = name; + int cnt = 0; + while (runp != NULL) + { + /* We ignore strings in the function name. */ + if (runp->type == string) + { + if (instr->operands[n].str != NULL) + error (EXIT_FAILURE, 0, + "%d: cannot have more than one string parameter", + i386_lineno - 1); + + instr->operands[n].str = runp->str; + } + else + { + assert (runp->type == nfield); + + /* Construct the function name. */ + if (cnt++ > 0) + obstack_1grow (&ob, '$'); + + if (runp->field == NULL) + /* Add some string which contains invalid characters. */ + obstack_grow_str (&ob, "!!!INVALID!!!"); + else + { + char *fieldname = runp->field->name; + + struct synonym search = { .from = fieldname }; + + struct synonym **res = tfind (&search, &synonyms, compare_syn); + if (res != NULL) + fieldname = (*res)->to; + + obstack_grow_str (&ob, fieldname); + } + + /* Now compute the bit offset of the field. */ + struct bitvalue *b = bytes; + int bitoff = 0; + if (runp->field != NULL) + while (b != NULL) + { + if (b->type == field && b->field != NULL) + { + if (strcmp (b->field->name, runp->field->name) == 0) + break; + bitoff += b->field->bits; + } + else + ++bitoff; + + b = b->next; + } + if (instr->operands[n].off1 == 0) + instr->operands[n].off1 = bitoff; + else if (instr->operands[n].off2 == 0) + instr->operands[n].off2 = bitoff; + else if (instr->operands[n].off3 == 0) + instr->operands[n].off3 = bitoff; + else + error (EXIT_FAILURE, 0, + "%d: cannot have more than three fields in parameter", + i386_lineno - 1); + + if (runp->field != NULL + && strncasecmp (runp->field->name, "mod", 3) == 0) + instr->modrm = 1; + } + + runp = runp->next; + } + if (obstack_object_size (&ob) == 0) + obstack_grow_str (&ob, "string"); + obstack_1grow (&ob, '\0'); + char *fct = obstack_finish (&ob); + + instr->operands[n].fct = fct; +} + + +#if 0 +static void +nameout (const void *nodep, VISIT value, int level) +{ + if (value == leaf || value == postorder) + printf (" %s\n", *(const char **) nodep); +} +#endif + + +static int +compare_argstring (const void *p1, const void *p2) +{ + const struct argstring *a1 = (const struct argstring *) p1; + const struct argstring *a2 = (const struct argstring *) p2; + + return strcmp (a1->str, a2->str); +} + + +static int maxoff[3][3]; +static int minoff[3][3] = { { 1000, 1000, 1000 }, + { 1000, 1000, 1000 }, + { 1000, 1000, 1000 } }; +static int nbitoff[3][3]; +static void *fct_names[3]; +static int nbitfct[3]; +static int nbitsuf; +static void *strs[3]; +static int nbitstr[3]; +static int total_bits = 2; // Already counted the rep/repe bits. + +static void +find_numbers (void) +{ + int nfct_names[3] = { 0, 0, 0 }; + int nstrs[3] = { 0, 0, 0 }; + + /* We reverse the order of the instruction list while processing it. + Later phases need it in the order in which the input file has + them. */ + struct instruction *reversed = NULL; + + struct instruction *runp = instructions; + while (runp != NULL) + { + for (int i = 0; i < 3; ++i) + if (runp->operands[i].fct != NULL) + { + struct argstring search = { .str = runp->operands[i].fct }; + if (tfind (&search, &fct_names[i], compare_argstring) == NULL) + { + struct argstring *newp = xmalloc (sizeof (*newp)); + newp->str = runp->operands[i].fct; + newp->idx = 0; + if (tsearch (newp, &fct_names[i], compare_argstring) == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + ++nfct_names[i]; + } + + if (runp->operands[i].str != NULL) + { + search.str = runp->operands[i].str; + if (tfind (&search, &strs[i], compare_argstring) == NULL) + { + struct argstring *newp = xmalloc (sizeof (*newp)); + newp->str = runp->operands[i].str; + newp->idx = 0; + if (tsearch (newp, &strs[i], compare_argstring) == NULL) + error (EXIT_FAILURE, errno, "tsearch"); + ++nstrs[i]; + } + } + + maxoff[i][0] = MAX (maxoff[i][0], runp->operands[i].off1); + maxoff[i][1] = MAX (maxoff[i][1], runp->operands[i].off2); + maxoff[i][2] = MAX (maxoff[i][2], runp->operands[i].off3); + + if (runp->operands[i].off1 > 0) + minoff[i][0] = MIN (minoff[i][0], runp->operands[i].off1); + if (runp->operands[i].off2 > 0) + minoff[i][1] = MIN (minoff[i][1], runp->operands[i].off2); + if (runp->operands[i].off3 > 0) + minoff[i][2] = MIN (minoff[i][2], runp->operands[i].off3); + } + + struct instruction *old = runp; + runp = runp->next; + + old->next = reversed; + reversed = old; + } + instructions = reversed; + + int d; + int c; + for (int i = 0; i < 3; ++i) + { + // printf ("min1 = %d, min2 = %d, min3 = %d\n", minoff[i][0], minoff[i][1], minoff[i][2]); + // printf ("max1 = %d, max2 = %d, max3 = %d\n", maxoff[i][0], maxoff[i][1], maxoff[i][2]); + + if (minoff[i][0] == 1000) + nbitoff[i][0] = 0; + else + { + nbitoff[i][0] = 1; + d = maxoff[i][0] - minoff[i][0]; + c = 1; + while (c < d) + { + ++nbitoff[i][0]; + c *= 2; + } + total_bits += nbitoff[i][0]; + } + + if (minoff[i][1] == 1000) + nbitoff[i][1] = 0; + else + { + nbitoff[i][1] = 1; + d = maxoff[i][1] - minoff[i][1]; + c = 1; + while (c < d) + { + ++nbitoff[i][1]; + c *= 2; + } + total_bits += nbitoff[i][1]; + } + + if (minoff[i][2] == 1000) + nbitoff[i][2] = 0; + else + { + nbitoff[i][2] = 1; + d = maxoff[i][2] - minoff[i][2]; + c = 1; + while (c < d) + { + ++nbitoff[i][2]; + c *= 2; + } + total_bits += nbitoff[i][2]; + } + // printf ("off1 = %d, off2 = %d, off3 = %d\n", nbitoff[i][0], nbitoff[i][1], nbitoff[i][2]); + + nbitfct[i] = 1; + d = nfct_names[i]; + c = 1; + while (c < d) + { + ++nbitfct[i]; + c *= 2; + } + total_bits += nbitfct[i]; + // printf ("%d fct[%d], %d bits\n", nfct_names[i], i, nbitfct[i]); + + if (nstrs[i] != 0) + { + nbitstr[i] = 1; + d = nstrs[i]; + c = 1; + while (c < d) + { + ++nbitstr[i]; + c *= 2; + } + total_bits += nbitstr[i]; + } + + // twalk (fct_names[i], nameout); + } + + nbitsuf = 0; + d = nsuffixes; + c = 1; + while (c < d) + { + ++nbitsuf; + c *= 2; + } + total_bits += nbitsuf; + // printf ("%d suffixes, %d bits\n", nsuffixes, nbitsuf); +} + + +static int +compare_syn (const void *p1, const void *p2) +{ + const struct synonym *s1 = (const struct synonym *) p1; + const struct synonym *s2 = (const struct synonym *) p2; + + return strcmp (s1->from, s2->from); +} + + +static int +compare_suf (const void *p1, const void *p2) +{ + const struct suffix *s1 = (const struct suffix *) p1; + const struct suffix *s2 = (const struct suffix *) p2; + + return strcmp (s1->name, s2->name); +} + + +static int count_op_str; +static int off_op_str; +static void +print_op_str (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + { + const char *str = (*(struct argstring **) nodep)->str; + fprintf (outfile, "%s\n \"%s", + count_op_str == 0 ? "" : "\\0\"", str); + (*(struct argstring **) nodep)->idx = ++count_op_str; + (*(struct argstring **) nodep)->off = off_op_str; + off_op_str += strlen (str) + 1; + } +} + + +static void +print_op_str_idx (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + printf (" %d,\n", (*(struct argstring **) nodep)->off); +} + + +static void +print_op_fct (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + { + fprintf (outfile, " FCT_%s,\n", (*(struct argstring **) nodep)->str); + (*(struct argstring **) nodep)->idx = ++count_op_str; + } +} + + +#if NMNES < 2 +# error "bogus NMNES value" +#endif + +static void +instrtable_out (void) +{ + find_numbers (); + +#if 0 + create_mnemonic_table (); + + fprintf (outfile, "#define MNEMONIC_BITS %zu\n", best_mnemonic_bits); +#else + fprintf (outfile, "#define MNEMONIC_BITS %ld\n", + lrint (ceil (log2 (NMNES)))); +#endif + fprintf (outfile, "#define SUFFIX_BITS %d\n", nbitsuf); + for (int i = 0; i < 3; ++i) + { + fprintf (outfile, "#define FCT%d_BITS %d\n", i + 1, nbitfct[i]); + if (nbitstr[i] != 0) + fprintf (outfile, "#define STR%d_BITS %d\n", i + 1, nbitstr[i]); + fprintf (outfile, "#define OFF%d_1_BITS %d\n", i + 1, nbitoff[i][0]); + fprintf (outfile, "#define OFF%d_1_BIAS %d\n", i + 1, minoff[i][0]); + if (nbitoff[i][1] != 0) + { + fprintf (outfile, "#define OFF%d_2_BITS %d\n", i + 1, nbitoff[i][1]); + fprintf (outfile, "#define OFF%d_2_BIAS %d\n", i + 1, minoff[i][1]); + } + if (nbitoff[i][2] != 0) + { + fprintf (outfile, "#define OFF%d_3_BITS %d\n", i + 1, nbitoff[i][2]); + fprintf (outfile, "#define OFF%d_3_BIAS %d\n", i + 1, minoff[i][2]); + } + } + + fputs ("\n#include \n\n", outfile); + + +#define APPEND(a, b) APPEND_ (a, b) +#define APPEND_(a, b) a##b +#define EMIT_SUFFIX(suf) \ + fprintf (outfile, "#define suffix_%s %d\n", #suf, APPEND (suffix_, suf)) + EMIT_SUFFIX (none); + EMIT_SUFFIX (w); + EMIT_SUFFIX (w0); + EMIT_SUFFIX (W); + EMIT_SUFFIX (tttn); + EMIT_SUFFIX (D); + EMIT_SUFFIX (w1); + EMIT_SUFFIX (W1); + + fputc_unlocked ('\n', outfile); + + for (int i = 0; i < 3; ++i) + { + /* Functions. */ + count_op_str = 0; + fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n NULL,\n", + i + 1); + twalk (fct_names[i], print_op_fct); + fputs ("};\n", outfile); + + /* The operand strings. */ + if (nbitstr[i] != 0) + { + count_op_str = 0; + off_op_str = 0; + fprintf (outfile, "static const char op%d_str[] =", i + 1); + twalk (strs[i], print_op_str); + fputs ("\";\n", outfile); + + fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n", + i + 1); + twalk (strs[i], print_op_str_idx); + fputs ("};\n", outfile); + } + } + + + fputs ("static const struct instr_enc instrtab[] =\n{\n", outfile); + struct instruction *instr; + for (instr = instructions; instr != NULL; instr = instr->next) + { + fputs (" {", outfile); + if (instr->mnemonic == (void *) -1l) + fputs (" .mnemonic = MNE_INVALID,", outfile); + else + fprintf (outfile, " .mnemonic = MNE_%s,", instr->mnemonic); + fprintf (outfile, " .rep = %d,", instr->rep); + fprintf (outfile, " .repe = %d,", instr->repe); + fprintf (outfile, " .suffix = %d,", instr->suffix); + fprintf (outfile, " .modrm = %d,", instr->modrm); + + for (int i = 0; i < 3; ++i) + { + int idx = 0; + if (instr->operands[i].fct != NULL) + { + struct argstring search = { .str = instr->operands[i].fct }; + struct argstring **res = tfind (&search, &fct_names[i], + compare_argstring); + assert (res != NULL); + idx = (*res)->idx; + } + fprintf (outfile, " .fct%d = %d,", i + 1, idx); + + idx = 0; + if (instr->operands[i].str != NULL) + { + struct argstring search = { .str = instr->operands[i].str }; + struct argstring **res = tfind (&search, &strs[i], + compare_argstring); + assert (res != NULL); + idx = (*res)->idx; + } + if (nbitstr[i] != 0) + fprintf (outfile, " .str%d = %d,", i + 1, idx); + + fprintf (outfile, " .off%d_1 = %d,", i + 1, + MAX (0, instr->operands[i].off1 - minoff[i][0])); + + if (nbitoff[i][1] != 0) + fprintf (outfile, " .off%d_2 = %d,", i + 1, + MAX (0, instr->operands[i].off2 - minoff[i][1])); + + if (nbitoff[i][2] != 0) + fprintf (outfile, " .off%d_3 = %d,", i + 1, + MAX (0, instr->operands[i].off3 - minoff[i][2])); + } + + fputs (" },\n", outfile); + } + fputs ("};\n", outfile); + + fputs ("static const uint8_t match_data[] =\n{\n", outfile); + size_t cnt = 0; + for (instr = instructions; instr != NULL; instr = instr->next, ++cnt) + { + /* First count the number of bytes. */ + size_t totalbits = 0; + size_t zerobits = 0; + bool leading_p = true; + size_t leadingbits = 0; + struct bitvalue *b = instr->bytes; + while (b != NULL) + { + if (b->type == zeroone) + { + ++totalbits; + zerobits = 0; + if (leading_p) + ++leadingbits; + } + else + { + totalbits += b->field->bits; + /* We must always count the mod/rm byte. */ + if (strncasecmp (b->field->name, "mod", 3) == 0) + zerobits = 0; + else + zerobits += b->field->bits; + leading_p = false; + } + b = b->next; + } + size_t nbytes = (totalbits - zerobits + 7) / 8; + assert (nbytes > 0); + size_t leadingbytes = leadingbits / 8; + + fprintf (outfile, " %#zx,", nbytes | (leadingbytes << 4)); + + /* Now create the mask and byte values. */ + uint8_t byte = 0; + uint8_t mask = 0; + int nbits = 0; + b = instr->bytes; + while (b != NULL) + { + if (b->type == zeroone) + { + byte = (byte << 1) | b->value; + mask = (mask << 1) | 1; + if (++nbits == 8) + { + if (leadingbytes > 0) + { + assert (mask == 0xff); + fprintf (outfile, " %#" PRIx8 ",", byte); + --leadingbytes; + } + else + fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", + mask, byte); + byte = mask = nbits = 0; + if (--nbytes == 0) + break; + } + } + else + { + assert (leadingbytes == 0); + + unsigned long int remaining = b->field->bits; + while (nbits + remaining > 8) + { + fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", + mask << (8 - nbits), byte << (8 - nbits)); + remaining = nbits + remaining - 8; + byte = mask = nbits = 0; + if (--nbytes == 0) + break; + } + byte <<= remaining; + mask <<= remaining; + nbits += remaining; + if (nbits == 8) + { + fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte); + byte = mask = nbits = 0; + if (--nbytes == 0) + break; + } + } + b = b->next; + } + + fputc_unlocked ('\n', outfile); + } + fputs ("};\n", outfile); +} + + +#if 0 +static size_t mnemonic_maxlen; +static size_t mnemonic_minlen; +static size_t +which_chars (const char *str[], size_t nstr) +{ + char used_char[256]; + memset (used_char, '\0', sizeof (used_char)); + mnemonic_maxlen = 0; + mnemonic_minlen = 10000; + for (size_t cnt = 0; cnt < nstr; ++cnt) + { + const unsigned char *cp = (const unsigned char *) str[cnt]; + mnemonic_maxlen = MAX (mnemonic_maxlen, strlen ((char *) cp)); + mnemonic_minlen = MIN (mnemonic_minlen, strlen ((char *) cp)); + do + used_char[*cp++] = 1; + while (*cp != '\0'); + } + size_t nused_char = 0; + for (size_t cnt = 0; cnt < 256; ++cnt) + if (used_char[cnt] != 0) + ++nused_char; + return nused_char; +} + + +static const char **mnemonic_strs; +static size_t nmnemonic_strs; +static void +add_mnemonics (const void *nodep, VISIT value, + int level __attribute__ ((unused))) +{ + if (value == leaf || value == postorder) + mnemonic_strs[nmnemonic_strs++] = *(const char **) nodep; +} + + +struct charfreq +{ + char ch; + int freq; +}; +static struct charfreq pfxfreq[256]; +static struct charfreq sfxfreq[256]; + + +static int +compare_freq (const void *p1, const void *p2) +{ + const struct charfreq *c1 = (const struct charfreq *) p1; + const struct charfreq *c2 = (const struct charfreq *) p2; + + if (c1->freq > c2->freq) + return -1; + if (c1->freq < c2->freq) + return 1; + return 0; +} + + +static size_t +compute_pfxfreq (const char *str[], size_t nstr) +{ + memset (pfxfreq, '\0', sizeof (pfxfreq)); + + for (size_t i = 0; i < nstr; ++i) + pfxfreq[i].ch = i; + + for (size_t i = 0; i < nstr; ++i) + ++pfxfreq[*((const unsigned char *) str[i])].freq; + + qsort (pfxfreq, 256, sizeof (struct charfreq), compare_freq); + + size_t n = 0; + while (n < 256 && pfxfreq[n].freq != 0) + ++n; + return n; +} + + +struct strsnlen +{ + const char *str; + size_t len; +}; + +static size_t +compute_sfxfreq (size_t nstr, struct strsnlen *strsnlen) +{ + memset (sfxfreq, '\0', sizeof (sfxfreq)); + + for (size_t i = 0; i < nstr; ++i) + sfxfreq[i].ch = i; + + for (size_t i = 0; i < nstr; ++i) + ++sfxfreq[((const unsigned char *) strchrnul (strsnlen[i].str, '\0'))[-1]].freq; + + qsort (sfxfreq, 256, sizeof (struct charfreq), compare_freq); + + size_t n = 0; + while (n < 256 && sfxfreq[n].freq != 0) + ++n; + return n; +} + + +static void +create_mnemonic_table (void) +{ + mnemonic_strs = xmalloc (nmnemonics * sizeof (char *)); + + twalk (mnemonics, add_mnemonics); + + (void) which_chars (mnemonic_strs, nmnemonic_strs); + + size_t best_so_far = 100000000; + char *best_prefix = NULL; + char *best_suffix = NULL; + char *best_table = NULL; + size_t best_table_size = 0; + size_t best_table_bits = 0; + size_t best_prefix_bits = 0; + + /* We can precompute the prefix characters. */ + size_t npfx_char = compute_pfxfreq (mnemonic_strs, nmnemonic_strs); + + /* Compute best size for string representation including explicit NUL. */ + for (size_t pfxbits = 0; (1u << pfxbits) < 2 * npfx_char; ++pfxbits) + { + char prefix[1 << pfxbits]; + size_t i; + for (i = 0; i < (1u << pfxbits) - 1; ++i) + prefix[i] = pfxfreq[i].ch; + prefix[i] = '\0'; + + struct strsnlen strsnlen[nmnemonic_strs]; + + for (i = 0; i < nmnemonic_strs; ++i) + { + if (strchr (prefix, *mnemonic_strs[i]) != NULL) + strsnlen[i].str = mnemonic_strs[i] + 1; + else + strsnlen[i].str = mnemonic_strs[i]; + strsnlen[i].len = strlen (strsnlen[i].str); + } + + /* With the prefixes gone, try to combine strings. */ + size_t nstrsnlen = 1; + for (i = 1; i < nmnemonic_strs; ++i) + { + size_t j; + for (j = 0; j < nstrsnlen; ++j) + if (strsnlen[i].len > strsnlen[j].len + && strcmp (strsnlen[j].str, + strsnlen[i].str + (strsnlen[i].len + - strsnlen[j].len)) == 0) + { + strsnlen[j] = strsnlen[i]; + break; + } + else if (strsnlen[i].len < strsnlen[j].len + && strcmp (strsnlen[i].str, + strsnlen[j].str + (strsnlen[j].len + - strsnlen[i].len)) == 0) + break; +; + if (j == nstrsnlen) + strsnlen[nstrsnlen++] = strsnlen[i]; + } + + size_t nsfx_char = compute_sfxfreq (nstrsnlen, strsnlen); + + for (size_t sfxbits = 0; (1u << sfxbits) < 2 * nsfx_char; ++sfxbits) + { + char suffix[1 << sfxbits]; + + for (i = 0; i < (1u << sfxbits) - 1; ++i) + suffix[i] = sfxfreq[i].ch; + suffix[i] = '\0'; + + size_t newlen[nstrsnlen]; + + for (i = 0; i < nstrsnlen; ++i) + if (strchr (suffix, strsnlen[i].str[strsnlen[i].len - 1]) != NULL) + newlen[i] = strsnlen[i].len - 1; + else + newlen[i] = strsnlen[i].len; + + char charused[256]; + memset (charused, '\0', sizeof (charused)); + size_t ncharused = 0; + + const char *tablestr[nstrsnlen]; + size_t ntablestr = 1; + tablestr[0] = strsnlen[0].str; + size_t table = newlen[0] + 1; + for (i = 1; i < nstrsnlen; ++i) + { + size_t j; + for (j = 0; j < ntablestr; ++j) + if (newlen[i] > newlen[j] + && memcmp (tablestr[j], + strsnlen[i].str + (newlen[i] - newlen[j]), + newlen[j]) == 0) + { + table += newlen[i] - newlen[j]; + tablestr[j] = strsnlen[i].str; + newlen[j] = newlen[i]; + break; + } + else if (newlen[i] < newlen[j] + && memcmp (strsnlen[i].str, + tablestr[j] + (newlen[j] - newlen[i]), + newlen[i]) == 0) + break; + + if (j == ntablestr) + { + table += newlen[i] + 1; + tablestr[ntablestr] = strsnlen[i].str; + newlen[ntablestr] = newlen[i]; + + ++ntablestr; + } + + for (size_t x = 0; x < newlen[j]; ++x) + if (charused[((const unsigned char *) tablestr[j])[x]]++ == 0) + ++ncharused; + } + + size_t ncharused_bits = 0; + i = 1; + while (i < ncharused) + { + i *= 2; + ++ncharused_bits; + } + + size_t table_bits = 0; + i = 1; + while (i < table) + { + i *= 2; + ++table_bits; + } + + size_t mnemonic_bits = table_bits + pfxbits + sfxbits; + size_t new_total = (((table + 7) / 8) * ncharused_bits + ncharused + + (pfxbits == 0 ? 0 : (1 << pfxbits) - 1) + + (sfxbits == 0 ? 0 : (1 << sfxbits) - 1) + + (((total_bits + mnemonic_bits + 7) / 8) + * ninstructions)); + + if (new_total < best_so_far) + { + best_so_far = new_total; + best_mnemonic_bits = mnemonic_bits; + + free (best_suffix); + best_suffix = xstrdup (suffix); + + free (best_prefix); + best_prefix = xstrdup (prefix); + best_prefix_bits = pfxbits; + + best_table_size = table; + best_table_bits = table_bits; + char *cp = best_table = xrealloc (best_table, table); + for (i = 0; i < ntablestr; ++i) + { + assert (cp + newlen[i] + 1 <= best_table + table); + cp = mempcpy (cp, tablestr[i], newlen[i]); + *cp++ = '\0'; + } + assert (cp == best_table + table); + } + } + } + + fputs ("static const char mnemonic_table[] =\n\"", outfile); + for (size_t i = 0; i < best_table_size; ++i) + { + if (((i + 1) % 60) == 0) + fputs ("\"\n\"", outfile); + if (!isascii (best_table[i]) || !isprint (best_table[i])) + fprintf (outfile, "\\%03o", best_table[i]); + else + fputc (best_table[i], outfile); + } + fputs ("\";\n", outfile); + + if (best_prefix[0] != '\0') + fprintf (outfile, + "static const char prefix[%zu] = \"%s\";\n" + "#define PREFIXCHAR_BITS %zu\n", + strlen (best_prefix), best_prefix, best_prefix_bits); + else + fputs ("#define NO_PREFIX\n", outfile); + + if (best_suffix[0] != '\0') + fprintf (outfile, "static const char suffix[%zu] = \"%s\";\n", + strlen (best_suffix), best_suffix); + else + fputs ("#define NO_SUFFIX\n", outfile); + + for (size_t i = 0; i < nmnemonic_strs; ++i) + { + const char *mne = mnemonic_strs[i]; + + size_t pfxval = 0; + char *cp = strchr (best_prefix, *mne); + if (cp != NULL) + { + pfxval = 1 + (cp - best_prefix); + ++mne; + } + + size_t l = strlen (mne); + + size_t sfxval = 0; + cp = strchr (best_suffix, mne[l - 1]); + if (cp != NULL) + { + sfxval = 1 + (cp - best_suffix); + --l; + } + + char *off = memmem (best_table, best_table_size, mne, l); + while (off[l] != '\0') + { + off = memmem (off + 1, best_table_size, mne, l); + assert (off != NULL); + } + + fprintf (outfile, "#define MNE_%s %#zx\n", + mnemonic_strs[i], + (off - best_table) + + ((pfxval + (sfxval << best_prefix_bits)) << best_table_bits)); + } +} +#endif diff --git a/libcpu/memory-access.h b/libcpu/memory-access.h new file mode 100644 index 00000000..779825fa --- /dev/null +++ b/libcpu/memory-access.h @@ -0,0 +1,182 @@ +/* Unaligned memory access functionality. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008 Red Hat, Inc. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _MEMORY_ACCESS_H +#define _MEMORY_ACCESS_H 1 + +#include +#include +#include +#include + + +/* When loading this file we require the macro MACHINE_ENCODING to be + defined to signal the endianness of the architecture which is + defined. */ +#ifndef MACHINE_ENCODING +# error "MACHINE_ENCODING needs to be defined" +#endif +#if MACHINE_ENCODING != __BIG_ENDIAN && MACHINE_ENCODING != __LITTLE_ENDIAN +# error "MACHINE_ENCODING must signal either big or little endian" +#endif + + +/* We use simple memory access functions in case the hardware allows it. + The caller has to make sure we don't have alias problems. */ +#if ALLOW_UNALIGNED + +# define read_2ubyte_unaligned(Addr) \ + (unlikely (MACHINE_ENCODING != __BYTE_ORDER) \ + ? bswap_16 (*((const uint16_t *) (Addr))) \ + : *((const uint16_t *) (Addr))) +# define read_2sbyte_unaligned(Addr) \ + (unlikely (MACHINE_ENCODING != __BYTE_ORDER) \ + ? (int16_t) bswap_16 (*((const int16_t *) (Addr))) \ + : *((const int16_t *) (Addr))) + +# define read_4ubyte_unaligned_noncvt(Addr) \ + *((const uint32_t *) (Addr)) +# define read_4ubyte_unaligned(Addr) \ + (unlikely (MACHINE_ENCODING != __BYTE_ORDER) \ + ? bswap_32 (*((const uint32_t *) (Addr))) \ + : *((const uint32_t *) (Addr))) +# define read_4sbyte_unaligned(Addr) \ + (unlikely (MACHINE_ENCODING != __BYTE_ORDER) \ + ? (int32_t) bswap_32 (*((const int32_t *) (Addr))) \ + : *((const int32_t *) (Addr))) + +# define read_8ubyte_unaligned(Addr) \ + (unlikely (MACHINE_ENCODING != __BYTE_ORDER) \ + ? bswap_64 (*((const uint64_t *) (Addr))) \ + : *((const uint64_t *) (Addr))) +# define read_8sbyte_unaligned(Addr) \ + (unlikely (MACHINE_ENCODING != __BYTE_ORDER) \ + ? (int64_t) bswap_64 (*((const int64_t *) (Addr))) \ + : *((const int64_t *) (Addr))) + +#else + +union unaligned + { + void *p; + uint16_t u2; + uint32_t u4; + uint64_t u8; + int16_t s2; + int32_t s4; + int64_t s8; + } attribute_packed; + +static inline uint16_t +read_2ubyte_unaligned (const void *p) +{ + const union unaligned *up = p; + if (MACHINE_ENCODING != __BYTE_ORDER) + return bswap_16 (up->u2); + return up->u2; +} +static inline int16_t +read_2sbyte_unaligned (const void *p) +{ + const union unaligned *up = p; + if (MACHINE_ENCODING != __BYTE_ORDER) + return (int16_t) bswap_16 (up->u2); + return up->s2; +} + +static inline uint32_t +read_4ubyte_unaligned_noncvt (const void *p) +{ + const union unaligned *up = p; + return up->u4; +} +static inline uint32_t +read_4ubyte_unaligned (const void *p) +{ + const union unaligned *up = p; + if (MACHINE_ENCODING != __BYTE_ORDER) + return bswap_32 (up->u4); + return up->u4; +} +static inline int32_t +read_4sbyte_unaligned (const void *p) +{ + const union unaligned *up = p; + if (MACHINE_ENCODING != __BYTE_ORDER) + return (int32_t) bswap_32 (up->u4); + return up->s4; +} + +static inline uint64_t +read_8ubyte_unaligned (const void *p) +{ + const union unaligned *up = p; + if (MACHINE_ENCODING != __BYTE_ORDER) + return bswap_64 (up->u8); + return up->u8; +} +static inline int64_t +read_8sbyte_unaligned (const void *p) +{ + const union unaligned *up = p; + if (MACHINE_ENCODING != __BYTE_ORDER) + return (int64_t) bswap_64 (up->u8); + return up->s8; +} + +#endif /* allow unaligned */ + + +#define read_2ubyte_unaligned_inc(Addr) \ + ({ uint16_t t_ = read_2ubyte_unaligned (Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \ + t_; }) +#define read_2sbyte_unaligned_inc(Addr) \ + ({ int16_t t_ = read_2sbyte_unaligned (Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \ + t_; }) + +#define read_4ubyte_unaligned_inc(Addr) \ + ({ uint32_t t_ = read_4ubyte_unaligned (Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \ + t_; }) +#define read_4sbyte_unaligned_inc(Addr) \ + ({ int32_t t_ = read_4sbyte_unaligned (Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \ + t_; }) + +#define read_8ubyte_unaligned_inc(Addr) \ + ({ uint64_t t_ = read_8ubyte_unaligned (Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \ + t_; }) +#define read_8sbyte_unaligned_inc(Addr) \ + ({ int64_t t_ = read_8sbyte_unaligned (Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \ + t_; }) + +#endif /* memory-access.h */ diff --git a/libcpu/riscv_disasm.c b/libcpu/riscv_disasm.c new file mode 100644 index 00000000..bc0d8f37 --- /dev/null +++ b/libcpu/riscv_disasm.c @@ -0,0 +1,1501 @@ +/* Disassembler for RISC-V. + Copyright (C) 2019 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2019. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../libebl/libeblP.h" + +#define MACHINE_ENCODING __LITTLE_ENDIAN +#include "memory-access.h" + + +#define ADD_CHAR(ch) \ + do { \ + if (unlikely (bufcnt == bufsize)) \ + goto enomem; \ + buf[bufcnt++] = (ch); \ + } while (0) + +#define ADD_STRING(str) \ + do { \ + const char *_str0 = (str); \ + size_t _len0 = strlen (_str0); \ + ADD_NSTRING (_str0, _len0); \ + } while (0) + +#define ADD_NSTRING(str, len) \ + do { \ + const char *_str = (str); \ + size_t _len = (len); \ + if (unlikely (bufcnt + _len > bufsize)) \ + goto enomem; \ + memcpy (buf + bufcnt, _str, _len); \ + bufcnt += _len; \ + } while (0) + + +static const char *regnames[32] = + { + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" + }; +#define REG(nr) ((char *) regnames[nr]) +#define REGP(nr) REG (8 + (nr)) + + +static const char *fregnames[32] = + { + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", + "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11" + }; +#define FREG(nr) ((char *) fregnames[nr]) +#define FREGP(nr) FREG (8 + (nr)) + + +struct known_csrs + { + uint16_t nr; + const char *name; + }; + +static int compare_csr (const void *a, const void *b) +{ + const struct known_csrs *ka = (const struct known_csrs *) a; + const struct known_csrs *kb = (const struct known_csrs *) b; + if (ka->nr < kb->nr) + return -1; + return ka->nr == kb->nr ? 0 : 1; +} + + +int +riscv_disasm (Ebl *ebl, + const uint8_t **startp, const uint8_t *end, GElf_Addr addr, + const char *fmt, DisasmOutputCB_t outcb, + DisasmGetSymCB_t symcb __attribute__((unused)), + void *outcbarg, void *symcbarg __attribute__((unused))) +{ + const char *const save_fmt = fmt; + +#define BUFSIZE 512 + char initbuf[BUFSIZE]; + size_t bufcnt; + size_t bufsize = BUFSIZE; + char *buf = initbuf; + + int retval = 0; + while (1) + { + const uint8_t *data = *startp; + assert (data <= end); + if (data + 2 > end) + { + if (data != end) + retval = -1; + break; + } + uint16_t first = read_2ubyte_unaligned (data); + + // Determine length. + size_t length; + if ((first & 0x3) != 0x3) + length = 2; + else if ((first & 0x1f) != 0x1f) + length = 4; + else if ((first & 0x3f) != 0x3f) + length = 6; + else if ((first & 0x7f) != 0x7f) + length = 8; + else + { + uint16_t nnn = (first >> 12) & 0x7; + if (nnn != 0x7) + length = 10 + 2 * nnn; + else + // This is invalid as of the RISC-V spec on 2019-06-21. + // The instruction is at least 192 bits in size so use + // this minimum size. + length = 24; + } + if (data + length > end) + { + retval = -1; + break; + } + + char *mne = NULL; + char mnebuf[32]; + char *op[5] = { NULL, NULL, NULL, NULL, NULL }; + char immbuf[32]; + size_t len; + char *strp = NULL; + char addrbuf[32]; + bufcnt = 0; + int64_t opaddr; + if (length == 2) + { + size_t idx = (first >> 13) * 3 + (first & 0x3); + switch (idx) + { + uint16_t rd; + uint16_t rs1; + uint16_t rs2; + + case 0: + if ((first & 0x1fe0) != 0) + { + mne = "addi"; + op[0] = REGP ((first & 0x1c) >> 2); + op[1] = REG (2); + opaddr = (((first >> 1) & 0x3c0) + | ((first >> 7) & 0x30) + | ((first >> 2) & 0x8) + | ((first >> 4) & 0x4)); + snprintf (addrbuf, sizeof (addrbuf), "%" PRIu64, opaddr); + op[2] = addrbuf; + } + else if (first == 0) + mne = "unimp"; + break; + case 1: + rs1 = (first >> 7) & 0x1f; + int16_t nzimm = ((0 - ((first >> 7) & 0x20)) + | ((first >> 2) & 0x1f)); + if (rs1 == 0) + mne = nzimm == 0 ? "nop" : "c.nop"; + else + { + mne = nzimm == 0 ? "c.addi" : "addi"; + op[0] = op[1] = REG (rs1); + snprintf (addrbuf, sizeof (addrbuf), "%" PRId16, nzimm); + op[2] = addrbuf; + } + break; + case 2: + rs1 = (first >> 7) & 0x1f; + op[0] = op[1] = REG (rs1); + opaddr = ((first >> 7) & 0x20) | ((first >> 2) & 0x1f); + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr); + op[2] = addrbuf; + mne = rs1 == 0 ? "c.slli" : "slli"; + break; + case 3: + op[0] = FREGP ((first >> 2) & 0x7); + opaddr = ((first << 1) & 0xc0) | ((first >> 7) & 0x38); + snprintf (addrbuf, sizeof (addrbuf), "%" PRIu64 "(%s)", + opaddr, REGP ((first >> 7) & 0x7)); + op[1] = addrbuf; + mne = "fld"; + break; + case 4: + if (ebl->class == ELFCLASS32) + { + mne = "jal"; + opaddr = (((first << 3) & 0x20) | ((first >> 2) & 0xe) + | ((first << 1) & 0x80) | ((first >> 1) | 0x40) + | ((first << 2) & 0x400) | (first & 0xb00) + | ((first >> 6) & 0x10)); + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr); + op[0] = addrbuf; + } + else + { + int32_t imm = (((UINT32_C (0) - ((first >> 12) & 0x1)) << 5) + | ((first >> 2) & 0x1f)); + uint16_t reg = (first >> 7) & 0x1f; + if (reg == 0) + { + // Reserved + len = snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx16, first); + strp = addrbuf; + } + else + { + if (imm == 0) + mne = "sext.w"; + else + { + mne = "addiw"; + snprintf (addrbuf, sizeof (addrbuf), "%" PRId32, imm); + op[2] = addrbuf; + } + op[0] = op[1] = REG (reg); + } + } + break; + case 5: + op[0] = FREG ((first >> 7) & 0x1f); + opaddr = ((first << 4) & 0x1c0) | ((first >> 7) & 0x20) | ((first >> 2) & 0x18); + snprintf (addrbuf, sizeof (addrbuf), "%" PRIu64 "(%s)", opaddr, REG (2)); + op[1] = addrbuf; + mne = "fld"; + break; + case 6: + case 18: + mne = idx == 6 ? "lw" : "sw"; + op[0] = REGP ((first >> 2) & 0x7); + opaddr = (((first >> 7) & 0x38) | ((first << 1) & 0x40) + | ((first >> 4) & 0x4)); + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", + opaddr, REGP ((first >> 7) & 0x7)); + op[1] = addrbuf; + break; + case 7: + mne = (first & 0xf80) == 0 ? "c.li" : "li"; + op[0] = REG((first >> 7) & 0x1f); + snprintf (addrbuf, sizeof (addrbuf), "%" PRId16, + (UINT16_C (0) - ((first >> 7) & 0x20)) | ((first >> 2) & 0x1f)); + op[1] = addrbuf; + break; + case 8: + rd = ((first >> 7) & 0x1f); + if (rd == 0) + { + len = snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx16, first); + strp = addrbuf; + } + else + { + uint16_t uimm = (((first << 4) & 0xc0) + | ((first >> 7) & 0x20) + | ((first >> 2) & 0x1c)); + mne = "lw"; + op[0] = REG (rd); + snprintf (addrbuf, sizeof (addrbuf), "%" PRIu16 "(%s)", uimm, REG (2)); + op[1] = addrbuf; + } + break; + case 9: + if (ebl->class == ELFCLASS32) + { + mne = "flw"; + op[0] = FREGP ((first >> 2) & 0x7); + opaddr = (((first << 1) & 0x40) + | ((first >> 7) & 0x38) + | ((first >> 4) & 0x4)); + } + else + { + mne = "ld"; + op[0] = REGP ((first >> 2) & 0x7); + opaddr = ((first >> 7) & 0x38) | ((first << 1) & 0xc0); + } + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", + opaddr, REGP ((first >> 7) & 0x7)); + op[1] = addrbuf; + break; + case 10: + if ((first & 0xf80) == (2 << 7)) + { + mne = "addi"; + op[0] = op[1] = REG (2); + opaddr = (((first >> 2) & 0x10) | ((first << 3) & 0x20) + | ((first << 1) & 0x40) | ((first << 4) & 0x180) + | ((UINT64_C (0) - ((first >> 12) & 0x1)) << 9)); + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64, opaddr); + op[2] = addrbuf; + } + else + { + mne = "lui"; + op[0] = REG((first & 0xf80) >> 7); + opaddr = (((UINT64_C (0) - ((first >> 12) & 0x1)) & ~0x1f) + | ((first >> 2) & 0x1f)); + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr & 0xfffff); + op[1] = addrbuf; + } + break; + case 11: + if (ebl->class == ELFCLASS32) + { + mne = "flw"; + op[0] = FREG ((first >> 7) & 0x1f); + opaddr = (((first << 4) & 0xc0) + | ((first >> 7) & 0x20) + | ((first >> 2) & 0x1c)); + } + else + { + mne = "ld"; + op[0] = REG ((first >> 7) & 0x1f); + opaddr = (((first << 4) & 0x1c0) + | ((first >> 7) & 0x20) + | ((first >> 2) & 0x18)); + } + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", opaddr, REG (2)); + op[1] = addrbuf; + break; + case 13: + if ((first & 0xc00) != 0xc00) + { + int16_t imm = ((first >> 7) & 0x20) | ((first >> 2) & 0x1f); + if ((first & 0xc00) == 0x800) + { + imm |= 0 - (imm & 0x20); + mne = "andi"; + snprintf (addrbuf, sizeof (addrbuf), "%" PRId16, imm); + } + else + { + if (ebl->class != ELFCLASS32 || imm < 32) + { + mne = (first & 0x400) ? "srai" : "srli"; + if (imm == 0) + { + strcpy (stpcpy (mnebuf, "c."), mne); + mne = mnebuf; + } + } + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx16, imm); + } + op[2] = addrbuf; + } + else + { + op[2] = REGP ((first >> 2) & 0x7); + static const char *const arithmne[8] = + { + "sub", "xor", "or", "and", "subw", "addw", NULL, NULL + }; + mne = (char *) arithmne[((first >> 10) & 0x4) | ((first >> 5) & 0x3)]; + } + op[0] = op[1] = REGP ((first >> 7) & 0x7); + break; + case 14: + rs1 = (first >> 7) & 0x1f; + rs2 = (first >> 2) & 0x1f; + op[0] = REG (rs1); + if ((first & 0x1000) == 0) + { + if (rs2 == 0) + { + op[1] = NULL; + if (rs1 == 1) + { + mne = "ret"; + op[0] = NULL; + } + else + mne = "jr"; + } + else + { + mne = rs1 != 0 ? "mv" : "c.mv"; + op[1] = REG (rs2); + } + } + else + { + if (rs2 == 0) + { + if (rs1 == 0) + { + mne = "ebreak"; + op[0] = op[1] = NULL; + } + else + mne = "jalr"; + } + else + { + mne = rs1 != 0 ? "add" : "c.add"; + op[2] = REG (rs2); + op[1] = op[0]; + } + } + break; + case 15: + op[0] = FREGP ((first >> 2) & 0x7); + opaddr = ((first << 1) & 0xc0) | ((first >> 7) & 0x38); + snprintf (addrbuf, sizeof (addrbuf), "%" PRIu64 "(%s)", + opaddr, REGP ((first >> 7) & 0x7)); + op[1] = addrbuf; + mne = "fsd"; + break; + case 16: + opaddr = (((UINT64_C (0) - ((first >> 12) & 0x1)) << 11) + | ((first << 2) & 0x400) + | ((first >> 1) & 0x300) + | ((first << 1) & 0x80) + | ((first >> 1) & 0x40) + | ((first << 3) & 0x20) + | ((first >> 7) & 0x10) + | ((first >> 2) & 0xe)); + mne = "j"; + // TODO translate address + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, addr + opaddr); + op[0] = addrbuf; + break; + case 17: + op[0] = FREG ((first >> 2) & 0x1f); + opaddr = ((first >> 1) & 0x1c0) | ((first >> 7) & 0x38); + snprintf (addrbuf, sizeof (addrbuf), "%" PRIu64 "(%s)", opaddr, REG (2)); + op[1] = addrbuf; + mne = "fsd"; + break; + case 19: + case 22: + mne = idx == 19 ? "beqz" : "bnez"; + op[0] = REG (8 + ((first >> 7) & 0x7)); + opaddr = addr + (((UINT64_C (0) - ((first >> 12) & 0x1)) & ~0xff) + | ((first << 1) & 0xc0) | ((first << 3) & 0x20) + | ((first >> 7) & 0x18) | ((first >> 2) & 0x6)); + // TODO translate address + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr); + op[1] = addrbuf; + break; + case 20: + op[0] = REG ((first >> 2) & 0x1f); + opaddr = ((first >> 1) & 0xc0) | ((first >> 7) & 0x3c); + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", opaddr, REG (2)); + op[1] = addrbuf; + mne = "sw"; + break; + case 21: + if (idx == 18 || ebl->class == ELFCLASS32) + { + mne = "fsw"; + op[0] = FREGP ((first >> 2) & 0x7); + opaddr = (((first >> 7) & 0x38) | ((first << 1) & 0x40) + | ((first >> 4) & 0x4)); + } + else + { + mne = "sd"; + op[0] = REGP ((first >> 2) & 0x7); + opaddr = ((first >> 7) & 0x38) | ((first << 1) & 0xc0); + } + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", + opaddr, REGP ((first >> 7) & 0x7)); + op[1] = addrbuf; + break; + case 23: + if (idx == 18 || ebl->class == ELFCLASS32) + { + mne = "fsw"; + op[0] = FREG ((first & 0x7c) >> 2); + opaddr = ((first & 0x1e00) >> 7) | ((first & 0x180) >> 1); + } + else + { + mne = "sd"; + op[0] = REG ((first & 0x7c) >> 2); + opaddr = ((first & 0x1c00) >> 7) | ((first & 0x380) >> 1); + } + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", opaddr, REG (2)); + op[1] = addrbuf; + break; + default: + break; + } + + if (strp == NULL && mne == NULL) + { + len = snprintf (immbuf, sizeof (immbuf), "0x%04" PRIx16, first); + strp = immbuf; + } + } + else if (length == 4) + { + uint32_t word = read_4ubyte_unaligned (data); + size_t idx = (word >> 2) & 0x1f; + + switch (idx) + { + static const char widthchar[4] = { 's', 'd', '\0', 'q' }; + static const char intwidthchar[4] = { 'w', 'd', '\0', 'q' }; + static const char *const rndmode[8] = { "rne", "rtz", "rdn", "rup", "rmm", "???", "???", "dyn" }; + uint32_t rd; + uint32_t rs1; + uint32_t rs2; + uint32_t rs3; + uint32_t func; + + case 0x00: + case 0x01: + // LOAD and LOAD-FP + rd = (word >> 7) & 0x1f; + op[0] = idx == 0x00 ? REG (rd) : FREG (rd); + opaddr = ((int32_t) word) >> 20; + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", + opaddr, REG ((word >> 15) & 0x1f)); + op[1] = addrbuf; + func = (word >> 12) & 0x7; + static const char *const loadmne[8] = + { + "lb", "lh", "lw", "ld", "lbu", "lhu", "lwu", NULL + }; + static const char *const floadmne[8] = + { + NULL, NULL, "flw", "fld", "flq", NULL, NULL, NULL + }; + mne = (char *) (idx == 0x00 ? loadmne[func] : floadmne[func]); + break; + case 0x03: + // MISC-MEM + rd = (word >> 7) & 0x1f; + rs1 = (word >> 15) & 0x1f; + func = (word >> 12) & 0x7; + + if (word == 0x8330000f) + mne = "fence.tso"; + else if (word == 0x0000100f) + mne = "fence.i"; + else if (func == 0 && rd == 0 && rs1 == 0 && (word & 0xf0000000) == 0) + { + static const char *const order[16] = + { + "unknown", "w", "r", "rw", "o", "ow", "or", "orw", + "i", "iw", "ir", "irw", "io", "iow", "ior", "iorw" + }; + uint32_t pred = (word >> 20) & 0xf; + uint32_t succ = (word >> 24) & 0xf; + if (pred != 0xf || succ != 0xf) + { + op[0] = (char *) order[succ]; + op[1] = (char *) order[pred]; + } + mne = "fence"; + } + break; + case 0x04: + case 0x06: + // OP-IMM and OP-IMM32 + rd = (word >> 7) & 0x1f; + op[0] = REG (rd); + rs1 = (word >> 15) & 0x1f; + op[1] = REG (rs1); + opaddr = ((int32_t) word) >> 20; + static const char *const opimmmne[8] = + { + "addi", NULL, "slti", "sltiu", "xori", NULL, "ori", "andi" + }; + func = (word >> 12) & 0x7; + mne = (char *) opimmmne[func]; + if (mne == NULL) + { + const uint64_t shiftmask = ebl->class == ELFCLASS32 ? 0x1f : 0x3f; + if (func == 0x1 && (opaddr & ~shiftmask) == 0) + mne = "slli"; + else if (func == 0x5 && (opaddr & ~shiftmask) == 0) + mne = "srli"; + else if (func == 0x5 && (opaddr & ~shiftmask) == 0x400) + mne = "srai"; + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr & shiftmask); + op[2] = addrbuf; + } + else if (func == 0x0 && (rd != 0 || idx == 0x06) && rs1 == 0 && rd != 0) + { + mne = "li"; + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64, opaddr); + op[1] = addrbuf; + } + else if (func == 0x00 && opaddr == 0) + { + if (idx == 0x06) + mne ="sext."; + else if (rd == 0) + { + mne = "nop"; + op[0] = op[1] = NULL; + } + else + mne = "mv"; + } + else if (func == 0x3 && opaddr == 1) + mne = "seqz"; + else if (func == 0x4 && opaddr == -1) + { + mne = "not"; + op[2] = NULL; + } + else + { + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64, opaddr); + op[2] = addrbuf; + + if (func == 0x0 && rs1 == 0 && rd != 0) + { + op[1] = op[2]; + op[2] = NULL; + mne = "li"; + } + } + if (mne != NULL && idx == 0x06) + { + mne = strcpy (mnebuf, mne); + strcat (mnebuf, "w"); + } + break; + case 0x05: + case 0x0d: + // LUI and AUIPC + mne = idx == 0x05 ? "auipc" : "lui"; + op[0] = REG ((word >> 7) & 0x1f); + opaddr = word >> 12; + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr); + op[1] = addrbuf; + break; + case 0x08: + case 0x09: + // STORE and STORE-FP + rs2 = (word >> 20) & 0x1f; + op[0] = idx == 0x08 ? REG (rs2) : FREG (rs2); + opaddr = ((((int64_t) ((int32_t) word) >> 20)) & ~0x1f) | ((word >> 7) & 0x1f); + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", + opaddr, REG ((word >> 15) & 0x1f)); + op[1] = addrbuf; + func = (word >> 12) & 0x7; + static const char *const storemne[8] = + { + "sb", "sh", "sw", "sd", NULL, NULL, NULL, NULL + }; + static const char *const fstoremne[8] = + { + NULL, NULL, "fsw", "fsd", "fsq", NULL, NULL, NULL + }; + mne = (char *) (idx == 0x08 ? storemne[func] : fstoremne[func]); + break; + case 0x0b: + // AMO + op[0] = REG ((word >> 7) & 0x1f); + rs1 = (word >> 15) & 0x1f; + rs2 = (word >> 20) & 0x1f; + snprintf (addrbuf, sizeof (addrbuf), "(%s)", REG (rs1)); + op[2] = addrbuf; + size_t width = (word >> 12) & 0x7; + func = word >> 27; + static const char *const amomne[32] = + { + "amoadd", "amoswap", "lr", "sc", "amoxor", NULL, NULL, NULL, + "amoor", NULL, NULL, NULL, "amoand", NULL, NULL, NULL, + "amomin", NULL, NULL, NULL, "amomax", NULL, NULL, NULL, + "amominu", NULL, NULL, NULL, "amomaxu", NULL, NULL, NULL + }; + if (amomne[func] != NULL && width >= 2 && width <= 3 + && (func != 0x02 || rs2 == 0)) + { + if (func == 0x02) + { + op[1] = op[2]; + op[2] = NULL; + } + else + op[1] = REG (rs2); + + char *cp = stpcpy (mnebuf, amomne[func]); + *cp++ = '.'; + *cp++ = " wd "[width]; + assert (cp[-1] != ' '); + static const char *const aqrlstr[4] = + { + "", ".rl", ".aq", ".aqrl" + }; + strcpy (cp, aqrlstr[(word >> 25) & 0x3]); + mne = mnebuf; + } + break; + case 0x0c: + case 0x0e: + // OP and OP-32 + if ((word & 0xbc000000) == 0) + { + rs1 = (word >> 15) & 0x1f; + rs2 = (word >> 20) & 0x1f; + op[0] = REG ((word >> 7) & 0x1f); + func = ((word >> 21) & 0x10) | ((word >> 27) & 0x8) | ((word >> 12) & 0x7); + static const char *const arithmne2[32] = + { + "add", "sll", "slt", "sltu", "xor", "srl", "or", "and", + "sub", NULL, NULL, NULL, NULL, "sra", NULL, NULL, + "mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + static const char *const arithmne3[32] = + { + "addw", "sllw", NULL, NULL, NULL, "srlw", NULL, NULL, + "subw", NULL, NULL, NULL, NULL, "sraw", NULL, NULL, + "mulw", NULL, NULL, NULL, "divw", "divuw", "remw", "remuw", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + if (func == 8 && rs1 == 0) + { + mne = idx == 0x0c ? "neg" : "negw"; + op[1] = REG (rs2); + } + else if (idx == 0x0c && rs2 == 0 && func == 2) + { + op[1] = REG (rs1); + mne = "sltz"; + } + else if (idx == 0x0c && rs1 == 0 && (func == 2 || func == 3)) + { + op[1] = REG (rs2); + mne = func == 2 ? "sgtz" : "snez"; + } + else + { + mne = (char *) (idx == 0x0c ? arithmne2[func] : arithmne3[func]); + op[1] = REG (rs1); + op[2] = REG (rs2); + } + } + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // MADD, MSUB, NMSUB, NMADD + if ((word & 0x06000000) != 0x04000000) + { + rd = (word >> 7) & 0x1f; + rs1 = (word >> 15) & 0x1f; + rs2 = (word >> 20) & 0x1f; + rs3 = (word >> 27) & 0x1f; + uint32_t rm = (word >> 12) & 0x7; + width = (word >> 25) & 0x3; + + static const char *const fmamne[4] = + { + "fmadd.", "fmsub.", "fnmsub.", "fnmadd." + }; + char *cp = stpcpy (mnebuf, fmamne[idx & 0x3]); + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + op[0] = FREG (rd); + op[1] = FREG (rs1); + op[2] = FREG (rs2); + op[3] = FREG (rs3); + if (rm != 0x7) + op[4] = (char *) rndmode[rm]; + } + break; + case 0x14: + // OP-FP + if ((word & 0x06000000) != 0x04000000) + { + width = (word >> 25) & 0x3; + rd = (word >> 7) & 0x1f; + rs1 = (word >> 15) & 0x1f; + rs2 = (word >> 20) & 0x1f; + func = word >> 27; + uint32_t rm = (word >> 12) & 0x7; + if (func < 4) + { + static const char *const fpop[4] = + { + "fadd", "fsub", "fmul", "fdiv" + }; + char *cp = stpcpy (mnebuf, fpop[func]); + *cp++ = '.'; + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + op[0] = FREG (rd); + op[1] = FREG (rs1); + op[2] = FREG (rs2); + if (rm != 0x7) + op[3] = (char *) rndmode[rm]; + } + else if (func == 0x1c && width != 2 && rs2 == 0 && rm <= 1) + { + char *cp; + if (rm == 0) + { + cp = stpcpy (mnebuf, "fmv.x."); + *cp++ = intwidthchar[width]; + } + else + { + cp = stpcpy (mnebuf, "fclass."); + *cp++ = widthchar[width]; + } + *cp = '\0'; + mne = mnebuf; + op[0] = REG (rd); + op[1] = FREG (rs1); + } + else if (func == 0x1e && width != 2 && rs2 == 0 && rm == 0) + { + char *cp = stpcpy (mnebuf, "fmv."); + *cp++ = intwidthchar[width]; + strcpy (cp, ".x"); + mne = mnebuf; + op[0] = FREG (rd); + op[1] = REG (rs1); + } + else if (func == 0x14) + { + uint32_t cmpop = (word >> 12) & 0x7; + if (cmpop < 3) + { + static const char *const mnefpcmp[3] = + { + "fle", "flt", "feq" + }; + char *cp = stpcpy (mnebuf, mnefpcmp[cmpop]); + *cp++ = '.'; + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + op[0] = REG (rd); + op[1] = FREG (rs1); + op[2] = FREG (rs2); + } + } + else if (func == 0x04) + { + uint32_t cmpop = (word >> 12) & 0x7; + if (cmpop < 3) + { + op[0] = FREG (rd); + op[1] = FREG (rs1); + + static const char *const mnefpcmp[3] = + { + "fsgnj.", "fsgnjn.", "fsgnjx." + }; + static const char *const altsignmne[3] = + { + "fmv.", "fneg.", "fabs." + }; + char *cp = stpcpy (mnebuf, rs1 == rs2 ? altsignmne[cmpop] : mnefpcmp[cmpop]); + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + + if (rs1 != rs2) + op[2] = FREG (rs2); + } + } + else if (func == 0x08 && width != 2 && rs2 <= 3 && rs2 != 2 && rs2 != width) + { + op[0] = FREG (rd); + op[1] = FREG (rs1); + char *cp = stpcpy (mnebuf, "fcvt."); + *cp++ = widthchar[width]; + *cp++ = '.'; + *cp++ = widthchar[rs2]; + *cp = '\0'; + mne = mnebuf; + } + else if ((func & 0x1d) == 0x18 && width != 2 && rs2 < 4) + { + char *cp = stpcpy (mnebuf, "fcvt."); + if (func == 0x18) + { + *cp++ = rs2 >= 2 ? 'l' : 'w'; + if ((rs2 & 1) == 1) + *cp++ = 'u'; + *cp++ = '.'; + *cp++ = widthchar[width]; + *cp = '\0'; + op[0] = REG (rd); + op[1] = FREG (rs1); + } + else + { + *cp++ = widthchar[width]; + *cp++ = '.'; + *cp++ = rs2 >= 2 ? 'l' : 'w'; + if ((rs2 & 1) == 1) + *cp++ = 'u'; + *cp = '\0'; + op[0] = FREG (rd); + op[1] = REG (rs1); + } + mne = mnebuf; + if (rm != 0x7 && (func == 0x18 || width == 0 || rs2 >= 2)) + op[2] = (char *) rndmode[rm]; + } + else if (func == 0x0b && rs2 == 0) + { + op[0] = FREG (rd); + op[1] = FREG (rs1); + char *cp = stpcpy (mnebuf, "fsqrt."); + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + if (rm != 0x7) + op[2] = (char *) rndmode[rm]; + } + else if (func == 0x05 && rm < 2) + { + op[0] = FREG (rd); + op[1] = FREG (rs1); + op[2] = FREG (rs2); + char *cp = stpcpy (mnebuf, rm == 0 ? "fmin." : "fmax."); + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + } + else if (func == 0x14 && rm <= 0x2) + { + op[0] = REG (rd); + op[1] = FREG (rs1); + op[2] = FREG (rs2); + static const char *const fltcmpmne[3] = + { + "fle.", "flt.", "feq." + }; + char *cp = stpcpy (mnebuf, fltcmpmne[rm]); + *cp++ = widthchar[width]; + *cp = '\0'; + mne = mnebuf; + } + } + break; + case 0x18: + // BRANCH + rs1 = (word >> 15) & 0x1f; + op[0] = REG (rs1); + rs2 = (word >> 20) & 0x1f; + op[1] = REG (rs2); + opaddr = addr + (((UINT64_C (0) - (word >> 31)) << 12) + + ((word << 4) & 0x800) + + ((word >> 20) & 0x7e0) + + ((word >> 7) & 0x1e)); + // TODO translate address + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr); + op[2] = addrbuf; + static const char *const branchmne[8] = + { + "beq", "bne", NULL, NULL, "blt", "bge", "bltu", "bgeu" + }; + func = (word >> 12) & 0x7; + mne = (char *) branchmne[func]; + if (rs1 == 0 && func == 5) + { + op[0] = op[1]; + op[1] = op[2]; + op[2] = NULL; + mne = "blez"; + } + else if (rs1 == 0 && func == 4) + { + op[0] = op[1]; + op[1] = op[2]; + op[2] = NULL; + mne = "bgtz"; + } + else if (rs2 == 0) + { + if (func == 0 || func == 1 || func == 4 || func == 5) + { + op[1] = op[2]; + op[2] = NULL; + strcpy (stpcpy (mnebuf, mne), "z"); + mne = mnebuf; + } + } + else if (func == 5 || func == 7) + { + // binutils use these opcodes and the reverse parameter order + char *tmp = op[0]; + op[0] = op[1]; + op[1] = tmp; + mne = func == 5 ? "ble" : "bleu"; + } + break; + case 0x19: + // JALR + if ((word & 0x7000) == 0) + { + rd = (word >> 7) & 0x1f; + rs1 = (word >> 15) & 0x1f; + opaddr = (int32_t) word >> 20; + size_t next = 0; + if (rd > 1) + op[next++] = REG (rd); + if (opaddr == 0) + { + if (rs1 != 0 || next == 0) + op[next] = REG (rs1); + } + else + { + snprintf (addrbuf, sizeof (addrbuf), "%" PRId64 "(%s)", opaddr, REG (rs1)); + op[next] = addrbuf; + } + mne = rd == 0 ? "jr" : "jalr"; + } + break; + case 0x1b: + // JAL + rd = (word >> 7) & 0x1f; + if (rd != 0) + op[0] = REG (rd); + opaddr = addr + ((UINT64_C (0) - ((word >> 11) & 0x100000)) + | (word & 0xff000) + | ((word >> 9) & 0x800) + | ((word >> 20) & 0x7fe)); + // TODO translate address + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx64, opaddr); + op[rd != 0] = addrbuf; + mne = rd == 0 ? "j" : "jal"; + break; + case 0x1c: + // SYSTEM + rd = (word >> 7) & 0x1f; + rs1 = (word >> 15) & 0x1f; + if (word == 0x00000073) + mne = "ecall"; + else if (word == 0x00100073) + mne = "ebreak"; + else if (word == 0x00200073) + mne = "uret"; + else if (word == 0x10200073) + mne = "sret"; + else if (word == 0x30200073) + mne = "mret"; + else if (word == 0x10500073) + mne = "wfi"; + else if ((word & 0x3000) == 0x2000 && rs1 == 0) + { + uint32_t csr = word >> 20; + if (/* csr >= 0x000 && */ csr <= 0x007) + { + static const char *const unprivrw[4] = + { + NULL, "frflags", "frrm", "frsr", + }; + mne = (char *) unprivrw[csr - 0x000]; + } + else if (csr >= 0xc00 && csr <= 0xc03) + { + static const char *const unprivrolow[3] = + { + "rdcycle", "rdtime", "rdinstret" + }; + mne = (char *) unprivrolow[csr - 0xc00]; + } + op[0] = REG ((word >> 7) & 0x1f); + } + else if ((word & 0x3000) == 0x1000 && rd == 0) + { + uint32_t csr = word >> 20; + if (/* csr >= 0x000 && */ csr <= 0x003) + { + static const char *const unprivrs[4] = + { + NULL, "fsflags", "fsrm", "fssr", + }; + static const char *const unprivrsi[4] = + { + NULL, "fsflagsi", "fsrmi", NULL + }; + mne = (char *) ((word & 0x4000) == 0 ? unprivrs : unprivrsi)[csr - 0x000]; + + if ((word & 0x4000) == 0) + op[0] = REG ((word >> 15) & 0x1f); + else + { + snprintf (immbuf, sizeof (immbuf), "%" PRIu32, (word >> 15) & 0x1f); + op[0] = immbuf; + } + } + } + if (mne == NULL && (word & 0x3000) != 0) + { + static const char *const mnecsr[8] = + { + NULL, "csrrw", "csrrs", "csrrc", + NULL, "csrrwi", "csrrsi", "csrrci" + }; + static const struct known_csrs known[] = + { + // This list must remain sorted by NR. + { 0x000, "ustatus" }, + { 0x001, "fflags" }, + { 0x002, "fram" }, + { 0x003, "fcsr" }, + { 0x004, "uie" }, + { 0x005, "utvec" }, + { 0x040, "uscratch" }, + { 0x041, "uepc" }, + { 0x042, "ucause" }, + { 0x043, "utval" }, + { 0x044, "uip" }, + { 0x100, "sstatus" }, + { 0x102, "sedeleg" }, + { 0x103, "sideleg" }, + { 0x104, "sie" }, + { 0x105, "stvec" }, + { 0x106, "scounteren" }, + { 0x140, "sscratch" }, + { 0x141, "sepc" }, + { 0x142, "scause" }, + { 0x143, "stval" }, + { 0x144, "sip" }, + { 0x180, "satp" }, + { 0x200, "vsstatus" }, + { 0x204, "vsie" }, + { 0x205, "vstvec" }, + { 0x240, "vsscratch" }, + { 0x241, "vsepc" }, + { 0x242, "vscause" }, + { 0x243, "vstval" }, + { 0x244, "vsip" }, + { 0x280, "vsatp" }, + { 0x600, "hstatus" }, + { 0x602, "hedeleg" }, + { 0x603, "hideleg" }, + { 0x605, "htimedelta" }, + { 0x606, "hcounteren" }, + { 0x615, "htimedeltah" }, + { 0x680, "hgatp" }, + { 0xc00, "cycle" }, + { 0xc01, "time" }, + { 0xc02, "instret" }, + { 0xc03, "hpmcounter3" }, + { 0xc04, "hpmcounter4" }, + { 0xc05, "hpmcounter5" }, + { 0xc06, "hpmcounter6" }, + { 0xc07, "hpmcounter7" }, + { 0xc08, "hpmcounter8" }, + { 0xc09, "hpmcounter9" }, + { 0xc0a, "hpmcounter10" }, + { 0xc0b, "hpmcounter11" }, + { 0xc0c, "hpmcounter12" }, + { 0xc0d, "hpmcounter13" }, + { 0xc0e, "hpmcounter14" }, + { 0xc0f, "hpmcounter15" }, + { 0xc10, "hpmcounter16" }, + { 0xc11, "hpmcounter17" }, + { 0xc12, "hpmcounter18" }, + { 0xc13, "hpmcounter19" }, + { 0xc14, "hpmcounter20" }, + { 0xc15, "hpmcounter21" }, + { 0xc16, "hpmcounter22" }, + { 0xc17, "hpmcounter23" }, + { 0xc18, "hpmcounter24" }, + { 0xc19, "hpmcounter25" }, + { 0xc1a, "hpmcounter26" }, + { 0xc1b, "hpmcounter27" }, + { 0xc1c, "hpmcounter28" }, + { 0xc1d, "hpmcounter29" }, + { 0xc1e, "hpmcounter30" }, + { 0xc1f, "hpmcounter31" }, + { 0xc80, "cycleh" }, + { 0xc81, "timeh" }, + { 0xc82, "instreth" }, + { 0xc83, "hpmcounter3h" }, + { 0xc84, "hpmcounter4h" }, + { 0xc85, "hpmcounter5h" }, + { 0xc86, "hpmcounter6h" }, + { 0xc87, "hpmcounter7h" }, + { 0xc88, "hpmcounter8h" }, + { 0xc89, "hpmcounter9h" }, + { 0xc8a, "hpmcounter10h" }, + { 0xc8b, "hpmcounter11h" }, + { 0xc8c, "hpmcounter12h" }, + { 0xc8d, "hpmcounter13h" }, + { 0xc8e, "hpmcounter14h" }, + { 0xc8f, "hpmcounter15h" }, + { 0xc90, "hpmcounter16h" }, + { 0xc91, "hpmcounter17h" }, + { 0xc92, "hpmcounter18h" }, + { 0xc93, "hpmcounter19h" }, + { 0xc94, "hpmcounter20h" }, + { 0xc95, "hpmcounter21h" }, + { 0xc96, "hpmcounter22h" }, + { 0xc97, "hpmcounter23h" }, + { 0xc98, "hpmcounter24h" }, + { 0xc99, "hpmcounter25h" }, + { 0xc9a, "hpmcounter26h" }, + { 0xc9b, "hpmcounter27h" }, + { 0xc9c, "hpmcounter28h" }, + { 0xc9d, "hpmcounter29h" }, + { 0xc9e, "hpmcounter30h" }, + { 0xc9f, "hpmcounter31h" }, + }; + uint32_t csr = word >> 20; + uint32_t instr = (word >> 12) & 0x7; + size_t last = 0; + if (rd != 0) + op[last++] = REG (rd); + struct known_csrs key = { csr, NULL }; + struct known_csrs *found = bsearch (&key, known, + sizeof (known) / sizeof (known[0]), + sizeof (known[0]), + compare_csr); + if (found) + op[last] = (char *) found->name; + else + { + snprintf (addrbuf, sizeof (addrbuf), "0x%" PRIx32, csr); + op[last] = addrbuf; + } + ++last; + if ((word & 0x4000) == 0) + op[last] = REG ((word >> 15) & 0x1f); + else + { + snprintf (immbuf, sizeof (immbuf), "%" PRIu32, (word >> 15) & UINT32_C(0x1f)); + op[last] = immbuf; + } + if (instr == 1 && rd == 0) + mne = "csrw"; + else if (instr == 2 && rd == 0) + mne = "csrs"; + else if (instr == 6 && rd == 0) + mne = "csrsi"; + else if (instr == 2 && rs1 == 0) + mne = "csrr"; + else if (instr == 3 && rd == 0) + mne = "csrc"; + else + mne = (char *) mnecsr[instr]; + } + break; + default: + break; + } + + if (strp == NULL && mne == NULL) + { + len = snprintf (addrbuf, sizeof (addrbuf), "0x%08" PRIx32, word); + strp = addrbuf; + } + } + else + { + // No instruction encodings defined for these sizes yet. + char *cp = stpcpy (mnebuf, "0x"); + assert (length % 2 == 0); + for (size_t i = 0; i < length; i += 2) + cp += snprintf (cp, mnebuf + sizeof (mnebuf) - cp, "%04" PRIx16, + read_2ubyte_unaligned (data + i)); + strp = mnebuf; + len = cp - mnebuf; + } + + if (strp == NULL) + { + + if (0) + { + /* Resize the buffer. */ + char *oldbuf; + enomem: + oldbuf = buf; + if (buf == initbuf) + buf = malloc (2 * bufsize); + else + buf = realloc (buf, 2 * bufsize); + if (buf == NULL) + { + buf = oldbuf; + retval = ENOMEM; + goto do_ret; + } + bufsize *= 2; + + bufcnt = 0; + } + + unsigned long string_end_idx = 0; + fmt = save_fmt; + const char *deferred_start = NULL; + size_t deferred_len = 0; + // XXX Can we get this from color.c? + static const char color_off[] = "\e[0m"; + while (*fmt != '\0') + { + if (*fmt != '%') + { + char ch = *fmt++; + if (ch == '\\') + { + switch ((ch = *fmt++)) + { + case '0' ... '7': + { + int val = ch - '0'; + ch = *fmt; + if (ch >= '0' && ch <= '7') + { + val *= 8; + val += ch - '0'; + ch = *++fmt; + if (ch >= '0' && ch <= '7' && val < 32) + { + val *= 8; + val += ch - '0'; + ++fmt; + } + } + ch = val; + } + break; + + case 'n': + ch = '\n'; + break; + + case 't': + ch = '\t'; + break; + + default: + retval = EINVAL; + goto do_ret; + } + } + else if (ch == '\e' && *fmt == '[') + { + deferred_start = fmt - 1; + do + ++fmt; + while (*fmt != 'm' && *fmt != '\0'); + + if (*fmt == 'm') + { + deferred_len = ++fmt - deferred_start; + continue; + } + + fmt = deferred_start + 1; + deferred_start = NULL; + } + ADD_CHAR (ch); + continue; + } + ++fmt; + + int width = 0; + while (isdigit (*fmt)) + width = width * 10 + (*fmt++ - '0'); + + int prec = 0; + if (*fmt == '.') + while (isdigit (*++fmt)) + prec = prec * 10 + (*fmt - '0'); + + size_t start_idx = bufcnt; + size_t non_printing = 0; + switch (*fmt++) + { + case 'm': + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + ADD_STRING (mne); + + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + + string_end_idx = bufcnt; + break; + + case 'o': + if (op[prec - 1] != NULL) + { + if (deferred_start != NULL) + { + ADD_NSTRING (deferred_start, deferred_len); + non_printing += deferred_len; + } + + ADD_STRING (op[prec - 1]); + + if (deferred_start != NULL) + { + ADD_STRING (color_off); + non_printing += strlen (color_off); + } + + string_end_idx = bufcnt; + } + else + bufcnt = string_end_idx; + break; + + case 'e': + string_end_idx = bufcnt; + break; + + case 'a': + /* Pad to requested column. */ + while (bufcnt - non_printing < (size_t) width) + ADD_CHAR (' '); + width = 0; + break; + + case 'l': + // TODO + break; + + default: + abort(); + } + + /* Pad according to the specified width. */ + while (bufcnt - non_printing < start_idx + width) + ADD_CHAR (' '); + } + + strp = buf; + len = bufcnt; + } + + addr += length; + *startp = data + length; + retval = outcb (strp, len, outcbarg); + if (retval != 0) + break; + } + + do_ret: + if (buf != initbuf) + free (buf); + + return retval; +} diff --git a/libcpu/x86_64_dis.h b/libcpu/x86_64_dis.h new file mode 100644 index 00000000..a0198bed --- /dev/null +++ b/libcpu/x86_64_dis.h @@ -0,0 +1,1632 @@ +#define MNEMONIC_BITS 10 +#define SUFFIX_BITS 3 +#define FCT1_BITS 7 +#define STR1_BITS 4 +#define OFF1_1_BITS 7 +#define OFF1_1_BIAS 3 +#define OFF1_2_BITS 7 +#define OFF1_2_BIAS 4 +#define OFF1_3_BITS 1 +#define OFF1_3_BIAS 7 +#define FCT2_BITS 6 +#define STR2_BITS 2 +#define OFF2_1_BITS 7 +#define OFF2_1_BIAS 5 +#define OFF2_2_BITS 7 +#define OFF2_2_BIAS 4 +#define OFF2_3_BITS 4 +#define OFF2_3_BIAS 7 +#define FCT3_BITS 4 +#define STR3_BITS 1 +#define OFF3_1_BITS 6 +#define OFF3_1_BIAS 10 +#define OFF3_2_BITS 1 +#define OFF3_2_BIAS 21 + +#include + +#define suffix_none 0 +#define suffix_w 1 +#define suffix_w0 2 +#define suffix_W 3 +#define suffix_tttn 4 +#define suffix_D 7 +#define suffix_w1 5 +#define suffix_W1 6 + +static const opfct_t op1_fct[] = +{ + NULL, + FCT_MOD$R_M, + FCT_Mod$R_m, + FCT_abs, + FCT_ax, + FCT_ax$w, + FCT_ccc, + FCT_ddd, + FCT_disp8, + FCT_ds_bx, + FCT_ds_si, + FCT_dx, + FCT_es_di, + FCT_freg, + FCT_imm$s, + FCT_imm$w, + FCT_imm16, + FCT_imm64$w, + FCT_imm8, + FCT_imms8, + FCT_mmxreg, + FCT_mod$16r_m, + FCT_mod$64r_m, + FCT_mod$8r_m, + FCT_mod$r_m, + FCT_mod$r_m$w, + FCT_reg, + FCT_reg$w, + FCT_reg64, + FCT_rel, + FCT_sel, + FCT_sreg2, + FCT_sreg3, + FCT_string, + FCT_xmmreg, +}; +static const char op1_str[] = + "%ax\0" + "%cl\0" + "%rax\0" + "%st\0" + "%xmm0\0" + "*"; +static const uint8_t op1_str_idx[] = { + 0, + 4, + 8, + 13, + 17, + 23, +}; +static const opfct_t op2_fct[] = +{ + NULL, + FCT_MOD$R_M, + FCT_Mod$R_m, + FCT_abs, + FCT_absval, + FCT_ax$w, + FCT_ccc, + FCT_ddd, + FCT_ds_si, + FCT_dx, + FCT_es_di, + FCT_freg, + FCT_imm8, + FCT_mmxreg, + FCT_mod$64r_m, + FCT_mod$r_m, + FCT_mod$r_m$w, + FCT_oreg, + FCT_oreg$w, + FCT_reg, + FCT_reg$w, + FCT_reg64, + FCT_sreg3, + FCT_string, + FCT_xmmreg, +}; +static const char op2_str[] = + "%rcx\0" + "%st"; +static const uint8_t op2_str_idx[] = { + 0, + 5, +}; +static const opfct_t op3_fct[] = +{ + NULL, + FCT_mmxreg, + FCT_mod$r_m, + FCT_reg, + FCT_string, + FCT_xmmreg, +}; +static const char op3_str[] = + "%rdx"; +static const uint8_t op3_str_idx[] = { + 0, +}; +static const struct instr_enc instrtab[] = +{ + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_adc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_add, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addsubpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addsubps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_and, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movslq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 21, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bsf, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bswap, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 26, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bt, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_btr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bts, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_bts, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_call, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 29, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_call, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 22, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lcall, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 22, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_clc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cli, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_syscall, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_clts, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sysret, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sysenter, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sysexit, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmov, .rep = 0, .repe = 0, .suffix = 4, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmps, .rep = 0, .repe = 1, .suffix = 1, .modrm = 0, .fct1 = 12, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 8, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpxchg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 15, .off1_2 = 11, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 8, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cpuid, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtdq2pd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpd2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttpd2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_dec, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_div, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_emms, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_enter, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 16, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 12, .str2 = 0, .off2_1 = 19, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fchs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fabs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ftst, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxam, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fld1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldl2t, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldl2e, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldpi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldlg2, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldln2, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldz, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_f2xm1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fyl2x, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fptan, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fpatan, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxtract, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fprem1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdecstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fincstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fprem, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fyl2xp1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsqrt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsincos, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_frndint, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fscale, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsin, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcos, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fadd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fadd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fadd, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmul, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsub, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubr, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fst, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fst, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fstp, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldenv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldcw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstenv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstcw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxch, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_faddp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fiadd, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmove, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fmulp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fimul, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisub, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fsubrp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisubr, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 1, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fbld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomip, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fbstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fchs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fclex, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_finit, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fwait, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnclex, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmove, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovbe, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovnb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovne, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovnbe, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovnu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcom, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcom, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomp, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcompp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcomip, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucomi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucomip, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcos, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdecstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdiv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdiv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdiv, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidivl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidiv, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivrp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 2, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivr, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidivrl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fidivr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fdivrp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 4, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 11, .str2 = 0, .off2_1 = 8, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ffree, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovbe, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ficom, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fcmovu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ficomp, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fild, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fildl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fildll, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fincstp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fninit, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fist, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fistp, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fistpll, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisttp, .rep = 0, .repe = 0, .suffix = 5, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fisttpll, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fldt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fstpt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fld, .rep = 0, .repe = 0, .suffix = 7, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucom, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_frstor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fucomp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 13, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnsave, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fnstsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_hlt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_idiv, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_imul, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_imul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_imul, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 14, .str1 = 0, .off1_1 = 13, .off1_2 = 2, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 3, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_in, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_in, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 11, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 3, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_inc, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ins, .rep = 1, .repe = 0, .suffix = 1, .modrm = 0, .fct1 = 11, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 10, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_int, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_int3, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_invd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_swapgs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_invlpg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_iret, .rep = 0, .repe = 0, .suffix = 6, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_j, .rep = 0, .repe = 0, .suffix = 4, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_j, .rep = 0, .repe = 0, .suffix = 4, .modrm = 0, .fct1 = 29, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_set, .rep = 0, .repe = 0, .suffix = 4, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_jmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_jmp, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 29, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_jmp, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 22, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ljmp, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 30, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 4, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ljmp, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 22, .str1 = 6, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lahf, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lar, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lea, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_leave, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lfs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lgs, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lgdt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lidt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lldt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lmsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lock, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lods, .rep = 1, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 10, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 3, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_loop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_loope, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_loopne, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 8, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lsl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ltr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 17, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 18, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 3, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 35, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 37, .off1_2 = 3, .off1_3 = 0, .fct2 = 3, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 6, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 21, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 6, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 7, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 21, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 7, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 32, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mov, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 22, .str2 = 0, .off2_1 = 5, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movs, .rep = 1, .repe = 0, .suffix = 1, .modrm = 0, .fct1 = 10, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 10, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsbl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movswl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movzbl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movzwl, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mul, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_neg, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pause, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_popcnt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_not, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_or, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_out, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 12, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_out, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 9, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_outs, .rep = 1, .repe = 0, .suffix = 1, .modrm = 0, .fct1 = 10, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 9, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 3, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 32, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_popf, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 10, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pushq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 2, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 28, .str1 = 0, .off1_1 = 2, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 14, .str1 = 0, .off1_1 = 5, .off1_2 = 2, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 31, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_push, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 32, .str1 = 0, .off1_1 = 7, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pushf, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rdmsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rdpmc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rdtsc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ret, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ret, .rep = 0, .repe = 0, .suffix = 3, .modrm = 0, .fct1 = 16, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lret, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lret, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 16, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rol, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rol, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rol, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ror, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ror, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ror, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rsm, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sahf, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sar, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sar, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sar, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sbb, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_scas, .rep = 0, .repe = 1, .suffix = 0, .modrm = 0, .fct1 = 12, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 3, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_set, .rep = 0, .repe = 0, .suffix = 4, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shl, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_shld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_shr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shr, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_shrd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_shrd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 2, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 2, .str3 = 0, .off3_1 = 6, .off3_2 = 0, }, + { .mnemonic = MNE_vmcall, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmlaunch, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmresume, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmxoff, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmread, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 28, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 14, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmwrite, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 22, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 21, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sgdt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_monitor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 3, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 1, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 4, .str3 = 1, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mwait, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 33, .str1 = 3, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 23, .str2 = 1, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sidt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sldt, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_smsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_stc, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_std, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sti, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_stos, .rep = 1, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 5, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 10, .str2 = 0, .off2_1 = 3, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_str, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sub, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_test, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_test, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_test, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ud2a, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_verr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_verw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 21, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_wbinvd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetch, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetchw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 23, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetchnta, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetcht0, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetcht1, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_prefetcht2, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_nop, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_wrmsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xadd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 15, .off1_2 = 11, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 8, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xchg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xchg, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 4, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 17, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xlat, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 9, .str1 = 0, .off1_1 = 5, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 27, .str1 = 0, .off1_1 = 7, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 25, .str1 = 0, .off1_1 = 5, .off1_2 = 9, .off1_3 = 0, .fct2 = 20, .str2 = 0, .off2_1 = 5, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 15, .str1 = 0, .off1_1 = 5, .off1_2 = 3, .off1_3 = 0, .fct2 = 5, .str2 = 0, .off2_1 = 11, .off2_2 = 3, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 15, .str1 = 0, .off1_1 = 13, .off1_2 = 3, .off1_3 = 0, .fct2 = 16, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xor, .rep = 0, .repe = 0, .suffix = 1, .modrm = 1, .fct1 = 19, .str1 = 0, .off1_1 = 13, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 3, .off2_2 = 9, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_emms, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pand, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pand, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pandn, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pandn, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_por, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_por, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pxor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pxor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpeqps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpltps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpleps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpunordps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpneqps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnltps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnleps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpordps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpeqss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpltss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpless, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpunordss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpneqss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnltss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpnless, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cmpordss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxrstor, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_fxsave, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ldmxcsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_stmxcsr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movupd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movups, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movupd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movups, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movddup, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movsldup, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhlpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpcklpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpcklps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpckhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_unpckhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movshdup, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movlhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movhps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movapd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movaps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movapd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movaps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsi2sd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsi2ss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpi2pd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpi2ps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttsd2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttss2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttpd2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttps2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpd2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsd2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtss2si, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtps2pi, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ucomisd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ucomiss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_comisd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_comiss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_getsec, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movmskpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movmskps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sqrtps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rsqrtss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rsqrtps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcpss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_rcpps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_andnps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_orpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_orps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xorpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_xorps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_addps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mulps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtsd2ss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtss2sd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtpd2ps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtps2pd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtps2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvttps2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_cvtdq2ps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_subps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_minps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_divps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maxps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packsswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packsswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packuswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packuswb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packssdw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_packssdw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpcklqdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_punpckhqdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pshufd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pshuflw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pshufhw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pshufw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 1, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_haddpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_haddps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_hsubpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_hsubps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movnti, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 26, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 1, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_pextrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 3, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_pextrw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 3, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_shufpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_shufps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 8, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmullw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmullw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movdq2q, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movq2dq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 20, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovmskb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovmskb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 20, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 19, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddusw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxub, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pavgw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 34, .str1 = 0, .off1_1 = 23, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_movntq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 20, .str1 = 0, .off1_1 = 15, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 11, .off2_2 = 17, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lddqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmuludq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmuludq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psadbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psadbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maskmovdqu, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 34, .str1 = 0, .off1_1 = 26, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_maskmovq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 20, .str1 = 0, .off1_1 = 18, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psubq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_paddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pshufb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pshufb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phaddsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaddubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phsubsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psignd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhrsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulhrsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pabsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 21, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_palignr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_palignr, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 1, .str2 = 0, .off2_1 = 19, .off2_2 = 25, .off2_3 = 0, .fct3 = 1, .str3 = 0, .off3_1 = 16, .off3_2 = 0, }, + { .mnemonic = MNE_vmclear, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmxon, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 21, .off1_2 = 25, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmptrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_vmptrst, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psraw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrad, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrlq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psrldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_psllq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 21, .off1_2 = 0, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 16, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pslldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 18, .str1 = 0, .off1_1 = 29, .off1_2 = 0, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 24, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_lfence, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mfence, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_sfence, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 0, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_clflush, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 24, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_INVALID, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 1, .str1 = 0, .off1_1 = 13, .off1_2 = 17, .off1_3 = 0, .fct2 = 13, .str2 = 0, .off2_1 = 13, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_blendps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_blendpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_blendvps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 5, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_blendvpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 5, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_dpps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_dppd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_insertps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_movntdqa, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_mpsadbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_packusdw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pblendvb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 33, .str1 = 5, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pblendw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpeqq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpestri, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpestrm, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpistri, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpistrm, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pcmpgtq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_phminposuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pinsrd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 15, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxud, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmaxuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsb, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminud, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pminuw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxbd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxbq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxwq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovsxdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxbw, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxbd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxbq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxwd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxwq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmovzxdq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmuldq, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_pmulld, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_ptest, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 2, .str1 = 0, .off1_1 = 29, .off1_2 = 33, .off1_3 = 0, .fct2 = 24, .str2 = 0, .off2_1 = 29, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, + { .mnemonic = MNE_roundps, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_roundpd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_roundss, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_roundsd, .rep = 0, .repe = 0, .suffix = 0, .modrm = 1, .fct1 = 18, .str1 = 0, .off1_1 = 37, .off1_2 = 0, .off1_3 = 0, .fct2 = 2, .str2 = 0, .off2_1 = 27, .off2_2 = 33, .off2_3 = 0, .fct3 = 5, .str3 = 0, .off3_1 = 24, .off3_2 = 0, }, + { .mnemonic = MNE_pop, .rep = 0, .repe = 0, .suffix = 0, .modrm = 0, .fct1 = 31, .str1 = 0, .off1_1 = 0, .off1_2 = 0, .off1_3 = 0, .fct2 = 0, .str2 = 0, .off2_1 = 0, .off2_2 = 0, .off2_3 = 0, .fct3 = 0, .str3 = 0, .off3_1 = 0, .off3_2 = 0, }, +}; +static const uint8_t match_data[] = +{ + 0x1, 0xfe, 0x14, + 0x2, 0xfe, 0x80, 0x38, 0x10, + 0x2, 0xfe, 0x82, 0x38, 0x10, + 0x2, 0xfe, 0x10, 0, 0, + 0x2, 0xfe, 0x12, 0, 0, + 0x1, 0xfe, 0x4, + 0x2, 0xfe, 0x80, 0x38, 0, + 0x12, 0x83, 0x38, 0, + 0x2, 0xfe, 0, 0, 0, + 0x2, 0xfe, 0x2, 0, 0, + 0x34, 0x66, 0xf, 0xd0, 0, 0, + 0x34, 0xf2, 0xf, 0xd0, 0, 0, + 0x1, 0xfe, 0x24, + 0x2, 0xfe, 0x80, 0x38, 0x20, + 0x2, 0xfe, 0x82, 0x38, 0x20, + 0x2, 0xfe, 0x20, 0, 0, + 0x2, 0xfe, 0x22, 0, 0, + 0x34, 0x66, 0xf, 0x54, 0, 0, + 0x23, 0xf, 0x54, 0, 0, + 0x34, 0x66, 0xf, 0x55, 0, 0, + 0x23, 0xf, 0x55, 0, 0, + 0x12, 0x63, 0, 0, + 0x23, 0xf, 0xbc, 0, 0, + 0x23, 0xf, 0xbd, 0, 0, + 0x12, 0xf, 0xf8, 0xc8, + 0x23, 0xf, 0xa3, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x20, + 0x23, 0xf, 0xbb, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x38, + 0x23, 0xf, 0xb3, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x30, + 0x23, 0xf, 0xab, 0, 0, + 0x23, 0xf, 0xba, 0x38, 0x28, + 0x11, 0xe8, + 0x12, 0xff, 0x38, 0x10, + 0x12, 0xff, 0x38, 0x18, + 0x11, 0x98, + 0x11, 0x99, + 0x11, 0xf8, + 0x11, 0xfc, + 0x11, 0xfa, + 0x22, 0xf, 0x5, + 0x22, 0xf, 0x6, + 0x22, 0xf, 0x7, + 0x22, 0xf, 0x34, + 0x22, 0xf, 0x35, + 0x11, 0xf5, + 0x13, 0xf, 0xf0, 0x40, 0, 0, + 0x1, 0xfe, 0x3c, + 0x2, 0xfe, 0x80, 0x38, 0x38, + 0x12, 0x83, 0x38, 0x38, + 0x2, 0xfe, 0x38, 0, 0, + 0x2, 0xfe, 0x3a, 0, 0, + 0x34, 0xf2, 0xf, 0xc2, 0, 0, + 0x34, 0xf3, 0xf, 0xc2, 0, 0, + 0x34, 0x66, 0xf, 0xc2, 0, 0, + 0x23, 0xf, 0xc2, 0, 0, + 0x1, 0xfe, 0xa6, + 0x13, 0xf, 0xfe, 0xb0, 0, 0, + 0x23, 0xf, 0xc7, 0x38, 0x8, + 0x22, 0xf, 0xa2, + 0x34, 0xf3, 0xf, 0xe6, 0, 0, + 0x34, 0xf2, 0xf, 0xe6, 0, 0, + 0x34, 0x66, 0xf, 0xe6, 0, 0, + 0x2, 0xfe, 0xfe, 0x38, 0x8, + 0x2, 0xfe, 0xf6, 0x38, 0x30, + 0x22, 0xf, 0x77, + 0x11, 0xc8, + 0x22, 0xd9, 0xd0, + 0x22, 0xd9, 0xe0, + 0x22, 0xd9, 0xe1, + 0x22, 0xd9, 0xe4, + 0x22, 0xd9, 0xe5, + 0x22, 0xd9, 0xe8, + 0x22, 0xd9, 0xe9, + 0x22, 0xd9, 0xea, + 0x22, 0xd9, 0xeb, + 0x22, 0xd9, 0xec, + 0x22, 0xd9, 0xed, + 0x22, 0xd9, 0xee, + 0x22, 0xd9, 0xf0, + 0x22, 0xd9, 0xf1, + 0x22, 0xd9, 0xf2, + 0x22, 0xd9, 0xf3, + 0x22, 0xd9, 0xf4, + 0x22, 0xd9, 0xf5, + 0x22, 0xd9, 0xf6, + 0x22, 0xd9, 0xf7, + 0x22, 0xd9, 0xf8, + 0x22, 0xd9, 0xf9, + 0x22, 0xd9, 0xfa, + 0x22, 0xd9, 0xfb, + 0x22, 0xd9, 0xfc, + 0x22, 0xd9, 0xfd, + 0x22, 0xd9, 0xfe, + 0x22, 0xd9, 0xff, + 0x12, 0xd8, 0xf8, 0xc0, + 0x12, 0xdc, 0xf8, 0xc0, + 0x2, 0xfb, 0xd8, 0x38, 0, + 0x12, 0xd8, 0xf8, 0xc8, + 0x12, 0xdc, 0xf8, 0xc8, + 0x2, 0xfb, 0xd8, 0x38, 0x8, + 0x12, 0xd8, 0xf8, 0xe0, + 0x12, 0xdc, 0xf8, 0xe0, + 0x2, 0xfb, 0xd8, 0x38, 0x20, + 0x12, 0xd8, 0xf8, 0xe8, + 0x12, 0xdc, 0xf8, 0xe8, + 0x2, 0xfb, 0xd8, 0x38, 0x28, + 0x12, 0xdd, 0xf8, 0xd0, + 0x2, 0xfb, 0xd9, 0x38, 0x10, + 0x12, 0xdd, 0xf8, 0xd8, + 0x2, 0xfb, 0xd9, 0x38, 0x18, + 0x12, 0xd9, 0x38, 0x20, + 0x12, 0xd9, 0x38, 0x28, + 0x12, 0xd9, 0x38, 0x30, + 0x12, 0xd9, 0x38, 0x38, + 0x12, 0xd9, 0xf8, 0xc8, + 0x12, 0xde, 0xf8, 0xc0, + 0x12, 0xda, 0xf8, 0xc0, + 0x2, 0xfb, 0xda, 0x38, 0, + 0x12, 0xda, 0xf8, 0xc8, + 0x12, 0xde, 0xf8, 0xc8, + 0x2, 0xfb, 0xda, 0x38, 0x8, + 0x12, 0xde, 0xf8, 0xe0, + 0x2, 0xfb, 0xda, 0x38, 0x20, + 0x12, 0xde, 0xf8, 0xe8, + 0x2, 0xfb, 0xda, 0x38, 0x28, + 0x22, 0xdf, 0xe0, + 0x12, 0xdf, 0x38, 0x20, + 0x12, 0xdf, 0xf8, 0xf0, + 0x12, 0xdf, 0x38, 0x30, + 0x22, 0xd9, 0xe0, + 0x33, 0x9b, 0xdb, 0xe2, + 0x33, 0x9b, 0xdb, 0xe3, + 0x11, 0x9b, + 0x22, 0xdb, 0xe2, + 0x12, 0xda, 0xf8, 0xc0, + 0x12, 0xda, 0xf8, 0xc8, + 0x12, 0xda, 0xf8, 0xd0, + 0x12, 0xda, 0xf8, 0xd8, + 0x12, 0xdb, 0xf8, 0xc0, + 0x12, 0xdb, 0xf8, 0xc8, + 0x12, 0xdb, 0xf8, 0xd0, + 0x12, 0xdb, 0xf8, 0xd8, + 0x12, 0xd8, 0xf8, 0xd0, + 0x2, 0xfb, 0xd8, 0x38, 0x10, + 0x12, 0xd8, 0xf8, 0xd8, + 0x2, 0xfb, 0xd8, 0x38, 0x18, + 0x22, 0xde, 0xd9, + 0x12, 0xdb, 0xf8, 0xf0, + 0x12, 0xdf, 0xf8, 0xf0, + 0x12, 0xdb, 0xf8, 0xe8, + 0x12, 0xdf, 0xf8, 0xe8, + 0x22, 0xd9, 0xff, + 0x22, 0xd9, 0xf6, + 0x12, 0xd8, 0xf8, 0xf0, + 0x12, 0xdc, 0xf8, 0xf0, + 0x2, 0xfb, 0xd8, 0x38, 0x30, + 0x12, 0xda, 0x38, 0x30, + 0x12, 0xde, 0xf8, 0xf0, + 0x12, 0xde, 0x38, 0x30, + 0x12, 0xde, 0xf8, 0xf8, + 0x12, 0xd8, 0xf8, 0xf8, + 0x12, 0xdc, 0xf8, 0xf8, + 0x2, 0xfb, 0xd8, 0x38, 0x38, + 0x12, 0xda, 0x38, 0x38, + 0x12, 0xde, 0x38, 0x38, + 0x12, 0xde, 0xf8, 0xf0, + 0x12, 0xdd, 0xf8, 0xc0, + 0x12, 0xda, 0xf8, 0xd0, + 0x2, 0xfb, 0xda, 0x38, 0x10, + 0x12, 0xda, 0xf8, 0xd8, + 0x2, 0xfb, 0xda, 0x38, 0x18, + 0x12, 0xdf, 0x38, 0, + 0x12, 0xdb, 0x38, 0, + 0x12, 0xdf, 0x38, 0x28, + 0x22, 0xd9, 0xf7, + 0x22, 0xdb, 0xe3, + 0x2, 0xfb, 0xdb, 0x38, 0x10, + 0x2, 0xfb, 0xdb, 0x38, 0x18, + 0x12, 0xdf, 0x38, 0x38, + 0x2, 0xfb, 0xdb, 0x38, 0x8, + 0x12, 0xdd, 0x38, 0x8, + 0x12, 0xdb, 0x38, 0x28, + 0x12, 0xdb, 0x38, 0x38, + 0x12, 0xd9, 0xf8, 0xc0, + 0x2, 0xfb, 0xd9, 0x38, 0, + 0x12, 0xdd, 0xf8, 0xe0, + 0x12, 0xdd, 0x38, 0x20, + 0x12, 0xdd, 0xf8, 0xe8, + 0x12, 0xdd, 0x38, 0x30, + 0x12, 0xdd, 0x38, 0x38, + 0x11, 0xf4, + 0x2, 0xfe, 0xf6, 0x38, 0x38, + 0x2, 0xfe, 0xf6, 0x38, 0x28, + 0x23, 0xf, 0xaf, 0, 0, + 0x2, 0xfd, 0x69, 0, 0, + 0x1, 0xfe, 0xe4, + 0x1, 0xfe, 0xec, + 0x2, 0xfe, 0xfe, 0x38, 0, + 0x1, 0xfe, 0x6c, + 0x11, 0xcd, + 0x11, 0xcc, + 0x22, 0xf, 0x8, + 0x33, 0xf, 0x1, 0xf8, + 0x23, 0xf, 0x1, 0x38, 0x38, + 0x11, 0xcf, + 0x1, 0xf0, 0x70, + 0x12, 0xf, 0xf0, 0x80, + 0x13, 0xf, 0xf0, 0x90, 0x38, 0, + 0x11, 0xe3, + 0x11, 0xeb, + 0x11, 0xe9, + 0x12, 0xff, 0x38, 0x20, + 0x11, 0xea, + 0x12, 0xff, 0x38, 0x28, + 0x11, 0x9f, + 0x23, 0xf, 0x2, 0, 0, + 0x12, 0x8d, 0, 0, + 0x11, 0xc9, + 0x23, 0xf, 0xb4, 0, 0, + 0x23, 0xf, 0xb5, 0, 0, + 0x23, 0xf, 0x1, 0x38, 0x10, + 0x23, 0xf, 0x1, 0x38, 0x18, + 0x23, 0xf, 0, 0x38, 0x10, + 0x23, 0xf, 0x1, 0x38, 0x30, + 0x11, 0xf0, + 0x1, 0xfe, 0xac, + 0x11, 0xe2, + 0x11, 0xe1, + 0x11, 0xe0, + 0x23, 0xf, 0x3, 0, 0, + 0x23, 0xf, 0xb2, 0, 0, + 0x23, 0xf, 0, 0x38, 0x18, + 0x2, 0xfe, 0x88, 0, 0, + 0x2, 0xfe, 0x8a, 0, 0, + 0x2, 0xfe, 0xc6, 0x38, 0, + 0x1, 0xf0, 0xb0, + 0x1, 0xfe, 0xa0, + 0x1, 0xfe, 0xa2, + 0x23, 0xf, 0x20, 0xc0, 0xc0, + 0x23, 0xf, 0x22, 0xc0, 0xc0, + 0x23, 0xf, 0x21, 0xc0, 0xc0, + 0x23, 0xf, 0x23, 0xc0, 0xc0, + 0x12, 0x8c, 0, 0, + 0x12, 0x8e, 0, 0, + 0x1, 0xfe, 0xa4, + 0x23, 0xf, 0xbe, 0, 0, + 0x23, 0xf, 0xbf, 0, 0, + 0x23, 0xf, 0xb6, 0, 0, + 0x23, 0xf, 0xb7, 0, 0, + 0x2, 0xfe, 0xf6, 0x38, 0x20, + 0x2, 0xfe, 0xf6, 0x38, 0x18, + 0x22, 0xf3, 0x90, + 0x11, 0x90, + 0x34, 0xf3, 0xf, 0xb8, 0, 0, + 0x2, 0xfe, 0xf6, 0x38, 0x10, + 0x2, 0xfe, 0x8, 0, 0, + 0x2, 0xfe, 0xa, 0, 0, + 0x2, 0xfe, 0x80, 0x38, 0x8, + 0x2, 0xfe, 0x82, 0x38, 0x8, + 0x1, 0xfe, 0xc, + 0x1, 0xfe, 0xe6, + 0x1, 0xfe, 0xee, + 0x1, 0xfe, 0x6e, + 0x12, 0x8f, 0xf8, 0xc0, + 0x12, 0x8f, 0x38, 0, + 0x12, 0xf, 0xc7, 0x81, + 0x11, 0x9d, + 0x12, 0xff, 0xf8, 0xf0, + 0x12, 0xff, 0x38, 0x30, + 0x1, 0xf8, 0x50, + 0x1, 0xf8, 0x58, + 0x1, 0xfd, 0x68, + 0x1, 0xe7, 0x6, + 0x12, 0xf, 0xc7, 0x80, + 0x11, 0x9c, + 0x2, 0xfe, 0xd0, 0x38, 0x10, + 0x2, 0xfe, 0xd2, 0x38, 0x10, + 0x2, 0xfe, 0xc0, 0x38, 0x10, + 0x2, 0xfe, 0xd0, 0x38, 0x18, + 0x2, 0xfe, 0xd2, 0x38, 0x18, + 0x2, 0xfe, 0xc0, 0x38, 0x18, + 0x22, 0xf, 0x32, + 0x22, 0xf, 0x33, + 0x22, 0xf, 0x31, + 0x11, 0xc3, + 0x11, 0xc2, + 0x11, 0xcb, + 0x11, 0xca, + 0x2, 0xfe, 0xd0, 0x38, 0, + 0x2, 0xfe, 0xd2, 0x38, 0, + 0x2, 0xfe, 0xc0, 0x38, 0, + 0x2, 0xfe, 0xd0, 0x38, 0x8, + 0x2, 0xfe, 0xd2, 0x38, 0x8, + 0x2, 0xfe, 0xc0, 0x38, 0x8, + 0x22, 0xf, 0xaa, + 0x11, 0x9e, + 0x2, 0xfe, 0xd0, 0x38, 0x38, + 0x2, 0xfe, 0xd2, 0x38, 0x38, + 0x2, 0xfe, 0xc0, 0x38, 0x38, + 0x2, 0xfe, 0x18, 0, 0, + 0x2, 0xfe, 0x1a, 0, 0, + 0x1, 0xfe, 0x1c, + 0x2, 0xfe, 0x80, 0x38, 0x18, + 0x2, 0xfe, 0x82, 0x38, 0x18, + 0x1, 0xfe, 0xae, + 0x13, 0xf, 0xf0, 0x90, 0x38, 0, + 0x2, 0xfe, 0xd0, 0x38, 0x20, + 0x2, 0xfe, 0xd2, 0x38, 0x20, + 0x2, 0xfe, 0xc0, 0x38, 0x20, + 0x2, 0xfe, 0xd0, 0x38, 0x28, + 0x23, 0xf, 0xa4, 0, 0, + 0x23, 0xf, 0xa5, 0, 0, + 0x2, 0xfe, 0xd2, 0x38, 0x28, + 0x2, 0xfe, 0xc0, 0x38, 0x28, + 0x23, 0xf, 0xac, 0, 0, + 0x23, 0xf, 0xad, 0, 0, + 0x33, 0xf, 0x1, 0xc1, + 0x33, 0xf, 0x1, 0xc2, + 0x33, 0xf, 0x1, 0xc3, + 0x33, 0xf, 0x1, 0xc4, + 0x23, 0xf, 0x78, 0, 0, + 0x23, 0xf, 0x79, 0, 0, + 0x23, 0xf, 0x1, 0x38, 0, + 0x33, 0xf, 0x1, 0xc8, + 0x33, 0xf, 0x1, 0xc9, + 0x23, 0xf, 0x1, 0x38, 0x8, + 0x23, 0xf, 0, 0x38, 0, + 0x23, 0xf, 0x1, 0x38, 0x20, + 0x11, 0xf9, + 0x11, 0xfd, + 0x11, 0xfb, + 0x1, 0xfe, 0xaa, + 0x23, 0xf, 0, 0x38, 0x8, + 0x2, 0xfe, 0x28, 0, 0, + 0x2, 0xfe, 0x2a, 0, 0, + 0x1, 0xfe, 0x2c, + 0x2, 0xfe, 0x80, 0x38, 0x28, + 0x2, 0xfe, 0x82, 0x38, 0x28, + 0x2, 0xfe, 0x84, 0, 0, + 0x1, 0xfe, 0xa8, + 0x2, 0xfe, 0xf6, 0x38, 0, + 0x22, 0xf, 0xb, + 0x23, 0xf, 0, 0x38, 0x20, + 0x23, 0xf, 0, 0x38, 0x28, + 0x22, 0xf, 0x9, + 0x23, 0xf, 0xd, 0x38, 0, + 0x23, 0xf, 0xd, 0x38, 0x8, + 0x23, 0xf, 0x18, 0x38, 0, + 0x23, 0xf, 0x18, 0x38, 0x8, + 0x23, 0xf, 0x18, 0x38, 0x10, + 0x23, 0xf, 0x18, 0x38, 0x18, + 0x23, 0xf, 0x1f, 0, 0, + 0x22, 0xf, 0x30, + 0x13, 0xf, 0xfe, 0xc0, 0, 0, + 0x2, 0xfe, 0x86, 0, 0, + 0x1, 0xf8, 0x90, + 0x11, 0xd7, + 0x2, 0xfe, 0x30, 0, 0, + 0x2, 0xfe, 0x32, 0, 0, + 0x1, 0xfe, 0x34, + 0x2, 0xfe, 0x80, 0x38, 0x30, + 0x2, 0xfe, 0x82, 0x38, 0x30, + 0x22, 0xf, 0x77, + 0x34, 0x66, 0xf, 0xdb, 0, 0, + 0x23, 0xf, 0xdb, 0, 0, + 0x34, 0x66, 0xf, 0xdf, 0, 0, + 0x23, 0xf, 0xdf, 0, 0, + 0x34, 0x66, 0xf, 0xf5, 0, 0, + 0x23, 0xf, 0xf5, 0, 0, + 0x34, 0x66, 0xf, 0xeb, 0, 0, + 0x23, 0xf, 0xeb, 0, 0, + 0x34, 0x66, 0xf, 0xef, 0, 0, + 0x23, 0xf, 0xef, 0, 0, + 0x23, 0xf, 0x55, 0, 0, + 0x23, 0xf, 0x54, 0, 0, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x1, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x2, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x3, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x4, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x5, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x6, + 0x24, 0xf, 0xc2, 0, 0, 0xff, 0x7, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x1, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x2, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x3, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x4, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x5, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x6, + 0x35, 0xf3, 0xf, 0xc2, 0, 0, 0xff, 0x7, + 0x23, 0xf, 0xae, 0x38, 0x8, + 0x23, 0xf, 0xae, 0x38, 0, + 0x23, 0xf, 0xae, 0x38, 0x10, + 0x23, 0xf, 0xae, 0x38, 0x18, + 0x34, 0xf2, 0xf, 0x10, 0, 0, + 0x34, 0xf3, 0xf, 0x10, 0, 0, + 0x34, 0x66, 0xf, 0x10, 0, 0, + 0x23, 0xf, 0x10, 0, 0, + 0x34, 0xf2, 0xf, 0x11, 0, 0, + 0x34, 0xf3, 0xf, 0x11, 0, 0, + 0x34, 0x66, 0xf, 0x11, 0, 0, + 0x23, 0xf, 0x11, 0, 0, + 0x34, 0xf2, 0xf, 0x12, 0, 0, + 0x34, 0xf3, 0xf, 0x12, 0, 0, + 0x34, 0x66, 0xf, 0x12, 0, 0, + 0x23, 0xf, 0x12, 0xc0, 0xc0, + 0x23, 0xf, 0x12, 0, 0, + 0x34, 0x66, 0xf, 0x13, 0xc0, 0xc0, + 0x23, 0xf, 0x13, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0x13, 0, 0, + 0x23, 0xf, 0x13, 0, 0, + 0x34, 0x66, 0xf, 0x14, 0, 0, + 0x23, 0xf, 0x14, 0, 0, + 0x34, 0x66, 0xf, 0x15, 0, 0, + 0x23, 0xf, 0x15, 0, 0, + 0x34, 0xf3, 0xf, 0x16, 0, 0, + 0x34, 0x66, 0xf, 0x16, 0, 0, + 0x23, 0xf, 0x16, 0xc0, 0xc0, + 0x23, 0xf, 0x16, 0, 0, + 0x34, 0x66, 0xf, 0x17, 0xc0, 0xc0, + 0x23, 0xf, 0x17, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0x17, 0, 0, + 0x23, 0xf, 0x17, 0, 0, + 0x34, 0x66, 0xf, 0x28, 0, 0, + 0x23, 0xf, 0x28, 0, 0, + 0x34, 0x66, 0xf, 0x29, 0, 0, + 0x23, 0xf, 0x29, 0, 0, + 0x34, 0xf2, 0xf, 0x2a, 0, 0, + 0x34, 0xf3, 0xf, 0x2a, 0, 0, + 0x34, 0x66, 0xf, 0x2a, 0, 0, + 0x23, 0xf, 0x2a, 0, 0, + 0x34, 0x66, 0xf, 0x2b, 0, 0, + 0x23, 0xf, 0x2b, 0, 0, + 0x34, 0xf2, 0xf, 0x2c, 0, 0, + 0x34, 0xf3, 0xf, 0x2c, 0, 0, + 0x34, 0x66, 0xf, 0x2c, 0, 0, + 0x23, 0xf, 0x2c, 0, 0, + 0x34, 0x66, 0xf, 0x2d, 0, 0, + 0x34, 0xf2, 0xf, 0x2d, 0, 0, + 0x34, 0xf3, 0xf, 0x2d, 0, 0, + 0x23, 0xf, 0x2d, 0, 0, + 0x34, 0x66, 0xf, 0x2e, 0, 0, + 0x23, 0xf, 0x2e, 0, 0, + 0x34, 0x66, 0xf, 0x2f, 0, 0, + 0x23, 0xf, 0x2f, 0, 0, + 0x22, 0xf, 0x37, + 0x34, 0x66, 0xf, 0x50, 0xc0, 0xc0, + 0x23, 0xf, 0x50, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0x51, 0, 0, + 0x34, 0xf2, 0xf, 0x51, 0, 0, + 0x34, 0xf3, 0xf, 0x51, 0, 0, + 0x23, 0xf, 0x51, 0, 0, + 0x34, 0xf3, 0xf, 0x52, 0, 0, + 0x23, 0xf, 0x52, 0, 0, + 0x34, 0xf3, 0xf, 0x53, 0, 0, + 0x23, 0xf, 0x53, 0, 0, + 0x34, 0x66, 0xf, 0x54, 0, 0, + 0x23, 0xf, 0x54, 0, 0, + 0x34, 0x66, 0xf, 0x55, 0, 0, + 0x23, 0xf, 0x55, 0, 0, + 0x34, 0x66, 0xf, 0x56, 0, 0, + 0x23, 0xf, 0x56, 0, 0, + 0x34, 0x66, 0xf, 0x57, 0, 0, + 0x23, 0xf, 0x57, 0, 0, + 0x34, 0xf2, 0xf, 0x58, 0, 0, + 0x34, 0xf3, 0xf, 0x58, 0, 0, + 0x34, 0x66, 0xf, 0x58, 0, 0, + 0x23, 0xf, 0x58, 0, 0, + 0x34, 0xf2, 0xf, 0x59, 0, 0, + 0x34, 0xf3, 0xf, 0x59, 0, 0, + 0x34, 0x66, 0xf, 0x59, 0, 0, + 0x23, 0xf, 0x59, 0, 0, + 0x34, 0xf2, 0xf, 0x5a, 0, 0, + 0x34, 0xf3, 0xf, 0x5a, 0, 0, + 0x34, 0x66, 0xf, 0x5a, 0, 0, + 0x23, 0xf, 0x5a, 0, 0, + 0x34, 0x66, 0xf, 0x5b, 0, 0, + 0x34, 0xf3, 0xf, 0x5b, 0, 0, + 0x23, 0xf, 0x5b, 0, 0, + 0x34, 0xf2, 0xf, 0x5c, 0, 0, + 0x34, 0xf3, 0xf, 0x5c, 0, 0, + 0x34, 0x66, 0xf, 0x5c, 0, 0, + 0x23, 0xf, 0x5c, 0, 0, + 0x34, 0xf2, 0xf, 0x5d, 0, 0, + 0x34, 0xf3, 0xf, 0x5d, 0, 0, + 0x34, 0x66, 0xf, 0x5d, 0, 0, + 0x23, 0xf, 0x5d, 0, 0, + 0x34, 0xf2, 0xf, 0x5e, 0, 0, + 0x34, 0xf3, 0xf, 0x5e, 0, 0, + 0x34, 0x66, 0xf, 0x5e, 0, 0, + 0x23, 0xf, 0x5e, 0, 0, + 0x34, 0xf2, 0xf, 0x5f, 0, 0, + 0x34, 0xf3, 0xf, 0x5f, 0, 0, + 0x34, 0x66, 0xf, 0x5f, 0, 0, + 0x23, 0xf, 0x5f, 0, 0, + 0x34, 0x66, 0xf, 0x60, 0, 0, + 0x23, 0xf, 0x60, 0, 0, + 0x34, 0x66, 0xf, 0x61, 0, 0, + 0x23, 0xf, 0x61, 0, 0, + 0x34, 0x66, 0xf, 0x62, 0, 0, + 0x23, 0xf, 0x62, 0, 0, + 0x34, 0x66, 0xf, 0x63, 0, 0, + 0x23, 0xf, 0x63, 0, 0, + 0x34, 0x66, 0xf, 0x64, 0, 0, + 0x23, 0xf, 0x64, 0, 0, + 0x34, 0x66, 0xf, 0x65, 0, 0, + 0x23, 0xf, 0x65, 0, 0, + 0x34, 0x66, 0xf, 0x66, 0, 0, + 0x23, 0xf, 0x66, 0, 0, + 0x34, 0x66, 0xf, 0x67, 0, 0, + 0x23, 0xf, 0x67, 0, 0, + 0x34, 0x66, 0xf, 0x68, 0, 0, + 0x23, 0xf, 0x68, 0, 0, + 0x34, 0x66, 0xf, 0x69, 0, 0, + 0x23, 0xf, 0x69, 0, 0, + 0x34, 0x66, 0xf, 0x6a, 0, 0, + 0x23, 0xf, 0x6a, 0, 0, + 0x34, 0x66, 0xf, 0x6b, 0, 0, + 0x23, 0xf, 0x6b, 0, 0, + 0x34, 0x66, 0xf, 0x6c, 0, 0, + 0x34, 0x66, 0xf, 0x6d, 0, 0, + 0x34, 0x66, 0xf, 0x6e, 0, 0, + 0x23, 0xf, 0x6e, 0, 0, + 0x34, 0x66, 0xf, 0x6f, 0, 0, + 0x34, 0xf3, 0xf, 0x6f, 0, 0, + 0x23, 0xf, 0x6f, 0, 0, + 0x34, 0x66, 0xf, 0x70, 0, 0, + 0x34, 0xf2, 0xf, 0x70, 0, 0, + 0x34, 0xf3, 0xf, 0x70, 0, 0, + 0x23, 0xf, 0x70, 0, 0, + 0x34, 0x66, 0xf, 0x74, 0, 0, + 0x23, 0xf, 0x74, 0, 0, + 0x34, 0x66, 0xf, 0x75, 0, 0, + 0x23, 0xf, 0x75, 0, 0, + 0x34, 0x66, 0xf, 0x76, 0, 0, + 0x23, 0xf, 0x76, 0, 0, + 0x34, 0x66, 0xf, 0x7c, 0, 0, + 0x34, 0xf2, 0xf, 0x7c, 0, 0, + 0x34, 0x66, 0xf, 0x7d, 0, 0, + 0x34, 0xf2, 0xf, 0x7d, 0, 0, + 0x34, 0x66, 0xf, 0x7e, 0, 0, + 0x34, 0xf3, 0xf, 0x7e, 0, 0, + 0x23, 0xf, 0x7e, 0, 0, + 0x34, 0x66, 0xf, 0x7f, 0, 0, + 0x34, 0xf3, 0xf, 0x7f, 0, 0, + 0x23, 0xf, 0x7f, 0, 0, + 0x23, 0xf, 0xc3, 0, 0, + 0x34, 0x66, 0xf, 0xc4, 0, 0, + 0x23, 0xf, 0xc4, 0, 0, + 0x34, 0x66, 0xf, 0xc5, 0xc0, 0xc0, + 0x23, 0xf, 0xc5, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xc6, 0, 0, + 0x23, 0xf, 0xc6, 0, 0, + 0x34, 0x66, 0xf, 0xd1, 0, 0, + 0x23, 0xf, 0xd1, 0, 0, + 0x34, 0x66, 0xf, 0xd2, 0, 0, + 0x23, 0xf, 0xd2, 0, 0, + 0x34, 0x66, 0xf, 0xd3, 0, 0, + 0x23, 0xf, 0xd3, 0, 0, + 0x34, 0x66, 0xf, 0xd4, 0, 0, + 0x23, 0xf, 0xd4, 0, 0, + 0x34, 0x66, 0xf, 0xd5, 0, 0, + 0x23, 0xf, 0xd5, 0, 0, + 0x34, 0x66, 0xf, 0xd6, 0, 0, + 0x34, 0xf2, 0xf, 0xd6, 0xc0, 0xc0, + 0x34, 0xf3, 0xf, 0xd6, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xd7, 0xc0, 0xc0, + 0x23, 0xf, 0xd7, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xd8, 0, 0, + 0x23, 0xf, 0xd8, 0, 0, + 0x34, 0x66, 0xf, 0xd9, 0, 0, + 0x23, 0xf, 0xd9, 0, 0, + 0x34, 0x66, 0xf, 0xda, 0, 0, + 0x23, 0xf, 0xda, 0, 0, + 0x34, 0x66, 0xf, 0xdc, 0, 0, + 0x23, 0xf, 0xdc, 0, 0, + 0x34, 0x66, 0xf, 0xdd, 0, 0, + 0x23, 0xf, 0xdd, 0, 0, + 0x34, 0x66, 0xf, 0xde, 0, 0, + 0x23, 0xf, 0xde, 0, 0, + 0x34, 0x66, 0xf, 0xe0, 0, 0, + 0x23, 0xf, 0xe0, 0, 0, + 0x34, 0x66, 0xf, 0xe1, 0, 0, + 0x23, 0xf, 0xe1, 0, 0, + 0x34, 0x66, 0xf, 0xe2, 0, 0, + 0x23, 0xf, 0xe2, 0, 0, + 0x34, 0x66, 0xf, 0xe3, 0, 0, + 0x23, 0xf, 0xe3, 0, 0, + 0x34, 0x66, 0xf, 0xe4, 0, 0, + 0x23, 0xf, 0xe4, 0, 0, + 0x34, 0x66, 0xf, 0xe5, 0, 0, + 0x23, 0xf, 0xe5, 0, 0, + 0x34, 0x66, 0xf, 0xe7, 0, 0, + 0x23, 0xf, 0xe7, 0, 0, + 0x34, 0x66, 0xf, 0xe8, 0, 0, + 0x23, 0xf, 0xe8, 0, 0, + 0x34, 0x66, 0xf, 0xe9, 0, 0, + 0x23, 0xf, 0xe9, 0, 0, + 0x34, 0x66, 0xf, 0xea, 0, 0, + 0x23, 0xf, 0xea, 0, 0, + 0x34, 0x66, 0xf, 0xec, 0, 0, + 0x23, 0xf, 0xec, 0, 0, + 0x34, 0x66, 0xf, 0xed, 0, 0, + 0x23, 0xf, 0xed, 0, 0, + 0x34, 0x66, 0xf, 0xee, 0, 0, + 0x23, 0xf, 0xee, 0, 0, + 0x34, 0xf2, 0xf, 0xf0, 0, 0, + 0x34, 0x66, 0xf, 0xf1, 0, 0, + 0x23, 0xf, 0xf1, 0, 0, + 0x34, 0x66, 0xf, 0xf2, 0, 0, + 0x23, 0xf, 0xf2, 0, 0, + 0x34, 0x66, 0xf, 0xf3, 0, 0, + 0x23, 0xf, 0xf3, 0, 0, + 0x34, 0x66, 0xf, 0xf4, 0, 0, + 0x23, 0xf, 0xf4, 0, 0, + 0x34, 0x66, 0xf, 0xf6, 0, 0, + 0x23, 0xf, 0xf6, 0, 0, + 0x34, 0x66, 0xf, 0xf7, 0xc0, 0xc0, + 0x23, 0xf, 0xf7, 0xc0, 0xc0, + 0x34, 0x66, 0xf, 0xf8, 0, 0, + 0x23, 0xf, 0xf8, 0, 0, + 0x34, 0x66, 0xf, 0xf9, 0, 0, + 0x23, 0xf, 0xf9, 0, 0, + 0x34, 0x66, 0xf, 0xfa, 0, 0, + 0x23, 0xf, 0xfa, 0, 0, + 0x34, 0x66, 0xf, 0xfb, 0, 0, + 0x23, 0xf, 0xfb, 0, 0, + 0x34, 0x66, 0xf, 0xfc, 0, 0, + 0x23, 0xf, 0xfc, 0, 0, + 0x34, 0x66, 0xf, 0xfd, 0, 0, + 0x23, 0xf, 0xfd, 0, 0, + 0x34, 0x66, 0xf, 0xfe, 0, 0, + 0x23, 0xf, 0xfe, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0, 0, 0, + 0x34, 0xf, 0x38, 0, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1, 0, 0, + 0x34, 0xf, 0x38, 0x1, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x2, 0, 0, + 0x34, 0xf, 0x38, 0x2, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3, 0, 0, + 0x34, 0xf, 0x38, 0x3, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x4, 0, 0, + 0x34, 0xf, 0x38, 0x4, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x5, 0, 0, + 0x34, 0xf, 0x38, 0x5, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x6, 0, 0, + 0x34, 0xf, 0x38, 0x6, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x7, 0, 0, + 0x34, 0xf, 0x38, 0x7, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x8, 0, 0, + 0x34, 0xf, 0x38, 0x8, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x9, 0, 0, + 0x34, 0xf, 0x38, 0x9, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0xa, 0, 0, + 0x34, 0xf, 0x38, 0xa, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0xb, 0, 0, + 0x34, 0xf, 0x38, 0xb, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1c, 0, 0, + 0x34, 0xf, 0x38, 0x1c, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1d, 0, 0, + 0x34, 0xf, 0x38, 0x1d, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x1e, 0, 0, + 0x34, 0xf, 0x38, 0x1e, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xf, 0, 0, + 0x34, 0xf, 0x3a, 0xf, 0, 0, + 0x34, 0x66, 0xf, 0xc7, 0x38, 0x30, + 0x34, 0xf3, 0xf, 0xc7, 0x38, 0x30, + 0x23, 0xf, 0xc7, 0x38, 0x30, + 0x23, 0xf, 0xc7, 0x38, 0x38, + 0x34, 0x66, 0xf, 0x71, 0xf8, 0xd0, + 0x23, 0xf, 0x71, 0xf8, 0xd0, + 0x34, 0x66, 0xf, 0x71, 0xf8, 0xe0, + 0x23, 0xf, 0x71, 0xf8, 0xe0, + 0x34, 0x66, 0xf, 0x71, 0xf8, 0xf0, + 0x23, 0xf, 0x71, 0xf8, 0xf0, + 0x34, 0x66, 0xf, 0x72, 0xf8, 0xd0, + 0x23, 0xf, 0x72, 0xf8, 0xd0, + 0x34, 0x66, 0xf, 0x72, 0xf8, 0xe0, + 0x23, 0xf, 0x72, 0xf8, 0xe0, + 0x34, 0x66, 0xf, 0x72, 0xf8, 0xf0, + 0x23, 0xf, 0x72, 0xf8, 0xf0, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xd0, + 0x23, 0xf, 0x73, 0xf8, 0xd0, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xd8, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xf0, + 0x23, 0xf, 0x73, 0xf8, 0xf0, + 0x34, 0x66, 0xf, 0x73, 0xf8, 0xf8, + 0x33, 0xf, 0xae, 0xe8, + 0x33, 0xf, 0xae, 0xf0, + 0x33, 0xf, 0xae, 0xf8, + 0x23, 0xf, 0xae, 0x38, 0x38, + 0x23, 0xf, 0xf, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xc, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xd, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x14, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x15, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x40, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x41, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x21, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x2a, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x42, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x2b, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x10, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xe, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x29, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x61, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x60, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x63, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x62, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x37, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x41, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x20, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x22, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3c, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3d, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3f, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3e, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x38, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x39, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3b, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x3a, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x20, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x21, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x22, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x23, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x24, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x25, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x30, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x31, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x32, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x33, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x34, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x35, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x28, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x40, 0, 0, + 0x45, 0x66, 0xf, 0x38, 0x17, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x8, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0x9, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xa, 0, 0, + 0x45, 0x66, 0xf, 0x3a, 0xb, 0, 0, + 0x1, 0xe7, 0x7, +}; diff --git a/libcpu/x86_64_disasm.c b/libcpu/x86_64_disasm.c new file mode 100644 index 00000000..947bc94e --- /dev/null +++ b/libcpu/x86_64_disasm.c @@ -0,0 +1,34 @@ +/* Disassembler for x86-64. + Copyright (C) 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define i386_disasm x86_64_disasm +#define DISFILE "x86_64_dis.h" +#define MNEFILE "x86_64.mnemonics" +#define X86_64 +#include "i386_disasm.c" diff --git a/libdw/ChangeLog b/libdw/ChangeLog new file mode 100644 index 00000000..b5462ef4 --- /dev/null +++ b/libdw/ChangeLog @@ -0,0 +1,3732 @@ +2021-04-19 Martin Liska + + * dwarf_begin_elf.c (check_section): Use startswith. + +2021-05-01 Mark Wielaard + + * libdw_form.c (__libdw_form_val_compute_len): Check indirect + form is not DW_FORM_indirect or DW_FORM_implicit_const. + +2021-04-23 Omar Sandoval + + * dwarf_child.c (__libdw_find_attr): Handle DW_FORM_indirect. + * dwarf_getattrs.c (dwarf_getattrs): Handle DW_FORM_indirect. + +2021-02-12 Mark Wielaard + + * dwarf_getlocation.c (attr_ok): For DWARF version 4 or higher + block forms are not expression locations. + (is_constant_offset): DW_FORM_implicit_const is also a constant. + +2020-12-20 Dmitry V. Levin + + * .gitignore: New file. + +2020-12-16 Dmitry V. Levin + + * libdwP.h (_): Remove. + +2020-12-12 Dmitry V. Levin + + * dwarf.h: Fix spelling typo in comment. + * dwarf_begin_elf.c (dwarf_begin_elf): Likewise. + * dwarf_getlocation.c (attr_ok, __libdw_intern_expression): Likewise. + * dwarf_getsrclines.c (read_srclines): Likewise. + * libdw.h: Fix spelling typos in comments. + * libdwP.h: Likewise. + +2020-12-09 Dmitry V. Levin + + * Makefile.am (noinst_PROGRAMS): Rename to noinst_DATA. + (libdw_so_SOURCES): Remove. + (MOSTLYCLEANFILES): Add libdw.so. + +2020-11-30 Dmitry V. Levin + + * Makefile.am (libdw.so$(EXEEXT)): Drop $(EXEEXT) suffix. + +2020-11-01 Érico N. Rolim + + * Makefile.am (libdw_so_LDLIBS): Add fts_LIBS. + +2020-10-28 Tom Tromey + + PR26773 + * dwarf_getlocation.c (store_implicit_value): Use + __libdw_get_uleb128_unchecked. + * memory-access.h (get_sleb128_step): Assume unsigned type for + 'var'. + (__libdw_get_sleb128, __libdw_get_sleb128_unchecked): Work in + unsigned type. Handle final byte. + +2020-10-19 Mark Wielaard + + * dwarf_frame_register.c (dwarf_frame_register): Declare ops_mem + as array of (at least) 3 elements. + * libdw.h (dwarf_frame_register): Add extra explanation of ops_mem + argument. + +2020-10-23 Tom Tromey + + * memory-access.h (read_3ubyte_unaligned_inc): Call + read_3ubyte_unaligned. + +2020-09-03 Mark Wielaard + + * dwarf.h: Add DW_CFA_AARCH64_negate_ra_state. + * cfi.h (struct Dwarf_CFI_s): Add e_machine field. + * cfi.c (execute_cfi): Recognize, but ignore + DW_CFA_AARCH64_negate_ra_state on aarch64. + * dwarf_getcfi.c (dwarf_getcfi): Set cfi e_machine. + * dwarf_getcfi_elf.c (allocate_cfi): Take ehdr as argument and set + cfi e_machine. + (getcfi_gnu_eh_frame): Pass ehdr to allocate_cfi. + (getcfi_scn_eh_frame): Likewise. + +2020-09-03 Mark Wielaard + + * libdw.map (ELFUTILS_0.126): Remove local wildcard. + (ELFUTILS_0.127): Likewise. + (ELFUTILS_0.130): Likewise. + (ELFUTILS_0.136): Likewise. + (ELFUTILS_0.138): Likewise. + +2020-08-25 Mark Wielaard + + * dwarf_getlocation.c (check_constant_offset): Rename to... + (is_constant_offset): .. this. + +2020-06-28 Mark Wielaard + + * linux-kernel-modules.c (intuit_kernel_bounds): Check read_address + returns an increasing address when searching for end. + +2020-06-16 Mark Wielaard + + * cfi.c (execute_cfi): Add missing FALLTHROUGH. + +2020-05-08 Mark Wielaard + + * libdw_visit_scopes.c (walk_children): Don't recurse into imported + DW_TAG_compile_units. + +2020-05-08 Mark Wielaard + + * dwarf_decl_file.c (dwarf_decl_file): Use attr CU instead of DIE + CU to resolve file name. + * dwarf_ranges.c(dwarf_ranges): Document which CU we use when. + * libdw.h (dwarf_attr_integrate): Extend documentation. + +2020-04-25 Mark Wielaard + + * libdw_alloc.c (__libdw_alloc_tail): Call Dwarf oom_handler() + when malloc fails. + +2020-04-17 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Handle .gnu.debuglto_ prefix. + +2019-10-28 Aaron Merey + + * Makefile.am (libdw_so_LDLIBS): Add -ldl for libdebuginfod.so dlopen. + +2019-11-10 Mark Wielaard + + * libdwP.h (libdw_unalloc): New define. + (libdw_typed_unalloc): Likewise. + (__libdw_thread_tail): New function declaration. + * libdw_alloc.c (__libdw_thread_tail): New function. + * dwarf_getabbrev.c (__libdw_getabbrev): Call libdw_typed_unalloc + when reading invalid data or when hash collission detected. + +2019-10-28 Jonathon Anderson + + * libdw_alloc.c: Added __libdw_alloc_tail. + (__libdw_allocate): Switch to use the mem_tails array. + * libdwP.h (Dwarf): Likewise. + * dwarf_begin_elf.c (dwarf_begin_elf): Support for above. + * dwarf_end.c (dwarf_end): Likewise. + * atomics.h: Add support for thread_local. + +2019-10-28 Mark Wielaard + + * dwarf_sig8_hash.h: Include libdw.h. Remove COMPARE. Include + dynamicsizehash_concurrent.h. + * dwarf_sig8_hash.c: Include dynamicsizehash_concurrent.c. + * dwarf_formref_die.c (dwarf_formref_die): Drop NULL argument to + Dwarf_Sig8_Hash_find. + +2019-08-26 Srđan Milaković + + * dwarf_abbrev_hash.{c,h}: Use the *_concurrent hash table. + +2019-11-01 Jonathon Anderson + + * dwarf_begin_elf.c (valid_p): Switch calloc for malloc for fake CUs. + Add explicit initialization of some fields. + * dwarf_end.c (cu_free): Add clause to limit freeing of CU internals. + +2019-08-26 Jonathon Anderson + + * libdw_alloc.c (__libdw_allocate): Added thread-safe stack allocator. + * libdwP.h (Dwarf): Likewise. + * dwarf_begin_elf.c (dwarf_begin_elf): Support for above. + * dwarf_end.c (dwarf_end): Likewise. + * Makefile.am: Use -pthread to provide rwlocks. + +2019-07-05 Omar Sandoval + + * Makefile.am (libdw_so_LIBS): Replace libebl.a with libebl_pic.a. + Move libebl_pic.a to the beginning so that libdw symbols are resolved. + (libdw_so_LDLIBS): Remove -ldl. + (libdw.so): Remove -rpath. + (libdw_a_LIBADD): Add libebl, libebl_backends, and libcpu objects. + +2019-08-25 Jonathon Anderson + + * dwarf_getcfi.c (dwarf_getcfi): Set default_same_value to false. + +2019-08-12 Mark Wielaard + + * libdw.map (ELFUTILS_0.177): Add new version of dwelf_elf_begin. + +2019-06-28 Mark Wielaard + + * libdw.map (ELFUTILS_0.177): New section. Add + dwelf_elf_e_machine_string. + +2019-05-16 Mark Wielaard + + * dwarf.h: Add DW_AT_GNU_numerator, DW_AT_GNU_denominator and + DW_AT_GNU_bias. + +2019-04-28 Mark Wielaard + + * dwarf_siblingof.c (dwarf_siblingof): Don't initialize addr. + +2019-04-28 Mark Wielaard + + * dwarf_getlocation.c (dwarf_getlocation_addr): Call + check_constant_offset with llbufs and listlens directly. + +2019-04-27 Mark Wielaard + + * dwarf_getlocation.c (store_implicit_value): Check dbg isn't + NULL. + +2019-02-02 Mark Wielaard + + * dwarf_nextcu.c (__libdw_next_unit): Define bytes_end. + Check there are enough bytes to read extended length, version + and unit. + +2019-01-20 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Check terminating NUL byte + for dir and file lists. + +2018-10-23 Mark Wielaard + + * dwarf_child.c (__libdw_find_attr): Initialize readp to NULL. + * dwarf_getattrs.c (dwarf_getattrs): Initialize die_addr to NULL. + +2018-10-20 Mark Wielaard + + * libdw.map (ELFUTILS_0.175): New section. Add dwelf_elf_begin. + +2018-10-29 Milian Wolff + + * dwarf_getcfi_elf.c (getcfi_shdr): Check sh_type != SHT_NOBITS. + +2018-09-13 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Drop ehdr argument, add and + use shstrndx argument. + (global_read): Likewise. + (scngrp_read): Likewise. + (dwarf_begin_elf): Call elf_getshdrstrndx. Pass shstrndx to + global_read or scngrp_read. + +2018-08-18 Mark Wielaard + + * dwarf_getabbrev.c (__libdw_getabbrev): Continue until both name + and form are zero. + * dwarf_hasattr.c (dwarf_hasattr): Stop when both name and form + are zero. + +2018-08-18 Mark Wielaard + + * dwarf_getaranges.c (dwarf_getaranges.c): Make sure there is enough + data to read the address and segment size. + +2018-07-04 Ross Burton + + * libdw_alloc.c: Remove error.h include. + +2018-06-28 Mark Wielaard + + * dwarf_next_cfi.c (dwarf_next_cfi): Check whether length is zero. + +2018-06-27 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Allow a single .debug_frame + section. + +2018-06-26 Mark Wielaard + + * libdw.h (dwarf_getscn_info): Remove. + * libdw.map (ELFUTILS_0.122): Remove dwarf_getscn_info. + +2018-06-25 Mark Wielaard + + * Makefile.am (libdw_a_SOURCES): Add dwarf_next_lines.c. + * libdw.h (dwarf_next_lines): New function declaration. + * libdw.map (ELFUTILS_0.173): New section. + * dwarf_next_lines.c: New files. + * dwarf_begin_elf.c (check_section): Don't error out when elf + decompression fails. + (valid_p): Allow just a single .debug_line section. + * dwarf_getsrclines.c (read_srclines): Keep files relative if comp_dir + is missing. + +2018-06-22 Mark Wielaard + + * dwarf_nextcu.c (__libdw_next_unit): Set next_off to -1 when it would + wrap around. + +2018-06-18 Mark Wielaard + + * dwarf_aggregate_size.c (array_size): New depth argument. Use + aggregate_size instead of dwarf_aggregate_size and pass depth. + (aggregate_size): New depth argument. Check depth isn't bigger + than MAX_DEPTH (256). Pass depth to recursive calls. + (dwarf_aggregate_size): ass zero as depth to aggregate_size. + +2018-06-18 Mark Wielaard + + * dwarf_peel_type.c (dwarf_peel_type): Limit modifier chain to 64. + +2018-06-18 Mark Wielaard + + * dwarf_aggregate_size.c (aggregate_size): Check die is not NULL. + +2018-06-17 Luiz Angelo Daros de Luca + + * dwarf_getsrclines.c (read_srclines): Intialize filelist early. + +2018-06-15 Mark Wielaard + + * dwarf_getlocation.c (check_constant_offset): Clarify DW_FORM_data16 + isn't really a constant. + (dwarf_getlocation): Don't handle DW_FORM_data16 as block. + (dwarf_getlocation_addr): Likewise. + (dwarf_getlocations): Likewise. + +2018-06-12 Mark Wielaard + + * memory-access.h (read_3ubyte_unaligned_inc): New define. + +2018-06-12 Mark Wielaard + + * libdw.h (__libdw_dieabbrev): Set die->abbrev to DWARF_END_ABBREV + on failure. + +2018-06-10 Mark Wielaard + + * dwarf_attr_integrate.c (dwarf_attr_integrate): Stop after 16 DIE + ref chains. + * dwarf_hasattr_integrate.c (dwarf_hasattr_integrate): Likewise. + +2018-06-08 Mark Wielaard + + * dwarf_getabbrev.c (dwarf_getabbrev): Check die and offset. + +2018-06-08 Mark Wielaard + + * dwarf_get_units.c (dwarf_get_units): Handle existing error, no + dwarf. + +2018-06-08 Mark Wielaard + + * dwarf_getlocation.c (store_implicit_value): Return error when + seeing bad DWARF or when tsearch runs out of memory. + (__libdw_intern_expression): Report error when store_implicit_value + reported an error. + +2018-06-08 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Sanity check ndirs and nfiles. + +2018-06-08 Mark Wielaard + + * dwarf_getlocation_attr.c (addr_valp): Set error and return NULL + when there is no .debug_addr section. + (dwarf_getlocation_attr): If addr_valp returns NULL, then return -1. + +2018-06-07 Mark Wielaard + + * libdw_findcu.c (__libdw_intern_next_unit): Report DWARF_E_VERSION, + not DWARF_E_INVALID_DWARF on unknown version. Set address_size and + offset_size to 8 when unknown. + +2018-06-06 Mark Wielaard + + * libdwP.h (__libdw_dieabbrev): Check DIE addr falls in cu. + +2018-06-06 Mark Wielaard + + * dwarf_getlocation_die.c (dwarf_getlocation_die): Check offset + falls inside cu data. + +2018-06-05 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Explicitly set diridx to -1 + in case dwarf_formudata fails. + +2018-06-05 Mark Wielaard + + * dwarf_getaranges (dwarf_getaranges): Free new_arange if + __libdw_findcu fails. + +2018-06-05 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Define dirarray early and + check whether or not it is equal to dirstack on exit/out before + cleanup. + +2018-06-05 Mark Wielaard + + * dwarf_getalt.c (find_debug_altlink): id_path array should be 2 + larger to contain MAX_BUILD_ID_BYTES. + +2018-05-31 Mark Wielaard + + * libdw_find_split_unit.c (try_split_file): New function extracted + from... + (__libdw_find_split_unit): ... here. Try both the relative and + absolute paths to find a .dwo file. + +2018-05-30 Mark Wielaard + + * libdw/dwarf_getsrclines.c (read_srclines): Change ndir and + ndirlist to size_t. Add check to see ndirlist doesn't overflow. + +2018-05-31 Mark Wielaard + + * dwarf_dieoffset.c: Check die->cu != NULL. Return -1, not ~0ul + on failure. + +2018-05-29 Mark Wielaard + + * dwarf_cuoffset.c (dwarf_cuoffset): Check die->cu is not NULL. + * dwarf_die_addr_die.c (dwarf_die_addr_die): Also search split + Dwarfs. + * libdwP.h (struct Dwarf): Add split_tree field. + (__libdw_find_split_dbg_addr): New internal function definition. + (__libdw_finddbg_cb): Likewise. + * libdw_find_split_unit.c (__libdw_find_split_unit): Insert split + Dwarf into skeleton dbg split_tree. + * libdw_findcu.c (__libdw_finddbg_cb): New function. + (__libdw_find_split_dbg_addr): Likewise. + * dwarf_end (dwarf_end): Destroy split_tree. + +2018-05-29 Mark Wielaard + + * dwarf.h: Add GNU DebugFission list entry encodings + DW_LLE_GNU_end_of_list_entry, + DW_LLE_GNU_base_address_selection_entry, + DW_LLE_GNU_start_end_entry and DW_LLE_GNU_start_length_entry. + * dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Handle + GNU DebugFission list entries. + +2018-05-28 Mark Wielaard + + * libdw_find_split_unit.c (__libdw_find_split_unit): End split_dwarf + only after we tried every unit id in it. + +2018-04-07 Mark Wielaard + + * libdwP.h (struct Dwarf_CU): Add locs_base. + (__libdw_cu_locs_base): New static inline function. + * libdw_findcu.c (__libdw_intern_next_unit): Initialize locs_base. + * dwarf_begin_elf.c (valid_p): Create fake_loclists_cu if necessary. + * dwarf_end.c (dwarf_end): Clean up fake_loclists_cu. + * dwarf_getlocation.c (initial_offset): Handle .debug_loclists. + (getlocations_addr): Likewise. + (dwarf_getlocation_addr): Likewise. + * dwarf_getlocation_attr.c (attr_form_cu): Use fake_loclists_cu for + DWARF5. + (initial_offset): Handle DW_FORM_loclistx. + * dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Handle + .debug_loclists. + * libdwP.h (struct Dwarf): Add fake_loclists_cu. + +2018-04-12 Mark Wielaard + + * dwarf.h: Add DWARF5 location list entry DW_LLE encodings. + * begin_elf.c (dwarf_scnnames): Add IDX_debug_loclists. + * dwarf_error.c (errmsgs): Remove DWARF_E_NO_LOCLIST. And replace + with DWARF_E_NO_DEBUG_LOC, DWARF_E_NO_DEBUG_LOCLISTS and + DWARF_E_NO_LOC_VALUE. + * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_loclists_base + and DW_FORM_loclistx. + * dwarf_getlocation.c (attr_ok): Use DWARF_E_NO_LOC_VALUE. + (initial_offset): Use DWARF_E_NO_DEBUG_LOC. + * libdwP.h: Add IDX_debug_rnglists. Remove DWARF_E_NO_LOCLIST. + Add DWARF_E_NO_DEBUG_LOC, DWARF_E_NO_DEBUG_LOCLISTS and + DWARF_E_NO_LOC_VALUE. + +2018-05-25 Mark Wielaard + + * libdw_find_split_unit.c (__libdw_find_split_unit): Extract linking + skeleton and split compile units code into... + * libdwP (__libdw_link_skel_split): ...this new function. + +2018-04-06 Mark Wielaard + + * dwarf_formaddr.c (__libdw_addrx): New function, extracted from... + (dwarf_formaddr): here. Use __libdw_addrx. + * dwarf_getlocation.c (getlocations_addr): Pass cu to + __libdw_read_begin_end_pair_inc. + * dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Take cu as + argument. Handle .debug_rnglists. + (initial_offset): Handle .debug_rnglists and DW_FORM_rnglistx. + (dwarf_ranges): Likewise. Check cu isn't NULL before use. Pass cu to + __libdw_read_begin_end_pair_inc. + * libdwP.h (__libdw_read_begin_end_pair_inc): Take cu as argument. + (__libdw_cu_ranges_base): Handle DW_AT_rnglists_base. + (__libdw_addrx): New function definition. + +2018-04-11 Mark Wielaard + + * dwarf.h: Add DWARF5 range list entry DW_RLE encodings. + * begin_elf.c (dwarf_scnnames): Add IDX_debug_rnglists. + * dwarf_error.c (errmsgs): Add DWARF_E_NO_DEBUG_RNGLISTS. + * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_rnglists_base + and DW_FORM_rnglistx. + * dwarf_getscopes.c (pc_match): Also check for + DWARF_E_NO_DEBUG_RNGLISTS. + * libdwP.h: Add IDX_debug_rnglists. + +2018-05-25 Mark Wielaard + + * dwarf_getlocation_attr.c (__libdw_cu_addr_base): Cast offset to + uintptr_t before returning as pointer. + +2018-05-22 Mark Wielaard + + * dwarf_getlocation.c (__libdw_cu_base_address): Treat errors of + getting lowpc or entrypc the same as missing base address (zero). + * dwarf_highpc (dwarf_highpc): Handle any address form. Always set + error when attribute could not be found. + +2018-05-21 Mark Wielaard + + * dwarf_begin_elf.c (valid_p): Add a fake_addr_cu to the result. + * dwarf_end.c (cu_free): Disconnect the fake_addr_cu from the split + dwarf if shared with skeleton. + (dwarf_end): release fake_addr_cu. + * dwarf_formaddr.c (__libdw_cu_addr_base): Move to... + * libdwP.h (__libdw_cu_addr_base): ... here. + (struct Dwarf): Add fake_addr_cu field. + * dwarf_formudata.c (dwarf_formudata): Handle + DW_FORM_GNU_addr_index and DW_FORM_addrx[1234]. + * dwarf_getlocation_attr.c (addr_valp): New static function. + (dwarf_getlocation_attr): Create attribute for values of + DW_OP_GNU_const_index, DW_OP_constx and DW_OP_GNU_addr_index and + DW_OP_addrx. + * libdw_find_split_unit.c (__libdw_find_split_unit): Connect + IDX_debug_addr sectiondata and fake_addr_cu between split and + skeleton. + +2018-05-20 Mark Wielaard + + * dwarf_cu_info.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_cu_info.c. + * libdw.h (dwarf_cu_info): New function declaration. + * libdw.map (ELFUTILS_0.171): Add dwarf_cu_info. + +2018-05-24 Mark Wielaard + + * dwarf_ranges.c (dwarf_ranges): Check for NULL cu. + * libdw_findcu.c (__libdw_intern_next_unit): Initialize ranges_base. + +2018-05-18 Mark Wielaard + + * dwarf_formudata.c (__libdw_formptr): Handle the special case + of IDX_debug_ranges for DW_UT_split_compile with version < 5. + * dwarf_highpc.c (dwarf_highpc): Use dwarf_lowpc, check for + split compile cudie. + * dwarf_lowpc.c (dwarf_lowpc): Check for split compile cudie. + * dwarf_ranges.c (dwarf_ranges): Switch cu and sectiondata for + split compile units. + * libdwP.h (struct Dwarf_CU): Add ranges_base field. + (__libdw_cu_ranges_base): New static inline function. + +2018-05-18 Mark Wielaard + + * libdw_findcu.c (__libdw_intern_next_unit): Init files to NULL. + * dwarf_getsrclines.c (dwarf_getsrclines): Handle split units by + taking the line table from the skeleton. + * dwarf_getsrcfiles.c (dwarf_getsrcfiles): Handle split units by + only taking the files from .debug_line offset zero (if it exists), + otherwise fall back to the skeleton. + +2018-05-17 Mark Wielaard + + * dwarf_begin_elf.c (__libdw_debugdir): New function. + (valid_p): Call __libdw_debugdir. + * dwarf_end.c (dwarf_end.c): Free debugdir. + * dwarf_getalt.c (__libdw_filepath): Extract __libdw_debugdir logic. + take debugdir as argument instead of fd. + (find_debug_altlink): Call __libdw_filepath with debugdir. + * libdwP.h (struct Dwarf): Add debugdir field. + (__libdw_debugdir): New function prototype. + (__libdw_filepath): Adjust prototype to take a const char * instead of + an int. + * libdw_find_split_unit.c (__libdw_find_split_unit): Call + __libdw_filepath with debugdir. + +2018-05-17 Mark Wielaard + + * dwarf_attr_integrate.c (dwarf_attr_integrate): Handle split_compile + unit DIE, search skeleton_compile unit DIE. + * dwarf_hasattr_integrate.c (dwarf_hasattr_integrate): Likewise. + * libdwP.h (is_cudie): Check cu is not NULL. + +2018-05-19 Mark Wielaard + + * libdwP.h (__libdw_find_split_unit): Mark as internal_function. + +2018-05-15 Mark Wielaard + + * Makefile.am (libdw_a_SOURCES): Add libdw_find_split_unit.c. + * dwarf_end.c (cu_free): Free split Dwarf. + * dwarf_get_units.c (dwarf_get_units): Handle DW_UT_skeleton by + calling __libdw_find_split_unit. + * libdwP.h (struct Dwarf_CU): Add split Dwarf_CU field. + (__libdw_find_split_unit): New function prototype. + (str_offsets_base_off): Use cu Dwarf if dbg is NULL. + (filepath): Rename to ... + (__libdw_filepath): This. Which is the actual function name in + dwarf_getalt.c. + (libdw_find_split_unit.c): New file. + * libdw_findcu.c (__libdw_intern_next_unit): Initialize split to -1. + +2018-05-15 Mark Wielaard + + * libdwP.h (__libdw_first_die_from_cu_start): Adjust commented out + asserts. + * libdw_findcu.c (__libdw_intern_next_unit): For version 4 DWARF if + the cudie has a DW_AT_GNU_dwi_id set the unit_id8 and unit_type to + DW_UT_skeleton or DW_UT_split_compile based on whether the cudie has + child DIEs and a DW_AT_GNU_dwo_name attribute. + +2018-05-14 Mark Wielaard + + * dwarf.h: Add GNU Debug Fission extensions. DW_AT_GNU_dwo_name, + DW_AT_GNU_dwo_id, DW_AT_GNU_ranges_base, DW_AT_GNU_addr_base, + DW_AT_GNU_pubnames, DW_AT_GNU_pubtypes. DW_FORM_GNU_addr_index, + DW_FORM_GNU_str_index. DW_OP_GNU_addr_index, DW_OP_GNU_const_index. + * dwarf_formaddr.c (dwarf_formaddr): Handle DW_FORM_GNU_addr_index + as DW_FORM_addrx. + (__libdw_cu_addr_base): Check for both DW_AT_GNU_addr_base and + DW_AT_addr_base. + * dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_GNU_str_index + as DW_FORM_strx. + * dwarf_formudata.c (dwarf_formudata): Recognize DW_AT_GNU_addr_base + as addrptr. Recognize DW_AT_GNU_ranges_base as rangelistptr. + * dwarf_getlocation.c (__libdw_intern_expression): Handle + DW_OP_GNU_addr_index as DW_OP_addrx and DW_OP_GNU_const_index as + DW_OP_constx. + * libdw_form.c (__libdw_form_val_compute_len): Handle + DW_FORM_GNU_addr_index and DW_FORM_GNU_str_index taking an uleb128. + +2018-05-12 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Also recognize .dwo section + name variants. + +2018-05-11 Mark Wielaard + + * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_macros as macptr. + * dwarf_getmacros.c (get_table_for_offset): Add DW_MACRO_define_sup, + DW_MACRO_undef_sup, DW_MACRO_import_sup, DW_MACRO_define_strx and + DW_MACRO_undef_strx. Add str_offsets_base_off to fake CU. Deal with + DW_AT_macros. Use libdw_valid_user_form. + +2018-05-09 Mark Wielaard + + * dwarf_formstring.c (__libdw_cu_str_off_base): Moved to... + * libdwP.h (__libdw_cu_str_off_base): ...here. Make static inline. + (str_offsets_base_off): New internal function that also parses + .debug_str_offsets header if necessary. + +2018-05-11 Mark Wielaard + + * dwarf_siblingof.c (dwarf_siblingof): Don't reference cu till it is + known the Dwarf_Die is came from is valid. + * libdwP.h (__libdw_dieabbrev): Check cu is not NULL. + +2018-05-08 Mark Wielaard + + * dwarf_formref.c (__libdw_formref): Explicitly don't handle + DW_FORM_ref_sup4 and DW_FORM_ref_sup8. + * dwarf_formref_die.c (dwarf_formref_die): Handle DW_FORM_ref_sup4 + and DW_FORM_ref_sup8. + * dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_strp_sup + as DW_FORM_GNU_strp_alt. + +2018-05-05 Mark Wielaard + + * dwarf.h: Add DWARF line content descriptions. + * libdwP.h (libdw_valid_user_form): New static function. + * dwarf_getsrclines.c (read_srclines): Check and parse version 5 + DWARF header, dir and file tables separately from older versions + where different. + +2018-04-24 Mark Wielaard + + * dwarf_begin_elf.c (dwarf_scnnames): Add ".debug_line_str". + * dwarf_error.c (errmsgs): Add DWARF_E_NO_DEBUG_STR and + DWARF_E_NO_DEBUG_LINE_STR. + * dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_line_strp. + Get data from either .debug_str or .debug_line_str. + * libdwP.h: Add IDX_debug_line_str, DWARF_E_NO_DEBUG_STR and + DWARF_E_NO_DEBUG_LINE_STR. + +2018-04-03 Mark Wielaard + + * dwarf_formudata.c (__libdw_formptr): Take and return const + unsigned char pointers. + * dwarf_getlocation.c (attr_base_address): Rename to... + (__libdw_cu_base_address): this. Take Dwarf_CU, check and set + base_address. + (initial_offset_base): Renamed to... + (initial_offset): this. Only provide offset. + (getlocations_addr): Move data size check and + address base addition into __libdw_read_begin_end_pair_inc. Use + __libdw_cu_base_address and initial_offset. Drop Elf_Data NULL + check (already done by initial_offset, through __libdw_formptr). + (dwarf_getlocations): Use __libdw_cu_base_address and initial_offset. + Drop Elf_Data NULL check. + * dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Change argument + type of readp to Add readend argument. Check data size. Include base + in begin and end result. + (initial_offset): New static function. + (dwarf_ranges): Don't check Elf_Data being NULL (already done by + initial_offset, through __libdw_formptr). Use __libdw_cu_base_address + and initial_offset. Remove base check and addition (already done by + __libdw_read_begin_end_pair_inc. + * libdwP.h (Dwarf_CU): Add base_address field. + (__libdw_read_begin_end_pair_inc): Change argument type of readp to + const. Add readend argument. + (__libdw_formptr): Take and return const unsigned char pointers. + * libdw_findcu.c (__libdw_intern_next_unit): Initialize Dwarf_CU + base_address. + +2018-04-04 Mark Wielaard + + * libdw_findcu.c (__libdw_intern_next_unit): Initialize Dwarf_CU + addr_base and str_off_base. + +2018-03-23 Mark Wielaard + + * dwarf_begin_elf.c (dwarf_scnnames): Add IDX_debug_str_offsets, + increase size. + * dwarf_error.c (errmsgs): Add DWARF_E_NO_STR_OFFSETS. + * dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_strx[1234]. + (__libdw_cu_str_off_base): New function. + * dwarf_formudata.c (dwarf_formudata): Handle IDX_debug_str_offsets + as stroffsetsptr. + * libdwP.h: Add IDX_debug_str_offsets and DWARF_E_NO_STR_OFFSETS. + (struct Dwarf_CU): Add str_off_base field. + (__libdw_cu_str_off_base): New function declaration. + +2018-03-22 Mark Wielaard + + * dwarf_begin_elf.c (dwarf_scnnames): Add IDX_debug_addr. + * dwarf_error.c (errmsgs): Add DWARF_E_NO_DEBUG_ADDR. + * dwarf_formaddr.c (dwarf_formaddr): Handle DW_FORM_addrx[1234]. + (__libdw_cu_addr_base): New function. + * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_addr_base as + addrptr. + * libdwP.h: Add IDX_debug_addr and DWARF_E_NO_DEBUG_ADDR. + (struct Dwarf_CU): Add addr_base field. + (__libdw_cu_addr_base): New function definition. + * memory-access.h (file_byte_order): New static function. + (read_3ubyte_unaligned): New inline function. + +2018-03-29 Mark Wielaard + + * libdw.h (dwarf_decl_file): Extend documentation. + (dwarf_linesrc): Likewise. + (dwarf_filesrc): Likewise. + +2018-03-06 Mark Wielaard + + * dwarf.h: Add DW_OP_implicit_pointer, DW_OP_addrx, DW_OP_constx, + DW_OP_entry_value, DW_OP_const_type, DW_OP_regval_type, + DW_OP_deref_type, DW_OP_xderef_type, DW_OP_convert and + DW_OP_reinterpret. + * dwarf_getlocation.c (__libdw_intern_expression): Handle + DW_OP_convert, DW_OP_reinterpret, DW_OP_addrx, DW_OP_constx, + DW_OP_regval_type, DW_OP_entry_value, DW_OP_implicit_pointer, + DW_OP_deref_type, DW_OP_xderef_type and DW_OP_const_type. + * dwarf_getlocation_attr.c (dwarf_getlocation_attr): Handle + DW_OP_entry_value, DW_OP_const_type and DW_OP_implicit_pointer. + * dwarf_getlocation_die.c (dwarf_getlocation_die): Handle + DW_OP_implicit_pointer, DW_OP_convert, DW_OP_reinterpret, + DW_OP_const_type, DW_OP_regval_type, DW_OP_deref_type and + DW_OP_xderef_type. + * dwarf_getlocation_implicit_pointer.c + (dwarf_getlocation_implicit_pointer): Handle DW_OP_implicit_pointer. + +2018-03-01 Mark Wielaard + + * dwarf.h: Add DW_AT_GNU_locviews and DW_AT_GNU_entry_view. + * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_GNU_locviews + as a loclistptr. + +2018-02-09 Mark Wielaard + + * dwarf_formblock.c (dwarf_formblock): Handle DW_FORM_data16 as a + 16 byte block. + +2018-02-09 Mark Wielaard + + * dwarf_child.c (__libdw_find_attr): Handle DW_FORM_implicit_const. + * dwarf_formsdata.c (dwarf_formsdata): Likewise. + * dwarf_formudata.c (dwarf_formudata): Likewise. + * dwarf_getabbrev.c (__libdw_getabbrev): Likewise. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_hasattr.c (dwarf_hasattr): Likewise. + * dwarf_getabbrevattr.c (dwarf_getabbrevattr_data): New function + that will also return any data associated with the abbrev. Which + currently is only for DW_FORM_implicit_const. Based on... + (dwarf_getabbrevattr): ... this function. Which now just calls + dwarf_getabbrevattr_data. + * libdw.h (dwarf_getabbrevattr_data): Declare new function. + * libdw.map (ELFUTILS_0.170): Add dwarf_getabbrevattr_data. + * libdwP.h (dwarf_getabbrevattr_data): INTDECL. + * memory-access.h (__libdw_get_sleb128_unchecked): New inlined + function based on __libdw_get_uleb128_unchecked. + +2018-02-08 Mark Wielaard + + * dwarf.h: Add DWARF5 DW_FORMs. + * libdwP.h (__libdw_form_val_compute_len): Handle fix length + DW_FORM_implicit_const, DW_FORM_addrx[1234], DW_FORM_strx[1234], + DW_FORM_ref_sup[48] and DW_FORM_data16. + * libdw_form.c (__libdw_form_val_compute_len): DW_FORM_strp_sup + and DW_FORM_line_strp are offset_size. DW_FORM_addrx, DW_FORM_strx, + DW_FORM_loclistx and DW_FORM_rnglistx are uleb128. + +2018-01-30 Mark Wielaard + + * Makefile.am (libdw_a_SOURCES): Add dwarf_get_units.c. + * dwarf_get_units.c: New file. + * libdw.h (dwarf_get_units): New function declaration. + * libdw.map (ELFUTILS_0.170): Add dwarf_get_units. + +2018-01-29 Mark Wielaard + + * dwarf.h (DW_UT_*): Add DWARF Unit Header Types. + * dwarf_cu_die.c (dwarf_cu_die): Rename arguments. type_signaturep + is now called unit_idp. type_offsetp is now called subdie_offsetp. + * dwarf_formref_die.c (dwarf_formref_die): Scan both .debug_info + and .debug_types sections for type units when type signature ref + not found. + * dwarf_getaranges.c (dwarf_getaranges): Use __libdw_findcu and + __libdw_first_die_off_from_cu instead of trying by hand. + * dwarf_getlocation_die.c (dwarf_getlocation_die): Use ISV4TU + instead of checking type_offset by hand. + * dwarf_getlocation_implicit_pointer.c + (dwarf_getlocation_implicit_pointer): Likewise. + * dwarf_nextcu.c (dwarf_next_unit): Call __libdw_next_unit. + (__libdw_next_unit): New function based on dwarf_next_unit with + DWARF5 header support. + * libdwP.h (struct Dwarf_CU): Renamed type_offset to subdie_offset + and type_sig8 to unit_id8. + (ISV4TU): New macro to determine whether a CU is a version 4 type + unit (which comes from the .debug_types section). + (DIE_OFFSET_FROM_CU_OFFSET): Replaced macro by real function... + (__libdw_first_die_from_cu_start): ... that also handles DWARF5 + unit headers. + (__libdw_first_die_off_from_cu): New function that calls the above + using the CU fields. + (CUDIE): Use __libdw_first_die_off_from_cu. + (SUBDIE): New macro that provides the DIE for a CU using the + subdie_offset. + (__libdw_next_unit): New internal function declaration. + * libdw_findcu.c (__libdw_intern_next_unit): Use __libdw_next_unit. + Accept DWARF version 5 headers. Setup unit_type. + (__libdw_findcu): Rename debug_types argument to v4_debug_types + argument (to indicate that we are looking in the .debug_types + section). Support finding the exact offset (unit header start). + +2018-01-25 Mark Wielaard + + * Makefile.am (libdw_a_SOURCES): Add dwarf_die_addr_die.c. + * dwarf_die_addr_die.c: New file. + * libdw.h (dwarf_die_addr_die): New function declaration. + * libdw.map (ELFUTILS_0.171): New section with dwarf_die_addr_die. + * libdwP.h (__libdw_findcu_addr): New internal function declaration. + * libdw_findcu.c (__libdw_findcu_addr): New internal function. + +2018-02-09 Joshua Watt + + * cfi.c (execute_cfi): Use FALLTHROUGH macro instead of comment. + * dwarf_frame_register.c (dwarf_frame_register): Likewise. + +2018-01-22 Mark Wielaard + + * Makefile.am (AM_CPPFLAGS): Add -I libdwelf. + * dwarf_begin_elf.c (dwarf_begin_elf): Initialize Dwarf alt_fd to -1. + * dwarf_end.c (dwarf_end): Call dwarf_end and close on the alt_dwarf + and alt_fd if we allocated them. + * dwarf_fromref_die.c (dwarf_formref_die): Call dwarf_getalt. + * dwarf_formstring.c (dwarf_formstring): Likewise. + * dwarf_getalt.c (__libdw_filepath): New internal function. + (find_debug_altlink): New static function. + (dwarf_getalt): Check Dwarf alt_dwarf and call find_debug_altlink. + Cache result. + * dwarf_setalt.c (dwarf_setalt): Clean up Dwarf alt_dwarf and alt_fd + if we allocated. + * libdw.h (dwarf_getalt): Extend documentation. + (dwarf_setalt): Likewise. + * libdwP.h (struct Dwarf): Add alt_fd field. + (filepath): Declare new internal function. + +2018-01-14 Petr Machata + + * dwarf_formsdata.c (dwarf_formsdata): + : Cast to signed char. + : Use read_*sbyte_unaligned instead of + read_*ubyte_unaligned. + +2017-12-26 Mark Wielaard + + * libdwP.h (struct Dwarf_Abbrev): Pack struct. Remove attrcnt, + use bitfields for has_children and code. + * dwarf_getabbrev.c (__libdw_getabbrev): Don't count attrs. + * dwarf_getattrcnt.c (dwarf_getattrcnt): Count attrs. + +2017-12-26 Mark Wielaard + + * memory-access.h (__libdw_get_uleb128_unchecked): New function. + (get_uleb128_unchecked): New define. + * dwarf_child.c (__libdw_find_attr): Use get_uleb128_unchecked to + read attr name and form. + * dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_hasattr.c (dwarf_hasattr): Likewise. + +2017-12-28 Mark Wielaard + + * dwarf_offdie.c (__libdw_offdie): Check sectiondata exists. + +2017-05-09 Ulf Hermann + Mark Wielaard + + * libdwP.h (__libdw_in_section): Fix check for the upper border of + the range. + (__libdw_offset_in_section): Likewise. + +2017-12-20 Mark Wielaard + + * libdwP.h (struct Dwarf_CU): Add sec_idx field. + (cu_sec_idx): Return cu->sec_idx. + * libdw_findcu.c (__libdw_intern_next_unit): Set cu sec_idx to + IDX_debug_info or IDX_debug_types. + * dwarf_begin_elf.c (valid_p): Set fake_loc_cu->sec_idx to + IDX_debug_loc. + * dwarf_getmacros.c (read_macros): Set fake_cu->sec_idx to + IDX_debug_macro or IDX_debug_macinfo. + +2017-12-12 Mark Wielaard + + * dwarf_aggregate_size.c (dwarf_aggregate_size): Don't peel the + given DIE. Reserve memory for a new DIE first. + +2017-12-11 Dima Kogan + + * dwarf_aggregate_size.c (array_size): Handle multi-dimensional + arrays properly. + +2017-11-03 Mark Wielaard + + * dwarf_getlocation.c (__libdw_intern_expression): Handle + DW_OP_GNU_variable_value. + * dwarf_getlocation_attr.c (dwarf_getlocation_attr): Likewise. + * dwarf_getlocation_die.c (dwarf_getlocation_die): Likewise. + +2017-11-03 Mark Wielaard + + * dwarf_getlocation.c (attr_ok): Always accept DW_FORM_exprloc. + Update list of acceptable attribute codes based on DWARF5. + +2017-11-03 Mark Wielaard + + * dwarf.h: Add DW_OP_GNU_variable_value. + +2017-10-03 Mark Wielaard + + * libdw.h: Define LIBDW_CIE_ID and use it in dwarf_cfi_cie_p. + +2017-08-18 Ulf Hermann + + * memory-access.h: Use attribute_packed. + +2017-02-27 Ulf Hermann + + * libdwP.h: Use attribute_hidden. + * libdw_alloc.c: Likewise. + +2017-02-27 Ulf Hermann + + * Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS. + +2017-07-26 Mark Wielaard + + * dwarf.h: Add DW_MACRO_* and compat defines for DW_MACRO_GNU_*. + * dwarf_getmacros.c (get_table_for_offset): Accept either version + 4 or 5. Use DW_MACRO names instead of DW_MACRO_GNU names. + (read_macros): Use table version for fake_cu. + +2017-07-26 Mark Wielaard + + * dwarf_peel_type.c (dwarf_peel_type): Handle DW_TAG_immutable_type, + DW_TAG_packed_type and DW_TAG_shared_type. + * libdw.h (dwarf_peel_type): Extend documentation. + +2017-07-26 Mark Wielaard + + * dwarf.h: Add DW_DEFAULTED_no, DW_DEFAULTED_in_class and + DW_DEFAULTED_out_of_class. + +2017-07-26 Mark Wielaard + + * dwarf.h: Add DW_CC_pass_by_reference and DW_CC_pass_by_reference. + +2017-07-26 Mark Wielaard + + * dwarf_default_lower_bound.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_default_lower_bound.c. + * dwarf_aggregate_size.c (array_size): Use dwarf_default_lower_bound. + * dwarf_error.c (errmsgs): Add DWARF_E_UNKNOWN_LANGUAGE. + * libdw.h: Add dwarf_default_lower_bound. + * libdw.map (ELFUTILS_0.170): Add dwarf_default_lower_bound. + * libdwP.h: Add DWARF_E_UNKNOWN_LANGUAGE and + dwarf_default_lower_bound INTDECL. + +2017-07-26 Mark Wielaard + + * dwarf.h: Add DW_LANG_OpenCL, DW_LANG_Modula3, + DW_LANG_C_plus_plus_03, DW_LANG_OCaml, DW_LANG_Rust, DW_LANG_Swift, + DW_LANG_Julia, DW_LANG_Dylan, DW_LANG_RenderScript, DW_LANG_BLISS. + * dwarf_aggregate_size.c (array_size): Add lower bound for + DW_LANG_C_plus_plus_03, DW_LANG_Python, DW_LANG_OpenCL, + DW_LANG_Haskell, DW_LANG_OCaml, DW_LANG_Rust, DW_LANG_Swift, + DW_LANG_Dylan, DW_LANG_RenderScript, DW_LANG_Modula3, + DW_LANG_Julia and DW_LANG_BLISS. + +2017-07-26 Mark Wielaard + + * dwarf.h: Add DW_ATE_UCS and DW_ATE_ASCII. + +2017-07-25 Mark Wielaard + + * dwarf.h: Add DW_TAG_coarray_type, DW_TAG_generic_subrange, + DW_TAG_dynamic_type, DW_TAG_call_site, DW_TAG_call_site_parameter, + DW_TAG_skeleton_unit, DW_TAG_immutable_type. Add reserved comments + for currently unused numbers. + +2017-07-25 Mark Wielaard + + * dwarf.h (DWARF attributes enum): Remove DW_AT_subscr_data, + DW_AT_element_list and DW_AT_member. Add DWARF5 attribute constants. + (DW_AT_subscr_data, DW_AT_element_list, DW_AT_member): New defines. + +2017-07-21 Mark Wielaard + + * dwarf_line_file.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_line_file.c. + * libdw.h (dwarf_line_file): New function declaration. + * libdw.map (ELFUTILS_0.170): New. Add dwarf_line_file. + +2017-02-17 Ulf Hermann + + * Makefile.am: Add libdw_so_LIBS to specify the archives libdw is is + made of, libdw_so_DEPS for libraries it depends on (including + libeu.a), libdw_so_LDLIBS to specify libraries libdw links against. + (libdw.so$(EXEEXT)): Add $(libdw_so_LDLIBS), remove enumeration of + library dependencies, use libdw_so_LIBS rather than relying on the + order of dependencies specified, add -z,relro. + +2017-04-20 Ulf Hermann + + * libdw.h: Remove attribute macro declarations and use + __noreturn_attribute__ as defined in libelf.h. + +2017-04-20 Ulf Hermann + + * dwarf_begin_elf.c: Include endian.h. + +2017-03-30 Mark Wielaard + + * dwarf_peel_type.c (dwarf_peel_type): Call dwarf_attr_integrate on + result. + +2016-10-22 Mark Wielaard + + * dwarf.h: Correct spelling of DW_LANG_PLI. Add compatibility define. + * dwarf_aggregate_size.c (array_size): Use correct spelling of + DW_LANG_PLI. + +2016-11-02 Mark Wielaard + + * cfi.c (execute_cfi): Add fallthrough comments. + * encoded-value.h (encoded_value_size): Add explicit return instead + of relying on fallthrough. + * dwfl_report_elf.c (__libdwfl_elf_address_range): Add fallthrough + comment. + +2016-10-11 Akihiko Odaki + + * dwarf_getpubnames.c: Remove sys/param.h include, add system.h. + * libdw_alloc.c: Likewise. + +2016-07-08 Mark Wielaard + + * libdw.map (ELFUTILS_0.167): New. Add dwelf_strtab_init, + dwelf_strtab_add, dwelf_strtab_add_len, dwelf_strtab_finalize, + dwelf_strent_off, dwelf_strent_str and dwelf_strtab_free. + +2016-02-13 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Calculate ndirs first, then + assign to ndirlist. + +2015-12-18 Mark Wielaard + + * libdwP.h (struct Dwarf): Remove sectiondata_gzip_mask. + (__libdw_free_zdata): Remove. + * dwarf_begin_elf.c (inflate_section): Remove. + (check_section): Remove __libdw_free_zdata calls. Use elf_compress + and elf_compress_gnu to decompress if necessary. + (valid_p): Remove __libdw_free_zdata calls. + (scngrp_read): Use elf_compress if section is compressed. Remove + __libdw_free_zdata calls. + * dwarf_end.c (__libdw_free_zdata): Remove. + (dwarf_end): Don't call __libdw_free_zdata. + +2015-10-28 Mark Wielaard + + * libdw.map (ELFUTILS_0.165): New. Add dwelf_scn_gnu_compressed_size. + +2015-12-02 Mark Wielaard + + * fde.c (intern_fde): Don't leak duplicate FDEs. + +2015-12-01 Mark Wielaard + + * fde.c (intern_fde): Don't intern an fde that doesn't cover a + valid code range. + +2015-12-01 Mark Wielaard + + * dwarf_end.c (dwarf_end): Call cu_free on fake_loc_cu if it exists. + +2015-10-14 Chih-Hung Hsieh + + * dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Move recursive + functions 'add_bkpt', 'entrypc_bkpt', and 'search_range' to file scope. + +2015-10-14 Chih-Hung Hsieh + + * libdw_visit_scopes.c (__libdw_visit_scopes): Move recursive nested + function 'walk_children' to file scope; inline 'recurse' at its call + site. + +2015-10-19 Mark Wielaard + + * frame-cache.c (__libdw_destroy_frame_cache): Call ebl_closebackend + if necessary. + +2015-10-16 Dmitry V. Levin + + * dwarf_getsrclines.c (read_srclines): Initialize state early. + +2015-10-13 Chih-Hung Hsieh + + * dwarf_getsrclines.c (read_srclines): Move nested functions + 'advance_pc' and 'add_new_line' to file scope and keep many + local state variables within one structure. + +2015-10-13 Chih-Hung Hsieh + + * dwarf_getscopevar.c (dwarf_getscopevar): Move nested + function 'file_matches' to file scope. + +2015-10-16 Mark Wielaard + + * Makefile.am (libdw.so): Add -lz. + +2015-10-14 Chih-Hung Hsieh + + * cfi.c (execute_cfi): Move nested functions 'enough_registers' + and 'require_cfa_offset' to file scope. + +2015-10-09 Josh Stone + + * dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat + and fstat. + +2015-10-05 Josh Stone + + * Makefile.am (libdw.so): Add AM_V_CCLD and AM_V_at silencers. + +2015-09-24 Jose E. Marchesi + + * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid + relocation overflows in some platforms. + +2015-09-23 Mark Wielaard + + * dwarf_error.c (__libdw_seterrno): Mark as internal_function. + * dwarf_formref.c (__libdw_formref): Likewise. + * libdw_findcu.c (__libdw_findcu): Likewise. + * libdw_visit_scopes.c (__libdw_visit_scopes): Likewise. + +2015-09-22 Mark Wielaard + + * *.c: Remove old-style function definitions. + +2015-09-15 Mark Wielaard + + * dwarf_peel_type.c (dwarf_peel_type): Don't reassign result pointer. + +2015-09-09 Chih-Hung Hsieh + + * dwarf_macro_getsrcfiles.c (dwarf_macro_getsrcfiles): Remove + redundant NULL tests on parameters declared with __nonnull_attribute__. + * dwarf_siblingof.c (dwarf_siblingof): Likewise. + * libdw_visit_scopes.c (__libdw_visit_scopes): Likewise. + +2015-09-04 Chih-Hung Hsieh + Mark Wielaard + + * dwarf_getlocation.c (getlocations_addr): Replace K&R function + definition with ansi-C definition and add const qualifier to + locs argument. + +2015-09-04 Chih-Hung Hsieh + + * libdw_findcu.c (__libdw_intern_next_unit): Replace K&R function + definition with ansi-C definitions. + (__libdw_findcu): Likewise. + +2015-08-25 Mark Wielaard + + * dwarf.h: Add DW_LANG_Haskell. + +2015-06-18 Mark Wielaard + + * dwarf_begin_elf.c (dwarf_begin_elf): Assert page size is big enough + to hold a Dwarf. + +2015-06-18 Mark Wielaard + + * dwarf_getpubnames.c (get_offsets): Always free mem on error. + +2015-06-18 Mark Wielaard + + * dwarf_getmacros.c (get_macinfo_table): Return NULL when + dwarf_formudata reports an error. + (get_table_for_offset): Likewise. + +2015-06-08 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Initialize dirarray early. + +2015-06-06 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Initialize filelist early. + +2015-05-27 Mark Wielaard + + * encoded-value.h (read_encoded_value): Check data d_size contains + at least enough data to hold a pointer for DW_EH_PE_indirect. + +2015-05-22 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Limit stack usage of lines + with MAX_STACK_LINES, files with MAX_STACK_LINES and dirs with + MAX_STACK_DIRS. Calculate number of dirs needed first, then + create dirarray directly, without needing the next field. Free + not stack allocated lines and files at the end. + +2015-05-19 Mark Wielaard + + * dwarf_getlocation.c (__libdw_intern_expression): Create a stack + allocated array to hold locs. Allocate locs bigger than the array + with malloc and free them when done. + +2015-05-11 Jonathan Lebon + + * libdwP.h (DWARF_E_COMPRESSED_ERROR): New enumerator. + * dwarf_error.c (errmsgs): Add DWARF_E_COMPRESSED_ERROR message. + * dwarf_begin_elf.c (inflate_section): New static function, lifted + from... + (check_section): ... here. Call inflate_section, set libdw errno to + DWARF_E_COMPRESSED_ERROR if .debug_info section couldn't be inflated. + +2015-05-11 Jonathan Lebon + + * dwarf_begin_elf.c (check_section): Add compressed flag. Always + check for .zdebug sections. Only wrap decompression in #if USE_ZLIB. + +2015-05-06 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Use an int64_t to store and + check the line number. + +2015-05-05 Mark Wielaard + + * dwarf_getaranges.c (dwarf_getaranges): Check there is enough data + left before reading values. + +2015-05-04 Anthony G. Basile + + * Makefile.am (libdw_so_SOURCES): Append $(argp_LDADD) to link + command. + +2015-04-22 Mark Wielaard + + * memory-access.h (__libdw_max_len_leb128): Take type_len as argument. + (__libdw_max_len_uleb128): New function. + (__libdw_max_len_sleb128): Likewise. + (__libdw_get_uleb128): Use __libdw_max_len_uleb128. + (__libdw_get_sleb128): Use __libdw_max_len_sleb128. + +2015-04-21 Mark Wielaard + + * dwarf_getmacros.c (read_macros): Allocate attributes dynamically + when there are more than 8. + +2015-04-01 Petr Machata + + * libdwP.h (DWARF_E_NOT_CUDIE): New enumerator. + (is_cudie): New function. + * dwarf_error.c (errmsgs): Add message for DWARF_E_NOT_CUDIE. + * dwarf_getsrcfiles.c (dwarf_getsrcfiles): Call is_cudie instead + of white-listing valid tags. + * dwarf_getsrclines.c (dwarf_getsrclines): Likewise. + +2015-03-18 Petr Machata + + * Makefile.am (pkginclude_HEADERS): Add known-dwarf.h. + (EXTRA_DIST): Remove known-dwarf.h. + +2015-02-09 Mark Wielaard + + * dwarf.h: Add DW_LANG_Fortran03 and DW_LANG_Fortran08. + * dwarf_aggregate_size.c (array_size): Recognize array lower bound + for new Fortran language codes is 1. + +2015-02-09 Mark Wielaard + + * dwarf.h: Add DW_TAG_atomic_type. + * libdw.h (dwarf_peel_type): Document DW_TAG_atomic_type. + * dwarf_peel_type.c (dwarf_peel_type): Handle DW_TAG_atomic_type. + +2015-02-11 Josh Stone + + * encoded-value.h (read_encoded_value): Initialize value. + +2015-02-11 Petr Machata + + * dwarf_ranges.c (dwarf_ranges): Do not bail out when neither + DW_AT_entry_pc nor DW_AT_low_pc are available. Instead remember + the fact in *BASEP and bail out later if it hasn't been updated by + __libdw_read_begin_end_pair_inc. + +2014-12-24 Mark Wielaard + + * dwarf_getsrc_die.c (dwarf_getsrc_die): Return the last line record + smaller than or equal to addr, rather than returning immediately on + a match. + +2015-01-07 Mark Wielaard + + * cfi.h (struct Dwarf_CFI_s): Add search_table_len. + * dwarf_getcfi_elf.c (getcfi_gnu_eh_frame): Check there is enough + room in the search table for all entries. Store search_table_len. + (getcfi_scn_eh_frame): Likewise. + * encoded-value.h (encoded_value_size): Don't abort, return zero. + (__libdw_cfi_read_address_inc): Check there is enough room to read + values. Pass other byte order to read functions. + (read_encoded_value): Check encoded_value_size. Don't abort, but + set libdw errno and report failure. Check there is enough room to + read values. + * fde.c (binary_search_fde): Check encoded value size. Add hdr + data buf and size to dummy_cfi. + +2015-01-04 Mark Wielaard + + * dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute + is after current DIE. + +2015-01-04 Mark Wielaard + + * cfi.c (enough_registers): Check reg < INT32_MAX / sizeof + (dwarf_frame_register). + +2015-01-02 Mark Wielaard + + * dwarf_getcfi_elf.c (parse_eh_frame_hdr): Add size check. + (getcfi_gnu_eh_frame): Remove size check. Check d_buf is not NULL. + (getcfi_scn_eh_frame): Check d_buf is not NULL. + +2015-01-02 Mark Wielaard + + * dwarf_getlocation.c (__libdw_intern_expression): Check dbg is not + NULL for DW_OP_call_ref and DW_OP_GNU_implicit_pointer. For + DW_OP_addr if dbg is NULL then read argument directly. + +2015-01-14 Jason P. Leasure + + * dwarf_formref_die.c (dwarf_formref_die): Offset is cu->type_offset + plus cu->start. + +2014-12-27 Mark Wielaard + + * dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute offset + still falls inside CU data. + +2015-01-11 Mark Wielaard + + * dwarf_func_inline.c (dwarf_func_inline_instances): Call + __libdw_visit_scopes with NULL imports. + * dwarf_getfuncs.c (dwarf_getfuncs): Likewise. + * dwarf_getscopes.c (pc_record): Likewise. + (dwarf_getscopes): Likewise. + * dwarf_getscopes_die.c (dwarf_getscopes_die): Likewise. + * libdwP.h (__libdw_visit_scopes): Add imports argument. + * libdw_visit_scopes.c (__libdw_visit_scopes): Likewise. Add new + function imports_contains. Push and pop imports around walk_children + when processing DW_TAG_imported_unit. + +2014-12-18 Ulrich Drepper + + * Makefile.am: Suppress output of textrel_check command. + +2014-12-16 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Check diridx is valid under + DW_LNE_define_file. + +2014-12-16 Mark Wielaard + + * dwarf_getpubnames.c (dwarf_getpubnames): Make sure there is enough + space to read die offset. + +2014-12-16 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Correct overflow check for + unit_length. + +2014-12-15 Mark Wielaard + + * dwarf_getpubnames.c (get_offsets): Make sure whole unit fall inside + section data. Set error to DWARF_E_NO_ENTRY if cnt is zero. + (dwarf_getpubnames): Make sure section data contains string zero + terminator. + +2014-12-16 Mark Wielaard + + * memory-access.h (__libdw_get_sleb128): Unroll the first step to help + the compiler optimize for the common single-byte case. + +2014-12-15 Josh Stone + + * memory-access.h (__libdw_max_len_leb128): New. + (__libdw_get_uleb128): Use __libdw_max_len_leb128. + (__libdw_get_sleb128): Likewise. + +2014-12-14 Mark Wielaard + + * cfi.c (execute_cfi): Add program bounds checks. + * dwarf_child.c (__libdw_find_attr): Add attrp bounds checks. + * dwarf_formblock.c (dwarf_formblock): Call get_uleb128 with endp. + * dwarf_formref.c (__libdw_formref): Add datap bounds checks. + * dwarf_formsdata.c (dwarf_formsdata): Likewise. + * dwarf_formudata.c (dwarf_formudata): Likewise. + * dwarf_frame_register.c (dwarf_frame_register): Call get_uleb128 + with end of data buf. + * dwarf_getabbrev.c (__libdw_getabbrev): Add abbrevp bounds checks. + * dwarf_getabbrevattr.c (dwarf_getabbrevattr): Assume get_uleb128 + call gets enough data. + * dwarf_getattrs,c (dwarf_getattrs): Call get_uleb128 with endp. + * dwarf_getlocation.c (store_implicit_value): Call get_uleb128 + with enough data. + (__libdw_intern_expression): Call get_uleb128/get_sleb128 with + end_data. + * dwarf_getmacros.c (get_table_for_offset): Add nforms bounds check. + * dwarf_getsrclines.c (read_srclines): Bounds check linep and call + get_uleb128 with lineendp. + * dwarf_hasattr.c (dwarf_hasattr): Bounds check attrp and call + get_uleb128 with endp. + * dwarf_next_cfi.c (dwarf_next_cfi): Bounds check bytes and call + get_uleb128/get_sleb128 with limit. + * encoded-value.h (read_encoded_value): Assume get_uleb128 and + get_sleb128 get called with enough data. + * fde.c (intern_fde): Call get_uleb128 with instructions_end. + * libdwP.h (__libdw_dieabbrev): Call get_uleb128 with die->cu->endp. + * libdw_form.c (__libdw_form_val_compute_len): Call get_uleb128 with + endp. + * memory-access.h (__libdw_get_uleb128): Take an extra endp. + Don't call get_uleb128_step if out of data. + (__libdw_get_sleb128): Likewise for get_sleb128_step. + +2014-12-12 Mark Wielaard + + * libdwP.h (struct Dwarf): Add fake_loc_cu. + (cu_data): Removed. + (DIE_OFFSET_FROM_CU_OFFSET): Don't use cu_data, use cu_sec_idx. + (__libdw_form_val_compute_len): Drop dbg and endp arguments. + (__libdw_form_val_len): Likewise. + * libdw_form.c (__libdw_form_val_compute_len): Likewise. + * libdw_findcu.c (__libdw_intern_next_unit): Don't use cu_data, use + the already found data buffer directly. + * dwarf_begin_elf.c (valid_p): Setup fake_loc_cu. + * dwarf_end.c (dwarf_end): Free fake_loc_cu. + * dwarf_child.c (__libdw_find_attr): Call __libdw_form_val_len with + just cu. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_formblock.c (dwarf_formblock): Add bounds checking. + * dwarf_getlocation_attr.c (attr_form_cu): New function. + (dwarf_getlocation_attr): Use attr_form_cu to set result->cu. + (getlocation): Handle empty blocks immediately. + * dwarf_getlocation_implicit_pointer.c (empty_cu): New static var. + (__libdw_empty_loc_attr): Drop cu argument, use empty_cu. + (dwarf_getlocation_implicit_pointer): Call __libdw_empty_loc_attr with + one argument. + * dwarf_getmacros.c (read_macros): Also setup startp and endp for + fake_cu. Call __libdw_form_val_len with just fake_cu. + * dwarf_formref_die.c (dwarf_formref_die): Don't use cu_data, get + datap and size directly from cu startp and endp. + +2014-12-11 Mark Wielaard + + * libdw_findcu.c (__libdw_intern_next_unit): Sanity check offset. + +2014-12-13 Mark Wielaard + + * dwarf_getaranges.c (compare_aranges): Make sure Dwarf_Addr + difference doesn't wrap around before returning as int. + +2014-12-11 Josh Stone + + * dwarf_getsrclines.c (struct linelist): Add sequence. + (compare_lines): Take linelists, and break ties by sequence. + (read_srclines): Use linelists for sorting. + (read_srclines::add_new_line): Set sequence. + +2014-12-10 Josh Stone + + * libdwP.h (Dwarf_CU): Add startp and endp boundaries. + * libdw_findcu.c (__libdw_intern_next_unit): Set startp and endp. + * dwarf_child.c (dwarf_child): Use cu->endp. + * dwarf_cuoffset.c (dwarf_cuoffset): Use cu->startp. + * dwarf_dieoffset.c (dwarf_dieoffset): Use cu->startp. + * dwarf_siblingof.c (dwarf_siblingof): Use both. + +2014-12-10 Josh Stone + + * dwarf_hasattr.c (dwarf_hasattr): Just walk abbrev for presence. + +2014-12-10 Josh Stone + + * libdwP.h (__libdw_dieabbrev): New die->abbrev lookup function. + * dwarf_child.c (__libdw_find_attr, dwarf_child): Use it. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_haschildren.c (dwarf_haschildren): Likewise. + * dwarf_tag.c (dwarf_tag): Likewise. + +2014-12-04 Mark Wielaard + + * libdwP.h (__libdw_form_val_compute_len): Add endp argument. + (__libdw_form_val_len): Likewise and check len doesn't overflow. + * libdw_form.c (__libdw_form_val_compute_len): Likewise. + * dwarf_child.c (__libdw_find_attr): Call __libdw_form_val_len + with endp. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_getmacros.c (read_macros): Likewise and check for errors. + +2014-12-02 Petr Machata + + * dwarf_getmacros.c (token_from_offset, offset_from_token): New + helper functions. + (do_dwarf_getmacros_die): Merge into dwarf_getmacros. + * libdw.h (DWARF_GETMACROS_START): New macro. + +2014-11-27 Mark Wielaard + + * Makefile.am (libdw.so): Use textrel_check. + +2014-11-27 Mark Wielaard + + * dwarf_getcfi_elf.c (getcfi_gnu_eh_frame): Initialize + search_table_entries and search_table_encoding. + +2014-11-24 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Check line_range is not zero + before usage. + +2014-11-23 Mark Wielaard + + * dwarf_attr.c (dwarf_attr): Check __libdw_find_attr return value. + * dwarf_hasattr.c (dwarf_hasattr): Likewise. + * dwarf_siblingof.c (dwarf_siblingof): Likewise. + +2014-11-23 Mark Wielaard + + * dwarf_getabbrev.c (__libdw_getabbrev): Don't assert on bad DWARF. + Set libdw errno and return NULL. + +2014-11-24 Mark Wielaard + + * dwarf.h (DW_LANG_C_plus_plus_11): Added. + (DW_LANG_C11): Likewise. + (DW_LANG_C_plus_plus_14): Likewise. + * dwarf_aggregate_size.c (array_size): Handle DW_LANG_C11, + DW_LANG_C_plus_plus_11, DW_LANG_C_plus_plus_14 and DW_LANG_Go + lower bound. + * dwarf_getfuncs.c (dwarf_getfuncs): Set c_cu to true for + DW_LANG_C11. + +2014-11-26 Mark Wielaard + + * dwarf.h (DW_AT_noreturn): Added. + +2014-11-11 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Do address_size comparison + explicitly as uint8_t. + (__libdw_getsrclines): Add internal_function to declaration. + +2014-09-10 Petr Machata + + * dwarf_macro_getparamcnt.c: New file. + * dwarf_macro_param.c: New file. + * dwarf_macro_getsrcfiles.c: New file. + * Makefile.am (libdw_a_SOURCES): Add the new files. + * libdwP.h (struct files_lines_s): New structure. + (DWARF_E_INVALID_OPCODE): New enumerator. + (struct Dwarf): New fields macro_ops, files_lines. + (Dwarf_Macro_Op_Proto, Dwarf_Macro_Op_Table): New structures for + keeping macro opcode prototypes in. + (Dwarf_Macro_s): Redefine from scratch. + (__libdw_getsrclines, __libdw_getcompdir, libdw_macro_nforms): New + internal interfaces. + * dwarf_error.c (errmsgs): Add a message for + DWARF_E_INVALID_OPCODE. + * dwarf_end.c (dwarf_end): Destroy struct Dwarf.macro_ops and + files_lines. + * libdw.h (dwarf_getmacros_off, dwarf_macro_getparamcnt) + (dwarf_macro_getsrcfiles, dwarf_macro_param): New public + interfaces. + * dwarf_getmacros.c (dwarf_getmacros_off): New function, + (get_offset_from, macro_op_compare, build_table) + (init_macinfo_table, get_macinfo_table, get_table_for_offset) + (cache_op_table, read_macros, gnu_macros_getmacros_off) + (macro_info_getmacros_off, do_dwarf_getmacros_die): New helper + functions. + (dwarf_getmacros): Adjust to dispatch to the new interfaces. + * dwarf_getsrclines.c (read_srclines): New function with guts + taken from dwarf_getsrclines. + (__libdw_getsrclines): Likewise. + (__libdw_getcompdir, files_lines_compare): New functions. + (dwarf_getsrclines): Make it dispatch to the new interfaces. + * dwarf_macro_param1.c (dwarf_macro_param1): Adjust to dispatch to + the new interfaces. + * dwarf_macro_param2.c (dwarf_macro_param2): Likewise. + * libdw.map (ELFUTILS_0.161): New. Add dwarf_getmacros_off, + dwarf_macro_getsrcfiles, dwarf_macro_getparamcnt, dwarf_macro_param. + +2014-10-06 Mark Wielaard + + * Makefile.am (libdw_a_SOURCES): Add dwarf_peel_type.c. + * dwarf_aggregate_size.c (get_type): Use dwarf_peel_type. + (aggregate_size): Likewise. Add old and new version. + * dwarf_peel_type.c: New file. + * libdw.h (dwarf_peel_type): New function declaration. + * libdwP.h (dwarf_peel_type): New internal declaration. + * libdw.map (ELFUTILS_0.161): New section. + +2014-10-15 Petr Machata + + * libdwP.h (struct Dwarf_Files_s.cu): Drop field. + * dwarf_getsrclines.c (dwarf_getsrclines): Don't set it. + +2014-10-05 Mark Wielaard + + * dwarf.h: Add DW_AT_GNU_deleted. + +2014-10-02 Mark Wielaard + + * dwarf_aggregate_size.c (aggregate_size): Return CU address_size + for sizeless DW_TAG_pointer_type, DW_TAG_reference_type or + DW_TAG_rvalue_reference_type. + +2014-09-12 Petr Machata + + * memory-access.h (read_ubyte_unaligned_inc): Allow only 4- and + 8-byte quantities. Consequently, rename to... + (read_addr_unaligned_inc): ... this. + (read_sbyte_unaligned_inc, read_ubyte_unaligned): Drop. + (read_sbyte_unaligned): Drop. + +2014-09-10 Petr Machata + + * dwarf_getlocation.c (attr_ok): Also accept + DW_AT_GNU_call_site_value, DW_AT_GNU_call_site_data_value, + DW_AT_GNU_call_site_target, DW_AT_GNU_call_site_target_clobbered. + +2014-08-15 Mark Wielaard + + * dwarf_cu_die.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_cu_die.c. + * libdw.h (dwarf_cu_die): New function declaration. + * libdw.map (ELFUTILS_0.160): Add dwarf_cu_die. + +2014-08-15 Mark Wielaard + + * dwarf_cu_getdwarf.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_cu_getdwarf.c. + * libdw.h (Dwarf_CU): New typedef. + (dwarf_cu_getdwarf): New function declaration. + * libdw.map (ELFUTILS_0.160): New. Add dwarf_cu_getdwarf. + +2014-06-18 Mark Wielaard + + * dwarf.h: Remove DW_TAG_mutable_type. + +2014-05-02 Mark Wielaard + + * libdwP.h (__check_build_id): Removed now unused. + +2014-05-01 Mark Wielaard + + * libdwP.h (struct Dwarf): Remove free_alt. + * dwarf_end.c (dwarf_end): Don't check free_alt, don't end alt_dwarf. + * dwarf_setalt.c (dwarf_setalt): Don't check or set free_alt. + +2014-04-30 Mark Wielaard + + * libdw.map (ELFUTILS_0.159): Add dwelf_elf_gnu_build_id. + +2014-04-15 Florian Weimer + + * dwarf_begin_elf.c (__check_build_id, try_debugaltlink) + (open_debugaltlink): Move to libdwfl. + (check_section): Do not locate alternate debuginfo. + +2014-04-24 Florian Weimer + + * libdw.map (ELFUTILS_0.159): Export dwelf_dwarf_gnu_debugaltlink. + +2014-04-22 Florian Weimer + + * dwarf_getalt.c, dwarf_setalt.c: New files. + * Makefile.am (libdw_a_SOURCES): Add them. + * libdw.h (dwarf_getalt, dwarf_setalt): Add function declarations. + * libdwP.h (dwarf_getalt, dwarf_setalt): Add internal function + declarations. + * libdw.map (ELFUTILS_0.159): Export the two new functions. + +2014-04-15 Florian Weimer + + * libdwP.h (enum IDX_gnu_debugaltlink): New. + * dwarf_begin_elf.c (dwarf_scnnames): Increase string size and add + .gnu_debugaltlink. + (check_section): Obtain .gnu_debugaltlink section from the + setiondata array. + +2014-04-11 Mark Wielaard + + * libdw.map (ELFUTILS_0.159): New. Add dwelf_elf_gnu_debuglink. + * Makefile.am (libdw.so): Depend on libdwelf_pic.a. + (libdwelf_objects): New variable. + (libdw_a_LIBADD): Add libdwelf objects. + +2014-04-22 Mark Wielaard + + * memory-access.h (get_sleb128_step): Remove undefined behavior + of left shifting a signed value. Replace it with a multiplication. + +2014-04-13 Mark Wielaard + + * Makefile.am: Remove !MUDFLAP conditions. + +2014-04-09 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Check for unsigned overflow + before calling malloc to uncompress data. + +2014-03-03 Jan Kratochvil + + Fix abort() on missing section headers. + * dwarf_begin_elf.c (check_section): Replace abort call by goto err. + New label err to return NULL. + +2014-02-05 Josh Stone + + * dwarf_decl_file.c (dwarf_decl_file): Read the idx as unsigned. + * dwarf_decl_line.c (__libdw_attr_intval): Read the line/column as + unsigned. Change the range assert to DWARF_E_INVALID_DWARF. + +2013-12-30 Mark Wielaard + + * libdw.map (ELFUTILS_0.158): Add dwfl_core_file_attach and + dwfl_linux_proc_attach. + +2013-12-20 Mark Wielaard + + * libdw.map (ELFUTILS_0.158): Add dwfl_getthread_frames. + +2013-12-18 Mark Wielaard + + * libdw.map (ELFUTILS_0.158): Remove dwfl_module_addrsym_elf and + dwfl_module_getsym_elf. Add dwfl_module_addrinfo and + dwfl_module_getsym_info. + +2013-12-16 Mark Wielaard + + * libdw.map (ELFUTILS_0.158): Add dwfl_module_getsymtab_first_global. + +2013-12-10 Josh Stone + + * memory-access.h (get_uleb128_rest_return): Removed. + (get_sleb128_rest_return): Removed. + (get_uleb128_step): Make this a self-contained block. + (get_sleb128_step): Ditto, and use a bitfield to extend signs. + (get_uleb128): Make this wholly implemented by __libdw_get_uleb128. + (get_sleb128): Make this wholly implemented by __libdw_get_sleb128. + (__libdw_get_uleb128): Simplify and inline for all callers. + (__libdw_get_sleb128): Ditto. + * dwarf_getlocation.c (store_implicit_value): Void the unused uleb128. + * memory-access.c: Delete file. + * Makefile.am (libdw_a_SOURCES): Remove it. + (DEFS): Remove the now unused -DIS_LIBDW. + +2013-12-09 Josh Stone + + * libdw_form.c (__libdw_form_val_compute_len): Renamed function from + __libdw_form_val_len, now handling only non-constant form lengths. + * libdwP.h (__libdw_form_val_len): New inlined function. + +2013-12-09 Mark Wielaard + + * dwarf_getlocation.c (__libdw_intern_expression): Handle empty + location expressions. + * dwarf_getlocation_attr.c (dwarf_getlocation_attr): When no + location found, return empty location expression. + * dwarf_getlocation_implicit_pointer.c + (dwarf_getlocation_implicit_pointer): Likewise. + (__libdw_empty_loc_attr): New internal function. + * libdwP.h (__libdw_empty_loc_attr): Define. + +2013-11-27 Mark Wielaard + + * libdw.map (ELFUTILS_0.158): Add dwfl_module_addrsym_elf and + dwfl_module_getsym_elf. + +2013-11-26 Mark Wielaard + + * libdw.map (ELFUTILS_0.156): Move dwfl_attach_state, dwfl_pid, + dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread, + dwfl_thread_state_registers, dwfl_thread_state_register_pc, + dwfl_getthreads, dwfl_thread_getframes and dwfl_frame_pc to ... + (ELFUTILS_0.158): ... here. + +2013-11-09 Mark Wielaard + + * dwarf_getaranges.c (dwarf_getaranges): Read segment_size and + check that it is zero. + +2013-11-07 Jan Kratochvil + + * cfi.h (struct Dwarf_Frame_s): Make the comment more specific. + * libdw.map (ELFUTILS_0.156): Add dwfl_attach_state, dwfl_pid, + dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread, + dwfl_thread_state_registers, dwfl_thread_state_register_pc, + dwfl_getthreads, dwfl_thread_getframes and dwfl_frame_pc. + +2013-11-01 Michael Forney + + * Makefile.am (libdwfl_objects): New definition. + (libdw_a_LIBADD): Use libdwfl_objects. + +2013-11-01 Michael Forney + + * Makefile.am: Use READELF. + +2013-10-30 Jan Kratochvil + + * libdw.map (ELFUTILS_0.158): New. + +2013-10-10 Mark Wielaard + + * dwarf_getfuncs.c (struct visitor_info): Rename start_offset to + start_addr and rename last_offset to last_addr. Now both void *. + (tree_visitor): Use start_add and die_addr instead of start_offset + and die_offset. + (dwarf_getfuncs): Use last_addr instead of last_offset. + +2013-10-06 Mark Wielaard + + * cfi.c (execute_cfi): Make sure DW_CFA_expression and + DW_CFA_val_expression are not used with abi_cfi. + +2013-10-03 Josh Stone + + * dwarf_formref_die.c (dwarf_formref_die): Don't hash the sig8 here. + * libdw_findcu.c (__libdw_intern_next_unit): Since this never revisits + a unit, make sure to always hash the sig8 here, so none are missed. + +2013-09-29 Mark Wielaard + + * dwarf_getlocation.c (store_implicit_value): Cast op->number2 to + uintptr_t before casting to char *. + (__libdw_intern_expression): Cast data to uintptr_t before casting + to Dwarf_Word. + * dwarf_getlocation_attr.c (dwarf_getlocation_attr): Cast + op->number2 to uintptr_t before casting to char *. + +2013-09-24 Josh Stone + + * libdw_visit_scopes.c (classify_die): Removed. + (may_have_scopes): New function to replace classify_die. There's no + need for full classification; just find tags that may contain scopes. + (__libdw_visit_scopes): Use a direct tag comparison for imported + units, and use may_have_scopes to test if recursion is needed. + +2013-09-20 Mark Wielaard + + * dwarf_getfuncs.c (visitor_info): New struct. + (tree_visitor): New function. + (dwarf_getfuncs): Use __libdw_visit_scopes with tree_visitor. + * libdw.h (dwarf_getfuncs): Expand function documentation. + +2013-09-12 Mark Wielaard + + * fde.c (intern_fde): Free fde and set libdw errno when start + or end could not be read. + +2013-08-24 Mark Wielaard + + * dwarf_getlocation.c (store_implicit_value): Don't take data + as argument, get block data from op number2. Return false when + block data length and op number don't match up. + (__libdw_intern_expression): Store start of block for + DW_OP_implicit_value and DW_OP_GNU_entry_value instead of + relative data offset. Also store block start (including length) + for DW_OP_GNU_const_type. Don't pass data to store_implicit_value. + * dwarf_getlocation_attr.c: New file. + * dwarf_getlocation_die.c: Likewise. + * libdw.h (dwarf_getlocation_die): New function definition. + (dwarf_getlocation_attr): Likewise. + * libdwP.h: Declare internal dwarf_getlocation_die. + * libdw.map (ELFUTILS_0.157): Add dwarf_getlocation_die and + dwarf_getlocation_attr. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getlocation_die.c and + dwarf_getlocation_attr.c. + +2013-08-23 Mark Wielaard + + * dwarf_getlocation.c (attr_ok): Also accept DW_AT_segment. + (attr_base_address): New function. + (initial_offset_base): New function. + (getlocations_addr): New function. Taken from... + (dwarf_getlocation_addr): here. Use new initial_offset_base and + getlocations_addr. + (dwarf_getlocations): New function. + * libdw.h (dwarf_getlocations): New function definition. + * libdw.map (ELFUTILS_0.157): New. + +2013-07-02 Mark Wielaard + + * dwarf_getsrclines.c (dwarf_getsrclines): Add new stack allocation + limit MAX_STACK_ALLOC. After MAX_STACK_ALLOC lines use malloc in + NEW_LINE macro. Free malloced line records if any at the end. + +2013-07-02 Mark Wielaard + + * dwarf_getcfi_elf.c (getcfi_shdr): Check sh_type == SHT_PROGBITS. + +2013-06-26 Mark Wielaard + + * libdw_visit_scopes.c (__libdw_visit_scopes): Don't reject root + DIEs without children. Return an error whenever dwarf_child or + dwarf_siblingof return an error. Don't call recurse and increase + the depth for an imported unit. Walk the children of an imported + unit as if they are logical children of the parent root DIE. + +2013-05-03 Mark Wielaard + + * dwarf_getsrclines.c (dwarf_getsrclines): Only set end_sequence + when nlinelist > 0. + +2013-04-28 Jan Kratochvil + + * libdw.map (ELFUTILS_0.156): New. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2013-04-10 Mark Wielaard + + * dwarf_formref_die.c (dwarf_formref_die): Reference size is only + equal to address size when we have a DW_FORM_ref_addr for DWARF + version 2. + +2013-03-25 Mark Wielaard + + * dwarf_getsrclines.c (dwarf_getsrclines): Mark highest address as + end_sequence. + +2013-03-12 Mark Wielaard + + * dwarf_getsrcfiles.c (dwarf_getsrcfiles): Allow DW_TAG_partial_unit. + * dwarf_getsrclines.c (dwarf_getsrclines): Likewise. + +2013-02-15 Mark Wielaard + + * dwarf_formstring.c (dwarf_formstring): Check dbg_ret->sectiondata, + not dbg->sectiondata. + +2013-01-07 Roland McGrath + + * memory-access.h + [ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New macro. + [!ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New inline function. + +2012-12-18 Mark Wielaard + + * dwarf_begin_elf.c (valid_p): Call Dwarf_Sig8_Hash_free if invalid. + (check_section): Likewise on error. + (scngrp_read): Likewise. + (dwarf_begin_elf): Likewise. + +2012-10-09 Petr Machata + + * dwarf_getlocation.c (__libdw_intern_expression): Handle + DW_OP_GNU_parameter_ref, DW_OP_GNU_convert, DW_OP_GNU_reinterpret, + DW_OP_GNU_regval_type, DW_OP_GNU_entry_value, + DW_OP_GNU_deref_type, DW_OP_GNU_const_type. + +2012-10-08 Jan Kratochvil + + * cfi.c: New include system.h. + (execute_cfi) (enough_registers): Clear new memory after realloc. + +2012-10-08 Jan Kratochvil + + * fde.c (__libdw_find_fde): Change to likely. Return + DWARF_E_NO_MATCH if .eh_frame_hdr points to FDE which is too short for + searched PC. + +2012-10-08 Jan Kratochvil + + * dwarf_getlocation.c (__libdw_intern_expression) : Make new + loclist element DW_OP_call_frame_cfa before decoding the opcodes. + Remove the later DW_OP_call_frame_cfa push to RESULT. + +2012-10-08 Jan Kratochvil + + Code cleanup. + * fde.c (binary_search_fde): Remove always true
= start> + conditional. Move L initialization upwards. + +2012-08-24 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Only probe for dwz multi files + when ENABLE_DWZ is defined. + * libdwP.h (__check_build_id): Only declare when ENABLE_DWZ is + defined. + +2012-08-16 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add known-dwarf.h. + * dwarf.h (DW_LANG_Go): Update comment. + (DW_LANG_Mips_Assembler): Likewise. + +2012-06-27 Mark Wielaard + + * dwarf.h: Add DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. + * dwarf_begin.c (dwarf_begin): Add INTDEF. + * dwarf_begin_elf.c (__check_build_id): New internal_function. + (try_debugaltlink): New function. + (open_debugaltlink): Likewise. + (check_section): Try open_debugaltlink for .gnu_debugaltlink. + * dwarf_end.c (dwarf_end): Free the alternative Dwarf descriptor if + necessary. + * dwarf_error.c (errmsgs): Add DWARF_E_NO_ALT_DEBUGLINK. + * dwarf_formref.c (__libdw_formref): Using DW_FORM_GNU_ref_alt + is an error here. + * dwarf_formref_die.c (dwarf_formref_die): Handle DW_FORM_GNU_ref_alt. + * dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_GNU_strp_alt. + * dwarf_formudata.c (__libdw_formptr): Adjust __libdw_read_offset + calls. + * dwarf_getpubnames.c (get_offsets): Adjust __libdw_read_offset call. + * libdwP.h: Add DWARF_E_NO_ALT_DEBUGLINK. + (struct Dwarf): Add alt_dwarf and free_alt fields. + (__libdw_read_offset): Add dbg_ret argument, use to check with + __libdw_offset_in_section. + (__check_build_id): New function declaration. + (dwarf_begin): Define as INTDECL. + * libdw_form.c (__libdw_form_val_len): Handle DW_FORM_GNU_ref_alt + and DW_FORM_GNU_strp_alt. + +2012-07-19 Mark Wielaard + + * dwarf.h: Add DW_OP_GNU_parameter_ref. + +2012-07-24 Mark Wielaard + + * dwarf.h: Correct spelling of DW_LANG_ObjC. + * dwarf_aggregate_size.c (array_size): Use correct spelling of + DW_LANG_ObjC. + +2012-07-24 Mark Wielaard + + * dwarf.h: Add DW_ATE_UTF. + +2012-06-27 Mark Wielaard + + * dwarf.h: Add DW_MACRO_GNU .debug_macro type encodings. + +2012-06-26 Mark Wielaard + + * libdwP.h: Add IDX_debug_macro. + * dwarf.h: Add DW_AT_GNU_macros. + * dwarf_begin_elf.c (dwarf_scnnames): Add .debug_macro. + * dwarf_formudata.c (dwarf_formudata): Recognize DW_AT_GNU_macros. + +2012-04-27 Mark Wielaard + + * libdw/dwarf_highpc.c (dwarf_highpc): Handle DW_AT_high_pc being + a constant offset from DW_AT_low_pc. + +2012-03-19 Tom Tromey + + * libdw_findcu.c (findcu_cb): Move earlier. + (__libdw_intern_next_unit): Add new CU to search tree here... + (__libdw_findcu): ... not here. + +2012-01-31 Mark Wielaard + + * dwarf_formudata.c (dwarf_formudata): Handle DW_FORM_sec_offset. + +2011-11-31 Mark Wielaard + + * Makefile.am (known-dwarf.h): Run gawk on config/known-dwarf.awk. + +2011-07-14 Mark Wielaard + + * libdw.h (dwarf_offdie): Fix documentation to mention .debug_info. + +2011-05-16 Jakub Jelinek + + * dwarf.h (DW_OP_GNU_const_type, DW_OP_GNU_regval_type, + DW_OP_GNU_deref_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret): + New. + +2011-04-26 Mark Wielaard + + * dwarf_child (dwarf_child): Sanity check end of section against + cu_data () of die->cu. + +2011-03-22 Mark Wielaard + + * dwarf.h: Add DW_TAG_GNU_call_site, + DW_TAG_GNU_call_site_parameter, + DW_AT_GNU_call_site_value, + DW_AT_GNU_call_site_data_value, + DW_AT_GNU_call_site_target, + DW_AT_GNU_call_site_target_clobbered, + DW_AT_GNU_tail_call, + DW_AT_GNU_all_tail_call_sites, + DW_AT_GNU_all_call_sites, + DW_AT_GNU_all_source_call_sites, + and DW_OP_GNU_entry_value. + +2011-03-10 Petr Machata + + * libdw/dwarf_tag.c (__libdw_findabbrev): Reject requests for + abbreviation with code 0. + +2011-03-09 Petr Machata + + * libdw/dwarf_child.c (dwarf_child): Check for section overrun. + +2011-02-23 Roland McGrath + + * libdwP.h (struct Dwarf) [USE_ZLIB]: New member sectiondata_gzip_mask. + Declare __libdw_free_zdata. + * dwarf_end.c [USE_ZLIB] (__libdw_free_zdata): New function. + (dwarf_end): Call it. + + * dwarf_begin_elf.c (valid_p): Likewise. + (check_section, scngrp_read): Likewise. + (check_section) [USE_ZLIB]: Grok .z* flavors of sections. + +2010-10-13 Roland McGrath + + * dwarf.h: Add DW_LANG_Go. + +2010-10-05 Roland McGrath + + * dwarf_getaranges.c: Use malloc rather than alloca, + since the total number of elements can be quite huge. + +2010-07-26 Roland McGrath + + * dwarf_getlocation_implicit_pointer.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.map (ELFUTILS_0.149): New set. + Add dwarf_getlocation_implicit_pointer. + * libdw.h: Declare it. + + * dwarf_offdie.c (do_offdie): Renamed to __libdw_offdie, made global. + (dwarf_offdie, dwarf_offdie_types): Update callers. + * libdwP.h: Declare it. + + * dwarf.h: Add DW_OP_GNU_implicit_pointer. + * dwarf_getlocation.c (__libdw_intern_expression): Handle it. + +2010-08-24 Roland McGrath + + * libdw.map (ELFUTILS_0.149): New set. Add dwfl_dwarf_line. + +2010-07-27 Roland McGrath + + * dwarf_formref_die.c: Fix sig8 hash insertion. + +2010-06-23 Roland McGrath + + * cfi.c (dwarf_cfi_validate_fde): Function removed. + * libdw.h: Remove it. + * libdw.map: Likewise. + +2010-06-22 Roland McGrath + + * dwarf_getlocation.c (check_constant_offset): data[48] are constant. + + * dwarf_getsrclines.c: Fix signed comparison warning in extended + opcode parsing. + +2010-06-21 Roland McGrath + + * dwarf.h: Add DW_TAG_GNU_* constants. + + * memory-access.h (get_sleb128_rest_return): Fix sign extension for + 10-byte case. + +2010-06-20 Roland McGrath + + * libdw_findcu.c (__libdw_findcu): Take new flag argument, + to search TUs instead of CUs. + * libdwP.h: Update decl. + (struct Dwarf): New member tu_tree. + * dwarf_end.c (dwarf_end): Clean up tu_tree. + * dwarf_offdie.c (do_offdie): New function, broken out of ... + (dwarf_offdie): ... here. + (dwarf_offdie_types): New function. + * libdw.h: Declare it. + * libdw.map (ELFUTILS_0.148): Add it. + + * libdwP.h (CUDIE): Use cu_data. + * dwarf_formblock.c: Likewise. + * dwarf_formref_die.c: Likewise. + * dwarf_diecu.c: Use CUDIE macro. + * dwarf_formaddr.c: Use cu_sec_idx. + +2010-06-16 Roland McGrath + + * dwarf_formref_die.c: Use dwarf_offdie only for DW_FORM_ref_addr, so + we don't repeat a CU lookup we've already done. Handle + DW_FORM_ref_sig8 using sig8_hash table and __libdw_intern_next_unit. + + * libdw_findcu.c (__libdw_intern_next_unit): New function, + broken out of ... + (__libdw_findcu): ... here. Call it. + * libdwP.h: Declare it. + (struct Dwarf): New member next_tu_offset. + + * dwarf_sig8_hash.c: New file. + * dwarf_sig8_hash.h: New file. + * Makefile.am (libdw_a_SOURCES, noinst_HEADERS): Add them. + * dwarf_abbrev_hash.c: Include dwarf_sig8_hash.h before + defining NO_UNDEF. + * libdwP.h (struct Dwarf): New member sig8_hash. + * dwarf_begin_elf.c: Call Dwarf_Sig8_Hash_init on it. + * dwarf_end.c: Call Dwarf_Sig8_Hash_free on it. + + * dwarf_nextcu.c (dwarf_next_unit): New function, broken out of ... + (dwarf_nextcu): ... here. Call it. + * libdw.h: Declare it. + * libdwP.h: Add INTDECL. + * libdw_findcu.c (__libdw_findcu): Use it instead of dwarf_nextcu. + * libdw.map (ELFUTILS_0.148): New set, add dwarf_next_unit. + + * libdwP.h (cu_sec_idx, cu_data): New functions. + Use .debug_types when CU is a TU. + * dwarf_cuoffset.c: Use that instead of assuming IDX_debug_info. + * dwarf_siblingof.c: Likewise. + * dwarf_formstring.c: Likewise. + * dwarf_formudata.c (__libdw_formptr, dwarf_formudata): Likewise. + * dwarf_getlocation.c (dwarf_getlocation): Likewise. + (dwarf_getlocation_addr): Likewise. + + * libdwP.h (struct Dwarf_CU): Add new members type_offset, type_sig8. + (DIE_OFFSET_FROM_CU_OFFSET): Take flag argument; if true, compute + .debug_types header size instead of .debug_info header size. + (CUDIE): Use it. + * dwarf_diecu.c: Update caller. + * dwarf_getaranges.c: Likewise. + * dwarf_nextcu.c: Likewise. + * libdw_findcu.c (__libdw_findcu): Initialize new members. + + * fde.c (fde_by_offset): Renamed to ... + (__libdw_fde_by_offset): ... this, made global and internal_function. + Don't take ADDRESS argument. + (__libdw_find_fde): Update caller. Do address sanity check here. + * cfi.h: Declare __libdw_fde_by_offset. + * cfi.c (dwarf_cfi_validate_fde): New function. + * libdw.h: Declare it. + * libdw.map (ELFUTILS_0.148): Add it. + + * cie.c (intern_new_cie): Canonicalize DW_EH_PE_absptr FDE encoding to + either DW_EH_PE_udata8 or DW_EH_PE_udata4. + + * encoded-value.h (read_encoded_value): Handle DW_EH_PE_indirect. + Don't assume DW_EH_PE_aligned refers to native address size. + + * cfi.c (execute_cfi): Barf on CIE initial instructions changing the + address. + +2010-06-17 Roland McGrath + + * libdwP.h (struct Dwarf_Line_s): Add members isa, discriminator, and + op_index. + * dwarf_getsrclines.c (dwarf_getsrclines): Move NEW_FILE macro guts + into an inner inline function. Set new fields. Check all fields for + overflow when setting. + * dwarf_lineisa.c: New file. + * dwarf_linediscriminator.c: New file. + * dwarf_lineop_index.c: New file. + * Makefile.am (libdw_a_SOURCES): Add them. + * libdw.map (ELFUTILS_0.148): Add them. + * libdw.h: Declare them. + +2010-06-16 Roland McGrath + + * dwarf_next_cfi.c: Fix version 4 return_address_register decoding. + + * fde.c (fde_by_offset): Renamed to ... + (__libdw_fde_by_offset): ... this, made global and internal_function. + Don't take ADDRESS argument. + (__libdw_find_fde): Update caller. Do address sanity check here. + * cfi.h: Declare __libdw_fde_by_offset. + * cfi.c (dwarf_cfi_validate_fde): New function. + * libdw.h: Declare it. + * libdw.map (ELFUTILS_0.148): Add it. + + * cie.c (intern_new_cie): Canonicalize DW_EH_PE_absptr FDE encoding to + either DW_EH_PE_udata8 or DW_EH_PE_udata4. + + * encoded-value.h (read_encoded_value): Handle DW_EH_PE_indirect. + Don't assume DW_EH_PE_aligned refers to native address size. + + * cfi.c (execute_cfi): Barf on CIE initial instructions changing the + address. + +2010-06-15 Roland McGrath + + * dwarf_formref.c (__libdw_formref): Diagnose DW_FORM_ref_sig8 like + DW_FORM_ref_addr. + * dwarf_formref_die.c (dwarf_formref_die): Diagnose it the same way + here, since we don't support it yet. + + * dwarf_next_cfi.c: Handle version 4 format. + + * dwarf_getsrclines.c: Handle version 4 format. + +2010-06-01 Roland McGrath + + * libdwP.h: Remove unused IDX_debug_*names, add IDX_debug_types. + * dwarf_begin_elf.c (dwarf_scnnames): Likewise. + + * libdwP.h (CIE_VERSION): Remove unused macro. + + * dwarf_getsrclines.c: Fix version field test. + * libdwP.h (DWARF_VERSION): Remove useless macro. + + * dwarf_formudata.c (__libdw_formptr): Fix DW_FORM_sec_offset handling. + + * dwarf_formblock.c (dwarf_formblock): Handle DW_FORM_exprloc. + + * libdw_findcu.c (__libdw_findcu): Accept version 4. + +2010-05-31 Mark Wielaard + + * cfi.h (dwarf_cfi_cie_p): Move definition from here, to .. + * libdw.h (dwarf_cfi_cie_p): ... here. + +2010-05-31 Mark Wielaard + + * dwarf.h: Fix DW_LANG_Python constant. + +2010-05-28 Eduardo Santiago + + * dwarf_getlocation.c (dwarf_getlocation): Do attr_ok check first + thing. + +2010-05-27 Roland McGrath + + * dwarf.h: Add DW_AT_enum_class, DW_AT_linkage_name, + DW_TAG_template_alias, DW_LANG_Python, DW_LNE_set_discriminator. + +2010-05-08 Roland McGrath + + * dwarf_getlocation.c (__libdw_intern_expression): Take new argument + REF_SIZE. Use that to handle DW_OP_call_ref correctly. + (getlocation): Update caller. + * dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise. + * dwarf_frame_register.c (dwarf_frame_register): Likewise. + * libdwP.h: Update decl. + +2010-04-26 Roland McGrath + + * cfi.h (struct Dwarf_Frame_s): Add cfa_invalid alternative in cfa_rule. + * cfi.c (execute_cfi): Set that instead of doing cfi_assert for + DW_CFA_def_cfa_{offset*,register} when a non-offset rule is in force. + * dwarf_frame_cfa.c (dwarf_frame_cfa): Handle cfa_invalid. + + * dwarf_getlocation.c (__libdw_intern_expression): Take new arg CFAP. + Prepend DW_OP_call_frame_cfa if true. + (getlocation): Update caller. + * dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise. + * dwarf_frame_register.c (dwarf_frame_register): Likewise. + * libdwP.h: Update decl. + +2010-04-22 Roland McGrath + + * cfi.c (execute_cfi): Never return without cleanup. + Free FS on failure. + (cie_cache_initial_state): Adjust caller to expect that free. + (__libdw_frame_at_address): Likewise. + +2010-03-10 Roland McGrath + + * libdw.map (ELFUTILS_0.146): New set. Add dwfl_core_file_report. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2010-02-02 Mark Wielaard + + * fde.c (intern_fde): Fix length check for sized_augmentation_data. + +2010-01-07 Roland McGrath + + * dwarf_getcfi_elf.c (getcfi_phdr): Use elf_getphdrnum. + +2010-01-05 Roland McGrath + + * dwarf_aggregate_size.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare it. + * libdwP.h: Add INTDECL. + * libdw.map (ELFUTILS_0.144): New set. Add dwarf_aggregate_size. + + * dwarf_srclang.c: Add INTDEF. + * libdwP.h: Add INTDECL. + + * dwarf.h: Add some more DW_AT_GNU_* types from gcc. + + * dwarf.h: Add DW_AT_GNU_vector, DW_AT_GNU_template_name. + +2009-11-21 Roland McGrath + + * dwarf_getlocation.c (check_constant_offset): Return 1 for all + non-constant forms. + +2009-10-15 Roland McGrath + + * libdw_form.c (__libdw_form_val_len): Grok DW_FORM_sec_offset, + DW_FORM_exprloc, DW_FORM_flag_present, and DW_FORM_ref_sig8. + +2009-09-17 Roland McGrath + + * dwarf_getlocation.c (dwarf_getlocation_implicit_value): Make OP + argument a pointer to const. + * libdw.h: Update decl. + +2009-09-10 Roland McGrath + + * dwarf_getlocation.c (store_implicit_value): New function. + (__libdw_intern_expression): Use it, handle DW_OP_implicit_value. + (dwarf_getlocation_implicit_value): New function. + * libdw.h: Declare it. + * libdw.map (ELFUTILS_0.143): Add it. + +2009-09-09 Mark Wielaard + + * dwarf_getcfi.c (dwarf_getcfi): Clear cfi->ebl. + +2009-08-21 Josh Stone + + * dwarf_hasattr_integrate.c: Integrate DW_AT_specification too. + +2009-08-10 Roland McGrath + + * dwarf_getscopevar.c: Use dwarf_diename. + +2009-08-09 Roland McGrath + + * libdw.map (ELFUTILS_0.143): New version set, + inherits from ELFUTILS_0.142. + * dwarf_arrayorder.c: Use OLD_VERSION and NEW_VERSION to define an + alias in the ELFUTILS_0.122 version set and the default in the new set. + * dwarf_srclang.c: Likewise. + * dwarf_decl_file.c: Likewise. + * dwarf_decl_line.c: Likewise. + * dwarf_decl_column.c: Likewise. + * dwarf_bytesize.c: Likewise. + * dwarf_bitsize.c: Likewise. + * dwarf_bitoffset.c: Likewise. + +2009-08-07 Roland McGrath + + * dwarf_arrayorder.c: Use dwarf_attr_integrate. + * dwarf_srclang.c: Likewise. + * dwarf_decl_file.c: Likewise. + * dwarf_decl_line.c (__libdw_attr_intval): Likewise. + * dwarf_bytesize.c: Likewise. + * dwarf_bitsize.c: Likewise. + * dwarf_bitoffset.c: Likewise. + +2009-07-22 Roland McGrath + + * dwarf_frame_cfa.c: Change calling convention. + * libdw.h: Update decl. + + * dwarf_frame_register.c: Change calling/return-value convention for + value-only results and undefined/same_value. + * libdw.h: Update decl. + + * dwarf_getlocation.c (__libdw_intern_expression): Take new bool + argument, append DW_OP_stack_value if set. Don't take NOPS argument, + return that value instead. + (getlocation): Update caller. + * dwarf_frame_cfa.c: Likewise. + * libdwP.h: Update decl. + +2009-07-21 Roland McGrath + + * dwarf_getsrc_file.c: Ignore a CU that just has no DW_AT_stmt_list. + Fix loop iteration after skipping a bogus or useless CU. + + * dwarf_entry_breakpoints.c: Handle 0 dwarf_errno () as harmless + absence, not DWARF_E_NO_DEBUG_LINE. + +2009-07-20 Roland McGrath + + * dwarf_getlocation.c (__libdw_intern_expression): + Handle DW_OP_stack_value. + +2009-07-16 Roland McGrath + + * dwarf_formudata.c (__libdw_formptr): Handle DW_FORM_sec_offset, + reject others when CU's version > 3. + + * dwarf_formflag.c: Handle DW_FORM_flag_present. + + * dwarf.h: Add DW_OP_{implicit,stack}_value from DWARF 4 draft. + Also DW_TAG_type_unit and DW_TAG_rvalue_reference_type. + Also DW_AT_signature, DW_AT_main_subprogram, DW_AT_data_bit_offset, + and DW_AT_const_expr. + Also DW_FORM_sec_offset, DW_FORM_exprloc, DW_FORM_flag_present, + and DW_FORM_ref_sig8. + +2009-07-15 Roland McGrath + + * dwarf_getlocation.c: Grok DW_OP_form_tls_address, + DW_OP_GNU_push_tls_address, and DW_OP_bit_piece. + +2009-07-13 Roland McGrath + + * dwarf_getlocation.c: Grok DW_OP_call_frame_cfa. + +2009-07-08 Roland McGrath + + * libdw.map (ELFUTILS_0.142): Add dwfl_module_dwarf_cfi, + dwfl_module_eh_cfi. + + * libdwP.h (struct Dwarf): Add member `cfi'. + * dwarf_end.c (dwarf_end): Call __libdw_destroy_frame_cache on it. + * dwarf_getcfi.c: New file. + * dwarf_getcfi_elf.c: New file. + * dwarf_cfi_end.c: New file. + * dwarf_cfi_addrframe.c: New file. + * dwarf_frame_cfa.c: New file. + * dwarf_frame_register.c: New file. + * dwarf_frame_return_address_register.c: New file. + * Makefile.am (libdw_a_SOURCES): Add them. + * unwind.h: Declare those functions. + * libdw.map (ELFUTILS_0.142): Export them. + + * dwarf_getlocation.c (__libdw_intern_expression): New function, + broken out of ... + (getlocation): ... here, call it. + * libdwP.h: Declare it. + + * cie.c: New file. + * fde.c: New file. + * frame-cache.c: New file. + * cfi.c: New file. + * cfi.h: New file. + * encoded-value.h: New file. + * Makefile.am (libdw_a_SOURCES, noinst_HEADERS): Add them. + * libdwP.h: Add DWARF_E_INVALID_CFI to errors enum. + * dwarf_error.c (errmsgs): Add element for it. + + * dwarf_next_cfi.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h (Dwarf_CIE, Dwarf_FDE, Dwarf_CIE_Entry): New types. + Declare dwarf_next_cfi. + * libdw.map (ELFUTILS_0.142): New set, inherits from ELFUTILS_0.136. + Add dwarf_next_cfi. + + * memory-access.h [! ALLOW_UNALIGNED] + (read_2ubyte_unaligned): Renamed to ... + (read_2ubyte_unaligned_1): ... this. Take bool rather than Dwarf *. + (read_2ubyte_unaligned): Define as macro passing dbg->other_byte_order. + (read_2sbyte_unaligned): Likewise. + (read_4ubyte_unaligned): Likewise. + (read_4sbyte_unaligned): Likewise. + (read_8ubyte_unaligned): Likewise. + (read_8sbyte_unaligned): Likewise. + + * libdwP.h (IDX_eh_frame): Remove it. + * dwarf_begin_elf.c (dwarf_scnnames): Remove its element. + +2009-07-08 Roland McGrath + + * libdwP.h (struct Dwarf_Line_s): Reorder members to pack better. + + * dwarf_getlocation.c (check_constant_offset): New function. + (dwarf_getlocation, dwarf_getlocation_addr): Call it to + handle DW_AT_data_member_location of data[48] as constant offset. + +2009-06-18 Roland McGrath + + * libdwP.h (__libdw_read_address_inc): Constify. + (__libdw_read_offset_inc): Likewise. + * dwarf_getaranges.c: Likewise. + * dwarf_getlocation.c: Likewise. + * dwarf_getsrclines.c: Likewise. + * dwarf_nextcu.c: Likewise. + +2009-05-05 Petr Machata + + * libdwP.h (__libdw_formptr): Declare new function. + * dwarf_formudata.c: Implement it here. + * dwarf_getlocation.c (dwarf_getlocation_addr): + Call it instead of hand-rolled offset handling code. + * dwarf_getsrclines.c (dwarf_getsrclines): Likewise. + * dwarf_ranges.c (dwarf_ranges): Likewise. + +2009-05-04 Petr Machata + + * libdwP.h (__libdw_read_begin_end_pair_inc): Declare new function. + * dwarf_ranges.c: Implement it here. + (dwarf_ranges): Call it. + * dwarf_getlocation.c (dwarf_getlocation_addr): Call it also here. + +2009-04-23 Petr Machata + + * dwarf_formaddr.c (dwarf_formaddr): Call __libdw_read_* instead + of read_*ubyte_unaligned. + * dwarf_formref_die.c (dwarf_formref_die): Likewise. + * dwarf_formstring.c (dwarf_formstring): Likewise. + * dwarf_formudate.c (dwarf_formudata): Likewise. + * dwarf_getaranges.c (dwarf_getaranges): Likewise. + * dwarf_getlocation.c (dwarf_getlocation_addr): Likewise. + * dwarf_getpubnames.c (get_offsets): Likewise. + * dwarf_nextcu.c (dwarf_nextcu): Likewise. + +2009-04-23 Petr Machata + + * libdwP.h (__libdw_read_addr_inc, __libdw_read_off_inc, + __libdw_read_addr, __libdw_read_off): Add four new internal + functions. + +2009-05-07 Roland McGrath + + * dwarf_getmacros.c (dwarf_getmacros): Use absolute section offset in + return value and OFFSET argument, not CU-relative. Only fetch the + attribute data when called with OFFSET of 0. + +2009-05-07 Petr Machata + + * dwarf_getmacros.c (dwarf_getmacros): Take into account offset in + DW_AT_macro_info attribute of CU DIE. + +2009-04-15 Roland McGrath + + * dwarf.h (DW_CIE_ID): Removed. + (DW_CIE_ID_32, DW_CIE_ID_64): New constants replace it. + +2009-04-01 Roland McGrath + + * dwarf.h: Add DW_CFA_GNU_negative_offset_extended. + +2009-01-28 Roland McGrath + + * libdwP.h (struct Dwarf_Line_s): Move out of struct Dwarf_Lines_s + defn so C++ doesn't scope the name to not match the Dwarf_Line typedef. + + * libdwP.h (struct Dwarf_Files_s): Replace dbg field with cu field. + +2009-01-26 Roland McGrath + + * dwarf_ranges.c: Return 0 when no ranges or *_pc attrs at all. + +2009-01-25 Roland McGrath + + * dwarf_getattrs.c: Correctly skip attribute values when restarting. + +2009-01-23 Roland McGrath + + * Makefile.am ($(srcdir)/known-dwarf.h): Target renamed back. + Put these rules under if MAINTAINER_MODE. + +2009-01-22 Roland McGrath + + * dwarf.h: Add DW_OP_GNU_encoded_addr. + +2009-01-21 Roland McGrath + + * Makefile.am (CLEANFILES): Renamed to ... + (MOSTLYCLEANFILES): ... here. + (CLEANFILES): New variable, add known-dwarf.h. + +2009-01-17 Roland McGrath + + * Makefile.am (known-dwarf.h): Target renamed, not in $(srcdir). + Make it unconditional. + (BUILT_SOURCES): Updated. + + * dwarf.h: Add description comments for DW_LANG_* values. + + * Makefile.am [MAINTAINER_MODE] + ($(srcdir)/known-dwarf.h): New target. + (BUILT_SOURCES): Add it. + + * dwarf.h: Add DW_OP_GNU_push_tls_address, DW_OP_GNU_uninit. + +2009-01-10 Ulrich Drepper + + * dwarf_error.c: Always use __thread. Remove all !USE_TLS code. + +2009-01-08 Roland McGrath + + * Makefile.am (libdw.so): Don't depend on $(zip_LIBS), just link it in. + +2008-01-06 Roland McGrath + + * libdwP.h (struct Dwarf_Abbrev): Change type of 'has_children' to bool. + Reorder members. + * dwarf_haschildren.c: Return -1 for error case, not 0. + + * Makefile.am (libdw.so): Link in $(zip_LIBS). + +2009-01-06 Ulrich Drepper + + * dwarf.h: Add definition for unwind and call frame information. + + * memory-access.h: Define read_ubyte_unaligned, read_sbyte_unaligned, + read_ubyte_unaligned_inc, and read_sbyte_unaligned_inc. + +2008-08-15 Roland McGrath + + * libdw.map (ELFUTILS_0.136): New version set, inherits from + ELFUTILS_0.130. Add dwfl_addrsegment, dwfl_report_segment. + +2008-01-21 Ulrich Drepper + + * dwarf_child.c: Minor optimizations. + * dwarf_getattrs.c: Likewise. + * dwarf_getpubnames.c: Likewise. + * dwarf_siblingof.c: Likewise. + * dwarf_tag.c: Likewise. + +2008-01-18 Ulrich Drepper + + * dwarf_getsrclines.c (dwarf_getsrclines): Don't require exact match + of DWARF_VERSION comparison, just fail if the file's version is newer. + +2008-01-17 Nick Clifton + + * dwarf.h (DWARF3_LENGTH_MIN_ESCAPE_CODE): New define. + (DWARF3_LENGTH_MAX_ESCAPE_CODE): New define. + (DWARF3_LENGTH_64_BIT): New define. + * dwarf_getaranges (dwarf_getaranges): Use the new definitions. + * dwarf_getpubnames: Include dwarf.h. + (get_offsets): Use the new definitions. + * dwarf_getsrclines.c (dwarf_getsrclines): Use the new defintions. + * dwarf_nextcu.c: Include dwarf.h. Correct comment. + (dwarf_nextcu): Use the new definitions. + + * libdwP.h (DIE_OFFSET_FROM_CU_OFFSET): New macro. + * dwarf_diecu.c (dwarf_diecu): Use the new macro. + * dwarf_getaranges (dwarf_getaranges): Use the new macro. + * dwarf_nextcu.c (dwarf_nextcu): Use the new macro. + + * dwarf_getpubnames (get_offsets): Replace assertion with test and + error return. + + * dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Use CUDIE. + + * dwarf_siblingof (dwarf_siblingof): Detect a NULL return pointer. + Set the address in the return structure to the address of the next + non-sibling die, if there is no sibling and the return pointer is + not the same as the die pointer. + * libdw.h: Expand the description of the dwarf_siblingof prototype. + + * dwarf_child.c: Fix typo in comment. + + * libdwP.h (DWARF_VERSION): Change to 3. + + * dwarf_formref.c (__libdw_formref.c): Handle attributes which do + not have a initialised valp pointer. + + * dwarf_getattrs.c (dwarf_getattrs): Return 1 rather than 0 when + the end of the attributes is reached. When the callback fails, + return the address of the failing attribute, not the address of + its successor. + * libdw.h: Expand the description of the dwarf_getattrs prototype. + + * dwarf_child.c (__libdw_find_attr): Use the new definition. + (dwarf_child): Likewise. + * dwarf_tag.c (__libdw_findabbrev): Likewise. + (dwarf_tag): Likewise. + +2008-01-08 Roland McGrath + + * Makefile.am (euinclude): Variable removed. + (pkginclude_HEADERS): Set this instead of euinclude_HEADERS. + (libdw.so): Pass -Wl,--enable-new-dtags,-rpath,$(pkglibdir). + +2007-10-17 Roland McGrath + + * libdw.h (__deprecated_attribute__): New macro. + (dwarf_formref): Mark it deprecated. + * dwarf_formref.c (__libdw_formref): New function, broken out of ... + (dwarf_formref): ... here. Call it. Remove INTDEF. + * libdwP.h: Remove INTDECL. + Declare __libdw_formref. + * dwarf_siblingof.c (dwarf_siblingof): Call __libdw_formref instead. + * dwarf_formref_die.c: Likewise. Handle DW_FORM_ref_addr here. + + * libdw_form.c (__libdw_form_val_len): Fix DW_FORM_ref_addr result, + needs to check CU->version. + + * libdwP.h (struct Dwarf_CU): New member `version'. + * libdw_findcu.c (__libdw_findcu): Initialize it. + + * dwarf_child.c: Return 1 for null entry as first child. + +2007-10-05 Roland McGrath + + * dwarf_begin_elf.c (check_section): Punt on SHT_NOBITS sections. + + * libdw.h (__extern_inline): Rename to __libdw_extern_inline. + [__OPTIMIZE__] (dwarf_whatattr, dwarf_whatform): Update uses. + +2007-10-03 Roland McGrath + + * libdw.map (ELFUTILS_0.130: Add dwfl_build_id_find_elf + and dwfl_build_id_find_debuginfo. + + * libdw.map (ELFUTILS_0.130): New version set, inherits from + ELFUTILS_0.127. Add dwfl_module_build_id, dwfl_module_report_build_id. + +2007-10-02 Roland McGrath + + * libdw_visit_scopes.c (classify_die): Return walk for class_type and + structure_type. + +2007-08-07 Roland McGrath + + * dwarf_getscopes.c (pc_match): Swallow dwarf_haspc error return when + error code is DWARF_E_NOERROR (0). + + * dwarf_getscopes.c (pc_record): Always bail early if DIE->prune. + Fix typo in __libdw_visit_scopes argument. + + * dwarf_getscopes.c (pc_match): Check dwarf_haspc error return, + swallow DWARF_E_NO_DEBUG_RANGES but not other errors. + +2007-07-03 Roland McGrath + + * libdw.h (__extern_inline): New macro. + [__OPTIMIZE__] (dwarf_whatattr, dwarf_whatform): Use it. + +2007-04-16 Roland McGrath + + * libdw.map (ELFUTILS_0.127): Add dwfl_module_address_section. + +2007-04-05 Roland McGrath + + * dwarf_getsrcdirs.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_getsrcdirs. + * libdw.map (ELFUTILS_0.127): Add it. + + * libdwP.h (struct Dwarf_Files_s): New member ndirs. + * dwarf_getsrclines.c (dwarf_getsrclines): Don't clobber NDIRLIST to + zero before we use it to check for DWARF_E_INVALID_DIR_IDX. + Save DIRARRAY in the Dwarf_Files. + + * dwarf_ranges.c (dwarf_ranges): Don't sign-extend 32-bit BEGIN + address to check for all-ones base address entry. Check directly. + Reported by Sébastien Dugué . + +2007-03-25 Roland McGrath + + * dwarf_begin_elf.c (check_section): Return Dwarf * instead of void. + Return NULL when freeing RESULT on error. + (global_read, scngrp_read): Check return value from check_section, + break out of loop after it has freed RESULT. + (valid_p): Handle null argument. + +2007-03-12 Roland McGrath + + * libdw.map (ELFUTILS_0.127): Add dwfl_report_begin_add. + +2007-03-04 Roland McGrath + + * libdw.map (ELFUTILS_0.127): New version set, inherits from + ELFUTILS_0.126. Add dwfl_module_addrsym. + +2007-02-10 Roland McGrath + + * dwarf.h (DW_OP_fbreg): Comment fix. + +2007-02-03 Roland McGrath + + * dwarf_getelf.c (dwarf_getelf): Renamed from dwarf_get_elf. + * libdw.map (ELFUTILS_0.126): New version set, inherits from + ELFUTILS_0.122. Move dwarf_getelf there; it was never truly + exported in the past. + +2006-12-17 Roland McGrath + + * dwarf_getlocation.c (dwarf_getlocation_addr): Use zero as base + address when the CU is missing attributes due to buggy GCC. + +2006-08-29 Roland McGrath + + * Makefile.am (CLEANFILES): Add libdw.so.$(VERSION). + + * libdw.h (dwarf_diecu): Add __nonnull_attribute__. + (dwarf_child): Don't list arg 1 in __nonnull_attribute__. + + * libdw_alloc.c (__libdw_allocate): Take new ALIGN argument, make sure + result is aligned. Adjust NEWP->remaining here for this allocation. + * libdwP.h: Update decl. + (libdw_alloc): Update caller. + +2006-07-12 Ulrich Drepper + + * dwarf_child.c: Adjust for internal_function_def removal. + * dwarf_getabbrev.c: Likewise. + * dwarf_tag.c: Likewise. + * libdw_form.c: Likewise. + * memory-access.c: Likewise. + +2006-06-28 Roland McGrath + + * libdw.map: Export dwfl_linecu, dwfl_line_comp_dir. + + * libdw.map: Bump to 0.122; export dwfl_module_getsymtab and + dwfl_module_getsym. + +2006-05-27 Ulrich Drepper + + * libdw.h: Add extern "C". + +2006-05-22 Ulrich Drepper + + * dwarf_getaranges.c (dwarf_getaranges): Handle files without + aranges information. + +2006-05-21 Ulrich Drepper + + * libdw.h: Add nonnull attributes to dwarf_tag, dwarf_getattrs, + dwarf_haschildren. + +2006-02-28 Roland McGrath + + * dwarf.h: Add missing DW_ATE_*, DW_TAG_*, DW_LANG_*, DW_CFA_*, + DW_OP_* values, to match DWARF 3.0. Add new DW_DS_*, DW_END_* + values from DWARF 3.0. + +2006-02-22 Roland McGrath + + * libdw.map: Bump to 0.120; export dwfl_version. + +2005-12-22 Roland McGrath + + * libdw.map: Bump to 0.119; export dwfl_linux_proc_maps_report. + +2005-12-12 Roland McGrath + + * dwarf_ranges.c: Copy CU base address-finding code from + dwarf_getlocation. + +2005-12-09 Roland McGrath + + * dwarf_getlocation.c (dwarf_getlocation_addr): Add some unlikelys. + Delay CU base lookup until it's needed. + If CU base lookup fails with no error, flag invalid DWARF. + +2005-11-25 Roland McGrath + + * libdw.map: Bump to 0.118; export dwfl_module_register_names. + +2005-11-15 Roland McGrath + + * Makefile.am [BUILD_STATIC] (AM_CFLAGS): Add -fpic. + +2005-11-13 Roland McGrath + + * libdw.map: Bump to 0.117; export dwfl_module_return_value_location. + +2005-10-27 Roland McGrath + + * dwarf_entry_breakpoints.c (search_range): Fix binary search code; + don't match end_sequence markers. + + * dwarf_getsrclines.c (compare_lines): Sort end_sequence markers + before normal records at the same address. + * dwarf_getsrc_die.c (dwarf_getsrc_die): Don't match an end_sequence + marker. + +2005-10-26 Roland McGrath + + * dwarf_getfuncs.c (dwarf_getfuncs): Use Dwarf_Die, not Dwarf_Func. + * dwarf_func_file.c: Renamed to ... + * dwarf_decl_file.c: ... here. + * dwarf_func_col.c: Renamed to ... + * dwarf_decl_column.c: ... here. + * dwarf_func_line.c: Renamed to ... + * dwarf_decl_line.c: ... here. + (dwarf_func_line): Renamed to ... + (dwarf_decl_line): ... this. Take a Dwarf_Die * argument. + (__libdw_func_intval): Renamed __libdw_attr_intval. + * dwarf_func_name.c: File removed. + * dwarf_func_lowpc.c: File removed. + * dwarf_func_highpc.c: File removed. + * dwarf_func_entrypc.c: File removed. + * dwarf_func_die.c: File removed. + * Makefile.am (libdw_a_SOURCES): Updated. + * libdw.h: Update decls. + (Dwarf_Func): Type removed. + * libdwP.h: Update decls. + (struct Dwarf_Func_s): Type removed. + * libdw.map: Updated. + + * libdwP.h (CUDIE): New macro. + * dwarf_getlocation.c (dwarf_getlocation_addr): Use it. + * dwarf_getscopes_die.c (dwarf_getscopes_die): Likewise. + * dwarf_ranges.c (dwarf_ranges): Likewise. + + * dwarf_getloclist.c: Renamed to ... + * dwarf_getlocation.c: ... here. + (getloclist): Renamed to getlocation. + (dwarf_getloclist): Renamed to dwarf_getlocation. + (dwarf_addrloclists): Renamed to dwarf_getlocation_addr. + * Makefile.am (libdw_a_SOURCES): Updated. + * libdw.h (dwarf_getloclist): Renamed to dwarf_getlocation. + (dwarf_addrloclists): Renamed dwarf_getlocation_addr. + (Dwarf_Loc): Renamed Dwarf_Op. + * libdwP.h (struct loc_s): Update use. + * libdw.map: Update map. + + * dwarf_entry_breakpoints.c: Use the second line record within the + function, regardless of its source location data. + +2005-10-25 Roland McGrath + + * dwarf_entry_breakpoints.c: Fall back to entrypc for contiguous too. + + * libdw.map: Add dwarf_entrypc, dwarf_entry_breakpoints. + +2005-10-14 Roland McGrath + + * dwarf_diecu.c (dwarf_diecu): New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_diecu. + * libdw.map: Export it. + + * libdw.map: Bump to 0.116; export dwarf_ranges. + +2005-09-20 Roland McGrath + + * dwarf_haspc.c: Use dwarf_ranges. + * dwarf_entry_breakpoints.c: Likewise. + + * dwarf_ranges.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_ranges. + * libdwP.h: Add INTDECL. + +2005-09-14 Roland McGrath + + * dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Fix braino in + prologue_end marker scanning loop. + +2005-09-11 Roland McGrath + + * dwarf.h: Comment typo fix. + +2005-09-07 Roland McGrath + + * dwarf_entry_breakpoints.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_entry_breakpoints. + + * dwarf_entrypc.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_entrypc. + * libdwP.h: Add INTDECL. + +2005-08-28 Ulrich Drepper + + * Makefile.am: Use $(LINK) not $(CC) when creating DSO. + (%.os): Use COMPILE.os. + (COMPILE.os): Filter out gconv options. + +2005-08-27 Roland McGrath + + * dwarf_getscopes.c (dwarf_getscopes): Rewritten using + __libdw_visit_scopes. + + * dwarf_getscopes_die.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_getscopes_die. + * libdw.map: Bump to 0.115 and add it. + + * libdw_visit_scopes.c (__libdw_visit_scopes): Pass a struct + containing a DIE and its parent pointer, instead of just Dwarf_Die. + Take two functions for both preorder and postorder visitors. + * libdwP.h: Update decl. + (struct Dwarf_Die_Chain): New type. + * dwarf_func_inline.c: Update uses. + + * dwarf_diename.c (dwarf_diename): Use dwarf_attr_integrate. + Add INTDEF. + * libdwP.h: Add INTDECL. + * dwarf_func_name.c (dwarf_func_name): Use dwarf_diename. + +2005-08-23 Roland McGrath + + * dwarf_attr_integrate.c (dwarf_attr_integrate): Treat + DW_AT_specification the same as DW_AT_abstract_origin. + +2005-08-20 Roland McGrath + + * libdw.map: Add dwfl_cumodule, remove dwfl_linecu. + Add dwfl_linux_kernel_report_offline, dwfl_offline_section_address, + and dwfl_report_offline. + +2005-08-19 Roland McGrath + + * libdw.map: Bump version to ELFUTILS_0.114 for libdwfl changes. + Add dwfl_module_relocate_address, dwfl_module_relocations, + dwfl_module_relocation_info. + +2005-08-18 Roland McGrath + + * dwarf_getscopes.c (dwarf_getscopes): Include the CU itself as + outermost scope in the results. + +2005-08-15 Roland McGrath + + * dwarf_func_inline.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_func_inline, dwarf_func_inline_instances. + * libdw.map: Add them. + + * dwarf_func_die.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_func_die. + * libdw.map: Add it. Bump version to ELFUTILS_0.114. + +2005-08-10 Ulrich Drepper + + * dwarf_getsrclines.c (dwarf_getsrclines): Correct fallout of renaming + of DW_LNS_set_epilog_begin. + +2005-08-09 Roland McGrath + + * dwarf.h (DW_LNS_set_epilog_begin): Renamed DW_LNS_set_epilogue_begin. + + * dwarf_end.c: Add INTDEF. + * dwarf_error.c (dwarf_errmsg): Likewise. + * libdwP.h (dwarf_end, dwarf_errmsg): Add INTDECLs. + +2005-08-01 Roland McGrath + + * dwarf_getaranges.c (dwarf_getaranges): Check for bogus offset. + * dwarf_getabbrev.c (__libdw_getabbrev): Likewise. + +2005-07-28 Ulrich Drepper + + * Makefile.am (libdw.so): No need to link with libeu.a anymore. + (libdw_a_LIBADD): Add all files from libdwfl.a. + +2005-07-27 Roland McGrath + + * Makefile.am (libdw.so): Link ../libdwfl/libdwfl_pic.a in, + along with ../libebl/libebl.a and ../lib/libeu.a; + depend on ../libelf/libelf.so. + (libdw_so_LDADD): New variable. + * libdw.map: Add dwfl_* symbols formerly in ../libdwfl/libdwfl.map. + + * libdw.map: Define an empty base version and move all symbols to + version ELFUTILS_0.111; don't define ELFUTILS_1.0 at all yet. + +2005-07-23 Ulrich Drepper + + * dwarf_error.c: Add internal alias for dwarf_errno. + * libdwP.h: Declare __dwarf_errno_internal. + * dwarf_getloclist.c: Use INTDEF for dwarf_errno. + + * dwarf_error.c [USE_TLS]: Actually use __thread in definition of + global_error. + +2005-06-01 Roland McGrath + + * dwarf_getaranges.c (dwarf_getaranges): Sort result array. + * dwarf_getarange_addr.c (dwarf_getarange_addr): Use binary search. + +2005-06-08 Roland McGrath + + * memory-access.h (get_uleb128_step, get_uleb128): Remove casts. + (get_sleb128_step, get_sleb128): Likewise. + * dwarf_getattrs.c (dwarf_getattrs): Add consts. + * dwarf_getloclist.c (getloclist): Likewise. + * dwarf_formblock.c (dwarf_formblock): Likewise. + * dwarf_getsrclines.c (dwarf_getsrclines): Likewise. + * dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise. + * dwarf_formref.c (dwarf_formref): Likewise. + * dwarf_formsdata.c (dwarf_formsdata): Likewise. + * dwarf_formudata.c (dwarf_formudata): Likewise. + * dwarf_haschildren.c (dwarf_haschildren): Likewise. + * dwarf_child.c (__libdw_find_attr, __libdw_find_attr): Likewise. + * dwarf_tag.c (dwarf_tag): Likewise. + * dwarf_getabbrev.c (__libdw_getabbrev): Likewise. + * memory-access.c (__libdw_get_uleb128, __libdw_get_sleb128): Likewise. + * libdw_form.c (__libdw_form_val_len): Likewise. + * libdwP.h: Update decl. + +2005-06-04 Roland McGrath + + * memory-access.h (get_uleb128_rest_return): New macro. + [! IS_LIBDW] (__libdw_get_uleb128): New static, defined using it. + (get_sleb128_rest_return): New macro. + [! IS_LIBDW] (__libdw_get_sleb128): New static, defined using it. + * memory-access.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + (DEFS): Add -DIS_LIBDW. + +2005-05-31 Roland McGrath + + * dwarf_formref_die.c (dwarf_formref_die): Add CU header offset to + formref offset. + +2005-05-30 Roland McGrath + + * dwarf_getloclist.c (dwarf_addrloclists): Use DW_AT_entry_pc for base + address if DW_AT_low_pc is missing. Not to spec, but GCC generates it. + + * dwarf_getloclist.c (dwarf_addrloclists): Don't sign-extend 4-byte + BEGIN value. Instead, match base address entries separately for + 32/64 size cases. + +2005-05-28 Roland McGrath + + * dwarf_getloclist.c (dwarf_addrloclists): Fix decoding to advance + past location expression contents. + +2005-05-23 Roland McGrath + + * dwarf_getsrclines.c: Comment typo fix. + + * dwarf_haspc.c (dwarf_haspc): Fix CU DIE address calculation. + * dwarf_getloclist.c (dwarf_addrloclists): Likewise. + +2005-05-22 Ulrich Drepper + + * libdwP.h: Only use INTDECL for alias prototypes. + +2005-05-19 Roland McGrath + + * dwarf_getloclist.c (attr_ok): Permit DW_AT_static_link too. + + * dwarf_getscopevar.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_getscopevar. + + * dwarf_getsrcfiles.c: Add INTDEF. + * dwarf_haschildren.c: Likewise. + * libdwP.h (dwarf_getsrcfiles, dwarf_haschildren): Add INTDECL. + + * dwarf_getscopes.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare dwarf_getscopes. + * libdw.map: Add it. + +2005-05-18 Roland McGrath + + * libdwP.h (IDX_debug_ranges): New enum constant. + * dwarf_begin_elf.c (dwarf_scnnames): Add it for ".debug_ranges". + * libdwP.h (DWARF_E_NO_DEBUG_RANGES): New enum constant. + * dwarf_error.c (errmsgs): Add it. + * dwarf_haspc.c: New file. + * libdw.h: Declare dwarf_haspc. + * libdw.map: Add it. + * libdwP.h: Add INTDECL. + + * dwarf_attr_integrate.c: New file. + * dwarf_hasattr_integrate.c: New file. + * Makefile.am (libdw_a_SOURCES): Add them. + * libdw.h: Declare dwarf_attr_integrate, dwarf_hasattr_integrate. + * libdw.map: Add them. + + * dwarf_hasattr.c: Add INTDEF. + * libdwP.h: Add INTDECL for it. + + * dwarf_formref_die.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h (dwarf_formref_die): Declare it. + * libdwP.h (dwarf_formref_die): Add INTDECL. + * libdw.map: Add it. + + * dwarf_getloclist.c (attr_ok, getloclist): New functions, broken out + of ... + (dwarf_getloclist): ... here. Call them. + (dwarf_addrloclists): New function. + * libdw.h: Declare it. + * libdw.map: Add it. + + * dwarf_getmacros.c (dwarf_getmacros): Don't bail at + DW_MACINFO_end_file. Recognize type 0 as terminator. + +2005-05-05 Roland McGrath + + * dwarf_getsrc_die.c (dwarf_getsrc_die): Use binary search. + + * dwarf_getsrclines.c (dwarf_getsrclines): Sort result array, since + the line program does not produce all entries in ascending order. + +2005-04-25 Ulrich Drepper + + * dwarf_getsrc_file.c (dwarf_getsrc_file): Handle multiple + occurences (e.g., inlines) better. + +2005-04-24 Ulrich Drepper + + * libdw.h (DWARF_END_ABBREV): Define. + * dwarf_getabbrev.c (__libdw_getabbrev): Return DWARF_END_ABBREV if + end is reached. + * dwarf_offabbrev.c (dwarf_offabbrev): Return -1 on error, 1 if end + of records reached. + * dwarf_tag.c (__libdw_findabbrev): Also recognize DWARF_END_ABBREV + as error of __libdw_getabbrev. + +2005-04-04 Ulrich Drepper + + * dwarf_getsrc_file.c (dwarf_getsrc_file): Minor optimization. + + * dwarf_getsrc_file.c (dwarf_getsrc_file): Always pass number of + results back to caller. + +2005-04-04 Roland McGrath + + * dwarf_getsrc_file.c (dwarf_getsrc_file): Use size_t for CUHL. + + * dwarf_func_line.c (__libdw_func_intval): Use internal_function in + defn. + +2005-04-04 Ulrich Drepper + + * dwarf_getsrc_file.c (dwarf_getsrc_file): Use INTUSE. + + * dwarf_getsrc_file.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getsrc_file.c. + * libdw.h: Declare dwarf_getsrc_file. + * libdw.map: Add dwarf_getsrc_file. + +2005-04-02 Ulrich Drepper + + * dwarf_func_entrypc.c: New file. + * dwarf_func_col.c: New file. + * dwarf_func_line.c: New file. + * dwarf_func_file.c: New file. + * libdw.h: Add prototypes for new functions. + * libdw.map: Add dwarf_func_entrypc, dwarf_func_col, dwarf_func_line, + dwarf_func_file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_func_entrypc.c, + dwarf_func_col.c, dwarf_func_line.c, dwarf_func_file.c. + * libdwP.h (struct Dwarf_Func_s): Add cudie element. + Declare __libdw_func_intval and __dwarf_formsdata_internal. + * dwarf_getfuncs.c: Also fill in cudie in Dwarf_Func object. + * dwarf_formsdata.c: Use INTUSE and INTDEF to avoid PLTs. + + * dwarf.h: Add some DWARF3 definitions. + +2005-04-01 Ulrich Drepper + + * dwarf_getfuncs.c: New file. + * dwarf_func_highpc.c: New file. + * dwarf_func_lowpc.c: New file. + * dwarf_func_name.c: New file. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getfuncs.c, + dwarf_func_highpc.c, dwarf_func_lowpc.c, and dwarf_func_name.c. + * libdw.map: Add dwarf_getfuncs, dwarf_func_highpc, dwarf_func_lowpc, + and dwarf_func_name. + * libdw.h: Add prototypes for new functions. + * dwarf_child.c: Use INTUSE and INTDEF to avoid PLTs. + * dwarf_siblingof.c: Likewise. + * dwarf_dieoffset.c: Likewise. + * dwarf_highpc.c: Likewise. + * dwarf_lowpc.c: Likewise. + * libdwP.h: Add prototypes for internal functions. + Define Dwarf_Func_s structure. + +2005-03-29 Ulrich Drepper + + * libdw.h: Add padding in Dwarf_die. + + * dwarf_arrayorder.c: Use INTUSE and INTDEF to avoid PLTs. + * dwarf_attr.c: Likewise. + * dwarf_begin.c: Likewise. + * dwarf_begin_elf.c: Likewise. + * dwarf_bitoffset.c: Likewise. + * dwarf_bitsize.c: Likewise. + * dwarf_bytesize.c: Likewise. + * dwarf_diename.c: Likewise. + * dwarf_formaddr.c: Likewise. + * dwarf_formblock.c: Likewise. + * dwarf_formref.c: Likewise. + * dwarf_formstring.c: Likewise. + * dwarf_formudata.c: Likewise. + * dwarf_getarange_addr.c: Likewise. + * dwarf_getarangeinfo.c: Likewise. + * dwarf_getaranges.c: Likewise. + * dwarf_getloclist.c: Likewise. + * dwarf_getmacros.c: Likewise. + * dwarf_getsrc_die.c: Likewise. + * dwarf_getsrcfiles.c: Likewise. + * dwarf_getsrclines.c: Likewise. + * dwarf_highpc.c: Likewise. + * dwarf_lowpc.c: Likewise. + * dwarf_nextcu.c: Likewise. + * dwarf_offdie.c: Likewise. + * dwarf_siblingof.c: Likewise. + * dwarf_srclang.c: Likewise. + * dwarf_tag.c: Likewise. + * libdw_findcu.c: Likewise. + * libdwP.h: Add prototypes for internal functions. + + * dwarf_addrdie.c: New file. + * dwarf_macro_opcode.c: New file. + * dwarf_macro_param1.c: New file. + * dwarf_macro_param2.c: New file. + * libdw.h: Add declarations. Move Dwarf_Macro definition to libdwP.h. + * libdwP.h: Remove Dwarf_Macro definition. + * Makefile.am (libdw_a_SOURCES): Add dwarf_addrdie.c, + dwarf_macro_opcode.c, dwarf_macro_param1.c, and dwarf_macro_param2.c. + * libdw.map: Add entries for new functions. + +2005-03-21 Ulrich Drepper + + * libdw.h: Handle broken gcc < 4. + +2005-02-15 Ulrich Drepper + + * Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2. + + * dwarf_begin_elf.c: Fix warnings. + * dwarf_dieoffset.c: Likewise. + * dwarf_end.c: Likewise. + * dwarf_error.c: Likewise. + * dwarf_getpubnames.c: Likewise. + + * libdwP.h: Add new error values. + * dwarf_error.c: Support new error values. + * dwarf_getpubnames.c: Check parameter value. + +2005-02-05 Ulrich Drepper + + * Makefile.am: Check for text relocations in constructed DSO. + + * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fmudflap. + +2005-02-04 Ulrich Drepper + + * dwarf_siblingof.c (dwarf_siblingof): Add some buffer boundary + checks to not read over buffer boundaries for ill-formed DWARF data. + +2004-09-25 Ulrich Drepper + + * dwarf_child.c: Make compile with gcc 4.0. + * dwarf_error.c: Likewise. + * dwarf_formblock.c: Likewise. + * dwarf_getabbrev.c: Likewise. + * dwarf_getattrs.c: Likewise. + * dwarf_getsrclines.c: Likewise. + * dwarf_tag.c: Likewise. + * libdw_form.c: Likewise. + +2004-01-20 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + + * dwarf_getloclist.c: Fix warnings gcc 3.4 spits out. + * dwarf_getsrclines.c: Likewise. + * dwarf_memory-access.h: Likewise. + +2004-01-19 Ulrich Drepper + + * dwarf_getsrcfiles.c: Third parameter can be NULL. + + * libdw.h: Define Dwarf_macro. Declare dwarf_getmacros. + Third parameter of dwarf_getsrcfiles can be NULL. + + * libdw.map: Add dwarf_getmacros. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getmacros. + * dwarf_getmacros.c: New file. + +2004-01-18 Ulrich Drepper + + * libdw.h: Second parameter of dwarf_getaranges can be NULL. + + * dwarf_nextcu.c: Return -1 if dwarf parameter is NULL. + + * dwarf_getsrclines.c: + Use read_2ubyte_unaligned_inc instead of _inc-less variant. + + * dwarf_getaranges.c: Allow naranges parameter to be NULL. + + * libdwP.h (_): Use elfutils domain. + + * dwarf_getsrclines.c (dwarf_getsrclines): Add more branch prediction. + + * dwarf_getsrclines.c: Fix typo in comment. + +2004-01-17 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + +2004-01-16 Ulrich Drepper + + * memory-access.h: Add lots of const in case a pointer passed is const. + + * dwarf_formflag.c: New file. + * dwarf_getattrs.c: New file. + * dwarf_error.c: Add new error value. + * libdw.h: Add prototypes for new functions. Adjust prototype for + dwarf_getpubnames. + * libdw.map: Add new functions. + * dwarf_getpubnames.c: Change type of return value and fourth parameter + to ptrdiff_t. + * libdwP.h: Add new error value. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getattrs.c and + dwarf_formflag.c. + + * dwarf_getpubnames.c (dwarf_getpubnames): Just fail if dbg is NULL. + +2004-01-12 Ulrich Drepper + + * dwarf_getarange_addr.c: New file + * dwarf_getarangeinfo.c: New file. + * dwarf_getaranges.c: New file. + * dwarf_onerange.c: New file. + * libdw.h: Declare new functions. Define Dwarf_Arange and + Dwarf_Aranges. + * libdw.map: Add new functions. + * libdwP.h: Add new errors. Add aranges member to struct Dwarf. + Define Dwarf_Aranges_s and Dwarf_Arange_s. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getaranges.c, + dwarf_onearange.c, dwarf_getarangeinfo.c, dwarf_getarange_addr.c. + * dwarf_error.c: Add new message. + +2004-01-11 Ulrich Drepper + + * Makefile.am (libdw_a_SOURCES): Add dwarf_lineaddr.c, dwarf_linecol.c, + dwarf_linebeginstatement.c, dwarf_lineendsequence.c, dwarf_lineblock.c, + dwarf_lineprologueend.c, dwarf_lineepiloguebegin.c, dwarf_onesrcline.c. + * dwarf_error.c: Add another message. + * dwarf_getsrc_die.c: Adjust for Dwarf_Files and Dwarf_Lines + introduction. + * dwarf_filesrc.c: Likewise. + * dwarf_getsrcfiles.c: Likewise. + * dwarf_getsrclines.c: Likewise. + * dwarf_lineaddr.c: New file. + * dwarf_linebeginstatement.c: New file. + * dwarf_lineblock.c: New file. + * dwarf_linecol.c: New file. + * dwarf_lineendsequence.c: New file. + * dwarf_lineepiloguebegin.c: New file. + * dwarf_lineno.c: New file. + * dwarf_lineprologueend.c: New file. + * dwarf_onesrcline.c: New file. + * dwarf_lineno.c: Change interface to store result in object pointed + to by second parameter. + * libdw.h: Add prototypes for new functions. Change dwarf_lineno + prototype. Define Dwarf_Files and Dwarf_Lines. + * libdw.map: Add new functions. + * libdwP.h: Define Dwarf_Files_s and Dwarf_Lines_s. + * libdw_findcu.c: Don't initialize nlines field. + + * dwarf_siblingof: Little optimization. + + * dwarf_begin.c: Remember that the ELF descriptor must be closed. + * dwarf_end.c: Close ELF descriptor if free_elf is set. + * libdwP.h (struct Dwarf): Add free_elf field. + + * Makefile.am (libdw_a_SOURCES): Add dwarf_getstring.c and + dwarf_offabbrev.c. + * dwarf_getstring.c: New file. + * dwarf_offabbrev.c: New file. + * libdw.map: Add dwarf_getstring and dwarf_offabbrev. + * dwarf_getabbrev.c (__libdw_getabbrev): Add new dbg and result + parameters. Don't allocate memory if not necessary and don't lookup + previous results if no CU given. + (dwarf_getabbrev): Adjust call to __libdw_getabbrev. + * dwarf_tag.c: Adjust call to __libdw_getabbrev. + * libdw.h: Declare dwarf_offabbrev and dwarf_getstring. + * libdwP.h: Change prototype for __libdw_getabbrev. + + * dwarf_getabbrevattr.c: Add offsetp parameter. Fill in before + returning if this is wanted. + +2004-01-09 Ulrich Drepper + + * dwarf_nextcu.c: Add new parameter offset_sizep. Initialize it + with offset_size value. + * libdw.h: Adjust dwarf_nextcu prototype. + * libdwP.h (struct Dwarf_CU): Add offset_size member. + * libdw_findcu.c: Adjust dwarf_nextcu call. Initialize offset_size + member of new CU struct. + * dwarf_formstring.c: Depend on offset_size not address_size for + DW_FORM_strp handling. + * dwarf_form.c: Likewise for DW_FORM_strp and DW_FORM_ref_addr. + + * dwarf_tag.c (__libdw_findabbrev): Return correct value for + failing lookup. + (dwarf_tag): Correctly recognize failed lookup. + + * dwarf_end.c (cu_free): Call tdestroy for locs member. Use new + function noop_free. + * dwarf_error.c: Add message for DWARF_E_NO_BLOCK. + * dwarf_formblock.c: New file. + * dwarf_getloclist.c: Rewrite to handle a single block. + * libdw.h: Define Dwarf_Block. Rename Dwarf_Loc members. Remove + Dwarf_Locdesc definition. Declare dwarf_formblock. Remove + dwarf_getloclistent declaration. + * libdw.map: Add dwarf_formblock, remove dwarf_getloclistent. + * libdwP.h: Define struct loc_s and DWARF_E_NO_BLOCK. + Add locs member to struct Dwarf_CU. + * libdw_fundcu.c: Initialize locs member of new CU. + * Makefile.am (libdw_a_SOURCES): Add dwarf_formblock.c. + Remove dwarf_getloclistent.c. + +2004-01-07 Ulrich Drepper + + * libdw.h: Use __nonnull__ attribute only for gcc >= 3.3. + * libdwP.h: Likewise. + + * dwarf_getloclist.c: New file. + * dwarf_getloclistent.c: New file. + * libdw.h: Define Dwarf_Loc and Dwarf_Locdesc. + Declare dwarf_getloclistent and dwarf_getloclist. + * libdw.map: Add dwarf_getloclistent and dwarf_getloclist. + * libdwP.h: Define DWARF_E_NO_LOCLIST. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getloclistent.c and + dwarf_getloclist.c. + + * dwarf_error.c: More error messages. + +2004-01-06 Ulrich Drepper + + * dwarf_getsrclines.c: Remove debugging support. + + * dwarf_getsrcfiles.c: New file. + * dwarf_filesrc.c: New file. + * libdw.h: Declare these functions. Define Dwarf_File. + * libdwP.c: Adjust Dwarf_File_s definition. + * libdw.map: Add these functions. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getsrcfiles.c and + dwarf_filesrc.c. + * dwarf_getsrclines.c: Initialize cu->files. + +2004-01-05 Ulrich Drepper + + * libdw.h: Add more nonnull function attributes. + + * dwarf_begin_elf.c (dwarf_begin_elf): Don't initialize mem_tail->next. + * dwarf_end.c (cu_free): New function. + (dwarf_end): Also free CU tree. Correct freeing of memory blocks. + * dwarf_error.c (errmsgs): Add new messages. + * dwarf_getsrc_die.c: New file. + * dwarf_getsrclines.c: New file. + * dwarf_lineno.c: New file. + * dwarf_linesrc.c: New file. + * dwarf_nextcu.c (dwarf_nextcu): Use read_*byte_unaligned_inc + instead of the *_inc-less variants. + * libdw.h: Define Dwarf_Line. Add some function attributes. Declare + dwarf_getsrclines, dwarf_getsrc_die, dwarf_lineno, and dwarf_linesrc. + * libdw.map: Add dwarf_getsrclines, dwarf_getsrc_die, dwarf_lineno, + and dwarf_linesrc. + * libdwP.h: Add more error codes. + (struct Dwarf): Remove mem_tail.next member. + (Dwarf_File): Define type. + (struct Dwarf_Line_s): Define type. + (struct Dwarf_CU): Add lines and nlines members. + (libdw_alloc): Define local variable _tail and use it. + Add some function attributes. + * libdw_alloc.c (__libdw_allocate): Don't initialize next member. + * libdw_findcu.c (__libdw_findcu): Initialize lines and nlines members. + * memory-access.h: Add unlikely for the endian conversion paths. + * Makefile.am (AM_CFLAGS): Add -std parameter. + (libdw_a_SOURCES): Add dwarf_getsrclines, dwarf_getsrc_die, + dwarf_lineno, and dwarf_linesrc. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/libdw/Makefile.am b/libdw/Makefile.am new file mode 100644 index 00000000..6b7834af --- /dev/null +++ b/libdw/Makefile.am @@ -0,0 +1,154 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2002-2010, 2012, 2014, 2016, 2018 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +if BUILD_STATIC +AM_CFLAGS += $(fpic_CFLAGS) +endif +AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdwelf -pthread +VERSION = 1 + +lib_LIBRARIES = libdw.a +noinst_LIBRARIES = libdw_pic.a +noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so) + +include_HEADERS = dwarf.h +pkginclude_HEADERS = libdw.h known-dwarf.h + +libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ + dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \ + dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \ + dwarf_attr.c dwarf_formstring.c \ + dwarf_abbrev_hash.c dwarf_sig8_hash.c \ + dwarf_attr_integrate.c dwarf_hasattr_integrate.c \ + dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \ + dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \ + dwarf_entrypc.c dwarf_haspc.c dwarf_highpc.c dwarf_ranges.c \ + dwarf_formref.c dwarf_formref_die.c dwarf_siblingof.c \ + dwarf_dieoffset.c dwarf_cuoffset.c dwarf_diecu.c \ + dwarf_hasattr.c dwarf_hasform.c \ + dwarf_whatform.c dwarf_whatattr.c \ + dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \ + dwarf_bitoffset.c dwarf_srclang.c dwarf_getabbrevtag.c \ + dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \ + dwarf_getattrcnt.c dwarf_getabbrevattr.c \ + dwarf_getsrclines.c dwarf_getsrc_die.c \ + dwarf_getscopes.c dwarf_getscopes_die.c dwarf_getscopevar.c \ + dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \ + dwarf_linecol.c dwarf_linebeginstatement.c \ + dwarf_lineendsequence.c dwarf_lineblock.c \ + dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ + dwarf_lineisa.c dwarf_linediscriminator.c \ + dwarf_lineop_index.c dwarf_line_file.c \ + dwarf_onesrcline.c dwarf_formblock.c \ + dwarf_getsrcfiles.c dwarf_filesrc.c dwarf_getsrcdirs.c \ + dwarf_getlocation.c dwarf_getstring.c dwarf_offabbrev.c \ + dwarf_getaranges.c dwarf_onearange.c dwarf_getarangeinfo.c \ + dwarf_getarange_addr.c dwarf_getattrs.c dwarf_formflag.c \ + dwarf_getmacros.c dwarf_macro_getparamcnt.c \ + dwarf_macro_opcode.c dwarf_macro_param.c \ + dwarf_macro_param1.c dwarf_macro_param2.c \ + dwarf_macro_getsrcfiles.c \ + dwarf_addrdie.c dwarf_getfuncs.c \ + dwarf_decl_file.c dwarf_decl_line.c dwarf_decl_column.c \ + dwarf_func_inline.c dwarf_getsrc_file.c \ + libdw_findcu.c libdw_form.c libdw_alloc.c \ + libdw_visit_scopes.c \ + dwarf_entry_breakpoints.c \ + dwarf_next_cfi.c \ + cie.c fde.c cfi.c frame-cache.c \ + dwarf_frame_info.c dwarf_frame_cfa.c dwarf_frame_register.c \ + dwarf_cfi_addrframe.c \ + dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \ + dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \ + dwarf_getlocation_die.c dwarf_getlocation_attr.c \ + dwarf_getalt.c dwarf_setalt.c dwarf_cu_getdwarf.c \ + dwarf_cu_die.c dwarf_peel_type.c dwarf_default_lower_bound.c \ + dwarf_die_addr_die.c dwarf_get_units.c \ + libdw_find_split_unit.c dwarf_cu_info.c \ + dwarf_next_lines.c + +if MAINTAINER_MODE +BUILT_SOURCES = $(srcdir)/known-dwarf.h +MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h +$(srcdir)/known-dwarf.h: $(top_srcdir)/config/known-dwarf.awk $(srcdir)/dwarf.h + gawk -f $^ > $@.new + mv -f $@.new $@ +endif + +libdw_pic_a_SOURCES = +am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os) + +libdw_so_LIBS = ../libebl/libebl_pic.a ../backends/libebl_backends_pic.a \ + ../libcpu/libcpu_pic.a libdw_pic.a ../libdwelf/libdwelf_pic.a \ + ../libdwfl/libdwfl_pic.a +libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so +libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(fts_LIBS) $(obstack_LIBS) $(zip_LIBS) -pthread +libdw.so: $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$@.$(VERSION),--enable-new-dtags \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \ + $(libdw_so_LDLIBS) + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + +install: install-am libdw.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libdw.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils + +libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a) +libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects)) + +libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a) +libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects)) + +libebl_objects = $(shell $(AR) t ../libebl/libebl.a) +libdw_a_LIBADD += $(addprefix ../libebl/,$(libebl_objects)) + +backends_objects = $(shell $(AR) t ../backends/libebl_backends.a) +libdw_a_LIBADD += $(addprefix ../backends/,$(backends_objects)) + +libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a) +libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects)) + +noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \ + dwarf_sig8_hash.h cfi.h encoded-value.h + +EXTRA_DIST = libdw.map + +MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) libdw.so libdw.so.$(VERSION) diff --git a/libdw/Makefile.in b/libdw/Makefile.in new file mode 100644 index 00000000..ff31f3db --- /dev/null +++ b/libdw/Makefile.in @@ -0,0 +1,1445 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@BUILD_STATIC_TRUE@am__append_2 = $(fpic_CFLAGS) +subdir = libdw +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(noinst_HEADERS) $(pkginclude_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(pkgincludedir)" +LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libdw_a_AR = $(AR) $(ARFLAGS) +libdw_a_DEPENDENCIES = $(addprefix ../libdwfl/,$(libdwfl_objects)) \ + $(addprefix ../libdwelf/,$(libdwelf_objects)) $(addprefix \ + ../libebl/,$(libebl_objects)) $(addprefix \ + ../backends/,$(backends_objects)) $(addprefix \ + ../libcpu/,$(libcpu_objects)) +am_libdw_a_OBJECTS = dwarf_begin.$(OBJEXT) dwarf_begin_elf.$(OBJEXT) \ + dwarf_end.$(OBJEXT) dwarf_getelf.$(OBJEXT) \ + dwarf_getpubnames.$(OBJEXT) dwarf_getabbrev.$(OBJEXT) \ + dwarf_tag.$(OBJEXT) dwarf_error.$(OBJEXT) \ + dwarf_nextcu.$(OBJEXT) dwarf_diename.$(OBJEXT) \ + dwarf_offdie.$(OBJEXT) dwarf_attr.$(OBJEXT) \ + dwarf_formstring.$(OBJEXT) dwarf_abbrev_hash.$(OBJEXT) \ + dwarf_sig8_hash.$(OBJEXT) dwarf_attr_integrate.$(OBJEXT) \ + dwarf_hasattr_integrate.$(OBJEXT) dwarf_child.$(OBJEXT) \ + dwarf_haschildren.$(OBJEXT) dwarf_formaddr.$(OBJEXT) \ + dwarf_formudata.$(OBJEXT) dwarf_formsdata.$(OBJEXT) \ + dwarf_lowpc.$(OBJEXT) dwarf_entrypc.$(OBJEXT) \ + dwarf_haspc.$(OBJEXT) dwarf_highpc.$(OBJEXT) \ + dwarf_ranges.$(OBJEXT) dwarf_formref.$(OBJEXT) \ + dwarf_formref_die.$(OBJEXT) dwarf_siblingof.$(OBJEXT) \ + dwarf_dieoffset.$(OBJEXT) dwarf_cuoffset.$(OBJEXT) \ + dwarf_diecu.$(OBJEXT) dwarf_hasattr.$(OBJEXT) \ + dwarf_hasform.$(OBJEXT) dwarf_whatform.$(OBJEXT) \ + dwarf_whatattr.$(OBJEXT) dwarf_bytesize.$(OBJEXT) \ + dwarf_arrayorder.$(OBJEXT) dwarf_bitsize.$(OBJEXT) \ + dwarf_bitoffset.$(OBJEXT) dwarf_srclang.$(OBJEXT) \ + dwarf_getabbrevtag.$(OBJEXT) dwarf_getabbrevcode.$(OBJEXT) \ + dwarf_abbrevhaschildren.$(OBJEXT) dwarf_getattrcnt.$(OBJEXT) \ + dwarf_getabbrevattr.$(OBJEXT) dwarf_getsrclines.$(OBJEXT) \ + dwarf_getsrc_die.$(OBJEXT) dwarf_getscopes.$(OBJEXT) \ + dwarf_getscopes_die.$(OBJEXT) dwarf_getscopevar.$(OBJEXT) \ + dwarf_linesrc.$(OBJEXT) dwarf_lineno.$(OBJEXT) \ + dwarf_lineaddr.$(OBJEXT) dwarf_linecol.$(OBJEXT) \ + dwarf_linebeginstatement.$(OBJEXT) \ + dwarf_lineendsequence.$(OBJEXT) dwarf_lineblock.$(OBJEXT) \ + dwarf_lineprologueend.$(OBJEXT) \ + dwarf_lineepiloguebegin.$(OBJEXT) dwarf_lineisa.$(OBJEXT) \ + dwarf_linediscriminator.$(OBJEXT) dwarf_lineop_index.$(OBJEXT) \ + dwarf_line_file.$(OBJEXT) dwarf_onesrcline.$(OBJEXT) \ + dwarf_formblock.$(OBJEXT) dwarf_getsrcfiles.$(OBJEXT) \ + dwarf_filesrc.$(OBJEXT) dwarf_getsrcdirs.$(OBJEXT) \ + dwarf_getlocation.$(OBJEXT) dwarf_getstring.$(OBJEXT) \ + dwarf_offabbrev.$(OBJEXT) dwarf_getaranges.$(OBJEXT) \ + dwarf_onearange.$(OBJEXT) dwarf_getarangeinfo.$(OBJEXT) \ + dwarf_getarange_addr.$(OBJEXT) dwarf_getattrs.$(OBJEXT) \ + dwarf_formflag.$(OBJEXT) dwarf_getmacros.$(OBJEXT) \ + dwarf_macro_getparamcnt.$(OBJEXT) dwarf_macro_opcode.$(OBJEXT) \ + dwarf_macro_param.$(OBJEXT) dwarf_macro_param1.$(OBJEXT) \ + dwarf_macro_param2.$(OBJEXT) dwarf_macro_getsrcfiles.$(OBJEXT) \ + dwarf_addrdie.$(OBJEXT) dwarf_getfuncs.$(OBJEXT) \ + dwarf_decl_file.$(OBJEXT) dwarf_decl_line.$(OBJEXT) \ + dwarf_decl_column.$(OBJEXT) dwarf_func_inline.$(OBJEXT) \ + dwarf_getsrc_file.$(OBJEXT) libdw_findcu.$(OBJEXT) \ + libdw_form.$(OBJEXT) libdw_alloc.$(OBJEXT) \ + libdw_visit_scopes.$(OBJEXT) dwarf_entry_breakpoints.$(OBJEXT) \ + dwarf_next_cfi.$(OBJEXT) cie.$(OBJEXT) fde.$(OBJEXT) \ + cfi.$(OBJEXT) frame-cache.$(OBJEXT) dwarf_frame_info.$(OBJEXT) \ + dwarf_frame_cfa.$(OBJEXT) dwarf_frame_register.$(OBJEXT) \ + dwarf_cfi_addrframe.$(OBJEXT) dwarf_getcfi.$(OBJEXT) \ + dwarf_getcfi_elf.$(OBJEXT) dwarf_cfi_end.$(OBJEXT) \ + dwarf_aggregate_size.$(OBJEXT) \ + dwarf_getlocation_implicit_pointer.$(OBJEXT) \ + dwarf_getlocation_die.$(OBJEXT) \ + dwarf_getlocation_attr.$(OBJEXT) dwarf_getalt.$(OBJEXT) \ + dwarf_setalt.$(OBJEXT) dwarf_cu_getdwarf.$(OBJEXT) \ + dwarf_cu_die.$(OBJEXT) dwarf_peel_type.$(OBJEXT) \ + dwarf_default_lower_bound.$(OBJEXT) \ + dwarf_die_addr_die.$(OBJEXT) dwarf_get_units.$(OBJEXT) \ + libdw_find_split_unit.$(OBJEXT) dwarf_cu_info.$(OBJEXT) \ + dwarf_next_lines.$(OBJEXT) +libdw_a_OBJECTS = $(am_libdw_a_OBJECTS) +libdw_pic_a_AR = $(AR) $(ARFLAGS) +libdw_pic_a_LIBADD = +libdw_pic_a_OBJECTS = $(am_libdw_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/cfi.Po ./$(DEPDIR)/cie.Po \ + ./$(DEPDIR)/dwarf_abbrev_hash.Po \ + ./$(DEPDIR)/dwarf_abbrevhaschildren.Po \ + ./$(DEPDIR)/dwarf_addrdie.Po \ + ./$(DEPDIR)/dwarf_aggregate_size.Po \ + ./$(DEPDIR)/dwarf_arrayorder.Po ./$(DEPDIR)/dwarf_attr.Po \ + ./$(DEPDIR)/dwarf_attr_integrate.Po ./$(DEPDIR)/dwarf_begin.Po \ + ./$(DEPDIR)/dwarf_begin_elf.Po ./$(DEPDIR)/dwarf_bitoffset.Po \ + ./$(DEPDIR)/dwarf_bitsize.Po ./$(DEPDIR)/dwarf_bytesize.Po \ + ./$(DEPDIR)/dwarf_cfi_addrframe.Po \ + ./$(DEPDIR)/dwarf_cfi_end.Po ./$(DEPDIR)/dwarf_child.Po \ + ./$(DEPDIR)/dwarf_cu_die.Po ./$(DEPDIR)/dwarf_cu_getdwarf.Po \ + ./$(DEPDIR)/dwarf_cu_info.Po ./$(DEPDIR)/dwarf_cuoffset.Po \ + ./$(DEPDIR)/dwarf_decl_column.Po \ + ./$(DEPDIR)/dwarf_decl_file.Po ./$(DEPDIR)/dwarf_decl_line.Po \ + ./$(DEPDIR)/dwarf_default_lower_bound.Po \ + ./$(DEPDIR)/dwarf_die_addr_die.Po ./$(DEPDIR)/dwarf_diecu.Po \ + ./$(DEPDIR)/dwarf_diename.Po ./$(DEPDIR)/dwarf_dieoffset.Po \ + ./$(DEPDIR)/dwarf_end.Po \ + ./$(DEPDIR)/dwarf_entry_breakpoints.Po \ + ./$(DEPDIR)/dwarf_entrypc.Po ./$(DEPDIR)/dwarf_error.Po \ + ./$(DEPDIR)/dwarf_filesrc.Po ./$(DEPDIR)/dwarf_formaddr.Po \ + ./$(DEPDIR)/dwarf_formblock.Po ./$(DEPDIR)/dwarf_formflag.Po \ + ./$(DEPDIR)/dwarf_formref.Po ./$(DEPDIR)/dwarf_formref_die.Po \ + ./$(DEPDIR)/dwarf_formsdata.Po ./$(DEPDIR)/dwarf_formstring.Po \ + ./$(DEPDIR)/dwarf_formudata.Po ./$(DEPDIR)/dwarf_frame_cfa.Po \ + ./$(DEPDIR)/dwarf_frame_info.Po \ + ./$(DEPDIR)/dwarf_frame_register.Po \ + ./$(DEPDIR)/dwarf_func_inline.Po \ + ./$(DEPDIR)/dwarf_get_units.Po ./$(DEPDIR)/dwarf_getabbrev.Po \ + ./$(DEPDIR)/dwarf_getabbrevattr.Po \ + ./$(DEPDIR)/dwarf_getabbrevcode.Po \ + ./$(DEPDIR)/dwarf_getabbrevtag.Po ./$(DEPDIR)/dwarf_getalt.Po \ + ./$(DEPDIR)/dwarf_getarange_addr.Po \ + ./$(DEPDIR)/dwarf_getarangeinfo.Po \ + ./$(DEPDIR)/dwarf_getaranges.Po \ + ./$(DEPDIR)/dwarf_getattrcnt.Po ./$(DEPDIR)/dwarf_getattrs.Po \ + ./$(DEPDIR)/dwarf_getcfi.Po ./$(DEPDIR)/dwarf_getcfi_elf.Po \ + ./$(DEPDIR)/dwarf_getelf.Po ./$(DEPDIR)/dwarf_getfuncs.Po \ + ./$(DEPDIR)/dwarf_getlocation.Po \ + ./$(DEPDIR)/dwarf_getlocation_attr.Po \ + ./$(DEPDIR)/dwarf_getlocation_die.Po \ + ./$(DEPDIR)/dwarf_getlocation_implicit_pointer.Po \ + ./$(DEPDIR)/dwarf_getmacros.Po \ + ./$(DEPDIR)/dwarf_getpubnames.Po \ + ./$(DEPDIR)/dwarf_getscopes.Po \ + ./$(DEPDIR)/dwarf_getscopes_die.Po \ + ./$(DEPDIR)/dwarf_getscopevar.Po \ + ./$(DEPDIR)/dwarf_getsrc_die.Po \ + ./$(DEPDIR)/dwarf_getsrc_file.Po \ + ./$(DEPDIR)/dwarf_getsrcdirs.Po \ + ./$(DEPDIR)/dwarf_getsrcfiles.Po \ + ./$(DEPDIR)/dwarf_getsrclines.Po \ + ./$(DEPDIR)/dwarf_getstring.Po ./$(DEPDIR)/dwarf_hasattr.Po \ + ./$(DEPDIR)/dwarf_hasattr_integrate.Po \ + ./$(DEPDIR)/dwarf_haschildren.Po ./$(DEPDIR)/dwarf_hasform.Po \ + ./$(DEPDIR)/dwarf_haspc.Po ./$(DEPDIR)/dwarf_highpc.Po \ + ./$(DEPDIR)/dwarf_line_file.Po ./$(DEPDIR)/dwarf_lineaddr.Po \ + ./$(DEPDIR)/dwarf_linebeginstatement.Po \ + ./$(DEPDIR)/dwarf_lineblock.Po ./$(DEPDIR)/dwarf_linecol.Po \ + ./$(DEPDIR)/dwarf_linediscriminator.Po \ + ./$(DEPDIR)/dwarf_lineendsequence.Po \ + ./$(DEPDIR)/dwarf_lineepiloguebegin.Po \ + ./$(DEPDIR)/dwarf_lineisa.Po ./$(DEPDIR)/dwarf_lineno.Po \ + ./$(DEPDIR)/dwarf_lineop_index.Po \ + ./$(DEPDIR)/dwarf_lineprologueend.Po \ + ./$(DEPDIR)/dwarf_linesrc.Po ./$(DEPDIR)/dwarf_lowpc.Po \ + ./$(DEPDIR)/dwarf_macro_getparamcnt.Po \ + ./$(DEPDIR)/dwarf_macro_getsrcfiles.Po \ + ./$(DEPDIR)/dwarf_macro_opcode.Po \ + ./$(DEPDIR)/dwarf_macro_param.Po \ + ./$(DEPDIR)/dwarf_macro_param1.Po \ + ./$(DEPDIR)/dwarf_macro_param2.Po \ + ./$(DEPDIR)/dwarf_next_cfi.Po ./$(DEPDIR)/dwarf_next_lines.Po \ + ./$(DEPDIR)/dwarf_nextcu.Po ./$(DEPDIR)/dwarf_offabbrev.Po \ + ./$(DEPDIR)/dwarf_offdie.Po ./$(DEPDIR)/dwarf_onearange.Po \ + ./$(DEPDIR)/dwarf_onesrcline.Po ./$(DEPDIR)/dwarf_peel_type.Po \ + ./$(DEPDIR)/dwarf_ranges.Po ./$(DEPDIR)/dwarf_setalt.Po \ + ./$(DEPDIR)/dwarf_siblingof.Po ./$(DEPDIR)/dwarf_sig8_hash.Po \ + ./$(DEPDIR)/dwarf_srclang.Po ./$(DEPDIR)/dwarf_tag.Po \ + ./$(DEPDIR)/dwarf_whatattr.Po ./$(DEPDIR)/dwarf_whatform.Po \ + ./$(DEPDIR)/fde.Po ./$(DEPDIR)/frame-cache.Po \ + ./$(DEPDIR)/libdw_alloc.Po \ + ./$(DEPDIR)/libdw_find_split_unit.Po \ + ./$(DEPDIR)/libdw_findcu.Po ./$(DEPDIR)/libdw_form.Po \ + ./$(DEPDIR)/libdw_visit_scopes.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) +DIST_SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(noinst_DATA) +HEADERS = $(include_HEADERS) $(noinst_HEADERS) $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(srcdir)/../libelf -I$(srcdir)/../libdwelf -pthread + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes \ + $(TRAMPOLINES_WARNING) $(LOGICAL_OP_WARNING) \ + $(DUPLICATED_COND_WARNING) $(NULL_DEREFERENCE_WARNING) \ + $(IMPLICIT_FALLTHROUGH_WARNING) $(if \ + $($(*F)_no_Werror),,-Werror) $(if \ + $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \ + $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) $(if \ + $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) $(am__append_2) +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +lib_LIBRARIES = libdw.a +noinst_LIBRARIES = libdw_pic.a +noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so) +include_HEADERS = dwarf.h +pkginclude_HEADERS = libdw.h known-dwarf.h +libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ + dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \ + dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \ + dwarf_attr.c dwarf_formstring.c \ + dwarf_abbrev_hash.c dwarf_sig8_hash.c \ + dwarf_attr_integrate.c dwarf_hasattr_integrate.c \ + dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \ + dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \ + dwarf_entrypc.c dwarf_haspc.c dwarf_highpc.c dwarf_ranges.c \ + dwarf_formref.c dwarf_formref_die.c dwarf_siblingof.c \ + dwarf_dieoffset.c dwarf_cuoffset.c dwarf_diecu.c \ + dwarf_hasattr.c dwarf_hasform.c \ + dwarf_whatform.c dwarf_whatattr.c \ + dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \ + dwarf_bitoffset.c dwarf_srclang.c dwarf_getabbrevtag.c \ + dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \ + dwarf_getattrcnt.c dwarf_getabbrevattr.c \ + dwarf_getsrclines.c dwarf_getsrc_die.c \ + dwarf_getscopes.c dwarf_getscopes_die.c dwarf_getscopevar.c \ + dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \ + dwarf_linecol.c dwarf_linebeginstatement.c \ + dwarf_lineendsequence.c dwarf_lineblock.c \ + dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ + dwarf_lineisa.c dwarf_linediscriminator.c \ + dwarf_lineop_index.c dwarf_line_file.c \ + dwarf_onesrcline.c dwarf_formblock.c \ + dwarf_getsrcfiles.c dwarf_filesrc.c dwarf_getsrcdirs.c \ + dwarf_getlocation.c dwarf_getstring.c dwarf_offabbrev.c \ + dwarf_getaranges.c dwarf_onearange.c dwarf_getarangeinfo.c \ + dwarf_getarange_addr.c dwarf_getattrs.c dwarf_formflag.c \ + dwarf_getmacros.c dwarf_macro_getparamcnt.c \ + dwarf_macro_opcode.c dwarf_macro_param.c \ + dwarf_macro_param1.c dwarf_macro_param2.c \ + dwarf_macro_getsrcfiles.c \ + dwarf_addrdie.c dwarf_getfuncs.c \ + dwarf_decl_file.c dwarf_decl_line.c dwarf_decl_column.c \ + dwarf_func_inline.c dwarf_getsrc_file.c \ + libdw_findcu.c libdw_form.c libdw_alloc.c \ + libdw_visit_scopes.c \ + dwarf_entry_breakpoints.c \ + dwarf_next_cfi.c \ + cie.c fde.c cfi.c frame-cache.c \ + dwarf_frame_info.c dwarf_frame_cfa.c dwarf_frame_register.c \ + dwarf_cfi_addrframe.c \ + dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \ + dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \ + dwarf_getlocation_die.c dwarf_getlocation_attr.c \ + dwarf_getalt.c dwarf_setalt.c dwarf_cu_getdwarf.c \ + dwarf_cu_die.c dwarf_peel_type.c dwarf_default_lower_bound.c \ + dwarf_die_addr_die.c dwarf_get_units.c \ + libdw_find_split_unit.c dwarf_cu_info.c \ + dwarf_next_lines.c + +@MAINTAINER_MODE_TRUE@BUILT_SOURCES = $(srcdir)/known-dwarf.h +@MAINTAINER_MODE_TRUE@MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h +libdw_pic_a_SOURCES = +am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os) +libdw_so_LIBS = ../libebl/libebl_pic.a ../backends/libebl_backends_pic.a \ + ../libcpu/libcpu_pic.a libdw_pic.a ../libdwelf/libdwelf_pic.a \ + ../libdwfl/libdwfl_pic.a + +libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so +libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(fts_LIBS) $(obstack_LIBS) $(zip_LIBS) -pthread +libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a) +libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects)) \ + $(addprefix ../libdwelf/,$(libdwelf_objects)) $(addprefix \ + ../libebl/,$(libebl_objects)) $(addprefix \ + ../backends/,$(backends_objects)) $(addprefix \ + ../libcpu/,$(libcpu_objects)) +libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a) +libebl_objects = $(shell $(AR) t ../libebl/libebl.a) +backends_objects = $(shell $(AR) t ../backends/libebl_backends.a) +libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a) +noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \ + dwarf_sig8_hash.h cfi.h encoded-value.h + +EXTRA_DIST = libdw.map +MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) libdw.so libdw.so.$(VERSION) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdw/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libdw/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libdw.a: $(libdw_a_OBJECTS) $(libdw_a_DEPENDENCIES) $(EXTRA_libdw_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdw.a + $(AM_V_AR)$(libdw_a_AR) libdw.a $(libdw_a_OBJECTS) $(libdw_a_LIBADD) + $(AM_V_at)$(RANLIB) libdw.a + +libdw_pic.a: $(libdw_pic_a_OBJECTS) $(libdw_pic_a_DEPENDENCIES) $(EXTRA_libdw_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdw_pic.a + $(AM_V_AR)$(libdw_pic_a_AR) libdw_pic.a $(libdw_pic_a_OBJECTS) $(libdw_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libdw_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_abbrev_hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_abbrevhaschildren.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_addrdie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_aggregate_size.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_arrayorder.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_attr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_attr_integrate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_begin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_begin_elf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bitoffset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bitsize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bytesize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cfi_addrframe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cfi_end.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_child.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cu_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cu_getdwarf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cu_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cuoffset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_decl_column.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_decl_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_decl_line.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_default_lower_bound.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_die_addr_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_diecu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_diename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_dieoffset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_end.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_entry_breakpoints.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_entrypc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_error.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_filesrc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formaddr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formblock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formflag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formref.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formref_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formsdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formstring.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formudata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_frame_cfa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_frame_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_frame_register.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_func_inline.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_get_units.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrev.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrevattr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrevcode.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrevtag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getalt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getarange_addr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getarangeinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getaranges.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getattrcnt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getattrs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getcfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getcfi_elf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getelf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getfuncs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getlocation.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getlocation_attr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getlocation_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getlocation_implicit_pointer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getmacros.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getpubnames.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getscopes.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getscopes_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getscopevar.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrc_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrc_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrcdirs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrcfiles.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrclines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getstring.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasattr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasattr_integrate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_haschildren.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasform.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_haspc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_highpc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_line_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineaddr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linebeginstatement.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineblock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linecol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linediscriminator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineendsequence.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineepiloguebegin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineisa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineno.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineop_index.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineprologueend.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linesrc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lowpc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_macro_getparamcnt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_macro_getsrcfiles.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_macro_opcode.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_macro_param.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_macro_param1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_macro_param2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_next_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_next_lines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_nextcu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_offabbrev.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_offdie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_onearange.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_onesrcline.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_peel_type.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_ranges.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_setalt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_siblingof.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_sig8_hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_srclang.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_tag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_whatattr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_whatform.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fde.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame-cache.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_alloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_find_split_unit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_findcu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_form.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_visit_scopes.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install-exec: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-exec-am +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/cfi.Po + -rm -f ./$(DEPDIR)/cie.Po + -rm -f ./$(DEPDIR)/dwarf_abbrev_hash.Po + -rm -f ./$(DEPDIR)/dwarf_abbrevhaschildren.Po + -rm -f ./$(DEPDIR)/dwarf_addrdie.Po + -rm -f ./$(DEPDIR)/dwarf_aggregate_size.Po + -rm -f ./$(DEPDIR)/dwarf_arrayorder.Po + -rm -f ./$(DEPDIR)/dwarf_attr.Po + -rm -f ./$(DEPDIR)/dwarf_attr_integrate.Po + -rm -f ./$(DEPDIR)/dwarf_begin.Po + -rm -f ./$(DEPDIR)/dwarf_begin_elf.Po + -rm -f ./$(DEPDIR)/dwarf_bitoffset.Po + -rm -f ./$(DEPDIR)/dwarf_bitsize.Po + -rm -f ./$(DEPDIR)/dwarf_bytesize.Po + -rm -f ./$(DEPDIR)/dwarf_cfi_addrframe.Po + -rm -f ./$(DEPDIR)/dwarf_cfi_end.Po + -rm -f ./$(DEPDIR)/dwarf_child.Po + -rm -f ./$(DEPDIR)/dwarf_cu_die.Po + -rm -f ./$(DEPDIR)/dwarf_cu_getdwarf.Po + -rm -f ./$(DEPDIR)/dwarf_cu_info.Po + -rm -f ./$(DEPDIR)/dwarf_cuoffset.Po + -rm -f ./$(DEPDIR)/dwarf_decl_column.Po + -rm -f ./$(DEPDIR)/dwarf_decl_file.Po + -rm -f ./$(DEPDIR)/dwarf_decl_line.Po + -rm -f ./$(DEPDIR)/dwarf_default_lower_bound.Po + -rm -f ./$(DEPDIR)/dwarf_die_addr_die.Po + -rm -f ./$(DEPDIR)/dwarf_diecu.Po + -rm -f ./$(DEPDIR)/dwarf_diename.Po + -rm -f ./$(DEPDIR)/dwarf_dieoffset.Po + -rm -f ./$(DEPDIR)/dwarf_end.Po + -rm -f ./$(DEPDIR)/dwarf_entry_breakpoints.Po + -rm -f ./$(DEPDIR)/dwarf_entrypc.Po + -rm -f ./$(DEPDIR)/dwarf_error.Po + -rm -f ./$(DEPDIR)/dwarf_filesrc.Po + -rm -f ./$(DEPDIR)/dwarf_formaddr.Po + -rm -f ./$(DEPDIR)/dwarf_formblock.Po + -rm -f ./$(DEPDIR)/dwarf_formflag.Po + -rm -f ./$(DEPDIR)/dwarf_formref.Po + -rm -f ./$(DEPDIR)/dwarf_formref_die.Po + -rm -f ./$(DEPDIR)/dwarf_formsdata.Po + -rm -f ./$(DEPDIR)/dwarf_formstring.Po + -rm -f ./$(DEPDIR)/dwarf_formudata.Po + -rm -f ./$(DEPDIR)/dwarf_frame_cfa.Po + -rm -f ./$(DEPDIR)/dwarf_frame_info.Po + -rm -f ./$(DEPDIR)/dwarf_frame_register.Po + -rm -f ./$(DEPDIR)/dwarf_func_inline.Po + -rm -f ./$(DEPDIR)/dwarf_get_units.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrev.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrevattr.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrevcode.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrevtag.Po + -rm -f ./$(DEPDIR)/dwarf_getalt.Po + -rm -f ./$(DEPDIR)/dwarf_getarange_addr.Po + -rm -f ./$(DEPDIR)/dwarf_getarangeinfo.Po + -rm -f ./$(DEPDIR)/dwarf_getaranges.Po + -rm -f ./$(DEPDIR)/dwarf_getattrcnt.Po + -rm -f ./$(DEPDIR)/dwarf_getattrs.Po + -rm -f ./$(DEPDIR)/dwarf_getcfi.Po + -rm -f ./$(DEPDIR)/dwarf_getcfi_elf.Po + -rm -f ./$(DEPDIR)/dwarf_getelf.Po + -rm -f ./$(DEPDIR)/dwarf_getfuncs.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation_attr.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation_die.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation_implicit_pointer.Po + -rm -f ./$(DEPDIR)/dwarf_getmacros.Po + -rm -f ./$(DEPDIR)/dwarf_getpubnames.Po + -rm -f ./$(DEPDIR)/dwarf_getscopes.Po + -rm -f ./$(DEPDIR)/dwarf_getscopes_die.Po + -rm -f ./$(DEPDIR)/dwarf_getscopevar.Po + -rm -f ./$(DEPDIR)/dwarf_getsrc_die.Po + -rm -f ./$(DEPDIR)/dwarf_getsrc_file.Po + -rm -f ./$(DEPDIR)/dwarf_getsrcdirs.Po + -rm -f ./$(DEPDIR)/dwarf_getsrcfiles.Po + -rm -f ./$(DEPDIR)/dwarf_getsrclines.Po + -rm -f ./$(DEPDIR)/dwarf_getstring.Po + -rm -f ./$(DEPDIR)/dwarf_hasattr.Po + -rm -f ./$(DEPDIR)/dwarf_hasattr_integrate.Po + -rm -f ./$(DEPDIR)/dwarf_haschildren.Po + -rm -f ./$(DEPDIR)/dwarf_hasform.Po + -rm -f ./$(DEPDIR)/dwarf_haspc.Po + -rm -f ./$(DEPDIR)/dwarf_highpc.Po + -rm -f ./$(DEPDIR)/dwarf_line_file.Po + -rm -f ./$(DEPDIR)/dwarf_lineaddr.Po + -rm -f ./$(DEPDIR)/dwarf_linebeginstatement.Po + -rm -f ./$(DEPDIR)/dwarf_lineblock.Po + -rm -f ./$(DEPDIR)/dwarf_linecol.Po + -rm -f ./$(DEPDIR)/dwarf_linediscriminator.Po + -rm -f ./$(DEPDIR)/dwarf_lineendsequence.Po + -rm -f ./$(DEPDIR)/dwarf_lineepiloguebegin.Po + -rm -f ./$(DEPDIR)/dwarf_lineisa.Po + -rm -f ./$(DEPDIR)/dwarf_lineno.Po + -rm -f ./$(DEPDIR)/dwarf_lineop_index.Po + -rm -f ./$(DEPDIR)/dwarf_lineprologueend.Po + -rm -f ./$(DEPDIR)/dwarf_linesrc.Po + -rm -f ./$(DEPDIR)/dwarf_lowpc.Po + -rm -f ./$(DEPDIR)/dwarf_macro_getparamcnt.Po + -rm -f ./$(DEPDIR)/dwarf_macro_getsrcfiles.Po + -rm -f ./$(DEPDIR)/dwarf_macro_opcode.Po + -rm -f ./$(DEPDIR)/dwarf_macro_param.Po + -rm -f ./$(DEPDIR)/dwarf_macro_param1.Po + -rm -f ./$(DEPDIR)/dwarf_macro_param2.Po + -rm -f ./$(DEPDIR)/dwarf_next_cfi.Po + -rm -f ./$(DEPDIR)/dwarf_next_lines.Po + -rm -f ./$(DEPDIR)/dwarf_nextcu.Po + -rm -f ./$(DEPDIR)/dwarf_offabbrev.Po + -rm -f ./$(DEPDIR)/dwarf_offdie.Po + -rm -f ./$(DEPDIR)/dwarf_onearange.Po + -rm -f ./$(DEPDIR)/dwarf_onesrcline.Po + -rm -f ./$(DEPDIR)/dwarf_peel_type.Po + -rm -f ./$(DEPDIR)/dwarf_ranges.Po + -rm -f ./$(DEPDIR)/dwarf_setalt.Po + -rm -f ./$(DEPDIR)/dwarf_siblingof.Po + -rm -f ./$(DEPDIR)/dwarf_sig8_hash.Po + -rm -f ./$(DEPDIR)/dwarf_srclang.Po + -rm -f ./$(DEPDIR)/dwarf_tag.Po + -rm -f ./$(DEPDIR)/dwarf_whatattr.Po + -rm -f ./$(DEPDIR)/dwarf_whatform.Po + -rm -f ./$(DEPDIR)/fde.Po + -rm -f ./$(DEPDIR)/frame-cache.Po + -rm -f ./$(DEPDIR)/libdw_alloc.Po + -rm -f ./$(DEPDIR)/libdw_find_split_unit.Po + -rm -f ./$(DEPDIR)/libdw_findcu.Po + -rm -f ./$(DEPDIR)/libdw_form.Po + -rm -f ./$(DEPDIR)/libdw_visit_scopes.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/cfi.Po + -rm -f ./$(DEPDIR)/cie.Po + -rm -f ./$(DEPDIR)/dwarf_abbrev_hash.Po + -rm -f ./$(DEPDIR)/dwarf_abbrevhaschildren.Po + -rm -f ./$(DEPDIR)/dwarf_addrdie.Po + -rm -f ./$(DEPDIR)/dwarf_aggregate_size.Po + -rm -f ./$(DEPDIR)/dwarf_arrayorder.Po + -rm -f ./$(DEPDIR)/dwarf_attr.Po + -rm -f ./$(DEPDIR)/dwarf_attr_integrate.Po + -rm -f ./$(DEPDIR)/dwarf_begin.Po + -rm -f ./$(DEPDIR)/dwarf_begin_elf.Po + -rm -f ./$(DEPDIR)/dwarf_bitoffset.Po + -rm -f ./$(DEPDIR)/dwarf_bitsize.Po + -rm -f ./$(DEPDIR)/dwarf_bytesize.Po + -rm -f ./$(DEPDIR)/dwarf_cfi_addrframe.Po + -rm -f ./$(DEPDIR)/dwarf_cfi_end.Po + -rm -f ./$(DEPDIR)/dwarf_child.Po + -rm -f ./$(DEPDIR)/dwarf_cu_die.Po + -rm -f ./$(DEPDIR)/dwarf_cu_getdwarf.Po + -rm -f ./$(DEPDIR)/dwarf_cu_info.Po + -rm -f ./$(DEPDIR)/dwarf_cuoffset.Po + -rm -f ./$(DEPDIR)/dwarf_decl_column.Po + -rm -f ./$(DEPDIR)/dwarf_decl_file.Po + -rm -f ./$(DEPDIR)/dwarf_decl_line.Po + -rm -f ./$(DEPDIR)/dwarf_default_lower_bound.Po + -rm -f ./$(DEPDIR)/dwarf_die_addr_die.Po + -rm -f ./$(DEPDIR)/dwarf_diecu.Po + -rm -f ./$(DEPDIR)/dwarf_diename.Po + -rm -f ./$(DEPDIR)/dwarf_dieoffset.Po + -rm -f ./$(DEPDIR)/dwarf_end.Po + -rm -f ./$(DEPDIR)/dwarf_entry_breakpoints.Po + -rm -f ./$(DEPDIR)/dwarf_entrypc.Po + -rm -f ./$(DEPDIR)/dwarf_error.Po + -rm -f ./$(DEPDIR)/dwarf_filesrc.Po + -rm -f ./$(DEPDIR)/dwarf_formaddr.Po + -rm -f ./$(DEPDIR)/dwarf_formblock.Po + -rm -f ./$(DEPDIR)/dwarf_formflag.Po + -rm -f ./$(DEPDIR)/dwarf_formref.Po + -rm -f ./$(DEPDIR)/dwarf_formref_die.Po + -rm -f ./$(DEPDIR)/dwarf_formsdata.Po + -rm -f ./$(DEPDIR)/dwarf_formstring.Po + -rm -f ./$(DEPDIR)/dwarf_formudata.Po + -rm -f ./$(DEPDIR)/dwarf_frame_cfa.Po + -rm -f ./$(DEPDIR)/dwarf_frame_info.Po + -rm -f ./$(DEPDIR)/dwarf_frame_register.Po + -rm -f ./$(DEPDIR)/dwarf_func_inline.Po + -rm -f ./$(DEPDIR)/dwarf_get_units.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrev.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrevattr.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrevcode.Po + -rm -f ./$(DEPDIR)/dwarf_getabbrevtag.Po + -rm -f ./$(DEPDIR)/dwarf_getalt.Po + -rm -f ./$(DEPDIR)/dwarf_getarange_addr.Po + -rm -f ./$(DEPDIR)/dwarf_getarangeinfo.Po + -rm -f ./$(DEPDIR)/dwarf_getaranges.Po + -rm -f ./$(DEPDIR)/dwarf_getattrcnt.Po + -rm -f ./$(DEPDIR)/dwarf_getattrs.Po + -rm -f ./$(DEPDIR)/dwarf_getcfi.Po + -rm -f ./$(DEPDIR)/dwarf_getcfi_elf.Po + -rm -f ./$(DEPDIR)/dwarf_getelf.Po + -rm -f ./$(DEPDIR)/dwarf_getfuncs.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation_attr.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation_die.Po + -rm -f ./$(DEPDIR)/dwarf_getlocation_implicit_pointer.Po + -rm -f ./$(DEPDIR)/dwarf_getmacros.Po + -rm -f ./$(DEPDIR)/dwarf_getpubnames.Po + -rm -f ./$(DEPDIR)/dwarf_getscopes.Po + -rm -f ./$(DEPDIR)/dwarf_getscopes_die.Po + -rm -f ./$(DEPDIR)/dwarf_getscopevar.Po + -rm -f ./$(DEPDIR)/dwarf_getsrc_die.Po + -rm -f ./$(DEPDIR)/dwarf_getsrc_file.Po + -rm -f ./$(DEPDIR)/dwarf_getsrcdirs.Po + -rm -f ./$(DEPDIR)/dwarf_getsrcfiles.Po + -rm -f ./$(DEPDIR)/dwarf_getsrclines.Po + -rm -f ./$(DEPDIR)/dwarf_getstring.Po + -rm -f ./$(DEPDIR)/dwarf_hasattr.Po + -rm -f ./$(DEPDIR)/dwarf_hasattr_integrate.Po + -rm -f ./$(DEPDIR)/dwarf_haschildren.Po + -rm -f ./$(DEPDIR)/dwarf_hasform.Po + -rm -f ./$(DEPDIR)/dwarf_haspc.Po + -rm -f ./$(DEPDIR)/dwarf_highpc.Po + -rm -f ./$(DEPDIR)/dwarf_line_file.Po + -rm -f ./$(DEPDIR)/dwarf_lineaddr.Po + -rm -f ./$(DEPDIR)/dwarf_linebeginstatement.Po + -rm -f ./$(DEPDIR)/dwarf_lineblock.Po + -rm -f ./$(DEPDIR)/dwarf_linecol.Po + -rm -f ./$(DEPDIR)/dwarf_linediscriminator.Po + -rm -f ./$(DEPDIR)/dwarf_lineendsequence.Po + -rm -f ./$(DEPDIR)/dwarf_lineepiloguebegin.Po + -rm -f ./$(DEPDIR)/dwarf_lineisa.Po + -rm -f ./$(DEPDIR)/dwarf_lineno.Po + -rm -f ./$(DEPDIR)/dwarf_lineop_index.Po + -rm -f ./$(DEPDIR)/dwarf_lineprologueend.Po + -rm -f ./$(DEPDIR)/dwarf_linesrc.Po + -rm -f ./$(DEPDIR)/dwarf_lowpc.Po + -rm -f ./$(DEPDIR)/dwarf_macro_getparamcnt.Po + -rm -f ./$(DEPDIR)/dwarf_macro_getsrcfiles.Po + -rm -f ./$(DEPDIR)/dwarf_macro_opcode.Po + -rm -f ./$(DEPDIR)/dwarf_macro_param.Po + -rm -f ./$(DEPDIR)/dwarf_macro_param1.Po + -rm -f ./$(DEPDIR)/dwarf_macro_param2.Po + -rm -f ./$(DEPDIR)/dwarf_next_cfi.Po + -rm -f ./$(DEPDIR)/dwarf_next_lines.Po + -rm -f ./$(DEPDIR)/dwarf_nextcu.Po + -rm -f ./$(DEPDIR)/dwarf_offabbrev.Po + -rm -f ./$(DEPDIR)/dwarf_offdie.Po + -rm -f ./$(DEPDIR)/dwarf_onearange.Po + -rm -f ./$(DEPDIR)/dwarf_onesrcline.Po + -rm -f ./$(DEPDIR)/dwarf_peel_type.Po + -rm -f ./$(DEPDIR)/dwarf_ranges.Po + -rm -f ./$(DEPDIR)/dwarf_setalt.Po + -rm -f ./$(DEPDIR)/dwarf_siblingof.Po + -rm -f ./$(DEPDIR)/dwarf_sig8_hash.Po + -rm -f ./$(DEPDIR)/dwarf_srclang.Po + -rm -f ./$(DEPDIR)/dwarf_tag.Po + -rm -f ./$(DEPDIR)/dwarf_whatattr.Po + -rm -f ./$(DEPDIR)/dwarf_whatform.Po + -rm -f ./$(DEPDIR)/fde.Po + -rm -f ./$(DEPDIR)/frame-cache.Po + -rm -f ./$(DEPDIR)/libdw_alloc.Po + -rm -f ./$(DEPDIR)/libdw_find_split_unit.Po + -rm -f ./$(DEPDIR)/libdw_findcu.Po + -rm -f ./$(DEPDIR)/libdw_form.Po + -rm -f ./$(DEPDIR)/libdw_visit_scopes.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLIBRARIES \ + uninstall-pkgincludeHEADERS + +.MAKE: all check install install-am install-exec install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-libLIBRARIES install-man install-pdf install-pdf-am \ + install-pkgincludeHEADERS install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLIBRARIES uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) +@MAINTAINER_MODE_TRUE@$(srcdir)/known-dwarf.h: $(top_srcdir)/config/known-dwarf.awk $(srcdir)/dwarf.h +@MAINTAINER_MODE_TRUE@ gawk -f $^ > $@.new +@MAINTAINER_MODE_TRUE@ mv -f $@.new $@ +libdw.so: $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$@.$(VERSION),--enable-new-dtags \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \ + $(libdw_so_LDLIBS) + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + +install: install-am libdw.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libdw.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libdw/cfi.c b/libdw/cfi.c new file mode 100644 index 00000000..a73fb03f --- /dev/null +++ b/libdw/cfi.c @@ -0,0 +1,530 @@ +/* CFI program execution. + Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "../libebl/libebl.h" +#include "cfi.h" +#include "memory-access.h" +#include "encoded-value.h" +#include "system.h" +#include +#include +#include + +#define CFI_PRIMARY_MAX 0x3f + +static Dwarf_Frame * +duplicate_frame_state (const Dwarf_Frame *original, + Dwarf_Frame *prev) +{ + size_t size = offsetof (Dwarf_Frame, regs[original->nregs]); + Dwarf_Frame *copy = malloc (size); + if (likely (copy != NULL)) + { + memcpy (copy, original, size); + copy->prev = prev; + } + return copy; +} + +static inline bool +enough_registers (Dwarf_Word reg, Dwarf_Frame **pfs, int *result) +{ + /* Don't allow insanely large register numbers. 268435456 registers + should be enough for anybody. And very large values might overflow + the array size and offsetof calculations below. */ + if (unlikely (reg >= INT32_MAX / sizeof ((*pfs)->regs[0]))) + { + *result = DWARF_E_INVALID_CFI; + return false; + } + + if ((*pfs)->nregs <= reg) + { + size_t size = offsetof (Dwarf_Frame, regs[reg + 1]); + Dwarf_Frame *bigger = realloc (*pfs, size); + if (unlikely (bigger == NULL)) + { + *result = DWARF_E_NOMEM; + return false; + } + else + { + eu_static_assert (reg_unspecified == 0); + memset (bigger->regs + bigger->nregs, 0, + (reg + 1 - bigger->nregs) * sizeof bigger->regs[0]); + bigger->nregs = reg + 1; + *pfs = bigger; + } + } + return true; +} + +static inline void +require_cfa_offset (Dwarf_Frame *fs) +{ + if (unlikely (fs->cfa_rule != cfa_offset)) + fs->cfa_rule = cfa_invalid; +} + +/* Returns a DWARF_E_* error code, usually NOERROR or INVALID_CFI. + Frees *STATE on failure. */ +static int +execute_cfi (Dwarf_CFI *cache, + const struct dwarf_cie *cie, + Dwarf_Frame **state, + const uint8_t *program, const uint8_t *const end, bool abi_cfi, + Dwarf_Addr loc, Dwarf_Addr find_pc) +{ + /* The caller should not give us anything out of range. */ + assert (loc <= find_pc); + + int result = DWARF_E_NOERROR; + +#define cfi_assert(ok) do { \ + if (likely (ok)) break; \ + result = DWARF_E_INVALID_CFI; \ + goto out; \ + } while (0) + + Dwarf_Frame *fs = *state; + +#define register_rule(regno, r_rule, r_value) do { \ + if (unlikely (! enough_registers (regno, &fs, &result))) \ + goto out; \ + fs->regs[regno].rule = reg_##r_rule; \ + fs->regs[regno].value = (r_value); \ + } while (0) + + while (program < end) + { + uint8_t opcode = *program++; + Dwarf_Word regno; + Dwarf_Word offset; + Dwarf_Word sf_offset; + Dwarf_Word operand = opcode & CFI_PRIMARY_MAX; + switch (opcode) + { + /* These cases move LOC, i.e. "create a new table row". */ + + case DW_CFA_advance_loc1: + operand = *program++; + FALLTHROUGH; + case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX: + advance_loc: + loc += operand * cie->code_alignment_factor; + break; + + case DW_CFA_advance_loc2: + cfi_assert (program + 2 <= end); + operand = read_2ubyte_unaligned_inc (cache, program); + goto advance_loc; + case DW_CFA_advance_loc4: + cfi_assert (program + 4 <= end); + operand = read_4ubyte_unaligned_inc (cache, program); + goto advance_loc; + case DW_CFA_MIPS_advance_loc8: + cfi_assert (program + 8 <= end); + operand = read_8ubyte_unaligned_inc (cache, program); + goto advance_loc; + + case DW_CFA_set_loc: + if (likely (!read_encoded_value (cache, cie->fde_encoding, + &program, &loc))) + break; + result = INTUSE(dwarf_errno) (); + goto out; + + /* Now all following cases affect this row, but do not touch LOC. + These cases end with 'continue'. We only get out of the + switch block for the row-copying (LOC-moving) cases above. */ + + case DW_CFA_def_cfa: + get_uleb128 (operand, program, end); + cfi_assert (program < end); + get_uleb128 (offset, program, end); + def_cfa: + fs->cfa_rule = cfa_offset; + fs->cfa_val_reg = operand; + fs->cfa_val_offset = offset; + /* Prime the rest of the Dwarf_Op so dwarf_frame_cfa can use it. */ + fs->cfa_data.offset.atom = DW_OP_bregx; + fs->cfa_data.offset.offset = 0; + continue; + + case DW_CFA_def_cfa_register: + get_uleb128 (regno, program, end); + require_cfa_offset (fs); + fs->cfa_val_reg = regno; + continue; + + case DW_CFA_def_cfa_sf: + get_uleb128 (operand, program, end); + cfi_assert (program < end); + get_sleb128 (sf_offset, program, end); + offset = sf_offset * cie->data_alignment_factor; + goto def_cfa; + + case DW_CFA_def_cfa_offset: + get_uleb128 (offset, program, end); + def_cfa_offset: + require_cfa_offset (fs); + fs->cfa_val_offset = offset; + continue; + + case DW_CFA_def_cfa_offset_sf: + get_sleb128 (sf_offset, program, end); + offset = sf_offset * cie->data_alignment_factor; + goto def_cfa_offset; + + case DW_CFA_def_cfa_expression: + /* DW_FORM_block is a ULEB128 length followed by that many bytes. */ + get_uleb128 (operand, program, end); + cfi_assert (operand <= (Dwarf_Word) (end - program)); + fs->cfa_rule = cfa_expr; + fs->cfa_data.expr.data = (unsigned char *) program; + fs->cfa_data.expr.length = operand; + program += operand; + continue; + + case DW_CFA_undefined: + get_uleb128 (regno, program, end); + register_rule (regno, undefined, 0); + continue; + + case DW_CFA_same_value: + get_uleb128 (regno, program, end); + register_rule (regno, same_value, 0); + continue; + + case DW_CFA_offset_extended: + get_uleb128 (operand, program, end); + cfi_assert (program < end); + FALLTHROUGH; + case DW_CFA_offset + 0 ... DW_CFA_offset + CFI_PRIMARY_MAX: + get_uleb128 (offset, program, end); + offset *= cie->data_alignment_factor; + offset_extended: + register_rule (operand, offset, offset); + continue; + + case DW_CFA_offset_extended_sf: + get_uleb128 (operand, program, end); + get_sleb128 (sf_offset, program, end); + offset_extended_sf: + offset = sf_offset * cie->data_alignment_factor; + goto offset_extended; + + case DW_CFA_GNU_negative_offset_extended: + /* GNU extension obsoleted by DW_CFA_offset_extended_sf. */ + get_uleb128 (operand, program, end); + cfi_assert (program < end); + get_uleb128 (offset, program, end); + sf_offset = -offset; + goto offset_extended_sf; + + case DW_CFA_val_offset: + get_uleb128 (operand, program, end); + cfi_assert (program < end); + get_uleb128 (offset, program, end); + offset *= cie->data_alignment_factor; + val_offset: + register_rule (operand, val_offset, offset); + continue; + + case DW_CFA_val_offset_sf: + get_uleb128 (operand, program, end); + cfi_assert (program < end); + get_sleb128 (sf_offset, program, end); + offset = sf_offset * cie->data_alignment_factor; + goto val_offset; + + case DW_CFA_register: + get_uleb128 (regno, program, end); + cfi_assert (program < end); + get_uleb128 (operand, program, end); + register_rule (regno, register, operand); + continue; + + case DW_CFA_expression: + /* Expression rule relies on section data, abi_cfi cannot use it. */ + assert (! abi_cfi); + get_uleb128 (regno, program, end); + offset = program - (const uint8_t *) cache->data->d.d_buf; + /* DW_FORM_block is a ULEB128 length followed by that many bytes. */ + cfi_assert (program < end); + get_uleb128 (operand, program, end); + cfi_assert (operand <= (Dwarf_Word) (end - program)); + program += operand; + register_rule (regno, expression, offset); + continue; + + case DW_CFA_val_expression: + /* Expression rule relies on section data, abi_cfi cannot use it. */ + assert (! abi_cfi); + get_uleb128 (regno, program, end); + /* DW_FORM_block is a ULEB128 length followed by that many bytes. */ + offset = program - (const uint8_t *) cache->data->d.d_buf; + get_uleb128 (operand, program, end); + cfi_assert (operand <= (Dwarf_Word) (end - program)); + program += operand; + register_rule (regno, val_expression, offset); + continue; + + case DW_CFA_restore_extended: + get_uleb128 (operand, program, end); + FALLTHROUGH; + case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX: + + if (unlikely (abi_cfi) && likely (opcode == DW_CFA_restore)) + { + /* Special case hack to give backend abi_cfi a shorthand. */ + cache->default_same_value = true; + continue; + } + + /* This can't be used in the CIE's own initial instructions. */ + cfi_assert (cie->initial_state != NULL); + + /* Restore the CIE's initial rule for this register. */ + if (unlikely (! enough_registers (operand, &fs, &result))) + goto out; + if (cie->initial_state->nregs > operand) + fs->regs[operand] = cie->initial_state->regs[operand]; + else + fs->regs[operand].rule = reg_unspecified; + continue; + + case DW_CFA_remember_state: + { + /* Duplicate the state and chain the copy on. */ + Dwarf_Frame *copy = duplicate_frame_state (fs, fs); + if (unlikely (copy == NULL)) + { + result = DWARF_E_NOMEM; + goto out; + } + fs = copy; + continue; + } + + case DW_CFA_restore_state: + { + /* Pop the current state off and use the old one instead. */ + Dwarf_Frame *prev = fs->prev; + cfi_assert (prev != NULL); + free (fs); + fs = prev; + continue; + } + + case DW_CFA_nop: + continue; + + case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */ + if (cache->e_machine == EM_AARCH64) + { + /* Toggles the return address state, indicating whether + the return address is encrypted or not on + aarch64. XXX not handled yet. */ + } + else + { + /* This is magic shorthand used only by SPARC. It's + equivalent to a bunch of DW_CFA_register and + DW_CFA_offset operations. */ + if (unlikely (! enough_registers (31, &fs, &result))) + goto out; + for (regno = 8; regno < 16; ++regno) + { + /* Find each %oN in %iN. */ + fs->regs[regno].rule = reg_register; + fs->regs[regno].value = regno + 16; + } + unsigned int address_size; + address_size = (cache->e_ident[EI_CLASS] == ELFCLASS32 + ? 4 : 8); + for (; regno < 32; ++regno) + { + /* Find %l0..%l7 and %i0..%i7 in a block at the CFA. */ + fs->regs[regno].rule = reg_offset; + fs->regs[regno].value = (regno - 16) * address_size; + } + } + continue; + + case DW_CFA_GNU_args_size: + /* XXX is this useful for anything? */ + get_uleb128 (operand, program, end); + continue; + + default: + cfi_assert (false); + continue; + } + + /* We get here only for the cases that have just moved LOC. */ + cfi_assert (cie->initial_state != NULL); + if (find_pc >= loc) + /* This advance has not yet reached FIND_PC. */ + fs->start = loc; + else + { + /* We have just advanced past the address we're looking for. + The state currently described is what we want to see. */ + fs->end = loc; + break; + } + } + + /* "The end of the instruction stream can be thought of as a + DW_CFA_set_loc (initial_location + address_range) instruction." + (DWARF 3.0 Section 6.4.3) + + When we fall off the end of the program without an advance_loc/set_loc + that put us past FIND_PC, the final state left by the FDE program + applies to this address (the caller ensured it was inside the FDE). + This address (FDE->end) is already in FS->end as set by the caller. */ + +#undef register_rule +#undef cfi_assert + + out: + + /* Pop any remembered states left on the stack. */ + while (fs->prev != NULL) + { + Dwarf_Frame *prev = fs->prev; + fs->prev = prev->prev; + free (prev); + } + + if (likely (result == DWARF_E_NOERROR)) + *state = fs; + else + free (fs); + + return result; +} + +static int +cie_cache_initial_state (Dwarf_CFI *cache, struct dwarf_cie *cie) +{ + int result = DWARF_E_NOERROR; + + if (likely (cie->initial_state != NULL)) + return result; + + /* This CIE has not been used before. Play out its initial + instructions and cache the initial state that results. + First we'll let the backend fill in the default initial + state for this machine's ABI. */ + + Dwarf_CIE abi_info = { DW_CIE_ID_64, NULL, NULL, 1, 1, -1, "", NULL, 0, 0 }; + + /* Make sure we have a backend handle cached. */ + if (unlikely (cache->ebl == NULL)) + { + cache->ebl = ebl_openbackend (cache->data->s->elf); + if (unlikely (cache->ebl == NULL)) + cache->ebl = (void *) -1l; + } + + /* Fetch the ABI's default CFI program. */ + if (likely (cache->ebl != (void *) -1l) + && unlikely (ebl_abi_cfi (cache->ebl, &abi_info) < 0)) + return DWARF_E_UNKNOWN_ERROR; + + Dwarf_Frame *cie_fs = calloc (1, sizeof (Dwarf_Frame)); + if (unlikely (cie_fs == NULL)) + return DWARF_E_NOMEM; + + /* If the default state of any register is not "undefined" + (i.e. call-clobbered), then the backend supplies instructions + for the standard initial state. */ + if (abi_info.initial_instructions_end > abi_info.initial_instructions) + { + /* Dummy CIE for backend's instructions. */ + struct dwarf_cie abi_cie = + { + .code_alignment_factor = abi_info.code_alignment_factor, + .data_alignment_factor = abi_info.data_alignment_factor, + }; + result = execute_cfi (cache, &abi_cie, &cie_fs, + abi_info.initial_instructions, + abi_info.initial_instructions_end, true, + 0, (Dwarf_Addr) -1l); + } + + /* Now run the CIE's initial instructions. */ + if (cie->initial_instructions_end > cie->initial_instructions + && likely (result == DWARF_E_NOERROR)) + result = execute_cfi (cache, cie, &cie_fs, + cie->initial_instructions, + cie->initial_instructions_end, false, + 0, (Dwarf_Addr) -1l); + + if (likely (result == DWARF_E_NOERROR)) + { + /* Now we have the initial state of things that all + FDEs using this CIE will start from. */ + cie_fs->cache = cache; + cie->initial_state = cie_fs; + } + + return result; +} + +int +internal_function +__libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, + Dwarf_Addr address, Dwarf_Frame **frame) +{ + int result = cie_cache_initial_state (cache, fde->cie); + if (likely (result == DWARF_E_NOERROR)) + { + Dwarf_Frame *fs = duplicate_frame_state (fde->cie->initial_state, NULL); + if (unlikely (fs == NULL)) + return DWARF_E_NOMEM; + + fs->fde = fde; + fs->start = fde->start; + fs->end = fde->end; + + result = execute_cfi (cache, fde->cie, &fs, + fde->instructions, fde->instructions_end, false, + fde->start, address); + if (likely (result == DWARF_E_NOERROR)) + *frame = fs; + } + return result; +} diff --git a/libdw/cfi.h b/libdw/cfi.h new file mode 100644 index 00000000..1b0d712f --- /dev/null +++ b/libdw/cfi.h @@ -0,0 +1,238 @@ +/* Internal definitions for libdw CFI interpreter. + Copyright (C) 2009-2010, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _UNWINDP_H +#define _UNWINDP_H 1 + +#include "libdwP.h" +#include "libelfP.h" +struct ebl; + +/* Cached CIE representation. */ +struct dwarf_cie +{ + Dwarf_Off offset; /* Our position, as seen in FDEs' CIE_pointer. */ + + Dwarf_Word code_alignment_factor; + Dwarf_Sword data_alignment_factor; + Dwarf_Word return_address_register; + + size_t fde_augmentation_data_size; + + // play out to initial state + const uint8_t *initial_instructions; + const uint8_t *initial_instructions_end; + + const Dwarf_Frame *initial_state; + + uint8_t fde_encoding; /* DW_EH_PE_* for addresses in FDEs. */ + uint8_t lsda_encoding; /* DW_EH_PE_* for LSDA in FDE augmentation. */ + + bool sized_augmentation_data; /* Saw 'z': FDEs have self-sized data. */ + bool signal_frame; /* Saw 'S': FDE is for a signal frame. */ +}; + +/* Cached FDE representation. */ +struct dwarf_fde +{ + struct dwarf_cie *cie; + + /* This FDE describes PC values in [start, end). */ + Dwarf_Addr start; + Dwarf_Addr end; + + const uint8_t *instructions; + const uint8_t *instructions_end; +}; + +/* This holds everything we cache about the CFI from each ELF file's + .debug_frame or .eh_frame section. */ +struct Dwarf_CFI_s +{ + /* Dwarf handle we came from. If null, this is .eh_frame data. */ + Dwarf *dbg; +#define CFI_IS_EH(cfi) ((cfi)->dbg == NULL) + + /* Data of the .debug_frame or .eh_frame section. */ + Elf_Data_Scn *data; + const unsigned char *e_ident; /* For EI_DATA and EI_CLASS. */ + + Dwarf_Addr frame_vaddr; /* DW_EH_PE_pcrel, address of frame section. */ + Dwarf_Addr textrel; /* DW_EH_PE_textrel base address. */ + Dwarf_Addr datarel; /* DW_EH_PE_datarel base address. */ + + /* Location of next unread entry in the section. */ + Dwarf_Off next_offset; + + /* Search tree for the CIEs, indexed by CIE_pointer (section offset). */ + void *cie_tree; + + /* Search tree for the FDEs, indexed by PC address. */ + void *fde_tree; + + /* Search tree for parsed DWARF expressions, indexed by raw pointer. */ + void *expr_tree; + + /* Backend hook. */ + struct ebl *ebl; + + /* Binary search table in .eh_frame_hdr section. */ + const uint8_t *search_table; + size_t search_table_len; + Dwarf_Addr search_table_vaddr; + size_t search_table_entries; + uint8_t search_table_encoding; + + uint16_t e_machine; + + /* True if the file has a byte order different from the host. */ + bool other_byte_order; + + /* Default rule for registers not previously mentioned + is same_value, not undefined. */ + bool default_same_value; +}; + + +enum dwarf_frame_rule + { + reg_unspecified, /* Uninitialized state. */ + reg_undefined, /* DW_CFA_undefined */ + reg_same_value, /* DW_CFA_same_value */ + reg_offset, /* DW_CFA_offset_extended et al */ + reg_val_offset, /* DW_CFA_val_offset et al */ + reg_register, /* DW_CFA_register */ + reg_expression, /* DW_CFA_expression */ + reg_val_expression, /* DW_CFA_val_expression */ + }; + +/* This describes what we know about an individual register. */ +struct dwarf_frame_register +{ + enum dwarf_frame_rule rule:3; + + /* The meaning of the value bits depends on the rule: + + Rule Value + ---- ----- + undefined unused + same_value unused + offset(N) N (register saved at CFA + value) + val_offset(N) N (register = CFA + value) + register(R) R (register = register #value) + expression(E) section offset of DW_FORM_block containing E + (register saved at address E computes) + val_expression(E) section offset of DW_FORM_block containing E + (register = value E computes) + */ + Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3); +}; + +/* This holds instructions for unwinding frame at a particular PC location + described by an FDE. */ +struct Dwarf_Frame_s +{ + /* This frame description covers PC values in [start, end). */ + Dwarf_Addr start; + Dwarf_Addr end; + + Dwarf_CFI *cache; + + /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state, + or NULL in an initial_state pseudo-frame. */ + Dwarf_Frame *prev; + + /* The FDE that generated this frame state. This points to its CIE, + which has the return_address_register and signal_frame flag. */ + struct dwarf_fde *fde; + + /* The CFA is unknown, is R+N, or is computed by a DWARF expression. + A bogon in the CFI can indicate an invalid/incalculable rule. + We store that as cfa_invalid rather than barfing when processing it, + so callers can ignore the bogon unless they really need that CFA. */ + enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule; + union + { + Dwarf_Op offset; + Dwarf_Block expr; + } cfa_data; + /* We store an offset rule as a DW_OP_bregx operation. */ +#define cfa_val_reg cfa_data.offset.number +#define cfa_val_offset cfa_data.offset.number2 + + size_t nregs; + struct dwarf_frame_register regs[]; +}; + + +/* Clean up the data structure and all it points to. */ +extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache) + __nonnull_attribute__ (1) internal_function; + +/* Enter a CIE encountered while reading through for FDEs. */ +extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset, + const Dwarf_CIE *info) + __nonnull_attribute__ (1, 3) internal_function; + +/* Look up a CIE_pointer for random access. */ +extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset) + __nonnull_attribute__ (1) internal_function; + + +/* Look for an FDE covering the given PC address. */ +extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache, + Dwarf_Addr address) + __nonnull_attribute__ (1) internal_function; + +/* Look for an FDE by its offset in the section. */ +extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache, + Dwarf_Off offset) + __nonnull_attribute__ (1) internal_function; + +/* Process the FDE that contains the given PC address, + to yield the frame state when stopped there. + The return value is a DWARF_E_* error code. */ +extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, + Dwarf_Addr address, Dwarf_Frame **frame) + __nonnull_attribute__ (1, 2, 4) internal_function; + + +/* Dummy struct for memory-access.h macros. */ +#define BYTE_ORDER_DUMMY(var, e_ident) \ + const struct { bool other_byte_order; } var = \ + { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB) \ + || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) } + + +INTDECL (dwarf_next_cfi) +INTDECL (dwarf_getcfi) +INTDECL (dwarf_getcfi_elf) +INTDECL (dwarf_cfi_end) +INTDECL (dwarf_cfi_addrframe) + +#endif /* unwindP.h */ diff --git a/libdw/cie.c b/libdw/cie.c new file mode 100644 index 00000000..1b0aae7c --- /dev/null +++ b/libdw/cie.c @@ -0,0 +1,196 @@ +/* CIE reading. + Copyright (C) 2009-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" +#include "encoded-value.h" +#include +#include +#include + + +static int +compare_cie (const void *a, const void *b) +{ + const struct dwarf_cie *cie1 = a; + const struct dwarf_cie *cie2 = b; + if (cie1->offset < cie2->offset) + return -1; + if (cie1->offset > cie2->offset) + return 1; + return 0; +} + +/* There is no CIE at OFFSET in the tree. Add it. */ +static struct dwarf_cie * +intern_new_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info) +{ + struct dwarf_cie *cie = malloc (sizeof (struct dwarf_cie)); + if (cie == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + cie->offset = offset; + cie->code_alignment_factor = info->code_alignment_factor; + cie->data_alignment_factor = info->data_alignment_factor; + cie->return_address_register = info->return_address_register; + + cie->fde_augmentation_data_size = 0; + cie->sized_augmentation_data = false; + cie->signal_frame = false; + + cie->fde_encoding = DW_EH_PE_absptr; + cie->lsda_encoding = DW_EH_PE_omit; + + /* Grok the augmentation string and its data. */ + const uint8_t *data = info->augmentation_data; + for (const char *ap = info->augmentation; *ap != '\0'; ++ap) + { + uint8_t encoding; + switch (*ap) + { + case 'z': + cie->sized_augmentation_data = true; + continue; + + case 'S': + cie->signal_frame = true; + continue; + + case 'L': /* LSDA pointer encoding byte. */ + cie->lsda_encoding = *data++; + if (!cie->sized_augmentation_data) + cie->fde_augmentation_data_size + += encoded_value_size (&cache->data->d, cache->e_ident, + cie->lsda_encoding, NULL); + continue; + + case 'R': /* FDE address encoding byte. */ + cie->fde_encoding = *data++; + continue; + + case 'P': /* Skip personality routine. */ + encoding = *data++; + data += encoded_value_size (&cache->data->d, cache->e_ident, + encoding, data); + continue; + + default: + /* Unknown augmentation string. If we have 'z' we can ignore it, + otherwise we must bail out. */ + if (cie->sized_augmentation_data) + continue; + } + /* We only get here when we need to bail out. */ + break; + } + + if ((cie->fde_encoding & 0x0f) == DW_EH_PE_absptr) + { + /* Canonicalize encoding to a specific size. */ + assert (DW_EH_PE_absptr == 0); + + /* XXX should get from dwarf_next_cfi with v4 header. */ + uint_fast8_t address_size + = cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + switch (address_size) + { + case 8: + cie->fde_encoding |= DW_EH_PE_udata8; + break; + case 4: + cie->fde_encoding |= DW_EH_PE_udata4; + break; + default: + free (cie); + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + } + + /* Save the initial instructions to be played out into initial state. */ + cie->initial_instructions = info->initial_instructions; + cie->initial_instructions_end = info->initial_instructions_end; + cie->initial_state = NULL; + + /* Add the new entry to the search tree. */ + if (tsearch (cie, &cache->cie_tree, &compare_cie) == NULL) + { + free (cie); + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + return cie; +} + +/* Look up a CIE_pointer for random access. */ +struct dwarf_cie * +internal_function +__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset) +{ + const struct dwarf_cie cie_key = { .offset = offset }; + struct dwarf_cie **found = tfind (&cie_key, &cache->cie_tree, &compare_cie); + if (found != NULL) + return *found; + + /* We have not read this CIE yet. Go find it. */ + Dwarf_Off next_offset = offset; + Dwarf_CFI_Entry entry; + int result = INTUSE(dwarf_next_cfi) (cache->e_ident, + &cache->data->d, CFI_IS_EH (cache), + offset, &next_offset, &entry); + if (result != 0 || entry.cie.CIE_id != DW_CIE_ID_64) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* If this happened to be what we would have read next, notice it. */ + if (cache->next_offset == offset) + cache->next_offset = next_offset; + + return intern_new_cie (cache, offset, &entry.cie); +} + +/* Enter a CIE encountered while reading through for FDEs. */ +void +internal_function +__libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info) +{ + const struct dwarf_cie cie_key = { .offset = offset }; + struct dwarf_cie **found = tfind (&cie_key, &cache->cie_tree, &compare_cie); + if (found == NULL) + /* We have not read this CIE yet. Enter it. */ + (void) intern_new_cie (cache, offset, info); +} diff --git a/libdw/dwarf.h b/libdw/dwarf.h new file mode 100644 index 00000000..19a4be96 --- /dev/null +++ b/libdw/dwarf.h @@ -0,0 +1,1029 @@ +/* This file defines standard DWARF types, structures, and macros. + Copyright (C) 2000-2011, 2014, 2016, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _DWARF_H +#define _DWARF_H 1 + +/* DWARF Unit Header Types. */ +enum + { + DW_UT_compile = 0x01, + DW_UT_type = 0x02, + DW_UT_partial = 0x03, + DW_UT_skeleton = 0x04, + DW_UT_split_compile = 0x05, + DW_UT_split_type = 0x06, + + DW_UT_lo_user = 0x80, + DW_UT_hi_user = 0xff + }; + +/* DWARF tags. */ +enum + { + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + /* 0x06 reserved. */ + /* 0x07 reserved. */ + DW_TAG_imported_declaration = 0x08, + /* 0x09 reserved. */ + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + /* 0x0c reserved. */ + DW_TAG_member = 0x0d, + /* 0x0e reserved. */ + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + /* 0x14 reserved. */ + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_parameter = 0x2f, + DW_TAG_template_value_parameter = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + DW_TAG_dwarf_procedure = 0x36, + DW_TAG_restrict_type = 0x37, + DW_TAG_interface_type = 0x38, + DW_TAG_namespace = 0x39, + DW_TAG_imported_module = 0x3a, + DW_TAG_unspecified_type = 0x3b, + DW_TAG_partial_unit = 0x3c, + DW_TAG_imported_unit = 0x3d, + /* 0x3e reserved. Was DW_TAG_mutable_type. */ + DW_TAG_condition = 0x3f, + DW_TAG_shared_type = 0x40, + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, + DW_TAG_coarray_type = 0x44, + DW_TAG_generic_subrange = 0x45, + DW_TAG_dynamic_type = 0x46, + DW_TAG_atomic_type = 0x47, + DW_TAG_call_site = 0x48, + DW_TAG_call_site_parameter = 0x49, + DW_TAG_skeleton_unit = 0x4a, + DW_TAG_immutable_type = 0x4b, + + DW_TAG_lo_user = 0x4080, + + DW_TAG_MIPS_loop = 0x4081, + DW_TAG_format_label = 0x4101, + DW_TAG_function_template = 0x4102, + DW_TAG_class_template = 0x4103, + + DW_TAG_GNU_BINCL = 0x4104, + DW_TAG_GNU_EINCL = 0x4105, + + DW_TAG_GNU_template_template_param = 0x4106, + DW_TAG_GNU_template_parameter_pack = 0x4107, + DW_TAG_GNU_formal_parameter_pack = 0x4108, + DW_TAG_GNU_call_site = 0x4109, + DW_TAG_GNU_call_site_parameter = 0x410a, + + DW_TAG_hi_user = 0xffff + }; + + +/* Children determination encodings. */ +enum + { + DW_CHILDREN_no = 0, + DW_CHILDREN_yes = 1 + }; + + +/* DWARF attributes encodings. */ +enum + { + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + /* 0x04 reserved. */ + /* 0x05 reserved. */ + /* 0x06 reserved. */ + /* 0x07 reserved. */ + /* 0x08 reserved. */ + DW_AT_ordering = 0x09, + /* 0x0a reserved. */ + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, /* Deprecated in DWARF4. */ + DW_AT_bit_size = 0x0d, + /* 0x0e reserved. */ + /* 0x0f reserved. */ + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + /* 0x14 reserved. */ + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + /* 0x1f reserved. */ + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + /* 0x23 reserved. */ + /* 0x24 reserved. */ + DW_AT_producer = 0x25, + /* 0x26 reserved. */ + DW_AT_prototyped = 0x27, + /* 0x28 reserved. */ + /* 0x29 reserved. */ + DW_AT_return_addr = 0x2a, + /* 0x2b reserved. */ + DW_AT_start_scope = 0x2c, + /* 0x2d reserved. */ + DW_AT_bit_stride = 0x2e, + DW_AT_upper_bound = 0x2f, + /* 0x30 reserved. */ + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, /* Deprecated in DWARF5. */ + DW_AT_namelist_item = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + DW_AT_allocated = 0x4e, + DW_AT_associated = 0x4f, + DW_AT_data_location = 0x50, + DW_AT_byte_stride = 0x51, + DW_AT_entry_pc = 0x52, + DW_AT_use_UTF8 = 0x53, + DW_AT_extension = 0x54, + DW_AT_ranges = 0x55, + DW_AT_trampoline = 0x56, + DW_AT_call_column = 0x57, + DW_AT_call_file = 0x58, + DW_AT_call_line = 0x59, + DW_AT_description = 0x5a, + DW_AT_binary_scale = 0x5b, + DW_AT_decimal_scale = 0x5c, + DW_AT_small = 0x5d, + DW_AT_decimal_sign = 0x5e, + DW_AT_digit_count = 0x5f, + DW_AT_picture_string = 0x60, + DW_AT_mutable = 0x61, + DW_AT_threads_scaled = 0x62, + DW_AT_explicit = 0x63, + DW_AT_object_pointer = 0x64, + DW_AT_endianity = 0x65, + DW_AT_elemental = 0x66, + DW_AT_pure = 0x67, + DW_AT_recursive = 0x68, + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + DW_AT_string_length_bit_size = 0x6f, + DW_AT_string_length_byte_size = 0x70, + DW_AT_rank = 0x71, + DW_AT_str_offsets_base = 0x72, + DW_AT_addr_base = 0x73, + DW_AT_rnglists_base = 0x74, + /* 0x75 reserved. */ + DW_AT_dwo_name = 0x76, + DW_AT_reference = 0x77, + DW_AT_rvalue_reference = 0x78, + DW_AT_macros = 0x79, + DW_AT_call_all_calls = 0x7a, + DW_AT_call_all_source_calls = 0x7b, + DW_AT_call_all_tail_calls = 0x7c, + DW_AT_call_return_pc = 0x7d, + DW_AT_call_value = 0x7e, + DW_AT_call_origin = 0x7f, + DW_AT_call_parameter = 0x80, + DW_AT_call_pc = 0x81, + DW_AT_call_tail_call = 0x82, + DW_AT_call_target = 0x83, + DW_AT_call_target_clobbered = 0x84, + DW_AT_call_data_location = 0x85, + DW_AT_call_data_value = 0x86, + DW_AT_noreturn = 0x87, + DW_AT_alignment = 0x88, + DW_AT_export_symbols = 0x89, + DW_AT_deleted = 0x8a, + DW_AT_defaulted = 0x8b, + DW_AT_loclists_base = 0x8c, + + DW_AT_lo_user = 0x2000, + + DW_AT_MIPS_fde = 0x2001, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, + DW_AT_MIPS_linkage_name = 0x2007, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + DW_AT_MIPS_stride_byte = 0x200c, + DW_AT_MIPS_stride_elem = 0x200d, + DW_AT_MIPS_ptr_dopetype = 0x200e, + DW_AT_MIPS_allocatable_dopetype = 0x200f, + DW_AT_MIPS_assumed_shape_dopetype = 0x2010, + DW_AT_MIPS_assumed_size = 0x2011, + + /* GNU extensions. */ + DW_AT_sf_names = 0x2101, + DW_AT_src_info = 0x2102, + DW_AT_mac_info = 0x2103, + DW_AT_src_coords = 0x2104, + DW_AT_body_begin = 0x2105, + DW_AT_body_end = 0x2106, + DW_AT_GNU_vector = 0x2107, + DW_AT_GNU_guarded_by = 0x2108, + DW_AT_GNU_pt_guarded_by = 0x2109, + DW_AT_GNU_guarded = 0x210a, + DW_AT_GNU_pt_guarded = 0x210b, + DW_AT_GNU_locks_excluded = 0x210c, + DW_AT_GNU_exclusive_locks_required = 0x210d, + DW_AT_GNU_shared_locks_required = 0x210e, + DW_AT_GNU_odr_signature = 0x210f, + DW_AT_GNU_template_name = 0x2110, + DW_AT_GNU_call_site_value = 0x2111, + DW_AT_GNU_call_site_data_value = 0x2112, + DW_AT_GNU_call_site_target = 0x2113, + DW_AT_GNU_call_site_target_clobbered = 0x2114, + DW_AT_GNU_tail_call = 0x2115, + DW_AT_GNU_all_tail_call_sites = 0x2116, + DW_AT_GNU_all_call_sites = 0x2117, + DW_AT_GNU_all_source_call_sites = 0x2118, + DW_AT_GNU_locviews = 0x2137, + DW_AT_GNU_entry_view = 0x2138, + DW_AT_GNU_macros = 0x2119, + DW_AT_GNU_deleted = 0x211a, + /* GNU Debug Fission extensions. */ + DW_AT_GNU_dwo_name = 0x2130, + DW_AT_GNU_dwo_id = 0x2131, + DW_AT_GNU_ranges_base = 0x2132, + DW_AT_GNU_addr_base = 0x2133, + DW_AT_GNU_pubnames = 0x2134, + DW_AT_GNU_pubtypes = 0x2135, + + /* https://gcc.gnu.org/wiki/DW_AT_GNU_numerator_denominator */ + DW_AT_GNU_numerator = 0x2303, + DW_AT_GNU_denominator = 0x2304, + /* https://gcc.gnu.org/wiki/DW_AT_GNU_bias */ + DW_AT_GNU_bias = 0x2305, + + DW_AT_hi_user = 0x3fff + }; + +/* Old unofficially attribute names. Should not be used. + Will not appear in known-dwarf.h */ + +/* DWARF1 array subscripts and element data types. */ +#define DW_AT_subscr_data 0x0a +/* DWARF1 enumeration literals. */ +#define DW_AT_element_list 0x0f +/* DWARF1 reference for variable to member structure, class or union. */ +#define DW_AT_member 0x14 + +/* DWARF form encodings. */ +enum + { + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16, + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_strx = 0x1a, + DW_FORM_addrx = 0x1b, + DW_FORM_ref_sup4 = 0x1c, + DW_FORM_strp_sup = 0x1d, + DW_FORM_data16 = 0x1e, + DW_FORM_line_strp = 0x1f, + DW_FORM_ref_sig8 = 0x20, + DW_FORM_implicit_const = 0x21, + DW_FORM_loclistx = 0x22, + DW_FORM_rnglistx = 0x23, + DW_FORM_ref_sup8 = 0x24, + DW_FORM_strx1 = 0x25, + DW_FORM_strx2 = 0x26, + DW_FORM_strx3 = 0x27, + DW_FORM_strx4 = 0x28, + DW_FORM_addrx1 = 0x29, + DW_FORM_addrx2 = 0x2a, + DW_FORM_addrx3 = 0x2b, + DW_FORM_addrx4 = 0x2c, + + /* GNU Debug Fission extensions. */ + DW_FORM_GNU_addr_index = 0x1f01, + DW_FORM_GNU_str_index = 0x1f02, + + DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo. */ + DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */ + }; + + +/* DWARF location operation encodings. */ +enum + { + DW_OP_addr = 0x03, /* Constant address. */ + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, /* Unsigned 1-byte constant. */ + DW_OP_const1s = 0x09, /* Signed 1-byte constant. */ + DW_OP_const2u = 0x0a, /* Unsigned 2-byte constant. */ + DW_OP_const2s = 0x0b, /* Signed 2-byte constant. */ + DW_OP_const4u = 0x0c, /* Unsigned 4-byte constant. */ + DW_OP_const4s = 0x0d, /* Signed 4-byte constant. */ + DW_OP_const8u = 0x0e, /* Unsigned 8-byte constant. */ + DW_OP_const8s = 0x0f, /* Signed 8-byte constant. */ + DW_OP_constu = 0x10, /* Unsigned LEB128 constant. */ + DW_OP_consts = 0x11, /* Signed LEB128 constant. */ + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, /* 1-byte stack index. */ + 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, /* Unsigned LEB128 addend. */ + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_bra = 0x28, /* Signed 2-byte constant. */ + 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_skip = 0x2f, /* Signed 2-byte constant. */ + DW_OP_lit0 = 0x30, /* Literal 0. */ + DW_OP_lit1 = 0x31, /* Literal 1. */ + DW_OP_lit2 = 0x32, /* Literal 2. */ + DW_OP_lit3 = 0x33, /* Literal 3. */ + DW_OP_lit4 = 0x34, /* Literal 4. */ + DW_OP_lit5 = 0x35, /* Literal 5. */ + DW_OP_lit6 = 0x36, /* Literal 6. */ + DW_OP_lit7 = 0x37, /* Literal 7. */ + DW_OP_lit8 = 0x38, /* Literal 8. */ + DW_OP_lit9 = 0x39, /* Literal 9. */ + DW_OP_lit10 = 0x3a, /* Literal 10. */ + DW_OP_lit11 = 0x3b, /* Literal 11. */ + DW_OP_lit12 = 0x3c, /* Literal 12. */ + DW_OP_lit13 = 0x3d, /* Literal 13. */ + DW_OP_lit14 = 0x3e, /* Literal 14. */ + DW_OP_lit15 = 0x3f, /* Literal 15. */ + DW_OP_lit16 = 0x40, /* Literal 16. */ + DW_OP_lit17 = 0x41, /* Literal 17. */ + DW_OP_lit18 = 0x42, /* Literal 18. */ + DW_OP_lit19 = 0x43, /* Literal 19. */ + DW_OP_lit20 = 0x44, /* Literal 20. */ + DW_OP_lit21 = 0x45, /* Literal 21. */ + DW_OP_lit22 = 0x46, /* Literal 22. */ + DW_OP_lit23 = 0x47, /* Literal 23. */ + DW_OP_lit24 = 0x48, /* Literal 24. */ + DW_OP_lit25 = 0x49, /* Literal 25. */ + DW_OP_lit26 = 0x4a, /* Literal 26. */ + DW_OP_lit27 = 0x4b, /* Literal 27. */ + DW_OP_lit28 = 0x4c, /* Literal 28. */ + DW_OP_lit29 = 0x4d, /* Literal 29. */ + DW_OP_lit30 = 0x4e, /* Literal 30. */ + DW_OP_lit31 = 0x4f, /* Literal 31. */ + DW_OP_reg0 = 0x50, /* Register 0. */ + DW_OP_reg1 = 0x51, /* Register 1. */ + DW_OP_reg2 = 0x52, /* Register 2. */ + DW_OP_reg3 = 0x53, /* Register 3. */ + DW_OP_reg4 = 0x54, /* Register 4. */ + DW_OP_reg5 = 0x55, /* Register 5. */ + DW_OP_reg6 = 0x56, /* Register 6. */ + DW_OP_reg7 = 0x57, /* Register 7. */ + DW_OP_reg8 = 0x58, /* Register 8. */ + DW_OP_reg9 = 0x59, /* Register 9. */ + DW_OP_reg10 = 0x5a, /* Register 10. */ + DW_OP_reg11 = 0x5b, /* Register 11. */ + DW_OP_reg12 = 0x5c, /* Register 12. */ + DW_OP_reg13 = 0x5d, /* Register 13. */ + DW_OP_reg14 = 0x5e, /* Register 14. */ + DW_OP_reg15 = 0x5f, /* Register 15. */ + DW_OP_reg16 = 0x60, /* Register 16. */ + DW_OP_reg17 = 0x61, /* Register 17. */ + DW_OP_reg18 = 0x62, /* Register 18. */ + DW_OP_reg19 = 0x63, /* Register 19. */ + DW_OP_reg20 = 0x64, /* Register 20. */ + DW_OP_reg21 = 0x65, /* Register 21. */ + DW_OP_reg22 = 0x66, /* Register 22. */ + DW_OP_reg23 = 0x67, /* Register 24. */ + DW_OP_reg24 = 0x68, /* Register 24. */ + DW_OP_reg25 = 0x69, /* Register 25. */ + DW_OP_reg26 = 0x6a, /* Register 26. */ + DW_OP_reg27 = 0x6b, /* Register 27. */ + DW_OP_reg28 = 0x6c, /* Register 28. */ + DW_OP_reg29 = 0x6d, /* Register 29. */ + DW_OP_reg30 = 0x6e, /* Register 30. */ + DW_OP_reg31 = 0x6f, /* Register 31. */ + DW_OP_breg0 = 0x70, /* Base register 0. */ + DW_OP_breg1 = 0x71, /* Base register 1. */ + DW_OP_breg2 = 0x72, /* Base register 2. */ + DW_OP_breg3 = 0x73, /* Base register 3. */ + DW_OP_breg4 = 0x74, /* Base register 4. */ + DW_OP_breg5 = 0x75, /* Base register 5. */ + DW_OP_breg6 = 0x76, /* Base register 6. */ + DW_OP_breg7 = 0x77, /* Base register 7. */ + DW_OP_breg8 = 0x78, /* Base register 8. */ + DW_OP_breg9 = 0x79, /* Base register 9. */ + DW_OP_breg10 = 0x7a, /* Base register 10. */ + DW_OP_breg11 = 0x7b, /* Base register 11. */ + DW_OP_breg12 = 0x7c, /* Base register 12. */ + DW_OP_breg13 = 0x7d, /* Base register 13. */ + DW_OP_breg14 = 0x7e, /* Base register 14. */ + DW_OP_breg15 = 0x7f, /* Base register 15. */ + DW_OP_breg16 = 0x80, /* Base register 16. */ + DW_OP_breg17 = 0x81, /* Base register 17. */ + DW_OP_breg18 = 0x82, /* Base register 18. */ + DW_OP_breg19 = 0x83, /* Base register 19. */ + DW_OP_breg20 = 0x84, /* Base register 20. */ + DW_OP_breg21 = 0x85, /* Base register 21. */ + DW_OP_breg22 = 0x86, /* Base register 22. */ + DW_OP_breg23 = 0x87, /* Base register 23. */ + DW_OP_breg24 = 0x88, /* Base register 24. */ + DW_OP_breg25 = 0x89, /* Base register 25. */ + DW_OP_breg26 = 0x8a, /* Base register 26. */ + DW_OP_breg27 = 0x8b, /* Base register 27. */ + DW_OP_breg28 = 0x8c, /* Base register 28. */ + DW_OP_breg29 = 0x8d, /* Base register 29. */ + DW_OP_breg30 = 0x8e, /* Base register 30. */ + DW_OP_breg31 = 0x8f, /* Base register 31. */ + DW_OP_regx = 0x90, /* Unsigned LEB128 register. */ + DW_OP_fbreg = 0x91, /* Signed LEB128 offset. */ + DW_OP_bregx = 0x92, /* ULEB128 register followed by SLEB128 off. */ + DW_OP_piece = 0x93, /* ULEB128 size of piece addressed. */ + DW_OP_deref_size = 0x94, /* 1-byte size of data retrieved. */ + DW_OP_xderef_size = 0x95, /* 1-byte size of data retrieved. */ + 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_form_tls_address = 0x9b,/* TLS offset to address in current thread */ + DW_OP_call_frame_cfa = 0x9c,/* CFA as determined by CFI. */ + DW_OP_bit_piece = 0x9d, /* ULEB128 size and ULEB128 offset in bits. */ + DW_OP_implicit_value = 0x9e, /* DW_FORM_block follows opcode. */ + DW_OP_stack_value = 0x9f, /* No operands, special like DW_OP_piece. */ + + DW_OP_implicit_pointer = 0xa0, + DW_OP_addrx = 0xa1, + DW_OP_constx = 0xa2, + DW_OP_entry_value = 0xa3, + DW_OP_const_type = 0xa4, + DW_OP_regval_type = 0xa5, + DW_OP_deref_type = 0xa6, + DW_OP_xderef_type = 0xa7, + DW_OP_convert = 0xa8, + DW_OP_reinterpret = 0xa9, + + /* GNU extensions. */ + DW_OP_GNU_push_tls_address = 0xe0, + DW_OP_GNU_uninit = 0xf0, + DW_OP_GNU_encoded_addr = 0xf1, + DW_OP_GNU_implicit_pointer = 0xf2, + DW_OP_GNU_entry_value = 0xf3, + DW_OP_GNU_const_type = 0xf4, + DW_OP_GNU_regval_type = 0xf5, + DW_OP_GNU_deref_type = 0xf6, + DW_OP_GNU_convert = 0xf7, + DW_OP_GNU_reinterpret = 0xf9, + DW_OP_GNU_parameter_ref = 0xfa, + + /* GNU Debug Fission extensions. */ + DW_OP_GNU_addr_index = 0xfb, + DW_OP_GNU_const_index = 0xfc, + + DW_OP_GNU_variable_value = 0xfd, + + DW_OP_lo_user = 0xe0, /* Implementation-defined range start. */ + DW_OP_hi_user = 0xff /* Implementation-defined range end. */ + }; + + +/* DWARF base type encodings. */ +enum + { + DW_ATE_void = 0x0, + DW_ATE_address = 0x1, + DW_ATE_boolean = 0x2, + DW_ATE_complex_float = 0x3, + DW_ATE_float = 0x4, + DW_ATE_signed = 0x5, + DW_ATE_signed_char = 0x6, + DW_ATE_unsigned = 0x7, + DW_ATE_unsigned_char = 0x8, + DW_ATE_imaginary_float = 0x9, + DW_ATE_packed_decimal = 0xa, + DW_ATE_numeric_string = 0xb, + DW_ATE_edited = 0xc, + DW_ATE_signed_fixed = 0xd, + DW_ATE_unsigned_fixed = 0xe, + DW_ATE_decimal_float = 0xf, + DW_ATE_UTF = 0x10, + DW_ATE_UCS = 0x11, + DW_ATE_ASCII = 0x12, + + DW_ATE_lo_user = 0x80, + DW_ATE_hi_user = 0xff + }; + + +/* DWARF decimal sign encodings. */ +enum + { + DW_DS_unsigned = 1, + DW_DS_leading_overpunch = 2, + DW_DS_trailing_overpunch = 3, + DW_DS_leading_separate = 4, + DW_DS_trailing_separate = 5, + }; + + +/* DWARF endianity encodings. */ +enum + { + DW_END_default = 0, + DW_END_big = 1, + DW_END_little = 2, + + DW_END_lo_user = 0x40, + DW_END_hi_user = 0xff + }; + + +/* DWARF accessibility encodings. */ +enum + { + DW_ACCESS_public = 1, + DW_ACCESS_protected = 2, + DW_ACCESS_private = 3 + }; + + +/* DWARF visibility encodings. */ +enum + { + DW_VIS_local = 1, + DW_VIS_exported = 2, + DW_VIS_qualified = 3 + }; + + +/* DWARF virtuality encodings. */ +enum + { + DW_VIRTUALITY_none = 0, + DW_VIRTUALITY_virtual = 1, + DW_VIRTUALITY_pure_virtual = 2 + }; + + +/* DWARF language encodings. */ +enum + { + DW_LANG_C89 = 0x0001, /* ISO C:1989 */ + DW_LANG_C = 0x0002, /* C */ + DW_LANG_Ada83 = 0x0003, /* ISO Ada:1983 */ + DW_LANG_C_plus_plus = 0x0004, /* ISO C++:1998 */ + DW_LANG_Cobol74 = 0x0005, /* ISO Cobol:1974 */ + DW_LANG_Cobol85 = 0x0006, /* ISO Cobol:1985 */ + DW_LANG_Fortran77 = 0x0007, /* ISO FORTRAN 77 */ + DW_LANG_Fortran90 = 0x0008, /* ISO Fortran 90 */ + DW_LANG_Pascal83 = 0x0009, /* ISO Pascal:1983 */ + DW_LANG_Modula2 = 0x000a, /* ISO Modula-2:1996 */ + DW_LANG_Java = 0x000b, /* Java */ + DW_LANG_C99 = 0x000c, /* ISO C:1999 */ + DW_LANG_Ada95 = 0x000d, /* ISO Ada:1995 */ + DW_LANG_Fortran95 = 0x000e, /* ISO Fortran 95 */ + DW_LANG_PLI = 0x000f, /* ISO PL/1:1976 */ + DW_LANG_ObjC = 0x0010, /* Objective-C */ + DW_LANG_ObjC_plus_plus = 0x0011, /* Objective-C++ */ + DW_LANG_UPC = 0x0012, /* Unified Parallel C */ + DW_LANG_D = 0x0013, /* D */ + DW_LANG_Python = 0x0014, /* Python */ + DW_LANG_OpenCL = 0x0015, /* OpenCL */ + DW_LANG_Go = 0x0016, /* Go */ + DW_LANG_Modula3 = 0x0017, /* Modula-3 */ + DW_LANG_Haskell = 0x0018, /* Haskell */ + DW_LANG_C_plus_plus_03 = 0x0019, /* ISO C++:2003 */ + DW_LANG_C_plus_plus_11 = 0x001a, /* ISO C++:2011 */ + DW_LANG_OCaml = 0x001b, /* OCaml */ + DW_LANG_Rust = 0x001c, /* Rust */ + DW_LANG_C11 = 0x001d, /* ISO C:2011 */ + DW_LANG_Swift = 0x001e, /* Swift */ + DW_LANG_Julia = 0x001f, /* Julia */ + DW_LANG_Dylan = 0x0020, /* Dylan */ + DW_LANG_C_plus_plus_14 = 0x0021, /* ISO C++:2014 */ + DW_LANG_Fortran03 = 0x0022, /* ISO/IEC 1539-1:2004 */ + DW_LANG_Fortran08 = 0x0023, /* ISO/IEC 1539-1:2010 */ + DW_LANG_RenderScript = 0x0024, /* RenderScript Kernal Language */ + DW_LANG_BLISS = 0x0025, /* BLISS */ + + DW_LANG_lo_user = 0x8000, + DW_LANG_Mips_Assembler = 0x8001, /* Assembler */ + DW_LANG_hi_user = 0xffff + }; + +/* Old (typo) '1' != 'I'. */ +#define DW_LANG_PL1 DW_LANG_PLI + +/* DWARF identifier case encodings. */ +enum + { + DW_ID_case_sensitive = 0, + DW_ID_up_case = 1, + DW_ID_down_case = 2, + DW_ID_case_insensitive = 3 + }; + + +/* DWARF calling conventions encodings. + Used as values of DW_AT_calling_convention for subroutines + (normal, program or nocall) or structures, unions and class types + (normal, reference or value). */ +enum + { + DW_CC_normal = 0x1, + DW_CC_program = 0x2, + DW_CC_nocall = 0x3, + DW_CC_pass_by_reference = 0x4, + DW_CC_pass_by_value = 0x5, + DW_CC_lo_user = 0x40, + DW_CC_hi_user = 0xff + }; + + +/* DWARF inline encodings. */ +enum + { + DW_INL_not_inlined = 0, + DW_INL_inlined = 1, + DW_INL_declared_not_inlined = 2, + DW_INL_declared_inlined = 3 + }; + + +/* DWARF ordering encodings. */ +enum + { + DW_ORD_row_major = 0, + DW_ORD_col_major = 1 + }; + + +/* DWARF discriminant descriptor encodings. */ +enum + { + DW_DSC_label = 0, + DW_DSC_range = 1 + }; + +/* DWARF defaulted member function encodings. */ +enum + { + DW_DEFAULTED_no = 0, + DW_DEFAULTED_in_class = 1, + DW_DEFAULTED_out_of_class = 2 + }; + +/* DWARF line content descriptions. */ +enum + { + DW_LNCT_path = 0x1, + DW_LNCT_directory_index = 0x2, + DW_LNCT_timestamp = 0x3, + DW_LNCT_size = 0x4, + DW_LNCT_MD5 = 0x5, + DW_LNCT_lo_user = 0x2000, + DW_LNCT_hi_user = 0x3fff + }; + +/* DWARF standard opcode encodings. */ +enum + { + DW_LNS_copy = 1, + DW_LNS_advance_pc = 2, + DW_LNS_advance_line = 3, + DW_LNS_set_file = 4, + DW_LNS_set_column = 5, + DW_LNS_negate_stmt = 6, + DW_LNS_set_basic_block = 7, + DW_LNS_const_add_pc = 8, + DW_LNS_fixed_advance_pc = 9, + DW_LNS_set_prologue_end = 10, + DW_LNS_set_epilogue_begin = 11, + DW_LNS_set_isa = 12 + }; + + +/* DWARF extended opcode encodings. */ +enum + { + DW_LNE_end_sequence = 1, + DW_LNE_set_address = 2, + DW_LNE_define_file = 3, + DW_LNE_set_discriminator = 4, + + DW_LNE_lo_user = 128, + DW_LNE_hi_user = 255 + }; + + +/* DWARF macinfo type encodings. */ +enum + { + DW_MACINFO_define = 1, + DW_MACINFO_undef = 2, + DW_MACINFO_start_file = 3, + DW_MACINFO_end_file = 4, + DW_MACINFO_vendor_ext = 255 + }; + + +/* DWARF debug_macro type encodings. */ +enum + { + DW_MACRO_define = 0x01, + DW_MACRO_undef = 0x02, + DW_MACRO_start_file = 0x03, + DW_MACRO_end_file = 0x04, + DW_MACRO_define_strp = 0x05, + DW_MACRO_undef_strp = 0x06, + DW_MACRO_import = 0x07, + DW_MACRO_define_sup = 0x08, + DW_MACRO_undef_sup = 0x09, + DW_MACRO_import_sup = 0x0a, + DW_MACRO_define_strx = 0x0b, + DW_MACRO_undef_strx = 0x0c, + DW_MACRO_lo_user = 0xe0, + DW_MACRO_hi_user = 0xff + }; + +/* Old GNU extension names for DWARF5 debug_macro type encodings. + There are no equivalents for the supplementary object file (sup) + and indirect string references (strx). */ +#define DW_MACRO_GNU_define DW_MACRO_define +#define DW_MACRO_GNU_undef DW_MACRO_undef +#define DW_MACRO_GNU_start_file DW_MACRO_start_file +#define DW_MACRO_GNU_end_file DW_MACRO_end_file +#define DW_MACRO_GNU_define_indirect DW_MACRO_define_strp +#define DW_MACRO_GNU_undef_indirect DW_MACRO_undef_strp +#define DW_MACRO_GNU_transparent_include DW_MACRO_import +#define DW_MACRO_GNU_lo_user DW_MACRO_lo_user +#define DW_MACRO_GNU_hi_user DW_MACRO_hi_user + + +/* Range list entry encoding. */ +enum + { + DW_RLE_end_of_list = 0x0, + DW_RLE_base_addressx = 0x1, + DW_RLE_startx_endx = 0x2, + DW_RLE_startx_length = 0x3, + DW_RLE_offset_pair = 0x4, + DW_RLE_base_address = 0x5, + DW_RLE_start_end = 0x6, + DW_RLE_start_length = 0x7 + }; + + +/* Location list entry encoding. */ +enum + { + DW_LLE_end_of_list = 0x0, + DW_LLE_base_addressx = 0x1, + DW_LLE_startx_endx = 0x2, + DW_LLE_startx_length = 0x3, + DW_LLE_offset_pair = 0x4, + DW_LLE_default_location = 0x5, + DW_LLE_base_address = 0x6, + DW_LLE_start_end = 0x7, + DW_LLE_start_length = 0x8 + }; + + +/* GNU DebugFission list entry encodings (.debug_loc.dwo). */ +enum + { + DW_LLE_GNU_end_of_list_entry = 0x0, + DW_LLE_GNU_base_address_selection_entry = 0x1, + DW_LLE_GNU_start_end_entry = 0x2, + DW_LLE_GNU_start_length_entry = 0x3 + }; + + +/* DWARF call frame instruction encodings. */ +enum + { + DW_CFA_advance_loc = 0x40, + DW_CFA_offset = 0x80, + DW_CFA_restore = 0xc0, + DW_CFA_extended = 0, + + 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_offset = 0x14, + DW_CFA_val_offset_sf = 0x15, + DW_CFA_val_expression = 0x16, + + DW_CFA_low_user = 0x1c, + DW_CFA_MIPS_advance_loc8 = 0x1d, + DW_CFA_GNU_window_save = 0x2d, + DW_CFA_AARCH64_negate_ra_state = 0x2d, + DW_CFA_GNU_args_size = 0x2e, + DW_CFA_GNU_negative_offset_extended = 0x2f, + DW_CFA_high_user = 0x3f + }; + +/* ID indicating CIE as opposed to FDE in .debug_frame. */ +enum + { + DW_CIE_ID_32 = 0xffffffffU, /* In 32-bit format CIE header. */ + DW_CIE_ID_64 = 0xffffffffffffffffULL /* In 64-bit format CIE header. */ + }; + + +/* Information for GNU unwind information. */ +enum + { + DW_EH_PE_absptr = 0x00, + DW_EH_PE_omit = 0xff, + + /* FDE data encoding. */ + DW_EH_PE_uleb128 = 0x01, + DW_EH_PE_udata2 = 0x02, + DW_EH_PE_udata4 = 0x03, + DW_EH_PE_udata8 = 0x04, + DW_EH_PE_sleb128 = 0x09, + DW_EH_PE_sdata2 = 0x0a, + DW_EH_PE_sdata4 = 0x0b, + DW_EH_PE_sdata8 = 0x0c, + DW_EH_PE_signed = 0x08, + + /* FDE flags. */ + DW_EH_PE_pcrel = 0x10, + DW_EH_PE_textrel = 0x20, + DW_EH_PE_datarel = 0x30, + DW_EH_PE_funcrel = 0x40, + DW_EH_PE_aligned = 0x50, + + DW_EH_PE_indirect = 0x80 + }; + + +/* DWARF XXX. */ +#define DW_ADDR_none 0 + +/* Section 7.2.2 of the DWARF3 specification defines a range of escape + codes that can appear in the length field of certain DWARF structures. + + These defines enumerate the minimum and maximum values of this range. + Currently only the maximum value is used (to indicate that 64-bit + values are going to be used in the dwarf data that accompanies the + structure). The other values are reserved. + + Note: There is a typo in DWARF3 spec (published Dec 20, 2005). In + sections 7.4, 7.5.1, 7.19, 7.20 the minimum escape code is referred to + as 0xffffff00 whereas in fact it should be 0xfffffff0. */ +#define DWARF3_LENGTH_MIN_ESCAPE_CODE 0xfffffff0u +#define DWARF3_LENGTH_MAX_ESCAPE_CODE 0xffffffffu +#define DWARF3_LENGTH_64_BIT DWARF3_LENGTH_MAX_ESCAPE_CODE + +#endif /* dwarf.h */ diff --git a/libdw/dwarf_abbrev_hash.c b/libdw/dwarf_abbrev_hash.c new file mode 100644 index 00000000..c2548140 --- /dev/null +++ b/libdw/dwarf_abbrev_hash.c @@ -0,0 +1,45 @@ +/* Implementation of hash table for DWARF .debug_abbrev section content. + Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "dwarf_sig8_hash.h" +#define NO_UNDEF +#include "libdwP.h" + +#define next_prime __libdwarf_next_prime +extern size_t next_prime (size_t) attribute_hidden; + +#include + +#undef next_prime +#define next_prime attribute_hidden __libdwarf_next_prime +#include "../lib/next_prime.c" diff --git a/libdw/dwarf_abbrev_hash.h b/libdw/dwarf_abbrev_hash.h new file mode 100644 index 00000000..a368c598 --- /dev/null +++ b/libdw/dwarf_abbrev_hash.h @@ -0,0 +1,38 @@ +/* Hash table for DWARF .debug_abbrev section content. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _DWARF_ABBREV_HASH_H +#define _DWARF_ABBREV_HASH_H 1 + +#define NAME Dwarf_Abbrev_Hash +#define TYPE Dwarf_Abbrev * + +#include + +#endif /* dwarf_abbrev_hash.h */ diff --git a/libdw/dwarf_abbrevhaschildren.c b/libdw/dwarf_abbrevhaschildren.c new file mode 100644 index 00000000..0f17c7ed --- /dev/null +++ b/libdw/dwarf_abbrevhaschildren.c @@ -0,0 +1,43 @@ +/* Return true if abbreviation is children flag set. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + + +int +dwarf_abbrevhaschildren (Dwarf_Abbrev *abbrev) +{ + return abbrev == NULL ? -1 : abbrev->has_children; +} diff --git a/libdw/dwarf_addrdie.c b/libdw/dwarf_addrdie.c new file mode 100644 index 00000000..3a08ab75 --- /dev/null +++ b/libdw/dwarf_addrdie.c @@ -0,0 +1,51 @@ +/* Return CU DIE containing given address. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +Dwarf_Die * +dwarf_addrdie (Dwarf *dbg, Dwarf_Addr addr, Dwarf_Die *result) +{ + Dwarf_Aranges *aranges; + size_t naranges; + Dwarf_Off off; + + if (INTUSE(dwarf_getaranges) (dbg, &aranges, &naranges) != 0 + || INTUSE(dwarf_getarangeinfo) (INTUSE(dwarf_getarange_addr) (aranges, + addr), + NULL, NULL, &off) != 0) + return NULL; + + return INTUSE(dwarf_offdie) (dbg, off, result); +} diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c new file mode 100644 index 00000000..75105e4d --- /dev/null +++ b/libdw/dwarf_aggregate_size.c @@ -0,0 +1,224 @@ +/* Compute size of an aggregate type from DWARF. + Copyright (C) 2010, 2014, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +static Dwarf_Die * +get_type (Dwarf_Die *die, Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem) +{ + Dwarf_Die *type = INTUSE(dwarf_formref_die) + (INTUSE(dwarf_attr_integrate) (die, DW_AT_type, attr_mem), type_mem); + + if (INTUSE(dwarf_peel_type) (type, type) != 0) + return NULL; + + return type; +} + +static int aggregate_size (Dwarf_Die *die, Dwarf_Word *size, + Dwarf_Die *type_mem, int depth); + +static int +array_size (Dwarf_Die *die, Dwarf_Word *size, + Dwarf_Attribute *attr_mem, int depth) +{ + Dwarf_Word eltsize; + Dwarf_Die type_mem, aggregate_type_mem; + if (aggregate_size (get_type (die, attr_mem, &type_mem), &eltsize, + &aggregate_type_mem, depth) != 0) + return -1; + + /* An array can have DW_TAG_subrange_type or DW_TAG_enumeration_type + children instead that give the size of each dimension. */ + + Dwarf_Die child; + if (INTUSE(dwarf_child) (die, &child) != 0) + return -1; + + bool any = false; + Dwarf_Word count_total = 1; + do + { + Dwarf_Word count; + switch (INTUSE(dwarf_tag) (&child)) + { + case DW_TAG_subrange_type: + /* This has either DW_AT_count or DW_AT_upper_bound. */ + if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_count, + attr_mem) != NULL) + { + if (INTUSE(dwarf_formudata) (attr_mem, &count) != 0) + return -1; + } + else + { + Dwarf_Sword upper; + Dwarf_Sword lower; + if (INTUSE(dwarf_formsdata) (INTUSE(dwarf_attr_integrate) + (&child, DW_AT_upper_bound, + attr_mem), &upper) != 0) + return -1; + + /* Having DW_AT_lower_bound is optional. */ + if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_lower_bound, + attr_mem) != NULL) + { + if (INTUSE(dwarf_formsdata) (attr_mem, &lower) != 0) + return -1; + } + else + { + Dwarf_Die cu = CUDIE (die->cu); + int lang = INTUSE(dwarf_srclang) (&cu); + if (lang == -1 + || INTUSE(dwarf_default_lower_bound) (lang, &lower) != 0) + return -1; + } + if (unlikely (lower > upper)) + return -1; + count = upper - lower + 1; + } + break; + + case DW_TAG_enumeration_type: + /* We have to find the DW_TAG_enumerator child with the + highest value to know the array's element count. */ + count = 0; + Dwarf_Die enum_child; + int has_children = INTUSE(dwarf_child) (die, &enum_child); + if (has_children < 0) + return -1; + if (has_children > 0) + do + if (INTUSE(dwarf_tag) (&enum_child) == DW_TAG_enumerator) + { + Dwarf_Word value; + if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (&enum_child, DW_AT_const_value, + attr_mem), &value) != 0) + return -1; + if (value >= count) + count = value + 1; + } + while (INTUSE(dwarf_siblingof) (&enum_child, &enum_child) > 0); + break; + + default: + continue; + } + + count_total *= count; + + any = true; + } + while (INTUSE(dwarf_siblingof) (&child, &child) == 0); + + if (!any) + return -1; + + /* This is a subrange_type or enumeration_type and we've set COUNT. + Now determine the stride for this array. */ + Dwarf_Word stride = eltsize; + if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_stride, + attr_mem) != NULL) + { + if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0) + return -1; + } + else if (INTUSE(dwarf_attr_integrate) (die, DW_AT_bit_stride, + attr_mem) != NULL) + { + if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0) + return -1; + if (stride % 8) /* XXX maybe compute in bits? */ + return -1; + stride /= 8; + } + + *size = count_total * stride; + return 0; +} + +static int +aggregate_size (Dwarf_Die *die, Dwarf_Word *size, + Dwarf_Die *type_mem, int depth) +{ + Dwarf_Attribute attr_mem; + +/* Arrays of arrays of subrange types of arrays... Don't recurse too deep. */ +#define MAX_DEPTH 256 + if (die == NULL || depth++ >= MAX_DEPTH) + return -1; + + if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_size, &attr_mem) != NULL) + return INTUSE(dwarf_formudata) (&attr_mem, size); + + switch (INTUSE(dwarf_tag) (die)) + { + case DW_TAG_subrange_type: + { + Dwarf_Die aggregate_type_mem; + return aggregate_size (get_type (die, &attr_mem, type_mem), + size, &aggregate_type_mem, depth); + } + + case DW_TAG_array_type: + return array_size (die, size, &attr_mem, depth); + + /* Assume references and pointers have pointer size if not given an + explicit DW_AT_byte_size. */ + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + *size = die->cu->address_size; + return 0; + } + + /* Most types must give their size directly. */ + return -1; +} + +int +dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size) +{ + Dwarf_Die die_mem, type_mem; + + if (INTUSE (dwarf_peel_type) (die, &die_mem) != 0) + return -1; + + return aggregate_size (&die_mem, size, &type_mem, 0); +} +INTDEF (dwarf_aggregate_size) +OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144) +NEW_VERSION (dwarf_aggregate_size, ELFUTILS_0.161) diff --git a/libdw/dwarf_arrayorder.c b/libdw/dwarf_arrayorder.c new file mode 100644 index 00000000..da64f992 --- /dev/null +++ b/libdw/dwarf_arrayorder.c @@ -0,0 +1,49 @@ +/* Return array order attribute of DIE. + Copyright (C) 2003, 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_arrayorder (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, DW_AT_ordering, &attr_mem), + &value) == 0 ? (int) value : -1; +} +OLD_VERSION (dwarf_arrayorder, ELFUTILS_0.122) +NEW_VERSION (dwarf_arrayorder, ELFUTILS_0.143) diff --git a/libdw/dwarf_attr.c b/libdw/dwarf_attr.c new file mode 100644 index 00000000..db8acfe5 --- /dev/null +++ b/libdw/dwarf_attr.c @@ -0,0 +1,52 @@ +/* Return specific DWARF attribute of a DIE. + Copyright (C) 2003, 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Attribute * +dwarf_attr (Dwarf_Die *die, unsigned int search_name, Dwarf_Attribute *result) +{ + if (die == NULL) + return NULL; + + /* Search for the attribute with the given name. */ + result->valp = __libdw_find_attr (die, search_name, &result->code, + &result->form); + /* Always fill in the CU information. */ + result->cu = die->cu; + + return result->valp != NULL && result->code == search_name ? result : NULL; +} +INTDEF(dwarf_attr) diff --git a/libdw/dwarf_attr_integrate.c b/libdw/dwarf_attr_integrate.c new file mode 100644 index 00000000..fc068638 --- /dev/null +++ b/libdw/dwarf_attr_integrate.c @@ -0,0 +1,73 @@ +/* Return specific DWARF attribute of a DIE, integrating indirections. + Copyright (C) 2005, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + +Dwarf_Attribute * +dwarf_attr_integrate (Dwarf_Die *die, unsigned int search_name, + Dwarf_Attribute *result) +{ + Dwarf_Die die_mem; + int chain = 16; /* Largest DIE ref chain we will follow. */ + do + { + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, search_name, result); + if (attr != NULL) + return attr; + + attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin, result); + if (attr == NULL) + attr = INTUSE(dwarf_attr) (die, DW_AT_specification, result); + if (attr == NULL) + break; + + die = INTUSE(dwarf_formref_die) (attr, &die_mem); + } + while (die != NULL && chain-- != 0); + + /* Not NULL if it didn't have abstract_origin and specification + attributes. If it is a split CU then see if the skeleton + has it. */ + if (die != NULL && is_cudie (die) + && die->cu->unit_type == DW_UT_split_compile) + { + Dwarf_CU *skel_cu = __libdw_find_split_unit (die->cu); + if (skel_cu != NULL) + { + Dwarf_Die skel_die = CUDIE (skel_cu); + return INTUSE(dwarf_attr) (&skel_die, search_name, result); + } + } + return NULL; +} +INTDEF (dwarf_attr_integrate) diff --git a/libdw/dwarf_begin.c b/libdw/dwarf_begin.c new file mode 100644 index 00000000..19d16e5c --- /dev/null +++ b/libdw/dwarf_begin.c @@ -0,0 +1,99 @@ +/* Create descriptor from file descriptor for processing file. + Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include + + +Dwarf * +dwarf_begin (int fd, Dwarf_Cmd cmd) +{ + Elf *elf; + Elf_Cmd elfcmd; + Dwarf *result = NULL; + + switch (cmd) + { + case DWARF_C_READ: + elfcmd = ELF_C_READ_MMAP; + break; + case DWARF_C_WRITE: + elfcmd = ELF_C_WRITE; + break; + case DWARF_C_RDWR: + elfcmd = ELF_C_RDWR; + break; + default: + /* No valid mode. */ + __libdw_seterrno (DWARF_E_INVALID_CMD); + return NULL; + } + + /* We have to call `elf_version' here since the user might have not + done it or initialized libelf with a different version. This + would break libdwarf since we are using the ELF data structures + in a certain way. */ + elf_version (EV_CURRENT); + + /* Get an ELF descriptor. */ + elf = elf_begin (fd, elfcmd, NULL); + if (elf == NULL) + { + /* Test why the `elf_begin" call failed. */ + struct stat st; + + if (fstat (fd, &st) == 0 && ! S_ISREG (st.st_mode)) + __libdw_seterrno (DWARF_E_NO_REGFILE); + else if (errno == EBADF) + __libdw_seterrno (DWARF_E_INVALID_FILE); + else + __libdw_seterrno (DWARF_E_IO_ERROR); + } + else + { + /* Do the real work now that we have an ELF descriptor. */ + result = INTUSE(dwarf_begin_elf) (elf, cmd, NULL); + + /* If this failed, free the resources. */ + if (result == NULL) + elf_end (elf); + else + result->free_elf = true; + } + + return result; +} +INTDEF(dwarf_begin) diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c new file mode 100644 index 00000000..9e944b86 --- /dev/null +++ b/libdw/dwarf_begin_elf.c @@ -0,0 +1,484 @@ +/* Create descriptor from ELF descriptor for processing file. + Copyright (C) 2002-2011, 2014, 2015, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libelfP.h" +#include "libdwP.h" + + +/* Section names. (Note .debug_str_offsets is the largest 19 chars.) */ +static const char dwarf_scnnames[IDX_last][19] = +{ + [IDX_debug_info] = ".debug_info", + [IDX_debug_types] = ".debug_types", + [IDX_debug_abbrev] = ".debug_abbrev", + [IDX_debug_addr] = ".debug_addr", + [IDX_debug_aranges] = ".debug_aranges", + [IDX_debug_line] = ".debug_line", + [IDX_debug_line_str] = ".debug_line_str", + [IDX_debug_frame] = ".debug_frame", + [IDX_debug_loc] = ".debug_loc", + [IDX_debug_loclists] = ".debug_loclists", + [IDX_debug_pubnames] = ".debug_pubnames", + [IDX_debug_str] = ".debug_str", + [IDX_debug_str_offsets] = ".debug_str_offsets", + [IDX_debug_macinfo] = ".debug_macinfo", + [IDX_debug_macro] = ".debug_macro", + [IDX_debug_ranges] = ".debug_ranges", + [IDX_debug_rnglists] = ".debug_rnglists", + [IDX_gnu_debugaltlink] = ".gnu_debugaltlink" +}; +#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0])) + +static Dwarf * +check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + /* Get the section header data. */ + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + /* We may read /proc/PID/mem with only program headers mapped and section + headers out of the mapped pages. */ + goto err; + + /* Ignore any SHT_NOBITS sections. Debugging sections should not + have been stripped, but in case of a corrupt file we won't try + to look at the missing data. */ + if (unlikely (shdr->sh_type == SHT_NOBITS)) + return result; + + /* Make sure the section is part of a section group only iff we + really need it. If we are looking for the global (= non-section + group debug info) we have to ignore all the info in section + groups. If we are looking into a section group we cannot look at + a section which isn't part of the section group. */ + if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0) + /* Ignore the section. */ + return result; + + + /* We recognize the DWARF section by their names. This is not very + safe and stable but the best we can do. */ + const char *scnname = elf_strptr (result->elf, shstrndx, + shdr->sh_name); + if (scnname == NULL) + { + /* The section name must be valid. Otherwise is the ELF file + invalid. */ + err: + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + /* Recognize the various sections. Most names start with .debug_. */ + size_t cnt; + bool gnu_compressed = false; + for (cnt = 0; cnt < ndwarf_scnnames; ++cnt) + { + size_t dbglen = strlen (dwarf_scnnames[cnt]); + size_t scnlen = strlen (scnname); + if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0 + && (dbglen == scnlen + || (scnlen == dbglen + 4 + && strstr (scnname, ".dwo") == scnname + dbglen))) + break; + else if (scnname[0] == '.' && scnname[1] == 'z' + && (strncmp (&scnname[2], &dwarf_scnnames[cnt][1], + dbglen - 1) == 0 + && (scnlen == dbglen + 1 + || (scnlen == dbglen + 5 + && strstr (scnname, + ".dwo") == scnname + dbglen + 1)))) + { + gnu_compressed = true; + break; + } + else if (scnlen > 14 /* .gnu.debuglto_ prefix. */ + && startswith (scnname, ".gnu.debuglto_") + && strcmp (&scnname[14], dwarf_scnnames[cnt]) == 0) + break; + } + + if (cnt >= ndwarf_scnnames) + /* Not a debug section; ignore it. */ + return result; + + if (unlikely (result->sectiondata[cnt] != NULL)) + /* A section appears twice. That's bad. We ignore the section. */ + return result; + + /* We cannot know whether or not a GNU compressed section has already + been uncompressed or not, so ignore any errors. */ + if (gnu_compressed) + elf_compress_gnu (scn, 0, 0); + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (elf_compress (scn, 0, 0) < 0) + { + /* It would be nice if we could fail with a specific error. + But we don't know if this was an essential section or not. + So just continue for now. See also valid_p(). */ + return result; + } + } + + /* Get the section data. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + goto err; + + if (data->d_buf == NULL || data->d_size == 0) + /* No data actually available, ignore it. */ + return result; + + /* We can now read the section data into results. */ + result->sectiondata[cnt] = data; + + return result; +} + + +/* Helper function to set debugdir field. We want to cache the dir + where we found this Dwarf ELF file to locate alt and dwo files. */ +char * +__libdw_debugdir (int fd) +{ + /* strlen ("/proc/self/fd/") = 14 + strlen () = 10 + 1 = 25. */ + char devfdpath[25]; + sprintf (devfdpath, "/proc/self/fd/%u", fd); + char *fdpath = realpath (devfdpath, NULL); + char *fddir; + if (fdpath != NULL && fdpath[0] == '/' + && (fddir = strrchr (fdpath, '/')) != NULL) + { + *++fddir = '\0'; + return fdpath; + } + return NULL; +} + + +/* Check whether all the necessary DWARF information is available. */ +static Dwarf * +valid_p (Dwarf *result) +{ + /* We looked at all the sections. Now determine whether all the + sections with debugging information we need are there. + + Require at least one section that can be read "standalone". */ + if (likely (result != NULL) + && unlikely (result->sectiondata[IDX_debug_info] == NULL + && result->sectiondata[IDX_debug_line] == NULL + && result->sectiondata[IDX_debug_frame] == NULL)) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_NO_DWARF); + free (result); + result = NULL; + } + + /* For dwarf_location_attr () we need a "fake" CU to indicate + where the "fake" attribute data comes from. This is a block + inside the .debug_loc or .debug_loclists section. */ + if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL) + { + result->fake_loc_cu = (Dwarf_CU *) malloc (sizeof (Dwarf_CU)); + if (unlikely (result->fake_loc_cu == NULL)) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_NOMEM); + free (result); + result = NULL; + } + else + { + result->fake_loc_cu->sec_idx = IDX_debug_loc; + result->fake_loc_cu->dbg = result; + result->fake_loc_cu->startp + = result->sectiondata[IDX_debug_loc]->d_buf; + result->fake_loc_cu->endp + = (result->sectiondata[IDX_debug_loc]->d_buf + + result->sectiondata[IDX_debug_loc]->d_size); + result->fake_loc_cu->locs = NULL; + result->fake_loc_cu->address_size = 0; + result->fake_loc_cu->version = 0; + result->fake_loc_cu->split = NULL; + } + } + + if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL) + { + result->fake_loclists_cu = (Dwarf_CU *) malloc (sizeof (Dwarf_CU)); + if (unlikely (result->fake_loclists_cu == NULL)) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_NOMEM); + free (result->fake_loc_cu); + free (result); + result = NULL; + } + else + { + result->fake_loclists_cu->sec_idx = IDX_debug_loclists; + result->fake_loclists_cu->dbg = result; + result->fake_loclists_cu->startp + = result->sectiondata[IDX_debug_loclists]->d_buf; + result->fake_loclists_cu->endp + = (result->sectiondata[IDX_debug_loclists]->d_buf + + result->sectiondata[IDX_debug_loclists]->d_size); + result->fake_loclists_cu->locs = NULL; + result->fake_loclists_cu->address_size = 0; + result->fake_loclists_cu->version = 0; + result->fake_loclists_cu->split = NULL; + } + } + + /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index + the dwarf_location_attr () will need a "fake" address CU to + indicate where the attribute data comes from. This is a just + inside the .debug_addr section, if it exists. */ + if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL) + { + result->fake_addr_cu = (Dwarf_CU *) malloc (sizeof (Dwarf_CU)); + if (unlikely (result->fake_addr_cu == NULL)) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_NOMEM); + free (result->fake_loc_cu); + free (result->fake_loclists_cu); + free (result); + result = NULL; + } + else + { + result->fake_addr_cu->sec_idx = IDX_debug_addr; + result->fake_addr_cu->dbg = result; + result->fake_addr_cu->startp + = result->sectiondata[IDX_debug_addr]->d_buf; + result->fake_addr_cu->endp + = (result->sectiondata[IDX_debug_addr]->d_buf + + result->sectiondata[IDX_debug_addr]->d_size); + result->fake_addr_cu->locs = NULL; + result->fake_addr_cu->address_size = 0; + result->fake_addr_cu->version = 0; + result->fake_addr_cu->split = NULL; + } + } + + if (result != NULL) + result->debugdir = __libdw_debugdir (result->elf->fildes); + + return result; +} + + +static Dwarf * +global_read (Dwarf *result, Elf *elf, size_t shstrndx) +{ + Elf_Scn *scn = NULL; + + while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL) + result = check_section (result, shstrndx, scn, false); + + return valid_p (result); +} + + +static Dwarf * +scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem); + if (shdr == NULL) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0 + && elf_compress (scngrp, 0, 0) < 0) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_COMPRESSED_ERROR); + free (result); + return NULL; + } + + /* SCNGRP is the section descriptor for a section group which might + contain debug sections. */ + Elf_Data *data = elf_getdata (scngrp, NULL); + if (data == NULL) + { + /* We cannot read the section content. Fail! */ + Dwarf_Sig8_Hash_free (&result->sig8_hash); + free (result); + return NULL; + } + + /* The content of the section is a number of 32-bit words which + represent section indices. The first word is a flag word. */ + Elf32_Word *scnidx = (Elf32_Word *) data->d_buf; + size_t cnt; + for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt) + { + Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]); + if (scn == NULL) + { + /* A section group refers to a non-existing section. Should + never happen. */ + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + result = check_section (result, shstrndx, scn, true); + if (result == NULL) + break; + } + + return valid_p (result); +} + + +Dwarf * +dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) +{ + GElf_Ehdr *ehdr; + GElf_Ehdr ehdr_mem; + + /* Get the ELF header of the file. We need various pieces of + information from it. */ + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + if (elf_kind (elf) != ELF_K_ELF) + __libdw_seterrno (DWARF_E_NOELF); + else + __libdw_seterrno (DWARF_E_GETEHDR_ERROR); + + return NULL; + } + + + /* Default memory allocation size. */ + size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *); + assert (sizeof (struct Dwarf) < mem_default_size); + + /* Allocate the data structure. */ + Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf)); + if (unlikely (result == NULL) + || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0)) + { + free (result); + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + /* Fill in some values. */ + if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) + || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) + result->other_byte_order = true; + + result->elf = elf; + result->alt_fd = -1; + + /* Initialize the memory handling. Initial blocks are allocated on first + actual allocation. */ + result->mem_default_size = mem_default_size; + result->oom_handler = __libdw_oom; + if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0) + { + free (result); + __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */ + return NULL; + } + result->mem_stacks = 0; + result->mem_tails = NULL; + + if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR) + { + /* All sections are recognized by name, so pass the section header + string index along to easily get the section names. */ + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + /* If the caller provides a section group we get the DWARF + sections only from this section group. Otherwise we search + for the first section with the required name. Further + sections with the name are ignored. The DWARF specification + does not really say this is allowed. */ + if (scngrp == NULL) + return global_read (result, elf, shstrndx); + else + return scngrp_read (result, elf, shstrndx, scngrp); + } + else if (cmd == DWARF_C_WRITE) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_UNIMPL); + free (result); + return NULL; + } + + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_CMD); + free (result); + return NULL; +} +INTDEF(dwarf_begin_elf) diff --git a/libdw/dwarf_bitoffset.c b/libdw/dwarf_bitoffset.c new file mode 100644 index 00000000..c1a3a343 --- /dev/null +++ b/libdw/dwarf_bitoffset.c @@ -0,0 +1,49 @@ +/* Return bit offset attribute of DIE. + Copyright (C) 2003, 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_bitoffset (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, DW_AT_bit_offset, &attr_mem), + &value) == 0 ? (int) value : -1; +} +OLD_VERSION (dwarf_bitoffset, ELFUTILS_0.122) +NEW_VERSION (dwarf_bitoffset, ELFUTILS_0.143) diff --git a/libdw/dwarf_bitsize.c b/libdw/dwarf_bitsize.c new file mode 100644 index 00000000..0ed9b710 --- /dev/null +++ b/libdw/dwarf_bitsize.c @@ -0,0 +1,49 @@ +/* Return bit size attribute of DIE. + Copyright (C) 2003, 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_bitsize (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, DW_AT_bit_size, &attr_mem), + &value) == 0 ? (int) value : -1; +} +OLD_VERSION (dwarf_bitsize, ELFUTILS_0.122) +NEW_VERSION (dwarf_bitsize, ELFUTILS_0.143) diff --git a/libdw/dwarf_bytesize.c b/libdw/dwarf_bytesize.c new file mode 100644 index 00000000..116cd321 --- /dev/null +++ b/libdw/dwarf_bytesize.c @@ -0,0 +1,49 @@ +/* Return byte size attribute of DIE. + Copyright (C) 2003, 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_bytesize (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, DW_AT_byte_size, &attr_mem), + &value) == 0 ? (int) value : -1; +} +OLD_VERSION (dwarf_bytesize, ELFUTILS_0.122) +NEW_VERSION (dwarf_bytesize, ELFUTILS_0.143) diff --git a/libdw/dwarf_cfi_addrframe.c b/libdw/dwarf_cfi_addrframe.c new file mode 100644 index 00000000..44240279 --- /dev/null +++ b/libdw/dwarf_cfi_addrframe.c @@ -0,0 +1,54 @@ +/* Compute frame state at PC. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" + +int +dwarf_cfi_addrframe (Dwarf_CFI *cache, Dwarf_Addr address, Dwarf_Frame **frame) +{ + /* Maybe there was a previous error. */ + if (cache == NULL) + return -1; + + struct dwarf_fde *fde = __libdw_find_fde (cache, address); + if (fde == NULL) + return -1; + + int error = __libdw_frame_at_address (cache, fde, address, frame); + if (error != DWARF_E_NOERROR) + { + __libdw_seterrno (error); + return -1; + } + return 0; +} +INTDEF (dwarf_cfi_addrframe) diff --git a/libdw/dwarf_cfi_end.c b/libdw/dwarf_cfi_end.c new file mode 100644 index 00000000..d68e2db3 --- /dev/null +++ b/libdw/dwarf_cfi_end.c @@ -0,0 +1,48 @@ +/* Clean up Dwarf_CFI structure. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include "cfi.h" +#include + +int +dwarf_cfi_end (Dwarf_CFI *cache) +{ + if (cache != NULL) + { + __libdw_destroy_frame_cache (cache); + free (cache); + } + + return 0; +} +INTDEF (dwarf_cfi_end) diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c new file mode 100644 index 00000000..c8c8bb61 --- /dev/null +++ b/libdw/dwarf_child.c @@ -0,0 +1,190 @@ +/* Return child of current DIE. + Copyright (C) 2003-2011, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + +/* Some arbitrary value not conflicting with any existing code. */ +#define INVALID 0xffffe444 + + +unsigned char * +internal_function +__libdw_find_attr (Dwarf_Die *die, unsigned int search_name, + unsigned int *codep, unsigned int *formp) +{ + const unsigned char *readp = NULL; + + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp); + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + const unsigned char *endp = die->cu->endp; + + /* Search the name attribute. Attribute has been checked when + Dwarf_Abbrev was created, we can read unchecked. */ + const unsigned char *attrp = abbrevp->attrp; + while (1) + { + /* Get attribute name and form. */ + unsigned int attr_name; + get_uleb128_unchecked (attr_name, attrp); + + unsigned int attr_form; + get_uleb128_unchecked (attr_form, attrp); + + /* We can stop if we found the attribute with value zero. */ + if (attr_name == 0 && attr_form == 0) + break; + + if (attr_form == DW_FORM_indirect) + { + get_uleb128 (attr_form, readp, endp); + if (attr_form == DW_FORM_indirect || + attr_form == DW_FORM_implicit_const) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + } + + /* Is this the name attribute? */ + if (attr_name == search_name && search_name != INVALID) + { + if (codep != NULL) + *codep = attr_name; + if (formp != NULL) + *formp = attr_form; + + /* Normally the attribute data comes from the DIE/info, + except for implicit_form, where it comes from the abbrev. */ + if (attr_form == DW_FORM_implicit_const) + return (unsigned char *) attrp; + else + return (unsigned char *) readp; + } + + /* Skip over the rest of this attribute (if there is any). */ + if (attr_form != 0) + { + size_t len = __libdw_form_val_len (die->cu, attr_form, readp); + if (unlikely (len == (size_t) -1l)) + { + readp = NULL; + break; + } + + // __libdw_form_val_len will have done a bounds check. + readp += len; + + // If the value is in the abbrev data, skip it. + if (attr_form == DW_FORM_implicit_const) + { + int64_t attr_value __attribute__((__unused__)); + get_sleb128_unchecked (attr_value, attrp); + } + } + } + + // XXX Do we need other values? + if (codep != NULL) + *codep = INVALID; + if (formp != NULL) + *formp = INVALID; + + return (unsigned char *) readp; +} + + +int +dwarf_child (Dwarf_Die *die, Dwarf_Die *result) +{ + /* Ignore previous errors. */ + if (die == NULL) + return -1; + + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + /* If there are no children, do not search. */ + if (! abbrevp->has_children) + return 1; + + /* Skip past the last attribute. */ + void *addr = __libdw_find_attr (die, INVALID, NULL, NULL); + + if (addr == NULL) + return -1; + + /* RESULT can be the same as DIE. So preserve what we need. */ + struct Dwarf_CU *cu = die->cu; + + /* It's kosher (just suboptimal) to have a null entry first thing (7.5.3). + So if this starts with ULEB128 of 0 (even with silly encoding of 0), + it is a kosher null entry and we do not really have any children. */ + const unsigned char *code = addr; + const unsigned char *endp = cu->endp; + while (1) + { + if (unlikely (code >= endp)) /* Truncated section. */ + return 1; + if (unlikely (*code == 0x80)) + ++code; + else + break; + } + if (unlikely (*code == '\0')) + return 1; + + /* Clear the entire DIE structure. This signals we have not yet + determined any of the information. */ + memset (result, '\0', sizeof (Dwarf_Die)); + + /* We have the address. */ + result->addr = addr; + + /* Same CU as the parent. */ + result->cu = cu; + + return 0; +} +INTDEF(dwarf_child) diff --git a/libdw/dwarf_cu_die.c b/libdw/dwarf_cu_die.c new file mode 100644 index 00000000..7594e7dc --- /dev/null +++ b/libdw/dwarf_cu_die.c @@ -0,0 +1,62 @@ +/* Internal definitions for libdwarf. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Die * +dwarf_cu_die (Dwarf_CU *cu, Dwarf_Die *result, Dwarf_Half *versionp, + Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, + uint8_t *offset_sizep, uint64_t *unit_idp, + Dwarf_Off *subdie_offsetp) +{ + if (cu == NULL) + return NULL; + + *result = CUDIE (cu); + + if (versionp != NULL) + *versionp = cu->version; + if (abbrev_offsetp != NULL) + *abbrev_offsetp = cu->orig_abbrev_offset; + if (address_sizep != NULL) + *address_sizep = cu->address_size; + if (offset_sizep != NULL) + *offset_sizep = cu->offset_size; + if (unit_idp != NULL) + *unit_idp = cu->unit_id8; + if (subdie_offsetp != NULL) + *subdie_offsetp = cu->subdie_offset; + + return result; +} diff --git a/libdw/dwarf_cu_getdwarf.c b/libdw/dwarf_cu_getdwarf.c new file mode 100644 index 00000000..562460fe --- /dev/null +++ b/libdw/dwarf_cu_getdwarf.c @@ -0,0 +1,46 @@ +/* Retrieve Dwarf descriptor underlying a Dwarf_CU. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libdwP.h" + + +Dwarf * +dwarf_cu_getdwarf (Dwarf_CU *cu) +{ + if (cu == NULL) + /* Some error occurred before. */ + return NULL; + + return cu->dbg; +} diff --git a/libdw/dwarf_cu_info.c b/libdw/dwarf_cu_info.c new file mode 100644 index 00000000..30aee6c7 --- /dev/null +++ b/libdw/dwarf_cu_info.c @@ -0,0 +1,103 @@ +/* Provides information and DIEs associated with the Dwarf_CU unit. + Copyright (C) 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_cu_info (Dwarf_CU *cu, + Dwarf_Half *version, uint8_t *unit_type, + Dwarf_Die *cudie, Dwarf_Die *subdie, + uint64_t *unit_id, + uint8_t *address_size, uint8_t *offset_size) +{ + if (cu == NULL) + return -1; + + if (version != NULL) + *version = cu->version; + + if (unit_type != NULL) + *unit_type = cu->unit_type; + + if (cudie != NULL) + { + if (cu->version >= 2 && cu->version <= 5 + && cu->unit_type >= DW_UT_compile + && cu->unit_type <= DW_UT_split_type) + *cudie = CUDIE (cu); + else + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + } + + if (subdie != NULL) + { + if (cu->version >= 2 && cu->version <= 5) + { + /* For types, return the actual type DIE. For skeletons, + find the associated split compile unit and return its + DIE. */ + if (cu->unit_type == DW_UT_type + || cu->unit_type == DW_UT_split_type) + *subdie = SUBDIE(cu); + else if (cu->unit_type == DW_UT_skeleton) + { + Dwarf_CU *split_cu = __libdw_find_split_unit (cu); + if (split_cu != NULL) + *subdie = CUDIE(split_cu); + else + memset (subdie, '\0', sizeof (Dwarf_Die)); + } + else + memset (subdie, '\0', sizeof (Dwarf_Die)); + } + else + goto invalid; + } + + if (unit_id != NULL) + *unit_id = cu->unit_id8; + + if (address_size != NULL) + *address_size = cu->address_size; + + if (offset_size != NULL) + *offset_size = cu->offset_size; + + return 0; +} diff --git a/libdw/dwarf_cuoffset.c b/libdw/dwarf_cuoffset.c new file mode 100644 index 00000000..f13b02fd --- /dev/null +++ b/libdw/dwarf_cuoffset.c @@ -0,0 +1,44 @@ +/* Return offset of DIE in CU. + Copyright (C) 2003-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Off +dwarf_cuoffset (Dwarf_Die *die) +{ + return ((die == NULL || die->cu == NULL) + ? (Dwarf_Off) -1l + : (Dwarf_Off) (die->addr - die->cu->startp)); +} diff --git a/libdw/dwarf_decl_column.c b/libdw/dwarf_decl_column.c new file mode 100644 index 00000000..08d36b87 --- /dev/null +++ b/libdw/dwarf_decl_column.c @@ -0,0 +1,44 @@ +/* Get column number of beginning of given declaration. + Copyright (C) 2005-2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_decl_column (Dwarf_Die *decl, int *colp) +{ + return __libdw_attr_intval (decl, colp, DW_AT_decl_column); +} +OLD_VERSION (dwarf_decl_column, ELFUTILS_0.122) +NEW_VERSION (dwarf_decl_column, ELFUTILS_0.143) diff --git a/libdw/dwarf_decl_file.c b/libdw/dwarf_decl_file.c new file mode 100644 index 00000000..d4aa0a18 --- /dev/null +++ b/libdw/dwarf_decl_file.c @@ -0,0 +1,89 @@ +/* Return file name containing definition of the given function. + Copyright (C) 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + + +const char * +dwarf_decl_file (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word idx = 0; + + if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, DW_AT_decl_file, &attr_mem), + &idx) != 0) + return NULL; + + /* Zero means no source file information available. */ + if (idx == 0) + { + __libdw_seterrno (DWARF_E_NO_ENTRY); + return NULL; + } + + /* Get the array of source files for the CU. */ + struct Dwarf_CU *cu = attr_mem.cu; + if (cu->lines == NULL) + { + Dwarf_Lines *lines; + size_t nlines; + + /* Let the more generic function do the work. It'll create more + data but that will be needed in an real program anyway. */ + (void) INTUSE(dwarf_getsrclines) (&CUDIE (cu), &lines, &nlines); + assert (cu->lines != NULL); + } + + if (cu->lines == (void *) -1l) + { + /* If the file index is not zero, there must be file information + available. */ + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + assert (cu->files != NULL && cu->files != (void *) -1l); + + if (idx >= cu->files->nfiles) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + return cu->files->info[idx].name; +} +OLD_VERSION (dwarf_decl_file, ELFUTILS_0.122) +NEW_VERSION (dwarf_decl_file, ELFUTILS_0.143) diff --git a/libdw/dwarf_decl_line.c b/libdw/dwarf_decl_line.c new file mode 100644 index 00000000..80fae6c9 --- /dev/null +++ b/libdw/dwarf_decl_line.c @@ -0,0 +1,70 @@ +/* Get line number of beginning of given function. + Copyright (C) 2005, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include "libdwP.h" + + +int +dwarf_decl_line (Dwarf_Die *func, int *linep) +{ + return __libdw_attr_intval (func, linep, DW_AT_decl_line); +} +OLD_VERSION (dwarf_decl_line, ELFUTILS_0.122) +NEW_VERSION (dwarf_decl_line, ELFUTILS_0.143) + + +int internal_function +__libdw_attr_intval (Dwarf_Die *die, int *linep, int attval) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word line; + + int res = INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, attval, &attr_mem), + &line); + if (res == 0) + { + if (line > INT_MAX) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + res = -1; + } + else + *linep = line; + } + + return res; +} diff --git a/libdw/dwarf_default_lower_bound.c b/libdw/dwarf_default_lower_bound.c new file mode 100644 index 00000000..a33a3433 --- /dev/null +++ b/libdw/dwarf_default_lower_bound.c @@ -0,0 +1,91 @@ +/* Get the default subrange lower bound for a given language. + Copyright (C) 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + +/* Determine default lower bound from language, as per the DWARF5 + "Subrange Type Entries" table. */ +int +dwarf_default_lower_bound (int lang, Dwarf_Sword *result) +{ + switch (lang) + { + case DW_LANG_C: + case DW_LANG_C89: + case DW_LANG_C99: + case DW_LANG_C11: + case DW_LANG_C_plus_plus: + case DW_LANG_C_plus_plus_03: + case DW_LANG_C_plus_plus_11: + case DW_LANG_C_plus_plus_14: + case DW_LANG_ObjC: + case DW_LANG_ObjC_plus_plus: + case DW_LANG_Java: + case DW_LANG_D: + case DW_LANG_Python: + case DW_LANG_UPC: + case DW_LANG_OpenCL: + case DW_LANG_Go: + case DW_LANG_Haskell: + case DW_LANG_OCaml: + case DW_LANG_Rust: + case DW_LANG_Swift: + case DW_LANG_Dylan: + case DW_LANG_RenderScript: + case DW_LANG_BLISS: + *result = 0; + return 0; + + case DW_LANG_Ada83: + case DW_LANG_Ada95: + case DW_LANG_Cobol74: + case DW_LANG_Cobol85: + case DW_LANG_Fortran77: + case DW_LANG_Fortran90: + case DW_LANG_Fortran95: + case DW_LANG_Fortran03: + case DW_LANG_Fortran08: + case DW_LANG_Pascal83: + case DW_LANG_Modula2: + case DW_LANG_Modula3: + case DW_LANG_PLI: + case DW_LANG_Julia: + *result = 1; + return 0; + + default: + __libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE); + return -1; + } +} +INTDEF (dwarf_default_lower_bound) diff --git a/libdw/dwarf_die_addr_die.c b/libdw/dwarf_die_addr_die.c new file mode 100644 index 00000000..65729166 --- /dev/null +++ b/libdw/dwarf_die_addr_die.c @@ -0,0 +1,70 @@ +/* Return offset of DIE. + Copyright (C) 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include "libdwP.h" + + +Dwarf_Die * +dwarf_die_addr_die (Dwarf *dbg, void *addr, Dwarf_Die *result) +{ + if (dbg == NULL) + return NULL; + + Dwarf_CU *cu = __libdw_findcu_addr (dbg, addr); + + if (cu == NULL) + { + Dwarf *alt = INTUSE (dwarf_getalt) (dbg); + if (alt != NULL) + cu = __libdw_findcu_addr (alt, addr); + } + + if (cu == NULL) + { + Dwarf *split = __libdw_find_split_dbg_addr (dbg, addr); + if (split != NULL) + cu = __libdw_findcu_addr (split, addr); + } + + if (cu == NULL) + { + memset (result, '\0', sizeof (Dwarf_Die)); + return NULL; + } + + *result = (Dwarf_Die) { .addr = addr, .cu = cu }; + + return result; +} diff --git a/libdw/dwarf_diecu.c b/libdw/dwarf_diecu.c new file mode 100644 index 00000000..5281c352 --- /dev/null +++ b/libdw/dwarf_diecu.c @@ -0,0 +1,52 @@ +/* Return CU DIE containing given DIE. + Copyright (C) 2005-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Die * +dwarf_diecu (Dwarf_Die *die, Dwarf_Die *result, uint8_t *address_sizep, + uint8_t *offset_sizep) +{ + if (die == NULL) + return NULL; + + *result = CUDIE (die->cu); + + if (address_sizep != NULL) + *address_sizep = die->cu->address_size; + if (offset_sizep != NULL) + *offset_sizep = die->cu->offset_size; + + return result; +} diff --git a/libdw/dwarf_diename.c b/libdw/dwarf_diename.c new file mode 100644 index 00000000..96450c1c --- /dev/null +++ b/libdw/dwarf_diename.c @@ -0,0 +1,47 @@ +/* Return string in name attribute of DIE. + Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +const char * +dwarf_diename (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + + return INTUSE(dwarf_formstring) (INTUSE(dwarf_attr_integrate) (die, + DW_AT_name, + &attr_mem)); +} +INTDEF (dwarf_diename) diff --git a/libdw/dwarf_dieoffset.c b/libdw/dwarf_dieoffset.c new file mode 100644 index 00000000..3a8e2cb6 --- /dev/null +++ b/libdw/dwarf_dieoffset.c @@ -0,0 +1,45 @@ +/* Return offset of DIE. + Copyright (C) 2003-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Off +dwarf_dieoffset (Dwarf_Die *die) +{ + return ((die == NULL || die->cu == NULL) + ? (Dwarf_Off) -1 + : (Dwarf_Off) (die->addr - die->cu->startp + die->cu->start)); +} +INTDEF(dwarf_dieoffset) diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c new file mode 100644 index 00000000..77f537a7 --- /dev/null +++ b/libdw/dwarf_end.c @@ -0,0 +1,157 @@ +/* Release debugging handling context. + Copyright (C) 2002-2011, 2014, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "libdwP.h" +#include "cfi.h" + + +static void +noop_free (void *arg __attribute__ ((unused))) +{ +} + + +static void +cu_free (void *arg) +{ + struct Dwarf_CU *p = (struct Dwarf_CU *) arg; + + tdestroy (p->locs, noop_free); + + /* Only free the CU internals if its not a fake CU. */ + if(p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu + && p != p->dbg->fake_addr_cu) + { + Dwarf_Abbrev_Hash_free (&p->abbrev_hash); + + /* Free split dwarf one way (from skeleton to split). */ + if (p->unit_type == DW_UT_skeleton + && p->split != NULL && p->split != (void *)-1) + { + /* The fake_addr_cu might be shared, only release one. */ + if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu) + p->split->dbg->fake_addr_cu = NULL; + INTUSE(dwarf_end) (p->split->dbg); + } + } +} + + +int +dwarf_end (Dwarf *dwarf) +{ + if (dwarf != NULL) + { + if (dwarf->cfi != NULL) + /* Clean up the CFI cache. */ + __libdw_destroy_frame_cache (dwarf->cfi); + + Dwarf_Sig8_Hash_free (&dwarf->sig8_hash); + + /* The search tree for the CUs. NB: the CU data itself is + allocated separately, but the abbreviation hash tables need + to be handled. */ + tdestroy (dwarf->cu_tree, cu_free); + tdestroy (dwarf->tu_tree, cu_free); + + /* Search tree for macro opcode tables. */ + tdestroy (dwarf->macro_ops, noop_free); + + /* Search tree for decoded .debug_lines units. */ + tdestroy (dwarf->files_lines, noop_free); + + /* And the split Dwarf. */ + tdestroy (dwarf->split_tree, noop_free); + + /* Free the internally allocated memory. */ + for (size_t i = 0; i < dwarf->mem_stacks; i++) + { + struct libdw_memblock *memp = dwarf->mem_tails[i]; + while (memp != NULL) + { + struct libdw_memblock *prevp = memp->prev; + free (memp); + memp = prevp; + } + } + if (dwarf->mem_tails != NULL) + free (dwarf->mem_tails); + pthread_rwlock_destroy (&dwarf->mem_rwl); + + /* Free the pubnames helper structure. */ + free (dwarf->pubnames_sets); + + /* Free the ELF descriptor if necessary. */ + if (dwarf->free_elf) + elf_end (dwarf->elf); + + /* Free the fake location list CU. */ + if (dwarf->fake_loc_cu != NULL) + { + cu_free (dwarf->fake_loc_cu); + free (dwarf->fake_loc_cu); + } + if (dwarf->fake_loclists_cu != NULL) + { + cu_free (dwarf->fake_loclists_cu); + free (dwarf->fake_loclists_cu); + } + if (dwarf->fake_addr_cu != NULL) + { + cu_free (dwarf->fake_addr_cu); + free (dwarf->fake_addr_cu); + } + + /* Did we find and allocate the alt Dwarf ourselves? */ + if (dwarf->alt_fd != -1) + { + INTUSE(dwarf_end) (dwarf->alt_dwarf); + close (dwarf->alt_fd); + } + + /* The cached dir we found the Dwarf ELF file in. */ + free (dwarf->debugdir); + + /* Free the context descriptor. */ + free (dwarf); + } + + return 0; +} +INTDEF(dwarf_end) diff --git a/libdw/dwarf_entry_breakpoints.c b/libdw/dwarf_entry_breakpoints.c new file mode 100644 index 00000000..c3c0f399 --- /dev/null +++ b/libdw/dwarf_entry_breakpoints.c @@ -0,0 +1,163 @@ +/* Find entry breakpoint locations for a function. + Copyright (C) 2005-2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "libdwP.h" +#include +#include + + +/* Add one breakpoint location to the result vector. */ +static inline int +add_bkpt (Dwarf_Addr pc, Dwarf_Addr **bkpts, int *pnbkpts) +{ + Dwarf_Addr *newlist = realloc (*bkpts, ++(*pnbkpts) * sizeof newlist[0]); + if (newlist == NULL) + { + free (*bkpts); + *bkpts = NULL; + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + newlist[*pnbkpts - 1] = pc; + *bkpts = newlist; + return *pnbkpts; +} + +/* Fallback result, break at the entrypc/lowpc value. */ +static inline int +entrypc_bkpt (Dwarf_Die *die, Dwarf_Addr **bkpts, int *pnbkpts) +{ + Dwarf_Addr pc; + return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc, bkpts, pnbkpts); +} + +/* Search a contiguous PC range for prologue-end markers. + If DWARF, look for proper markers. + Failing that, if ADHOC, look for the ad hoc convention. */ +static inline int +search_range (Dwarf_Addr low, Dwarf_Addr high, + bool dwarf, bool adhoc, + Dwarf_Lines *lines, size_t nlines, + Dwarf_Addr **bkpts, int *pnbkpts) +{ + size_t l = 0, u = nlines; + while (l < u) + { + size_t idx = (l + u) / 2; + if (lines->info[idx].addr < low) + l = idx + 1; + else if (lines->info[idx].addr > low) + u = idx; + else if (lines->info[idx].end_sequence) + l = idx + 1; + else + { + l = idx; + break; + } + } + if (l < u) + { + if (dwarf) + for (size_t i = l; i < u && lines->info[i].addr < high; ++i) + if (lines->info[i].prologue_end + && add_bkpt (lines->info[i].addr, bkpts, pnbkpts) < 0) + return -1; + if (adhoc && *pnbkpts == 0) + while (++l < nlines && lines->info[l].addr < high) + if (!lines->info[l].end_sequence) + return add_bkpt (lines->info[l].addr, bkpts, pnbkpts); + return *pnbkpts; + } + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; +} + +int +dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts) +{ + int nbkpts = 0; + *bkpts = NULL; + + /* Fetch the CU's line records to look for this DIE's addresses. */ + Dwarf_Die cudie = CUDIE (die->cu); + Dwarf_Lines *lines; + size_t nlines; + if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0) + { + int error = INTUSE (dwarf_errno) (); + if (error == 0) /* CU has no DW_AT_stmt_list. */ + return entrypc_bkpt (die, bkpts, &nbkpts); + __libdw_seterrno (error); + return -1; + } + + /* Search each contiguous address range for DWARF prologue_end markers. */ + + Dwarf_Addr base; + Dwarf_Addr begin; + Dwarf_Addr end; + ptrdiff_t offset = INTUSE(dwarf_ranges) (die, 0, &base, &begin, &end); + if (offset < 0) + return -1; + + /* Most often there is a single contiguous PC range for the DIE. */ + if (offset == 1) + return search_range (begin, end, true, true, lines, nlines, bkpts, &nbkpts) + ?: entrypc_bkpt (die, bkpts, &nbkpts); + + Dwarf_Addr lowpc = (Dwarf_Addr) -1l; + Dwarf_Addr highpc = (Dwarf_Addr) -1l; + while (offset > 0) + { + /* We have an address range entry. */ + if (search_range (begin, end, true, false, + lines, nlines, bkpts, &nbkpts) < 0) + return -1; + + if (begin < lowpc) + { + lowpc = begin; + highpc = end; + } + + offset = INTUSE(dwarf_ranges) (die, offset, &base, &begin, &end); + } + + /* If we didn't find any proper DWARF markers, then look in the + lowest-addressed range for an ad hoc marker. Failing that, + fall back to just using the entrypc value. */ + return (nbkpts + ?: (lowpc == (Dwarf_Addr) -1l ? 0 + : search_range (lowpc, highpc, false, true, + lines, nlines, bkpts, &nbkpts)) + ?: entrypc_bkpt (die, bkpts, &nbkpts)); +} diff --git a/libdw/dwarf_entrypc.c b/libdw/dwarf_entrypc.c new file mode 100644 index 00000000..0ef3b0ea --- /dev/null +++ b/libdw/dwarf_entrypc.c @@ -0,0 +1,48 @@ +/* Return entry PC attribute of DIE. + Copyright (C) 2003, 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_entrypc (Dwarf_Die *die, Dwarf_Addr *return_addr) +{ + Dwarf_Attribute attr_mem; + + return INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_entry_pc, + &attr_mem) + ?: INTUSE(dwarf_attr) (die, DW_AT_low_pc, + &attr_mem), + return_addr); +} +INTDEF(dwarf_entrypc) diff --git a/libdw/dwarf_error.c b/libdw/dwarf_error.c new file mode 100644 index 00000000..46ea16b3 --- /dev/null +++ b/libdw/dwarf_error.c @@ -0,0 +1,130 @@ +/* Retrieve ELF descriptor used for DWARF access. + Copyright (C) 2002-2005, 2009, 2014, 2015, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libdwP.h" + + +/* The error number. */ +static __thread int global_error; + + +int +dwarf_errno (void) +{ + int result = global_error; + global_error = DWARF_E_NOERROR; + return result; +} +INTDEF(dwarf_errno) + + +/* XXX For now we use string pointers. Once the table stablelizes + make it more DSO-friendly. */ +static const char *errmsgs[] = + { + [DWARF_E_NOERROR] = N_("no error"), + [DWARF_E_UNKNOWN_ERROR] = N_("unknown error"), + [DWARF_E_INVALID_ACCESS] = N_("invalid access"), + [DWARF_E_NO_REGFILE] = N_("no regular file"), + [DWARF_E_IO_ERROR] = N_("I/O error"), + [DWARF_E_INVALID_ELF] = N_("invalid ELF file"), + [DWARF_E_NO_DWARF] = N_("no DWARF information"), + [DWARF_E_COMPRESSED_ERROR] = N_("cannot decompress DWARF"), + [DWARF_E_NOELF] = N_("no ELF file"), + [DWARF_E_GETEHDR_ERROR] = N_("cannot get ELF header"), + [DWARF_E_NOMEM] = N_("out of memory"), + [DWARF_E_UNIMPL] = N_("not implemented"), + [DWARF_E_INVALID_CMD] = N_("invalid command"), + [DWARF_E_INVALID_VERSION] = N_("invalid version"), + [DWARF_E_INVALID_FILE] = N_("invalid file"), + [DWARF_E_NO_ENTRY] = N_("no entries found"), + [DWARF_E_INVALID_DWARF] = N_("invalid DWARF"), + [DWARF_E_NO_STRING] = N_("no string data"), + [DWARF_E_NO_DEBUG_STR] = N_(".debug_str section missing"), + [DWARF_E_NO_DEBUG_LINE_STR] = N_(".debug_line_str section missing"), + [DWARF_E_NO_STR_OFFSETS] = N_(".debug_str_offsets section missing"), + [DWARF_E_NO_ADDR] = N_("no address value"), + [DWARF_E_NO_CONSTANT] = N_("no constant value"), + [DWARF_E_NO_REFERENCE] = N_("no reference value"), + [DWARF_E_INVALID_REFERENCE] = N_("invalid reference value"), + [DWARF_E_NO_DEBUG_LINE] = N_(".debug_line section missing"), + [DWARF_E_INVALID_DEBUG_LINE] = N_("invalid .debug_line section"), + [DWARF_E_TOO_BIG] = N_("debug information too big"), + [DWARF_E_VERSION] = N_("invalid DWARF version"), + [DWARF_E_INVALID_DIR_IDX] = N_("invalid directory index"), + [DWARF_E_ADDR_OUTOFRANGE] = N_("address out of range"), + [DWARF_E_NO_DEBUG_LOC] = N_(".debug_loc section missing"), + [DWARF_E_NO_DEBUG_LOCLISTS] = N_(".debug_loclists section missing"), + [DWARF_E_NO_LOC_VALUE] = N_("not a location list value"), + [DWARF_E_NO_BLOCK] = N_("no block data"), + [DWARF_E_INVALID_LINE_IDX] = N_("invalid line index"), + [DWARF_E_INVALID_ARANGE_IDX] = N_("invalid address range index"), + [DWARF_E_NO_MATCH] = N_("no matching address range"), + [DWARF_E_NO_FLAG] = N_("no flag value"), + [DWARF_E_INVALID_OFFSET] = N_("invalid offset"), + [DWARF_E_NO_DEBUG_RANGES] = N_(".debug_ranges section missing"), + [DWARF_E_NO_DEBUG_RNGLISTS] = N_(".debug_rnglists section missing"), + [DWARF_E_INVALID_CFI] = N_("invalid CFI section"), + [DWARF_E_NO_ALT_DEBUGLINK] = N_("no alternative debug link found"), + [DWARF_E_INVALID_OPCODE] = N_("invalid opcode"), + [DWARF_E_NOT_CUDIE] = N_("not a CU (unit) DIE"), + [DWARF_E_UNKNOWN_LANGUAGE] = N_("unknown language code"), + [DWARF_E_NO_DEBUG_ADDR] = N_(".debug_addr section missing"), + }; +#define nerrmsgs (sizeof (errmsgs) / sizeof (errmsgs[0])) + + +void +internal_function +__libdw_seterrno (int value) +{ + global_error = (value >= 0 && value < (int) nerrmsgs + ? value : DWARF_E_UNKNOWN_ERROR); +} + + +const char * +dwarf_errmsg (int error) +{ + int last_error = global_error; + + if (error == 0) + return last_error != 0 ? _(errmsgs[last_error]) : NULL; + else if (error < -1 || error >= (int) nerrmsgs) + return _(errmsgs[DWARF_E_UNKNOWN_ERROR]); + + return _(errmsgs[error == -1 ? last_error : error]); +} +INTDEF(dwarf_errmsg) diff --git a/libdw/dwarf_filesrc.c b/libdw/dwarf_filesrc.c new file mode 100644 index 00000000..d866ce72 --- /dev/null +++ b/libdw/dwarf_filesrc.c @@ -0,0 +1,51 @@ +/* Find source file information. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +const char * +dwarf_filesrc (Dwarf_Files *file, size_t idx, Dwarf_Word *mtime, + Dwarf_Word *length) +{ + if (file == NULL || idx >= file->nfiles) + return NULL; + + if (mtime != NULL) + *mtime = file->info[idx].mtime; + + if (length != NULL) + *length = file->info[idx].length; + + return file->info[idx].name; +} diff --git a/libdw/dwarf_formaddr.c b/libdw/dwarf_formaddr.c new file mode 100644 index 00000000..9cd3d200 --- /dev/null +++ b/libdw/dwarf_formaddr.c @@ -0,0 +1,148 @@ +/* Return address represented by attribute. + Copyright (C) 2003-2010, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +__libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr) +{ + Dwarf_Off addr_off = __libdw_cu_addr_base (cu); + if (addr_off == (Dwarf_Off) -1) + return -1; + + Dwarf *dbg = cu->dbg; + if (dbg->sectiondata[IDX_debug_addr] == NULL) + { + __libdw_seterrno (DWARF_E_NO_DEBUG_ADDR); + return -1; + } + + /* The section should at least contain room for one address. */ + int address_size = cu->address_size; + if (cu->address_size > dbg->sectiondata[IDX_debug_addr]->d_size) + { + invalid_offset: + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + + if (addr_off > (dbg->sectiondata[IDX_debug_addr]->d_size + - address_size)) + goto invalid_offset; + + idx *= address_size; + if (idx > (dbg->sectiondata[IDX_debug_addr]->d_size + - address_size - addr_off)) + goto invalid_offset; + + const unsigned char *datap; + datap = dbg->sectiondata[IDX_debug_addr]->d_buf + addr_off + idx; + if (address_size == 4) + *addr = read_4ubyte_unaligned (dbg, datap); + else + *addr = read_8ubyte_unaligned (dbg, datap); + + return 0; +} + +int +dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr) +{ + if (attr == NULL) + return -1; + + Dwarf_Word idx; + Dwarf_CU *cu = attr->cu; + Dwarf *dbg = cu->dbg; + const unsigned char *datap = attr->valp; + const unsigned char *endp = attr->cu->endp; + switch (attr->form) + { + /* There is one form that just encodes the whole address. */ + case DW_FORM_addr: + if (__libdw_read_address (dbg, cu_sec_idx (cu), datap, + cu->address_size, return_addr)) + return -1; + return 0; + + /* All others encode an index into the .debug_addr section where + the address can be found. */ + case DW_FORM_GNU_addr_index: + case DW_FORM_addrx: + if (datap >= endp) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + get_uleb128 (idx, datap, endp); + break; + + case DW_FORM_addrx1: + if (datap >= endp - 1) + goto invalid; + idx = *datap; + break; + + case DW_FORM_addrx2: + if (datap >= endp - 2) + goto invalid; + idx = read_2ubyte_unaligned (dbg, datap); + break; + + case DW_FORM_addrx3: + if (datap >= endp - 3) + goto invalid; + idx = read_3ubyte_unaligned (dbg, datap); + break; + + case DW_FORM_addrx4: + if (datap >= endp - 4) + goto invalid; + idx = read_4ubyte_unaligned (dbg, datap); + break; + + default: + __libdw_seterrno (DWARF_E_NO_ADDR); + return -1; + } + + /* So we got an index. Lets see if it is valid and we can get the actual + address. */ + if (__libdw_addrx (cu, idx, return_addr) != 0) + return -1; + + return 0; +} +INTDEF(dwarf_formaddr) diff --git a/libdw/dwarf_formblock.c b/libdw/dwarf_formblock.c new file mode 100644 index 00000000..924baf45 --- /dev/null +++ b/libdw/dwarf_formblock.c @@ -0,0 +1,103 @@ +/* Return block represented by attribute. + Copyright (C) 2004-2010, 2014, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block) +{ + if (attr == NULL) + return -1; + + const unsigned char *datap = attr->valp; + const unsigned char *endp = attr->cu->endp; + + switch (attr->form) + { + case DW_FORM_block1: + if (unlikely (endp - datap < 1)) + goto invalid; + return_block->length = *(uint8_t *) attr->valp; + return_block->data = attr->valp + 1; + break; + + case DW_FORM_block2: + if (unlikely (endp - datap < 2)) + goto invalid; + return_block->length = read_2ubyte_unaligned (attr->cu->dbg, attr->valp); + return_block->data = attr->valp + 2; + break; + + case DW_FORM_block4: + if (unlikely (endp - datap < 4)) + goto invalid; + return_block->length = read_4ubyte_unaligned (attr->cu->dbg, attr->valp); + return_block->data = attr->valp + 4; + break; + + case DW_FORM_block: + case DW_FORM_exprloc: + if (unlikely (endp - datap < 1)) + goto invalid; + get_uleb128 (return_block->length, datap, endp); + return_block->data = (unsigned char *) datap; + break; + + case DW_FORM_data16: + /* The DWARFv5 spec calls this constant class, but we interpret + it as a block that the user will need to interpret when + converting to a value. */ + if (unlikely (endp - datap < 16)) + goto invalid; + return_block->length = 16; + return_block->data = (unsigned char *) datap; + break; + + default: + __libdw_seterrno (DWARF_E_NO_BLOCK); + return -1; + } + + if (unlikely (return_block->length > (size_t) (endp - return_block->data))) + { + /* Block does not fit. */ + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + return 0; +} +INTDEF(dwarf_formblock) diff --git a/libdw/dwarf_formflag.c b/libdw/dwarf_formflag.c new file mode 100644 index 00000000..b48ede4e --- /dev/null +++ b/libdw/dwarf_formflag.c @@ -0,0 +1,59 @@ +/* Return flag represented by attribute. + Copyright (C) 2004-2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_formflag (Dwarf_Attribute *attr, bool *return_bool) +{ + if (attr == NULL) + return -1; + + if (attr->form == DW_FORM_flag_present) + { + *return_bool = true; + return 0; + } + + if (unlikely (attr->form != DW_FORM_flag)) + { + __libdw_seterrno (DWARF_E_NO_FLAG); + return -1; + } + + *return_bool = *attr->valp != 0; + + return 0; +} diff --git a/libdw/dwarf_formref.c b/libdw/dwarf_formref.c new file mode 100644 index 00000000..2bae2a44 --- /dev/null +++ b/libdw/dwarf_formref.c @@ -0,0 +1,112 @@ +/* Return reference offset represented by attribute. + Copyright (C) 2003-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + +int +internal_function +__libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) +{ + const unsigned char *datap = attr->valp; + const unsigned char *endp = attr->cu->endp; + + if (attr->valp == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_REFERENCE); + return -1; + } + + switch (attr->form) + { + case DW_FORM_ref1: + if (datap + 1 > endp) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + *return_offset = *attr->valp; + break; + + case DW_FORM_ref2: + if (datap + 2 > endp) + goto invalid; + *return_offset = read_2ubyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_ref4: + if (datap + 4 > endp) + goto invalid; + *return_offset = read_4ubyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_ref8: + if (datap + 8 > endp) + goto invalid; + *return_offset = read_8ubyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_ref_udata: + if (datap + 1 > endp) + goto invalid; + get_uleb128 (*return_offset, datap, endp); + break; + + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_ref_alt: + case DW_FORM_ref_sup4: + case DW_FORM_ref_sup8: + /* These aren't handled by dwarf_formref, only by dwarf_formref_die. */ + __libdw_seterrno (DWARF_E_INVALID_REFERENCE); + return -1; + + default: + __libdw_seterrno (DWARF_E_NO_REFERENCE); + return -1; + } + + return 0; +} + +/* This is the old public entry point. + It is now deprecated in favor of dwarf_formref_die. */ +int +dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) +{ + if (attr == NULL) + return -1; + + return __libdw_formref (attr, return_offset); +} diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c new file mode 100644 index 00000000..48ba8194 --- /dev/null +++ b/libdw/dwarf_formref_die.c @@ -0,0 +1,137 @@ +/* Look up the DIE in a reference-form attribute. + Copyright (C) 2005-2010, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" +#include + + +Dwarf_Die * +dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result) +{ + if (attr == NULL) + return NULL; + + struct Dwarf_CU *cu = attr->cu; + + Dwarf_Off offset; + if (attr->form == DW_FORM_ref_addr || attr->form == DW_FORM_GNU_ref_alt + || attr->form == DW_FORM_ref_sup4 || attr->form == DW_FORM_ref_sup8) + { + /* This has an absolute offset. */ + + uint8_t ref_size; + if (cu->version == 2 && attr->form == DW_FORM_ref_addr) + ref_size = cu->address_size; + else if (attr->form == DW_FORM_ref_sup4) + ref_size = 4; + else if (attr->form == DW_FORM_ref_sup8) + ref_size = 8; + else + ref_size = cu->offset_size; + + Dwarf *dbg_ret = (attr->form == DW_FORM_GNU_ref_alt + ? INTUSE(dwarf_getalt) (cu->dbg) : cu->dbg); + + if (dbg_ret == NULL) + { + __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK); + return NULL; + } + + if (__libdw_read_offset (cu->dbg, dbg_ret, IDX_debug_info, attr->valp, + ref_size, &offset, IDX_debug_info, 0)) + return NULL; + + return INTUSE(dwarf_offdie) (dbg_ret, offset, result); + } + + const unsigned char *datap; + size_t size; + if (attr->form == DW_FORM_ref_sig8) + { + /* This doesn't have an offset, but instead a value we + have to match in the type unit headers. */ + + uint64_t sig = read_8ubyte_unaligned (cu->dbg, attr->valp); + cu = Dwarf_Sig8_Hash_find (&cu->dbg->sig8_hash, sig); + if (cu == NULL) + { + /* Not seen before. We have to scan through the type units. + Since DWARFv5 these can (also) be found in .debug_info, + so scan that first. */ + bool scan_debug_types = false; + do + { + cu = __libdw_intern_next_unit (attr->cu->dbg, scan_debug_types); + if (cu == NULL) + { + if (scan_debug_types == false) + scan_debug_types = true; + else + { + __libdw_seterrno (INTUSE(dwarf_errno) () + ?: DWARF_E_INVALID_REFERENCE); + return NULL; + } + } + } + while (cu == NULL || cu->unit_id8 != sig); + } + + int secid = cu_sec_idx (cu); + datap = cu->dbg->sectiondata[secid]->d_buf; + size = cu->dbg->sectiondata[secid]->d_size; + offset = cu->start + cu->subdie_offset; + } + else + { + /* Other forms produce an offset from the CU. */ + if (unlikely (__libdw_formref (attr, &offset) != 0)) + return NULL; + + datap = cu->startp; + size = cu->endp - cu->startp; + } + + if (unlikely (offset >= size)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + memset (result, '\0', sizeof (Dwarf_Die)); + result->addr = (char *) datap + offset; + result->cu = cu; + return result; +} +INTDEF (dwarf_formref_die) diff --git a/libdw/dwarf_formsdata.c b/libdw/dwarf_formsdata.c new file mode 100644 index 00000000..def32c9d --- /dev/null +++ b/libdw/dwarf_formsdata.c @@ -0,0 +1,101 @@ +/* Return signed constant represented by attribute. + Copyright (C) 2003, 2005, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_sval) +{ + if (attr == NULL) + return -1; + + const unsigned char *datap = attr->valp; + const unsigned char *endp = attr->cu->endp; + + switch (attr->form) + { + case DW_FORM_data1: + if (datap + 1 > endp) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + *return_sval = (signed char) *attr->valp; + break; + + case DW_FORM_data2: + if (datap + 2 > endp) + goto invalid; + *return_sval = read_2sbyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_data4: + if (datap + 4 > endp) + goto invalid; + *return_sval = read_4sbyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_data8: + if (datap + 8 > endp) + goto invalid; + *return_sval = read_8sbyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_sdata: + if (datap + 1 > endp) + goto invalid; + get_sleb128 (*return_sval, datap, endp); + break; + + case DW_FORM_udata: + if (datap + 1 > endp) + goto invalid; + get_uleb128 (*return_sval, datap, endp); + break; + + case DW_FORM_implicit_const: + // The data comes from the abbrev, which has been bounds checked. + get_sleb128_unchecked (*return_sval, datap); + break; + + default: + __libdw_seterrno (DWARF_E_NO_CONSTANT); + return -1; + } + + return 0; +} +INTDEF(dwarf_formsdata) diff --git a/libdw/dwarf_formstring.c b/libdw/dwarf_formstring.c new file mode 100644 index 00000000..c3e892a8 --- /dev/null +++ b/libdw/dwarf_formstring.c @@ -0,0 +1,180 @@ +/* Return string associated with given attribute. + Copyright (C) 2003-2010, 2013, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +const char * +dwarf_formstring (Dwarf_Attribute *attrp) +{ + /* Ignore earlier errors. */ + if (attrp == NULL) + return NULL; + + /* We found it. Now determine where the string is stored. */ + if (attrp->form == DW_FORM_string) + /* A simple inlined string. */ + return (const char *) attrp->valp; + + Dwarf_CU *cu = attrp->cu; + Dwarf *dbg = cu->dbg; + Dwarf *dbg_ret = ((attrp->form == DW_FORM_GNU_strp_alt + || attrp->form == DW_FORM_strp_sup) + ? INTUSE(dwarf_getalt) (dbg) : dbg); + + if (unlikely (dbg_ret == NULL)) + { + __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK); + return NULL; + } + + Elf_Data *data = ((attrp->form == DW_FORM_line_strp) + ? dbg_ret->sectiondata[IDX_debug_line_str] + : dbg_ret->sectiondata[IDX_debug_str]); + if (data == NULL) + { + __libdw_seterrno ((attrp->form == DW_FORM_line_strp) + ? DWARF_E_NO_DEBUG_LINE_STR + : DWARF_E_NO_DEBUG_STR); + return NULL; + } + + uint64_t off; + if (attrp->form == DW_FORM_strp + || attrp->form == DW_FORM_GNU_strp_alt + || attrp->form == DW_FORM_strp_sup) + { + if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu), + attrp->valp, cu->offset_size, &off, + IDX_debug_str, 1)) + return NULL; + } + else if (attrp->form == DW_FORM_line_strp) + { + if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (cu), + attrp->valp, cu->offset_size, &off, + IDX_debug_line_str, 1)) + return NULL; + } + else + { + Dwarf_Word idx; + const unsigned char *datap = attrp->valp; + const unsigned char *endp = cu->endp; + switch (attrp->form) + { + case DW_FORM_strx: + case DW_FORM_GNU_str_index: + if (datap >= endp) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + get_uleb128 (idx, datap, endp); + break; + + case DW_FORM_strx1: + if (datap >= endp - 1) + goto invalid; + idx = *datap; + break; + + case DW_FORM_strx2: + if (datap >= endp - 2) + goto invalid; + idx = read_2ubyte_unaligned (dbg, datap); + break; + + case DW_FORM_strx3: + if (datap >= endp - 3) + goto invalid; + idx = read_3ubyte_unaligned (dbg, datap); + break; + + case DW_FORM_strx4: + if (datap >= endp - 4) + goto invalid; + idx = read_4ubyte_unaligned (dbg, datap); + break; + + default: + __libdw_seterrno (DWARF_E_NO_STRING); + return NULL; + } + + /* So we got an index in the .debug_str_offsets. Lets see if it + is valid and we can get the actual .debug_str offset. */ + Dwarf_Off str_off = __libdw_cu_str_off_base (cu); + if (str_off == (Dwarf_Off) -1) + return NULL; + + if (dbg->sectiondata[IDX_debug_str_offsets] == NULL) + { + __libdw_seterrno (DWARF_E_NO_STR_OFFSETS); + return NULL; + } + + /* The section should at least contain room for one offset. */ + int offset_size = cu->offset_size; + if (cu->offset_size > dbg->sectiondata[IDX_debug_str_offsets]->d_size) + { + invalid_offset: + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return NULL; + } + + /* And the base offset should be at least inside the section. */ + if (str_off > (dbg->sectiondata[IDX_debug_str_offsets]->d_size + - offset_size)) + goto invalid_offset; + + size_t max_idx = (dbg->sectiondata[IDX_debug_str_offsets]->d_size + - offset_size - str_off) / offset_size; + if (idx > max_idx) + goto invalid_offset; + + datap = (dbg->sectiondata[IDX_debug_str_offsets]->d_buf + + str_off + (idx * offset_size)); + if (offset_size == 4) + off = read_4ubyte_unaligned (dbg, datap); + else + off = read_8ubyte_unaligned (dbg, datap); + + if (off > dbg->sectiondata[IDX_debug_str]->d_size) + goto invalid_offset; + } + + return (const char *) data->d_buf + off; +} +INTDEF(dwarf_formstring) diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c new file mode 100644 index 00000000..26f86f12 --- /dev/null +++ b/libdw/dwarf_formudata.c @@ -0,0 +1,357 @@ +/* Return unsigned constant represented by attribute. + Copyright (C) 2003-2012, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + +internal_function const unsigned char * +__libdw_formptr (Dwarf_Attribute *attr, int sec_index, + int err_nodata, const unsigned char **endpp, + Dwarf_Off *offsetp) +{ + if (attr == NULL) + return NULL; + + const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index]; + Dwarf_CU *skel = NULL; /* See below, needed for GNU DebugFission. */ + if (unlikely (d == NULL + && sec_index == IDX_debug_ranges + && attr->cu->version < 5 + && attr->cu->unit_type == DW_UT_split_compile)) + { + skel = __libdw_find_split_unit (attr->cu); + if (skel != NULL) + d = skel->dbg->sectiondata[IDX_debug_ranges]; + } + + if (unlikely (d == NULL)) + { + __libdw_seterrno (err_nodata); + return NULL; + } + + Dwarf_Word offset; + if (attr->form == DW_FORM_sec_offset) + { + /* GNU DebugFission is slightly odd. It uses DW_FORM_sec_offset + in split units, but they are really (unrelocated) offsets + from the skeleton DW_AT_GNU_ranges_base (which is only used + for the split unit, not the skeleton ranges itself, see also + DW_AT_rnglists_base, which is used in DWARF5 for both, but + points to the offsets index). So it isn't really a formptr, + but an offset + base calculation. */ + if (unlikely (skel != NULL)) + { + Elf_Data *data = attr->cu->dbg->sectiondata[cu_sec_idx (attr->cu)]; + const unsigned char *datap = attr->valp; + size_t size = attr->cu->offset_size; + if (unlikely (data == NULL + || datap < (const unsigned char *) data->d_buf + || data->d_size < size + || ((size_t) (datap + - (const unsigned char *) data->d_buf) + > data->d_size - size))) + goto invalid; + + if (size == 4) + offset = read_4ubyte_unaligned (attr->cu->dbg, datap); + else + offset = read_8ubyte_unaligned (attr->cu->dbg, datap); + + offset += __libdw_cu_ranges_base (skel); + } + else + { + if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg, + cu_sec_idx (attr->cu), attr->valp, + attr->cu->offset_size, &offset, + sec_index, 0)) + return NULL; + } + } + else if (attr->cu->version > 3) + goto invalid; + else + switch (attr->form) + { + case DW_FORM_data4: + case DW_FORM_data8: + if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg, + cu_sec_idx (attr->cu), + attr->valp, + attr->form == DW_FORM_data4 ? 4 : 8, + &offset, sec_index, 0)) + return NULL; + break; + + default: + if (INTUSE(dwarf_formudata) (attr, &offset)) + return NULL; + }; + + unsigned char *readp = d->d_buf + offset; + unsigned char *endp = d->d_buf + d->d_size; + if (unlikely (readp >= endp)) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + if (endpp != NULL) + *endpp = endp; + if (offsetp != NULL) + *offsetp = offset; + return readp; +} + +int +dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval) +{ + if (attr == NULL) + return -1; + + const unsigned char *datap = attr->valp; + const unsigned char *endp = attr->cu->endp; + + switch (attr->form) + { + case DW_FORM_data1: + if (datap + 1 > endp) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + *return_uval = *attr->valp; + break; + + case DW_FORM_data2: + if (datap + 2 > endp) + goto invalid; + *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp); + break; + + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_sec_offset: + /* Before DWARF4 data4 and data8 are pure constants unless the + attribute also allows offsets (*ptr classes), since DWARF4 + they are always just constants (start_scope is special though, + since it only could express a rangelist since DWARF4). */ + if (attr->form == DW_FORM_sec_offset + || (attr->cu->version < 4 && attr->code != DW_AT_start_scope)) + { + switch (attr->code) + { + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_location: + case DW_AT_return_addr: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_string_length: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + case DW_AT_GNU_locviews: + case DW_AT_loclists_base: + if (attr->cu->version < 5) + { + /* loclistptr */ + if (__libdw_formptr (attr, IDX_debug_loc, + DWARF_E_NO_DEBUG_LOC, NULL, + return_uval) == NULL) + return -1; + } + else + { + /* loclist, loclistsptr */ + if (__libdw_formptr (attr, IDX_debug_loclists, + DWARF_E_NO_DEBUG_LOCLISTS, NULL, + return_uval) == NULL) + return -1; + } + break; + + case DW_AT_macro_info: + /* macptr into .debug_macinfo */ + if (__libdw_formptr (attr, IDX_debug_macinfo, + DWARF_E_NO_ENTRY, NULL, + return_uval) == NULL) + return -1; + break; + + case DW_AT_GNU_macros: + case DW_AT_macros: + /* macptr into .debug_macro */ + if (__libdw_formptr (attr, IDX_debug_macro, + DWARF_E_NO_ENTRY, NULL, + return_uval) == NULL) + return -1; + break; + + case DW_AT_ranges: + case DW_AT_start_scope: + case DW_AT_GNU_ranges_base: + case DW_AT_rnglists_base: + if (attr->cu->version < 5) + { + /* rangelistptr */ + if (__libdw_formptr (attr, IDX_debug_ranges, + DWARF_E_NO_DEBUG_RANGES, NULL, + return_uval) == NULL) + return -1; + } + else + { + /* rnglistsptr */ + if (__libdw_formptr (attr, IDX_debug_rnglists, + DWARF_E_NO_DEBUG_RNGLISTS, NULL, + return_uval) == NULL) + return -1; + } + break; + + case DW_AT_stmt_list: + /* lineptr */ + if (__libdw_formptr (attr, IDX_debug_line, + DWARF_E_NO_DEBUG_LINE, NULL, + return_uval) == NULL) + return -1; + break; + + case DW_AT_addr_base: + case DW_AT_GNU_addr_base: + /* addrptr */ + if (__libdw_formptr (attr, IDX_debug_addr, + DWARF_E_NO_DEBUG_ADDR, NULL, + return_uval) == NULL) + return -1; + break; + + case DW_AT_str_offsets_base: + /* stroffsetsptr */ + if (__libdw_formptr (attr, IDX_debug_str_offsets, + DWARF_E_NO_STR_OFFSETS, NULL, + return_uval) == NULL) + return -1; + break; + + default: + /* sec_offset can only be used by one of the above attrs. */ + if (attr->form == DW_FORM_sec_offset) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + /* Not one of the special attributes, just a constant. */ + if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu), + attr->valp, + attr->form == DW_FORM_data4 ? 4 : 8, + return_uval)) + return -1; + break; + } + } + else + { + /* We are dealing with a constant data4 or data8. */ + if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu), + attr->valp, + attr->form == DW_FORM_data4 ? 4 : 8, + return_uval)) + return -1; + } + break; + + case DW_FORM_sdata: + if (datap + 1 > endp) + goto invalid; + get_sleb128 (*return_uval, datap, endp); + break; + + case DW_FORM_udata: + case DW_FORM_rnglistx: + case DW_FORM_loclistx: + if (datap + 1 > endp) + goto invalid; + get_uleb128 (*return_uval, datap, endp); + break; + + case DW_FORM_implicit_const: + // The data comes from the abbrev, which has been bounds checked. + get_sleb128_unchecked (*return_uval, datap); + break; + + /* These are indexes into the .debug_addr section, normally resolved + with dwarf_formaddr. Here treat as constants. */ + case DW_FORM_GNU_addr_index: + case DW_FORM_addrx: + if (datap >= endp) + goto invalid; + get_uleb128 (*return_uval, datap, endp); + break; + + case DW_FORM_addrx1: + if (datap >= endp - 1) + goto invalid; + *return_uval = *datap; + break; + + case DW_FORM_addrx2: + if (datap >= endp - 2) + goto invalid; + *return_uval = read_2ubyte_unaligned (attr->cu->dbg, datap); + break; + + case DW_FORM_addrx3: + if (datap >= endp - 3) + goto invalid; + *return_uval = read_3ubyte_unaligned (attr->cu->dbg, datap); + break; + + case DW_FORM_addrx4: + if (datap >= endp - 4) + goto invalid; + *return_uval = read_4ubyte_unaligned (attr->cu->dbg, datap); + break; + + default: + __libdw_seterrno (DWARF_E_NO_CONSTANT); + return -1; + } + + return 0; +} +INTDEF(dwarf_formudata) diff --git a/libdw/dwarf_frame_cfa.c b/libdw/dwarf_frame_cfa.c new file mode 100644 index 00000000..07f998cd --- /dev/null +++ b/libdw/dwarf_frame_cfa.c @@ -0,0 +1,77 @@ +/* Get CFA expression for frame. + Copyright (C) 2009-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" +#include +#include + +int +dwarf_frame_cfa (Dwarf_Frame *fs, Dwarf_Op **ops, size_t *nops) +{ + /* Maybe there was a previous error. */ + if (fs == NULL) + return -1; + + int result = 0; + switch (fs->cfa_rule) + { + case cfa_undefined: + *ops = NULL; + *nops = 0; + break; + + case cfa_offset: + /* The Dwarf_Op was already fully initialized by execute_cfi. */ + *ops = &fs->cfa_data.offset; + *nops = 1; + break; + + case cfa_expr: + /* Parse the expression into internal form. */ + result = __libdw_intern_expression + (NULL, fs->cache->other_byte_order, + fs->cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8, 4, + &fs->cache->expr_tree, &fs->cfa_data.expr, false, false, + ops, nops, IDX_debug_frame); + break; + + case cfa_invalid: + __libdw_seterrno (DWARF_E_INVALID_CFI); + result = -1; + break; + + default: + abort (); + } + + return result; +} diff --git a/libdw/dwarf_frame_info.c b/libdw/dwarf_frame_info.c new file mode 100644 index 00000000..9ba560fc --- /dev/null +++ b/libdw/dwarf_frame_info.c @@ -0,0 +1,50 @@ +/* Get return address register for frame. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" + +int +dwarf_frame_info (Dwarf_Frame *fs, Dwarf_Addr *start, Dwarf_Addr *end, + bool *signalp) +{ + /* Maybe there was a previous error. */ + if (fs == NULL) + return -1; + + if (start != NULL) + *start = fs->start; + if (end != NULL) + *end = fs->end; + if (signalp != NULL) + *signalp = fs->fde->cie->signal_frame; + return fs->fde->cie->return_address_register; +} diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c new file mode 100644 index 00000000..bcf3fa03 --- /dev/null +++ b/libdw/dwarf_frame_register.c @@ -0,0 +1,119 @@ +/* Get register location expression for frame. + Copyright (C) 2009-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" +#include + +int +dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op ops_mem[3], + Dwarf_Op **ops, size_t *nops) +{ + /* Maybe there was a previous error. */ + if (fs == NULL) + return -1; + + if (unlikely (regno < 0)) + { + __libdw_seterrno (DWARF_E_INVALID_ACCESS); + return -1; + } + + *ops = ops_mem; + *nops = 0; + + if (unlikely ((size_t) regno >= fs->nregs)) + goto default_rule; + + const struct dwarf_frame_register *reg = &fs->regs[regno]; + + switch (reg->rule) + { + case reg_unspecified: + default_rule: + /* Use the default rule for registers not yet mentioned in CFI. */ + if (fs->cache->default_same_value) + goto same_value; + FALLTHROUGH; + case reg_undefined: + /* The value is known to be unavailable. */ + break; + + case reg_same_value: + same_value: + /* The location is not known here, but the caller might know it. */ + *ops = NULL; + break; + + case reg_offset: + case reg_val_offset: + ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_call_frame_cfa }; + if (reg->value != 0) + ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_plus_uconst, + .number = reg->value }; + if (reg->rule == reg_val_offset) + /* A value, not a location. */ + ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_stack_value }; + *ops = ops_mem; + break; + + case reg_register: + ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_regx, + .number = reg->value }; + break; + + case reg_val_expression: + case reg_expression: + { + unsigned int address_size = (fs->cache->e_ident[EI_CLASS] == ELFCLASS32 + ? 4 : 8); + + Dwarf_Block block; + const uint8_t *p = fs->cache->data->d.d_buf + reg->value; + const uint8_t *end = (fs->cache->data->d.d_buf + + fs->cache->data->d.d_size); + get_uleb128 (block.length, p, end); + block.data = (void *) p; + + /* Parse the expression into internal form. */ + if (__libdw_intern_expression (NULL, + fs->cache->other_byte_order, + address_size, 4, + &fs->cache->expr_tree, &block, + true, reg->rule == reg_val_expression, + ops, nops, IDX_debug_frame) < 0) + return -1; + break; + } + } + + return 0; +} diff --git a/libdw/dwarf_func_inline.c b/libdw/dwarf_func_inline.c new file mode 100644 index 00000000..1f04adfa --- /dev/null +++ b/libdw/dwarf_func_inline.c @@ -0,0 +1,101 @@ +/* Convenience functions for handling DWARF descriptions of inline functions. + Copyright (C) 2005,2006,2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + +struct visitor_info +{ + void *die_addr; + int (*callback) (Dwarf_Die *, void *); + void *arg; +}; + +static int +scope_visitor (unsigned int depth __attribute__ ((unused)), + struct Dwarf_Die_Chain *die, void *arg) +{ + struct visitor_info *const v = arg; + + if (INTUSE(dwarf_tag) (&die->die) != DW_TAG_inlined_subroutine) + return DWARF_CB_OK; + + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&die->die, DW_AT_abstract_origin, + &attr_mem); + if (attr == NULL) + return DWARF_CB_OK; + + Dwarf_Die origin_mem; + Dwarf_Die *origin = INTUSE(dwarf_formref_die) (attr, &origin_mem); + if (origin == NULL) + return DWARF_CB_ABORT; + + if (origin->addr != v->die_addr) + return DWARF_CB_OK; + + return (*v->callback) (&die->die, v->arg); +} + +int +dwarf_func_inline (Dwarf_Die *func) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word val; + if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (func, DW_AT_inline, + &attr_mem), + &val) == 0) + switch (val) + { + case DW_INL_not_inlined: + return 0; + + case DW_INL_declared_not_inlined: + return -1; + + case DW_INL_inlined: + case DW_INL_declared_inlined: + return 1; + } + + return 0; +} + +int +dwarf_func_inline_instances (Dwarf_Die *func, + int (*callback) (Dwarf_Die *, void *), + void *arg) +{ + struct visitor_info v = { func->addr, callback, arg }; + struct Dwarf_Die_Chain cu = { .die = CUDIE (func->cu), .parent = NULL }; + return __libdw_visit_scopes (0, &cu, NULL, &scope_visitor, NULL, &v); +} diff --git a/libdw/dwarf_get_units.c b/libdw/dwarf_get_units.c new file mode 100644 index 00000000..6215bf4b --- /dev/null +++ b/libdw/dwarf_get_units.c @@ -0,0 +1,131 @@ +/* Iterate through the CU units for a given Dwarf. + Copyright (C) 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libdwP.h" + +int +dwarf_get_units (Dwarf *dwarf, Dwarf_CU *cu, Dwarf_CU **next_cu, + Dwarf_Half *version, uint8_t *unit_type, + Dwarf_Die *cudie, Dwarf_Die *subdie) +{ + /* Handle existing error. */ + if (dwarf == NULL) + return -1; + + Dwarf_Off off; + bool v4type; + if (cu == NULL) + { + off = 0; + v4type = false; + } + else + { + off = cu->end; + v4type = cu->sec_idx != IDX_debug_info; + + /* Make sure we got a real (not fake) CU. */ + if (cu->sec_idx != IDX_debug_info && cu->sec_idx != IDX_debug_types) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + + /* Do we have to switch to the other section, or are we at the end? */ + if (! v4type) + { + if (off >= cu->dbg->sectiondata[IDX_debug_info]->d_size) + { + if (cu->dbg->sectiondata[IDX_debug_types] == NULL) + return 1; + + off = 0; + v4type = true; + } + } + else + if (off >= cu->dbg->sectiondata[IDX_debug_types]->d_size) + return 1; + } + + *next_cu = __libdw_findcu (dwarf, off, v4type); + if (*next_cu == NULL) + return -1; + + Dwarf_CU *next = (*next_cu); + + if (version != NULL) + *version = next->version; + + if (unit_type != NULL) + *unit_type = next->unit_type; + + if (cudie != NULL) + { + if (next->version >= 2 && next->version <= 5 + && next->unit_type >= DW_UT_compile + && next->unit_type <= DW_UT_split_type) + *cudie = CUDIE (next); + else + memset (cudie, '\0', sizeof (Dwarf_Die)); + } + + if (subdie != NULL) + { + if (next->version >= 2 && next->version <= 5) + { + /* For types, return the actual type DIE. For skeletons, + find the associated split compile unit and return its + DIE. */ + if (next->unit_type == DW_UT_type + || next->unit_type == DW_UT_split_type) + *subdie = SUBDIE(next); + else if (next->unit_type == DW_UT_skeleton) + { + Dwarf_CU *split_cu = __libdw_find_split_unit (next); + if (split_cu != NULL) + *subdie = CUDIE(split_cu); + else + memset (subdie, '\0', sizeof (Dwarf_Die)); + } + else + memset (subdie, '\0', sizeof (Dwarf_Die)); + } + else + memset (subdie, '\0', sizeof (Dwarf_Die)); + } + + return 0; +} diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c new file mode 100644 index 00000000..13bee493 --- /dev/null +++ b/libdw/dwarf_getabbrev.c @@ -0,0 +1,186 @@ +/* Get abbreviation at given offset. + Copyright (C) 2003, 2004, 2005, 2006, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Abbrev * +internal_function +__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, + size_t *lengthp, Dwarf_Abbrev *result) +{ + /* Don't fail if there is not .debug_abbrev section. */ + if (dbg->sectiondata[IDX_debug_abbrev] == NULL) + return NULL; + + if (offset >= dbg->sectiondata[IDX_debug_abbrev]->d_size) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return NULL; + } + + const unsigned char *abbrevp + = (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset; + + if (*abbrevp == '\0') + /* We are past the last entry. */ + return DWARF_END_ABBREV; + + /* 7.5.3 Abbreviations Tables + + [...] Each declaration begins with an unsigned LEB128 number + representing the abbreviation code itself. [...] The + abbreviation code is followed by another unsigned LEB128 + number that encodes the entry's tag. [...] + + [...] Following the tag encoding is a 1-byte value that + determines whether a debugging information entry using this + abbreviation has child entries or not. [...] + + [...] Finally, the child encoding is followed by a series of + attribute specifications. Each attribute specification + consists of two parts. The first part is an unsigned LEB128 + number representing the attribute's name. The second part is + an unsigned LEB128 number representing the attribute's form. */ + const unsigned char *end = (dbg->sectiondata[IDX_debug_abbrev]->d_buf + + dbg->sectiondata[IDX_debug_abbrev]->d_size); + const unsigned char *start_abbrevp = abbrevp; + unsigned int code; + get_uleb128 (code, abbrevp, end); + + /* Check whether this code is already in the hash table. */ + bool foundit = false; + Dwarf_Abbrev *abb = NULL; + if (cu == NULL + || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code)) == NULL) + { + if (result == NULL) + abb = libdw_typed_alloc (dbg, Dwarf_Abbrev); + else + abb = result; + } + else + { + foundit = true; + + if (unlikely (abb->offset != offset)) + { + /* A duplicate abbrev code at a different offset, + that should never happen. */ + invalid: + if (! foundit) + libdw_typed_unalloc (dbg, Dwarf_Abbrev); + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* If the caller doesn't need the length we are done. */ + if (lengthp == NULL) + goto out; + } + + /* If there is already a value in the hash table we are going to + overwrite its content. This must not be a problem, since the + content better be the same. */ + abb->code = code; + if (abbrevp >= end) + goto invalid; + get_uleb128 (abb->tag, abbrevp, end); + if (abbrevp + 1 >= end) + goto invalid; + abb->has_children = *abbrevp++ == DW_CHILDREN_yes; + abb->attrp = (unsigned char *) abbrevp; + abb->offset = offset; + + /* Skip over all the attributes and check rest of the abbrev is valid. */ + unsigned int attrname; + unsigned int attrform; + do + { + if (abbrevp >= end) + goto invalid; + get_uleb128 (attrname, abbrevp, end); + if (abbrevp >= end) + goto invalid; + get_uleb128 (attrform, abbrevp, end); + if (attrform == DW_FORM_implicit_const) + { + int64_t formval __attribute__((__unused__)); + if (abbrevp >= end) + goto invalid; + get_sleb128 (formval, abbrevp, end); + } + } + while (attrname != 0 || attrform != 0); + + /* Return the length to the caller if she asked for it. */ + if (lengthp != NULL) + *lengthp = abbrevp - start_abbrevp; + + /* Add the entry to the hash table. */ + if (cu != NULL && ! foundit) + if (Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb) == -1) + { + /* The entry was already in the table, remove the one we just + created and get the one already inserted. */ + libdw_typed_unalloc (dbg, Dwarf_Abbrev); + abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code); + } + + out: + return abb; +} + + +Dwarf_Abbrev * +dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, size_t *lengthp) +{ + if (die == NULL || die->cu == NULL) + return NULL; + + Dwarf_CU *cu = die->cu; + Dwarf *dbg = cu->dbg; + Dwarf_Off abbrev_offset = cu->orig_abbrev_offset; + Elf_Data *data = dbg->sectiondata[IDX_debug_abbrev]; + if (data == NULL) + return NULL; + + if (offset >= data->d_size - abbrev_offset) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return NULL; + } + + return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp, NULL); +} diff --git a/libdw/dwarf_getabbrevattr.c b/libdw/dwarf_getabbrevattr.c new file mode 100644 index 00000000..54ff604f --- /dev/null +++ b/libdw/dwarf_getabbrevattr.c @@ -0,0 +1,94 @@ +/* Get specific attribute of abbreviation. + Copyright (C) 2003, 2004, 2005, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + + +int +dwarf_getabbrevattr_data (Dwarf_Abbrev *abbrev, size_t idx, + unsigned int *namep, unsigned int *formp, + Dwarf_Sword *datap, Dwarf_Off *offsetp) +{ + if (abbrev == NULL) + return -1; + + size_t cnt = 0; + const unsigned char *attrp = abbrev->attrp; + const unsigned char *start_attrp; + unsigned int name; + unsigned int form; + Dwarf_Word data; + + do + { + start_attrp = attrp; + + /* Attribute code and form are encoded as ULEB128 values. + Already checked when Dwarf_Abbrev was created, read unchecked. */ + get_uleb128_unchecked (name, attrp); + get_uleb128_unchecked (form, attrp); + + if (form == DW_FORM_implicit_const) + get_sleb128_unchecked (data, attrp); + else + data = 0; + + /* If both values are zero the index is out of range. */ + if (name == 0 && form == 0) + return -1; + } + while (cnt++ < idx); + + /* Store the result if requested. */ + if (namep != NULL) + *namep = name; + if (formp != NULL) + *formp = form; + if (datap != NULL) + *datap = data; + if (offsetp != NULL) + *offsetp = (start_attrp - abbrev->attrp) + abbrev->offset; + + return 0; +} +INTDEF(dwarf_getabbrevattr_data) + +int +dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx, unsigned int *namep, + unsigned int *formp, Dwarf_Off *offsetp) +{ + return INTUSE(dwarf_getabbrevattr_data) (abbrev, idx, namep, formp, + NULL, offsetp); +} diff --git a/libdw/dwarf_getabbrevcode.c b/libdw/dwarf_getabbrevcode.c new file mode 100644 index 00000000..86917084 --- /dev/null +++ b/libdw/dwarf_getabbrevcode.c @@ -0,0 +1,43 @@ +/* Get abbreviation code. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + + +unsigned int +dwarf_getabbrevcode (Dwarf_Abbrev *abbrev) +{ + return abbrev == NULL ? 0 : abbrev->code; +} diff --git a/libdw/dwarf_getabbrevtag.c b/libdw/dwarf_getabbrevtag.c new file mode 100644 index 00000000..52aaa3f3 --- /dev/null +++ b/libdw/dwarf_getabbrevtag.c @@ -0,0 +1,43 @@ +/* Get abbreviation tag. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + + +unsigned int +dwarf_getabbrevtag (Dwarf_Abbrev *abbrev) +{ + return abbrev == NULL ? 0 : abbrev->tag; +} diff --git a/libdw/dwarf_getalt.c b/libdw/dwarf_getalt.c new file mode 100644 index 00000000..0a12dfae --- /dev/null +++ b/libdw/dwarf_getalt.c @@ -0,0 +1,184 @@ +/* Retrieves the DWARF descriptor for debugaltlink data. + Copyright (C) 2014, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include "libelfP.h" +#include "libdwelfP.h" +#include "system.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +char * +internal_function +__libdw_filepath (const char *debugdir, const char *dir, const char *file) +{ + if (file == NULL) + return NULL; + + if (file[0] == '/') + return strdup (file); + + if (dir != NULL && dir[0] == '/') + { + size_t dirlen = strlen (dir); + size_t filelen = strlen (file); + size_t len = dirlen + 1 + filelen + 1; + char *path = malloc (len); + if (path != NULL) + { + char *c = mempcpy (path, dir, dirlen); + if (dir[dirlen - 1] != '/') + *c++ = '/'; + mempcpy (c, file, filelen + 1); + } + return path; + } + + if (debugdir != NULL) + { + size_t debugdirlen = strlen (debugdir); + size_t dirlen = dir != NULL ? strlen (dir) : 0; + size_t filelen = strlen (file); + size_t len = debugdirlen + 1 + dirlen + 1 + filelen + 1; + char *path = malloc (len); + if (path != NULL) + { + char *c = mempcpy (path, debugdir, debugdirlen); + if (dirlen > 0) + { + c = mempcpy (c, dir, dirlen); + if (dir[dirlen - 1] != '/') + *c++ = '/'; + } + mempcpy (c, file, filelen + 1); + return path; + } + } + + return NULL; +} + +static void +find_debug_altlink (Dwarf *dbg) +{ + const char *altname; + const void *build_id; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (dbg, + &altname, + &build_id); + + /* Couldn't even get the debugaltlink. It probably doesn't exist. */ + if (build_id_len <= 0) + return; + + const uint8_t *id = (const uint8_t *) build_id; + size_t id_len = build_id_len; + int fd = -1; + + /* We only look in the standard path. And relative to the dbg file. */ +#define DEBUGINFO_PATH "/usr/lib/debug" + + /* We don't handle very short or really large build-ids. We need at + at least 3 and allow for up to 64 (normally ids are 20 long). */ +#define MIN_BUILD_ID_BYTES 3 +#define MAX_BUILD_ID_BYTES 64 + if (id_len >= MIN_BUILD_ID_BYTES && id_len <= MAX_BUILD_ID_BYTES) + { + /* Note sizeof a string literal includes the trailing zero. */ + char id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1 + + 2 + 1 + (MAX_BUILD_ID_BYTES - 1) * 2 + sizeof ".debug"]; + sprintf (&id_path[0], "%s%s", DEBUGINFO_PATH, "/.build-id/"); + sprintf (&id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1], + "%02" PRIx8 "/", (uint8_t) id[0]); + for (size_t i = 1; i < id_len; ++i) + sprintf (&id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1 + + 3 + (i - 1) * 2], "%02" PRIx8, (uint8_t) id[i]); + strcpy (&id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1 + + 3 + (id_len - 1) * 2], ".debug"); + + fd = TEMP_FAILURE_RETRY (open (id_path, O_RDONLY)); + } + + /* Fall back on (possible relative) alt file path. */ + if (fd < 0) + { + char *altpath = __libdw_filepath (dbg->debugdir, NULL, altname); + if (altpath != NULL) + { + fd = TEMP_FAILURE_RETRY (open (altpath, O_RDONLY)); + free (altpath); + } + } + + if (fd >= 0) + { + Dwarf *alt = dwarf_begin (fd, O_RDONLY); + if (alt != NULL) + { + dbg->alt_dwarf = alt; + dbg->alt_fd = fd; + } + else + close (fd); + } +} + +Dwarf * +dwarf_getalt (Dwarf *main) +{ + /* Only try once. */ + if (main == NULL || main->alt_dwarf == (void *) -1) + return NULL; + + if (main->alt_dwarf != NULL) + return main->alt_dwarf; + + find_debug_altlink (main); + + /* If we found nothing, make sure we don't try again. */ + if (main->alt_dwarf == NULL) + { + main->alt_dwarf = (void *) -1; + return NULL; + } + + return main->alt_dwarf; +} +INTDEF (dwarf_getalt) diff --git a/libdw/dwarf_getarange_addr.c b/libdw/dwarf_getarange_addr.c new file mode 100644 index 00000000..d383e228 --- /dev/null +++ b/libdw/dwarf_getarange_addr.c @@ -0,0 +1,60 @@ +/* Get address range which includes given address. + Copyright (C) 2004, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +Dwarf_Arange * +dwarf_getarange_addr (Dwarf_Aranges *aranges, Dwarf_Addr addr) +{ + if (aranges == NULL) + return NULL; + + /* The ranges are sorted by address, so we can use binary search. */ + size_t l = 0, u = aranges->naranges; + while (l < u) + { + size_t idx = (l + u) / 2; + if (addr < aranges->info[idx].addr) + u = idx; + else if (addr > aranges->info[idx].addr + && addr - aranges->info[idx].addr >= aranges->info[idx].length) + l = idx + 1; + else + return &aranges->info[idx]; + } + + __libdw_seterrno (DWARF_E_NO_MATCH); + return NULL; +} +INTDEF(dwarf_getarange_addr) diff --git a/libdw/dwarf_getarangeinfo.c b/libdw/dwarf_getarangeinfo.c new file mode 100644 index 00000000..67b6e671 --- /dev/null +++ b/libdw/dwarf_getarangeinfo.c @@ -0,0 +1,53 @@ +/* Return list address ranges. + Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp, + Dwarf_Word *lengthp, Dwarf_Off *offsetp) +{ + if (arange == NULL) + return -1; + + if (addrp != NULL) + *addrp = arange->addr; + if (lengthp != NULL) + *lengthp = arange->length; + if (offsetp != NULL) + *offsetp = arange->offset; + + return 0; +} +INTDEF(dwarf_getarangeinfo) diff --git a/libdw/dwarf_getaranges.c b/libdw/dwarf_getaranges.c new file mode 100644 index 00000000..de5b81ba --- /dev/null +++ b/libdw/dwarf_getaranges.c @@ -0,0 +1,277 @@ +/* Return list address ranges. + Copyright (C) 2000-2010, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" +#include + +struct arangelist +{ + Dwarf_Arange arange; + struct arangelist *next; +}; + +/* Compare by Dwarf_Arange.addr, given pointers into an array of pointeers. */ +static int +compare_aranges (const void *a, const void *b) +{ + struct arangelist *const *p1 = a, *const *p2 = b; + struct arangelist *l1 = *p1, *l2 = *p2; + if (l1->arange.addr != l2->arange.addr) + return (l1->arange.addr < l2->arange.addr) ? -1 : 1; + return 0; +} + +int +dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, size_t *naranges) +{ + if (dbg == NULL) + return -1; + + if (dbg->aranges != NULL) + { + *aranges = dbg->aranges; + if (naranges != NULL) + *naranges = dbg->aranges->naranges; + return 0; + } + + if (dbg->sectiondata[IDX_debug_aranges] == NULL) + { + /* No such section. */ + *aranges = NULL; + if (naranges != NULL) + *naranges = 0; + return 0; + } + + if (dbg->sectiondata[IDX_debug_aranges]->d_buf == NULL) + return -1; + + struct arangelist *arangelist = NULL; + unsigned int narangelist = 0; + + const unsigned char *readp = dbg->sectiondata[IDX_debug_aranges]->d_buf; + const unsigned char *readendp + = readp + dbg->sectiondata[IDX_debug_aranges]->d_size; + + while (readp < readendp) + { + const unsigned char *hdrstart = readp; + + /* Each entry starts with a header: + + 1. A 4-byte or 12-byte length containing the length of the + set of entries for this compilation unit, not including the + length field itself. [...] + + 2. A 2-byte version identifier containing the value 2 for + DWARF Version 2.1. + + 3. A 4-byte or 8-byte offset into the .debug_info section. [...] + + 4. A 1-byte unsigned integer containing the size in bytes of + an address (or the offset portion of an address for segmented + addressing) on the target system. + + 5. A 1-byte unsigned integer containing the size in bytes of + a segment descriptor on the target system. */ + if (unlikely (readp + 4 > readendp)) + goto invalid; + + Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int length_bytes = 4; + if (length == DWARF3_LENGTH_64_BIT) + { + if (unlikely (readp + 8 > readendp)) + goto invalid; + + length = read_8ubyte_unaligned_inc (dbg, readp); + length_bytes = 8; + } + else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE + && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) + goto invalid; + + if (unlikely (readp + 2 > readendp)) + goto invalid; + + unsigned int version = read_2ubyte_unaligned_inc (dbg, readp); + if (version != 2) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + fail: + while (arangelist != NULL) + { + struct arangelist *next = arangelist->next; + free (arangelist); + arangelist = next; + } + return -1; + } + + Dwarf_Word offset = 0; + if (__libdw_read_offset_inc (dbg, + IDX_debug_aranges, &readp, + length_bytes, &offset, IDX_debug_info, 4)) + goto fail; + + /* Next up two bytes for address and segment size. */ + if (readp + 2 > readendp) + goto invalid; + + unsigned int address_size = *readp++; + if (unlikely (address_size != 4 && address_size != 8)) + goto invalid; + + /* We don't actually support segment selectors. */ + unsigned int segment_size = *readp++; + if (segment_size != 0) + goto invalid; + + /* Round the address to the next multiple of 2*address_size. */ + readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size))) + % (2 * address_size)); + + while (1) + { + Dwarf_Word range_address; + Dwarf_Word range_length; + + if (__libdw_read_address_inc (dbg, IDX_debug_aranges, &readp, + address_size, &range_address)) + goto fail; + + if (readp + address_size > readendp) + goto invalid; + + if (address_size == 4) + range_length = read_4ubyte_unaligned_inc (dbg, readp); + else + range_length = read_8ubyte_unaligned_inc (dbg, readp); + + /* Two zero values mark the end. */ + if (range_address == 0 && range_length == 0) + break; + + /* We don't use alloca for these temporary structures because + the total number of them can be quite large. */ + struct arangelist *new_arange = malloc (sizeof *new_arange); + if (unlikely (new_arange == NULL)) + { + __libdw_seterrno (DWARF_E_NOMEM); + goto fail; + } + + new_arange->arange.addr = range_address; + new_arange->arange.length = range_length; + + /* We store the actual CU DIE offset, not the CU header offset. */ + Dwarf_CU *cu = __libdw_findcu (dbg, offset, false); + if (unlikely (cu == NULL)) + { + /* We haven't gotten a chance to link in the new_arange + into the arangelist, don't leak it. */ + free (new_arange); + goto fail; + } + new_arange->arange.offset = __libdw_first_die_off_from_cu (cu); + + new_arange->next = arangelist; + arangelist = new_arange; + ++narangelist; + + /* Sanity-check the data. */ + if (unlikely (new_arange->arange.offset + >= dbg->sectiondata[IDX_debug_info]->d_size)) + goto invalid; + } + } + + if (narangelist == 0) + { + assert (arangelist == NULL); + if (naranges != NULL) + *naranges = 0; + *aranges = NULL; + return 0; + } + + /* Allocate the array for the result. */ + void *buf = libdw_alloc (dbg, Dwarf_Aranges, + sizeof (Dwarf_Aranges) + + narangelist * sizeof (Dwarf_Arange), 1); + + /* First use the buffer for the pointers, and sort the entries. + We'll write the pointers in the end of the buffer, and then + copy into the buffer from the beginning so the overlap works. */ + assert (sizeof (Dwarf_Arange) >= sizeof (Dwarf_Arange *)); + struct arangelist **sortaranges + = (buf + sizeof (Dwarf_Aranges) + + ((sizeof (Dwarf_Arange) - sizeof sortaranges[0]) * narangelist)); + + /* The list is in LIFO order and usually they come in clumps with + ascending addresses. So fill from the back to probably start with + runs already in order before we sort. */ + unsigned int i = narangelist; + while (i-- > 0) + { + sortaranges[i] = arangelist; + arangelist = arangelist->next; + } + assert (arangelist == NULL); + + /* Sort by ascending address. */ + qsort (sortaranges, narangelist, sizeof sortaranges[0], &compare_aranges); + + /* Now that they are sorted, put them in the final array. + The buffers overlap, so we've clobbered the early elements + of SORTARANGES by the time we're reading the later ones. */ + *aranges = buf; + (*aranges)->dbg = dbg; + (*aranges)->naranges = narangelist; + dbg->aranges = *aranges; + if (naranges != NULL) + *naranges = narangelist; + for (i = 0; i < narangelist; ++i) + { + struct arangelist *elt = sortaranges[i]; + (*aranges)->info[i] = elt->arange; + free (elt); + } + + return 0; +} +INTDEF(dwarf_getaranges) diff --git a/libdw/dwarf_getattrcnt.c b/libdw/dwarf_getattrcnt.c new file mode 100644 index 00000000..a05976d4 --- /dev/null +++ b/libdw/dwarf_getattrcnt.c @@ -0,0 +1,61 @@ +/* Get number of attributes of abbreviation. + Copyright (C) 2003, 2004, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp) +{ + if (abbrev == NULL) + return -1; + + const unsigned char *abbrevp = abbrev->attrp; + + /* Skip over all the attributes and count them while doing so. */ + int attrcnt = 0; + unsigned int attrname; + unsigned int attrform; + do + { + /* We can use unchecked since they were checked when the Dwrf_Abbrev + was created. */ + get_uleb128_unchecked (attrname, abbrevp); + get_uleb128_unchecked (attrform, abbrevp); + } + while (attrname != 0 && attrform != 0 && ++attrcnt); + + *attrcntp = attrcnt; + + return 0; +} diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c new file mode 100644 index 00000000..770c32c9 --- /dev/null +++ b/libdw/dwarf_getattrs.c @@ -0,0 +1,132 @@ +/* Get attributes of the DIE. + Copyright (C) 2004, 2005, 2008, 2009, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +ptrdiff_t +dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), + void *arg, ptrdiff_t offset) +{ + if (die == NULL) + return -1l; + + if (unlikely (offset == 1)) + return 1; + + const unsigned char *die_addr = NULL; + + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &die_addr); + + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1l; + } + + const unsigned char *endp = die->cu->endp; + + /* This is where the attributes start. */ + const unsigned char *attrp = abbrevp->attrp; + const unsigned char *const offset_attrp = abbrevp->attrp + offset; + + /* Go over the list of attributes. */ + while (1) + { + /* Get attribute name and form. Dwarf_Abbrev was checked when + created, so we can read unchecked. */ + Dwarf_Attribute attr; + const unsigned char *remembered_attrp = attrp; + + get_uleb128_unchecked (attr.code, attrp); + get_uleb128_unchecked (attr.form, attrp); + + /* We can stop if we found the attribute with value zero. */ + if (attr.code == 0 && attr.form == 0) + /* Do not return 0 here - there would be no way to + distinguish this value from the attribute at offset 0. + Instead we return +1 which would never be a valid + offset of an attribute. */ + return 1l; + + if (attr.form == DW_FORM_indirect) + { + get_uleb128 (attr.form, die_addr, endp); + if (attr.form == DW_FORM_indirect || + attr.form == DW_FORM_implicit_const) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1l; + } + } + + /* If we are not to OFFSET_ATTRP yet, we just have to skip + the values of the intervening attributes. */ + if (remembered_attrp >= offset_attrp) + { + /* Fill in the rest. */ + if (attr.form == DW_FORM_implicit_const) + attr.valp = (unsigned char *) attrp; + else + attr.valp = (unsigned char *) die_addr; + attr.cu = die->cu; + + /* Now call the callback function. */ + if (callback (&attr, arg) != DWARF_CB_OK) + /* Return the offset of the start of the attribute, so that + dwarf_getattrs() can be restarted from this point if the + caller so desires. */ + return remembered_attrp - abbrevp->attrp; + } + + /* Skip over the rest of this attribute (if there is any). */ + if (attr.form != 0) + { + size_t len = __libdw_form_val_len (die->cu, attr.form, die_addr); + if (unlikely (len == (size_t) -1l)) + /* Something wrong with the file. */ + return -1l; + + // __libdw_form_val_len will have done a bounds check. + die_addr += len; + + if (attr.form == DW_FORM_implicit_const) + { + int64_t attr_value __attribute__((__unused__)); + get_sleb128_unchecked (attr_value, attrp); + } + } + } + /* NOTREACHED */ +} diff --git a/libdw/dwarf_getcfi.c b/libdw/dwarf_getcfi.c new file mode 100644 index 00000000..afa8a460 --- /dev/null +++ b/libdw/dwarf_getcfi.c @@ -0,0 +1,78 @@ +/* Get CFI from DWARF file. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include "cfi.h" +#include + +Dwarf_CFI * +dwarf_getcfi (Dwarf *dbg) +{ + if (dbg == NULL) + return NULL; + + if (dbg->cfi == NULL && dbg->sectiondata[IDX_debug_frame] != NULL) + { + Dwarf_CFI *cfi = libdw_typed_alloc (dbg, Dwarf_CFI); + + cfi->dbg = dbg; + cfi->data = (Elf_Data_Scn *) dbg->sectiondata[IDX_debug_frame]; + + cfi->search_table = NULL; + cfi->search_table_vaddr = 0; + cfi->search_table_entries = 0; + cfi->search_table_encoding = DW_EH_PE_omit; + + cfi->frame_vaddr = 0; + cfi->textrel = 0; + cfi->datarel = 0; + + cfi->e_ident = (unsigned char *) elf_getident (dbg->elf, NULL); + + GElf_Ehdr ehdr; + gelf_getehdr (dbg->elf, &ehdr); + cfi->e_machine = ehdr.e_machine; + + cfi->other_byte_order = dbg->other_byte_order; + cfi->default_same_value = false; + + cfi->next_offset = 0; + cfi->cie_tree = cfi->fde_tree = cfi->expr_tree = NULL; + + cfi->ebl = NULL; + + dbg->cfi = cfi; + } + + return dbg->cfi; +} +INTDEF (dwarf_getcfi) diff --git a/libdw/dwarf_getcfi_elf.c b/libdw/dwarf_getcfi_elf.c new file mode 100644 index 00000000..c0e3cadd --- /dev/null +++ b/libdw/dwarf_getcfi_elf.c @@ -0,0 +1,338 @@ +/* Get CFI from ELF file's exception-handling info. + Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libdwP.h" +#include "cfi.h" +#include "encoded-value.h" +#include + + +static Dwarf_CFI * +allocate_cfi (Elf *elf, const GElf_Ehdr *ehdr, GElf_Addr vaddr) +{ + Dwarf_CFI *cfi = calloc (1, sizeof *cfi); + if (cfi == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + cfi->e_ident = (unsigned char *) elf_getident (elf, NULL); + if (cfi->e_ident == NULL) + { + free (cfi); + __libdw_seterrno (DWARF_E_GETEHDR_ERROR); + return NULL; + } + + cfi->e_machine = ehdr->e_machine; + + if ((BYTE_ORDER == LITTLE_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2MSB) + || (BYTE_ORDER == BIG_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2LSB)) + cfi->other_byte_order = true; + + cfi->frame_vaddr = vaddr; + cfi->textrel = 0; /* XXX ? */ + cfi->datarel = 0; /* XXX ? */ + + return cfi; +} + +static const uint8_t * +parse_eh_frame_hdr (const uint8_t *hdr, size_t hdr_size, GElf_Addr hdr_vaddr, + const GElf_Ehdr *ehdr, GElf_Addr *eh_frame_vaddr, + size_t *table_entries, uint8_t *table_encoding) +{ + const uint8_t *h = hdr; + + if (hdr_size < 4 || *h++ != 1) /* version */ + return (void *) -1l; + + uint8_t eh_frame_ptr_encoding = *h++; + uint8_t fde_count_encoding = *h++; + uint8_t fde_table_encoding = *h++; + + if (eh_frame_ptr_encoding == DW_EH_PE_omit) + return (void *) -1l; + + /* Dummy used by read_encoded_value. */ + Elf_Data_Scn dummy_cfi_hdr_data = + { + .d = { .d_buf = (void *) hdr, .d_size = hdr_size } + }; + Dwarf_CFI dummy_cfi = + { + .e_ident = ehdr->e_ident, + .datarel = hdr_vaddr, + .frame_vaddr = hdr_vaddr, + .data = &dummy_cfi_hdr_data, + }; + + if (unlikely (read_encoded_value (&dummy_cfi, eh_frame_ptr_encoding, &h, + eh_frame_vaddr))) + return (void *) -1l; + + if (fde_count_encoding != DW_EH_PE_omit) + { + Dwarf_Word fde_count; + if (unlikely (read_encoded_value (&dummy_cfi, fde_count_encoding, &h, + &fde_count))) + return (void *) -1l; + if (fde_count != 0 && (size_t) fde_count == fde_count + && fde_table_encoding != DW_EH_PE_omit + && (fde_table_encoding &~ DW_EH_PE_signed) != DW_EH_PE_uleb128) + { + *table_entries = fde_count; + *table_encoding = fde_table_encoding; + return h; + } + } + + return NULL; +} + +static Dwarf_CFI * +getcfi_gnu_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, const GElf_Phdr *phdr) +{ + Elf_Data *data = elf_getdata_rawchunk (elf, phdr->p_offset, phdr->p_filesz, + ELF_T_BYTE); + if (data == NULL || data->d_buf == NULL) + { + invalid_hdr: + /* XXX might be read error or corrupt phdr */ + __libdw_seterrno (DWARF_E_INVALID_CFI); + return NULL; + } + + size_t vsize, dmax; + Dwarf_Addr eh_frame_ptr; + size_t search_table_entries = 0; + uint8_t search_table_encoding = 0; + const uint8_t *search_table = parse_eh_frame_hdr (data->d_buf, phdr->p_filesz, + phdr->p_vaddr, ehdr, + &eh_frame_ptr, + &search_table_entries, + &search_table_encoding); + + /* Make sure there is enough room for the entries in the table, + each entry consists of 2 encoded values. */ + vsize = encoded_value_size (data, ehdr->e_ident, search_table_encoding, + NULL); + dmax = phdr->p_filesz - (search_table - (const uint8_t *) data->d_buf); + if (unlikely (search_table == (void *) -1l + || vsize == 0 + || search_table_entries > (dmax / vsize) / 2)) + goto invalid_hdr; + + Dwarf_Off eh_frame_offset = eh_frame_ptr - phdr->p_vaddr + phdr->p_offset; + Dwarf_Word eh_frame_size = 0; + + /* XXX we have no way without section headers to know the size + of the .eh_frame data. Calculate the largest it might possibly be. + This won't be wasteful if the file is already mmap'd, but if it isn't + it might be quite excessive. */ + size_t filesize; + if (elf_rawfile (elf, &filesize) != NULL) + eh_frame_size = filesize - eh_frame_offset; + + data = elf_getdata_rawchunk (elf, eh_frame_offset, eh_frame_size, ELF_T_BYTE); + if (data == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_ELF); /* XXX might be read error */ + return NULL; + } + Dwarf_CFI *cfi = allocate_cfi (elf, ehdr, eh_frame_ptr); + if (cfi != NULL) + { + cfi->data = (Elf_Data_Scn *) data; + + if (search_table != NULL) + { + cfi->search_table = search_table; + cfi->search_table_len = phdr->p_filesz; + cfi->search_table_vaddr = phdr->p_vaddr; + cfi->search_table_encoding = search_table_encoding; + cfi->search_table_entries = search_table_entries; + } + } + return cfi; +} + +/* Search the phdrs for PT_GNU_EH_FRAME. */ +static Dwarf_CFI * +getcfi_phdr (Elf *elf, const GElf_Ehdr *ehdr) +{ + size_t phnum; + if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) + return NULL; + + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (unlikely (phdr == NULL)) + return NULL; + if (phdr->p_type == PT_GNU_EH_FRAME) + return getcfi_gnu_eh_frame (elf, ehdr, phdr); + } + + __libdw_seterrno (DWARF_E_NO_DWARF); + return NULL; +} + +static Dwarf_CFI * +getcfi_scn_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, + Elf_Scn *hdr_scn, GElf_Addr hdr_vaddr) +{ + Elf_Data *data = elf_rawdata (scn, NULL); + if (data == NULL || data->d_buf == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_ELF); + return NULL; + } + Dwarf_CFI *cfi = allocate_cfi (elf, ehdr, shdr->sh_addr); + if (cfi != NULL) + { + cfi->data = (Elf_Data_Scn *) data; + if (hdr_scn != NULL) + { + Elf_Data *hdr_data = elf_rawdata (hdr_scn, NULL); + if (hdr_data != NULL && hdr_data->d_buf != NULL) + { + size_t vsize, dmax; + GElf_Addr eh_frame_vaddr; + cfi->search_table_vaddr = hdr_vaddr; + cfi->search_table + = parse_eh_frame_hdr (hdr_data->d_buf, hdr_data->d_size, + hdr_vaddr, ehdr, &eh_frame_vaddr, + &cfi->search_table_entries, + &cfi->search_table_encoding); + cfi->search_table_len = hdr_data->d_size; + + /* Make sure there is enough room for the entries in the table, + each entry consists of 2 encoded values. */ + vsize = encoded_value_size (hdr_data, ehdr->e_ident, + cfi->search_table_encoding, NULL); + dmax = hdr_data->d_size - (cfi->search_table + - (const uint8_t *) hdr_data->d_buf); + if (unlikely (cfi->search_table == (void *) -1l + || vsize == 0 + || cfi->search_table_entries > (dmax / vsize) / 2)) + { + free (cfi); + /* XXX might be read error or corrupt phdr */ + __libdw_seterrno (DWARF_E_INVALID_CFI); + return NULL; + } + + /* Sanity check. */ + if (unlikely (eh_frame_vaddr != shdr->sh_addr)) + cfi->search_table = NULL; + } + } + } + return cfi; +} + +/* Search for the sections named ".eh_frame" and ".eh_frame_hdr". */ +static Dwarf_CFI * +getcfi_shdr (Elf *elf, const GElf_Ehdr *ehdr) +{ + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + { + __libdw_seterrno (DWARF_E_GETEHDR_ERROR); + return NULL; + } + + if (shstrndx != 0) + { + Elf_Scn *hdr_scn = NULL; + GElf_Addr hdr_vaddr = 0; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + continue; + const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (name == NULL) + continue; + if (!strcmp (name, ".eh_frame_hdr")) + { + hdr_scn = scn; + hdr_vaddr = shdr->sh_addr; + } + else if (!strcmp (name, ".eh_frame")) + { + if (shdr->sh_type != SHT_NOBITS) + return getcfi_scn_eh_frame (elf, ehdr, scn, shdr, + hdr_scn, hdr_vaddr); + else + return NULL; + } + } + } + + return (void *) -1l; +} + +Dwarf_CFI * +dwarf_getcfi_elf (Elf *elf) +{ + if (elf_kind (elf) != ELF_K_ELF) + { + __libdw_seterrno (DWARF_E_NOELF); + return NULL; + } + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (unlikely (ehdr == NULL)) + { + __libdw_seterrno (DWARF_E_INVALID_ELF); + return NULL; + } + + Dwarf_CFI *result = getcfi_shdr (elf, ehdr); + if (result == (void *) -1l) + result = getcfi_phdr (elf, ehdr); + + return result; +} +INTDEF (dwarf_getcfi_elf) diff --git a/libdw/dwarf_getelf.c b/libdw/dwarf_getelf.c new file mode 100644 index 00000000..2d6268ea --- /dev/null +++ b/libdw/dwarf_getelf.c @@ -0,0 +1,47 @@ +/* Retrieve ELF descriptor used for DWARF access. + Copyright (C) 2002, 2004, 2007 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libdwP.h" + + +Elf * +dwarf_getelf (Dwarf *dwarf) +{ + if (dwarf == NULL) + /* Some error occurred before. */ + return NULL; + + return dwarf->elf; +} diff --git a/libdw/dwarf_getfuncs.c b/libdw/dwarf_getfuncs.c new file mode 100644 index 00000000..b95f06f4 --- /dev/null +++ b/libdw/dwarf_getfuncs.c @@ -0,0 +1,118 @@ +/* Get function information. + Copyright (C) 2005, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +struct visitor_info +{ + /* The user callback of dwarf_getfuncs. */ + int (*callback) (Dwarf_Die *, void *); + + /* The user arg value to dwarf_getfuncs. */ + void *arg; + + /* Addr of the DIE offset where to (re)start the search. Zero for all. */ + void *start_addr; + + /* Last subprogram DIE addr seen. */ + void *last_addr; + + /* The CU only contains C functions. Allows pruning of most subtrees. */ + bool c_cu; +}; + +static int +tree_visitor (unsigned int depth __attribute__ ((unused)), + struct Dwarf_Die_Chain *chain, void *arg) +{ + struct visitor_info *const v = arg; + Dwarf_Die *die = &chain->die; + void *start_addr = v->start_addr; + void *die_addr = die->addr; + + /* Pure C CUs can only contain defining subprogram DIEs as direct + children of the CU DIE or as nested function inside a normal C + code constructs. */ + int tag = INTUSE(dwarf_tag) (die); + if (v->c_cu + && tag != DW_TAG_subprogram + && tag != DW_TAG_lexical_block + && tag != DW_TAG_inlined_subroutine) + { + chain->prune = true; + return DWARF_CB_OK; + } + + /* Skip all DIEs till we found the (re)start addr. */ + if (start_addr != NULL) + { + if (die_addr == start_addr) + v->start_addr = NULL; + return DWARF_CB_OK; + } + + /* If this isn't a (defining) subprogram entity, skip DIE. */ + if (tag != DW_TAG_subprogram + || INTUSE(dwarf_hasattr) (die, DW_AT_declaration)) + return DWARF_CB_OK; + + v->last_addr = die_addr; + return (*v->callback) (die, v->arg); +} + +ptrdiff_t +dwarf_getfuncs (Dwarf_Die *cudie, int (*callback) (Dwarf_Die *, void *), + void *arg, ptrdiff_t offset) +{ + if (unlikely (cudie == NULL + || INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit)) + return -1; + + int lang = INTUSE(dwarf_srclang) (cudie); + bool c_cu = (lang == DW_LANG_C89 + || lang == DW_LANG_C + || lang == DW_LANG_C99 + || lang == DW_LANG_C11); + + struct visitor_info v = { callback, arg, (void *) offset, NULL, c_cu }; + struct Dwarf_Die_Chain chain = { .die = CUDIE (cudie->cu), + .parent = NULL }; + int res = __libdw_visit_scopes (0, &chain, NULL, &tree_visitor, NULL, &v); + + if (res == DWARF_CB_ABORT) + return (ptrdiff_t) v.last_addr; + else + return res; +} diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c new file mode 100644 index 00000000..5db3cf97 --- /dev/null +++ b/libdw/dwarf_getlocation.c @@ -0,0 +1,1030 @@ +/* Return location expression list. + Copyright (C) 2000-2010, 2013-2015, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include + + +static bool +attr_ok (Dwarf_Attribute *attr) +{ + if (attr == NULL) + return false; + + /* If it is an exprloc, it is obviously OK. */ + if (dwarf_whatform (attr) == DW_FORM_exprloc) + return true; + + if (attr->cu->version >= 4) + { + /* Must be an exprloc (or constant), just not any block form. */ + switch (dwarf_whatform (attr)) + { + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + __libdw_seterrno (DWARF_E_NO_LOC_VALUE); + return false; + default: + break; + } + } + + /* Otherwise must be one of the attributes listed below. Older + DWARF versions might have encoded the exprloc as block, and we + cannot easily distinguish attributes in the loclist class because + the same forms are used for different classes. */ + switch (attr->code) + { + case DW_AT_location: + case DW_AT_byte_size: + case DW_AT_bit_offset: + case DW_AT_bit_size: + case DW_AT_lower_bound: + case DW_AT_bit_stride: + case DW_AT_upper_bound: + case DW_AT_count: + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_data_location: + case DW_AT_byte_stride: + case DW_AT_rank: + case DW_AT_call_value: + case DW_AT_call_target: + case DW_AT_call_target_clobbered: + case DW_AT_call_data_location: + case DW_AT_call_data_value: + case DW_AT_data_member_location: + case DW_AT_vtable_elem_location: + case DW_AT_string_length: + case DW_AT_use_location: + case DW_AT_frame_base: + case DW_AT_return_addr: + case DW_AT_static_link: + case DW_AT_segment: + case DW_AT_GNU_call_site_value: + case DW_AT_GNU_call_site_data_value: + case DW_AT_GNU_call_site_target: + case DW_AT_GNU_call_site_target_clobbered: + break; + + default: + __libdw_seterrno (DWARF_E_NO_LOC_VALUE); + return false; + } + + return true; +} + + +struct loclist +{ + uint8_t atom; + Dwarf_Word number; + Dwarf_Word number2; + Dwarf_Word offset; + struct loclist *next; +}; + + +static int +loc_compare (const void *p1, const void *p2) +{ + const struct loc_s *l1 = (const struct loc_s *) p1; + const struct loc_s *l2 = (const struct loc_s *) p2; + + if ((uintptr_t) l1->addr < (uintptr_t) l2->addr) + return -1; + if ((uintptr_t) l1->addr > (uintptr_t) l2->addr) + return 1; + + return 0; +} + +/* For each DW_OP_implicit_value, we store a special entry in the cache. + This points us directly to the block data for later fetching. + Returns zero on success, -1 on bad DWARF or 1 if tsearch failed. */ +static int +store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op) +{ + if (dbg == NULL) + return -1; + struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s, + sizeof (struct loc_block_s), 1); + const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2; + /* Skip the block length. */ + __libdw_get_uleb128_unchecked (&data); + block->addr = op; + block->data = (unsigned char *) data; + block->length = op->number; + if (unlikely (tsearch (block, cache, loc_compare) == NULL)) + return 1; + return 0; +} + +int +dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op, + Dwarf_Block *return_block) +{ + if (attr == NULL) + return -1; + + struct loc_block_s fake = { .addr = (void *) op }; + struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare); + if (unlikely (found == NULL)) + { + __libdw_seterrno (DWARF_E_NO_BLOCK); + return -1; + } + + return_block->length = (*found)->length; + return_block->data = (*found)->data; + return 0; +} + +/* If the given attribute is DW_AT_data_member_location and it has constant + form then create a fake location using DW_OP_plus_uconst and the offset + value. On success returns zero and fills in llbuf (when not NULL) and + sets listlen to 1. Returns 1 when this isn't a DW_AT_data_member_location + offset. Returns -1 and sets dwarf_errno on failure (bad DWARF data). */ +static int +is_constant_offset (Dwarf_Attribute *attr, + Dwarf_Op **llbuf, size_t *listlen) +{ + if (attr->code != DW_AT_data_member_location) + return 1; + + switch (attr->form) + { + /* Punt for any non-constant form. */ + default: + return 1; + + /* Note, we don't regard DW_FORM_data16 as a constant form, + even though technically it is according to the standard. */ + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_implicit_const: + break; + } + + /* Check whether we already cached this location. */ + struct loc_s fake = { .addr = attr->valp }; + struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare); + + if (found == NULL) + { + Dwarf_Word offset; + if (INTUSE(dwarf_formudata) (attr, &offset) != 0) + return -1; + + Dwarf_Op *result = libdw_alloc (attr->cu->dbg, + Dwarf_Op, sizeof (Dwarf_Op), 1); + + result->atom = DW_OP_plus_uconst; + result->number = offset; + result->number2 = 0; + result->offset = 0; + + /* Insert a record in the search tree so we can find it again later. */ + struct loc_s *newp = libdw_alloc (attr->cu->dbg, + struct loc_s, sizeof (struct loc_s), + 1); + newp->addr = attr->valp; + newp->loc = result; + newp->nloc = 1; + + found = tsearch (newp, &attr->cu->locs, loc_compare); + } + + assert ((*found)->nloc == 1); + + if (llbuf != NULL) + { + *llbuf = (*found)->loc; + *listlen = 1; + } + + return 0; +} + +int +internal_function +__libdw_intern_expression (Dwarf *dbg, bool other_byte_order, + unsigned int address_size, unsigned int ref_size, + void **cache, const Dwarf_Block *block, + bool cfap, bool valuep, + Dwarf_Op **llbuf, size_t *listlen, int sec_index) +{ + /* Empty location expressions don't have any ops to intern. */ + if (block->length == 0) + { + *listlen = 0; + return 0; + } + + /* Check whether we already looked at this list. */ + struct loc_s fake = { .addr = block->data }; + struct loc_s **found = tfind (&fake, cache, loc_compare); + if (found != NULL) + { + /* We already saw it. */ + *llbuf = (*found)->loc; + *listlen = (*found)->nloc; + + if (valuep) + { + assert (*listlen > 1); + assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value); + } + + return 0; + } + + const unsigned char *data = block->data; + const unsigned char *const end_data = data + block->length; + + const struct { bool other_byte_order; } bo = { other_byte_order }; + + struct loclist *loclist = NULL; + unsigned int n = 0; + + /* Stack allocate at most this many locs. */ +#define MAX_STACK_LOCS 256 + struct loclist stack_locs[MAX_STACK_LOCS]; +#define NEW_LOC() ({ struct loclist *ll; \ + ll = (likely (n < MAX_STACK_LOCS) \ + ? &stack_locs[n] \ + : malloc (sizeof (struct loclist))); \ + if (unlikely (ll == NULL)) \ + goto nomem; \ + n++; \ + ll->next = loclist; \ + loclist = ll; \ + ll; }) + + if (cfap) + { + /* Synthesize the operation to push the CFA before the expression. */ + struct loclist *newloc = NEW_LOC (); + newloc->atom = DW_OP_call_frame_cfa; + newloc->number = 0; + newloc->number2 = 0; + newloc->offset = -1; + } + + /* Decode the opcodes. It is possible in some situations to have a + block of size zero. */ + while (data < end_data) + { + struct loclist *newloc; + newloc = NEW_LOC (); + newloc->number = 0; + newloc->number2 = 0; + newloc->offset = data - block->data; + + switch ((newloc->atom = *data++)) + { + case DW_OP_addr: + /* Address, depends on address size of CU. */ + if (dbg == NULL) + { + // XXX relocation? + if (address_size == 4) + { + if (unlikely (data + 4 > end_data)) + goto invalid; + else + newloc->number = read_4ubyte_unaligned_inc (&bo, data); + } + else + { + if (unlikely (data + 8 > end_data)) + goto invalid; + else + newloc->number = read_8ubyte_unaligned_inc (&bo, data); + } + } + else if (__libdw_read_address_inc (dbg, sec_index, &data, + address_size, &newloc->number)) + goto invalid; + break; + + case DW_OP_call_ref: + case DW_OP_GNU_variable_value: + /* DW_FORM_ref_addr, depends on offset size of CU. */ + if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data, + ref_size, + &newloc->number, + IDX_debug_info, 0)) + goto invalid; + break; + + case DW_OP_deref: + case DW_OP_dup: + case DW_OP_drop: + case DW_OP_over: + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + case DW_OP_lit0 ... DW_OP_lit31: + case DW_OP_reg0 ... DW_OP_reg31: + case DW_OP_nop: + case DW_OP_push_object_address: + case DW_OP_call_frame_cfa: + case DW_OP_form_tls_address: + case DW_OP_GNU_push_tls_address: + case DW_OP_stack_value: + /* No operand. */ + break; + + case DW_OP_const1u: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + if (unlikely (data >= end_data)) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + returnmem: + /* Free any dynamically allocated loclists, if any. */ + while (n > MAX_STACK_LOCS) + { + struct loclist *loc = loclist; + loclist = loc->next; + free (loc); + n--; + } + return -1; + } + + newloc->number = *data++; + break; + + case DW_OP_const1s: + if (unlikely (data >= end_data)) + goto invalid; + + newloc->number = *((int8_t *) data); + ++data; + break; + + case DW_OP_const2u: + if (unlikely (data + 2 > end_data)) + goto invalid; + + newloc->number = read_2ubyte_unaligned_inc (&bo, data); + break; + + case DW_OP_const2s: + case DW_OP_skip: + case DW_OP_bra: + case DW_OP_call2: + if (unlikely (data + 2 > end_data)) + goto invalid; + + newloc->number = read_2sbyte_unaligned_inc (&bo, data); + break; + + case DW_OP_const4u: + if (unlikely (data + 4 > end_data)) + goto invalid; + + newloc->number = read_4ubyte_unaligned_inc (&bo, data); + break; + + case DW_OP_const4s: + case DW_OP_call4: + case DW_OP_GNU_parameter_ref: + if (unlikely (data + 4 > end_data)) + goto invalid; + + newloc->number = read_4sbyte_unaligned_inc (&bo, data); + break; + + case DW_OP_const8u: + if (unlikely (data + 8 > end_data)) + goto invalid; + + newloc->number = read_8ubyte_unaligned_inc (&bo, data); + break; + + case DW_OP_const8s: + if (unlikely (data + 8 > end_data)) + goto invalid; + + newloc->number = read_8sbyte_unaligned_inc (&bo, data); + break; + + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + case DW_OP_convert: + case DW_OP_GNU_convert: + case DW_OP_reinterpret: + case DW_OP_GNU_reinterpret: + case DW_OP_addrx: + case DW_OP_GNU_addr_index: + case DW_OP_constx: + case DW_OP_GNU_const_index: + get_uleb128 (newloc->number, data, end_data); + break; + + case DW_OP_consts: + case DW_OP_breg0 ... DW_OP_breg31: + case DW_OP_fbreg: + get_sleb128 (newloc->number, data, end_data); + break; + + case DW_OP_bregx: + get_uleb128 (newloc->number, data, end_data); + if (unlikely (data >= end_data)) + goto invalid; + get_sleb128 (newloc->number2, data, end_data); + break; + + case DW_OP_bit_piece: + case DW_OP_regval_type: + case DW_OP_GNU_regval_type: + get_uleb128 (newloc->number, data, end_data); + if (unlikely (data >= end_data)) + goto invalid; + get_uleb128 (newloc->number2, data, end_data); + break; + + case DW_OP_implicit_value: + case DW_OP_entry_value: + case DW_OP_GNU_entry_value: + /* This cannot be used in a CFI expression. */ + if (unlikely (dbg == NULL)) + goto invalid; + + /* start of block inc. len. */ + newloc->number2 = (Dwarf_Word) (uintptr_t) data; + get_uleb128 (newloc->number, data, end_data); /* Block length. */ + if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number)) + goto invalid; + data += newloc->number; /* Skip the block. */ + break; + + case DW_OP_implicit_pointer: + case DW_OP_GNU_implicit_pointer: + /* DW_FORM_ref_addr, depends on offset size of CU. */ + if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data, + ref_size, + &newloc->number, + IDX_debug_info, 0)) + goto invalid; + if (unlikely (data >= end_data)) + goto invalid; + get_uleb128 (newloc->number2, data, end_data); /* Byte offset. */ + break; + + case DW_OP_deref_type: + case DW_OP_GNU_deref_type: + case DW_OP_xderef_type: + if (unlikely (data + 1 >= end_data)) + goto invalid; + newloc->number = *data++; + get_uleb128 (newloc->number2, data, end_data); + break; + + case DW_OP_const_type: + case DW_OP_GNU_const_type: + { + size_t size; + get_uleb128 (newloc->number, data, end_data); + if (unlikely (data >= end_data)) + goto invalid; + + /* start of block inc. len. */ + newloc->number2 = (Dwarf_Word) (uintptr_t) data; + size = *data++; + if (unlikely ((Dwarf_Word) (end_data - data) < size)) + goto invalid; + data += size; /* Skip the block. */ + } + break; + + default: + goto invalid; + } + } + + if (unlikely (n == 0)) + { + /* This is not allowed. + It would mean an empty location expression, which we handled + already as a special case above. */ + goto invalid; + } + + if (valuep) + { + struct loclist *newloc = NEW_LOC (); + newloc->atom = DW_OP_stack_value; + newloc->number = 0; + newloc->number2 = 0; + newloc->offset = data - block->data; + } + + /* Allocate the array. */ + Dwarf_Op *result; + if (dbg != NULL) + result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n); + else + { + result = malloc (sizeof *result * n); + if (result == NULL) + { + nomem: + __libdw_seterrno (DWARF_E_NOMEM); + goto returnmem; + } + } + + /* Store the result. */ + *llbuf = result; + *listlen = n; + + do + { + /* We populate the array from the back since the list is backwards. */ + --n; + result[n].atom = loclist->atom; + result[n].number = loclist->number; + result[n].number2 = loclist->number2; + result[n].offset = loclist->offset; + + if (result[n].atom == DW_OP_implicit_value) + { + int store = store_implicit_value (dbg, cache, &result[n]); + if (unlikely (store != 0)) + { + if (store < 0) + goto invalid; + else + goto nomem; + } + } + + struct loclist *loc = loclist; + loclist = loclist->next; + if (unlikely (n + 1 > MAX_STACK_LOCS)) + free (loc); + } + while (n > 0); + + /* Insert a record in the search tree so that we can find it again later. */ + struct loc_s *newp; + if (dbg != NULL) + newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1); + else + { + newp = malloc (sizeof *newp); + if (newp == NULL) + { + free (result); + goto nomem; + } + } + + newp->addr = block->data; + newp->loc = result; + newp->nloc = *listlen; + (void) tsearch (newp, cache, loc_compare); + + /* We did it. */ + return 0; +} + +static int +getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, + Dwarf_Op **llbuf, size_t *listlen, int sec_index) +{ + /* Empty location expressions don't have any ops to intern. + Note that synthetic empty_cu doesn't have an associated DWARF dbg. */ + if (block->length == 0) + { + *listlen = 0; + return 0; + } + + return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order, + cu->address_size, (cu->version == 2 + ? cu->address_size + : cu->offset_size), + &cu->locs, block, + false, false, + llbuf, listlen, sec_index); +} + +int +dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen) +{ + if (! attr_ok (attr)) + return -1; + + int result = is_constant_offset (attr, llbuf, listlen); + if (result != 1) + return result; /* Either success 0, or -1 to indicate error. */ + + /* If it has a block form, it's a single location expression. + Except for DW_FORM_data16, which is a 128bit constant. */ + if (attr->form == DW_FORM_data16) + { + __libdw_seterrno (DWARF_E_NO_BLOCK); + return -1; + } + Dwarf_Block block; + if (INTUSE(dwarf_formblock) (attr, &block) != 0) + return -1; + + return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu)); +} + +Dwarf_Addr +__libdw_cu_base_address (Dwarf_CU *cu) +{ + if (cu->base_address == (Dwarf_Addr) -1) + { + Dwarf_Addr base; + + /* Fetch the CU's base address. */ + Dwarf_Die cudie = CUDIE (cu); + + /* Find the base address of the compilation unit. It will + normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, + the base address could be overridden by DW_AT_entry_pc. It's + been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc + for compilation units with discontinuous ranges. */ + Dwarf_Attribute attr_mem; + if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0 + && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, + DW_AT_entry_pc, + &attr_mem), + &base) != 0) + { + /* The compiler provided no base address when it should + have. Buggy GCC does this when it used absolute + addresses in the location list and no DW_AT_ranges. */ + base = 0; + } + cu->base_address = base; + } + + return cu->base_address; +} + +static int +initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset) +{ + size_t secidx = (attr->cu->version < 5 + ? IDX_debug_loc : IDX_debug_loclists); + + Dwarf_Word start_offset; + if (attr->form == DW_FORM_loclistx) + { + Dwarf_Word idx; + Dwarf_CU *cu = attr->cu; + const unsigned char *datap = attr->valp; + const unsigned char *endp = cu->endp; + if (datap >= endp) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + get_uleb128 (idx, datap, endp); + + Elf_Data *data = cu->dbg->sectiondata[secidx]; + if (data == NULL && cu->unit_type == DW_UT_split_compile) + { + cu = __libdw_find_split_unit (cu); + if (cu != NULL) + data = cu->dbg->sectiondata[secidx]; + } + + if (data == NULL) + { + __libdw_seterrno (secidx == IDX_debug_loc + ? DWARF_E_NO_DEBUG_LOC + : DWARF_E_NO_DEBUG_LOCLISTS); + return -1; + } + + Dwarf_Off loc_base_off = __libdw_cu_locs_base (cu); + + /* The section should at least contain room for one offset. */ + size_t sec_size = cu->dbg->sectiondata[secidx]->d_size; + size_t offset_size = cu->offset_size; + if (offset_size > sec_size) + { + invalid_offset: + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + + /* And the base offset should be at least inside the section. */ + if (loc_base_off > (sec_size - offset_size)) + goto invalid_offset; + + size_t max_idx = (sec_size - offset_size - loc_base_off) / offset_size; + if (idx > max_idx) + goto invalid_offset; + + datap = (cu->dbg->sectiondata[secidx]->d_buf + + loc_base_off + (idx * offset_size)); + if (offset_size == 4) + start_offset = read_4ubyte_unaligned (cu->dbg, datap); + else + start_offset = read_8ubyte_unaligned (cu->dbg, datap); + + start_offset += loc_base_off; + } + else + { + if (__libdw_formptr (attr, secidx, + (secidx == IDX_debug_loc + ? DWARF_E_NO_DEBUG_LOC + : DWARF_E_NO_DEBUG_LOCLISTS), + NULL, &start_offset) == NULL) + return -1; + } + + *offset = start_offset; + return 0; +} + +static ptrdiff_t +getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset, + Dwarf_Addr *basep, Dwarf_Addr *startp, Dwarf_Addr *endp, + Dwarf_Addr address, const Elf_Data *locs, Dwarf_Op **expr, + size_t *exprlen) +{ + Dwarf_CU *cu = attr->cu; + Dwarf *dbg = cu->dbg; + size_t secidx = cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists; + const unsigned char *readp = locs->d_buf + offset; + const unsigned char *readendp = locs->d_buf + locs->d_size; + + Dwarf_Addr begin; + Dwarf_Addr end; + + next: + switch (__libdw_read_begin_end_pair_inc (cu, secidx, + &readp, readendp, + cu->address_size, + &begin, &end, basep)) + { + case 0: /* got location range. */ + break; + case 1: /* base address setup. */ + goto next; + case 2: /* end of loclist */ + return 0; + default: /* error */ + return -1; + } + + /* We have a location expression. */ + Dwarf_Block block; + if (secidx == IDX_debug_loc) + { + if (readendp - readp < 2) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + block.length = read_2ubyte_unaligned_inc (dbg, readp); + } + else + { + if (readendp - readp < 1) + goto invalid; + get_uleb128 (block.length, readp, readendp); + } + block.data = (unsigned char *) readp; + if (readendp - readp < (ptrdiff_t) block.length) + goto invalid; + readp += block.length; + + /* Note these addresses include any base (if necessary) already. */ + *startp = begin; + *endp = end; + + /* If address is minus one we want them all, otherwise only matching. */ + if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp)) + goto next; + + if (getlocation (cu, &block, expr, exprlen, secidx) != 0) + return -1; + + return readp - (unsigned char *) locs->d_buf; +} + +int +dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address, + Dwarf_Op **llbufs, size_t *listlens, size_t maxlocs) +{ + if (! attr_ok (attr)) + return -1; + + if (llbufs == NULL) + maxlocs = SIZE_MAX; + + /* If it has a block form, it's a single location expression. + Except for DW_FORM_data16, which is a 128bit constant. */ + Dwarf_Block block; + if (attr->form != DW_FORM_data16 + && INTUSE(dwarf_formblock) (attr, &block) == 0) + { + if (maxlocs == 0) + return 0; + if (llbufs != NULL && + getlocation (attr->cu, &block, &llbufs[0], &listlens[0], + cu_sec_idx (attr->cu)) != 0) + return -1; + return listlens[0] == 0 ? 0 : 1; + } + + if (attr->form != DW_FORM_data16) + { + int error = INTUSE(dwarf_errno) (); + if (unlikely (error != DWARF_E_NO_BLOCK)) + { + __libdw_seterrno (error); + return -1; + } + } + + /* If is_constant_offset is successful, we are done with 1 result. */ + int result = is_constant_offset (attr, llbufs, listlens); + if (result != 1) + return result ?: 1; + + Dwarf_Addr base, start, end; + Dwarf_Op *expr; + size_t expr_len; + ptrdiff_t off = 0; + size_t got = 0; + + /* This is a true loclistptr, fetch the initial base address and offset. */ + base = __libdw_cu_base_address (attr->cu); + if (base == (Dwarf_Addr) -1) + return -1; + + if (initial_offset (attr, &off) != 0) + return -1; + + size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists; + const Elf_Data *d = attr->cu->dbg->sectiondata[secidx]; + + while (got < maxlocs + && (off = getlocations_addr (attr, off, &base, &start, &end, + address, d, &expr, &expr_len)) > 0) + { + /* This one matches the address. */ + if (llbufs != NULL) + { + llbufs[got] = expr; + listlens[got] = expr_len; + } + ++got; + } + + /* We might stop early, so off can be zero or positive on success. */ + if (off < 0) + return -1; + + return got; +} + +ptrdiff_t +dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep, + Dwarf_Addr *startp, Dwarf_Addr *endp, Dwarf_Op **expr, + size_t *exprlen) +{ + if (! attr_ok (attr)) + return -1; + + /* 1 is an invalid offset, meaning no more locations. */ + if (offset == 1) + return 0; + + if (offset == 0) + { + /* If it has a block form, it's a single location expression. + Except for DW_FORM_data16, which is a 128bit constant. */ + Dwarf_Block block; + if (attr->form != DW_FORM_data16 + && INTUSE(dwarf_formblock) (attr, &block) == 0) + { + if (getlocation (attr->cu, &block, expr, exprlen, + cu_sec_idx (attr->cu)) != 0) + return -1; + + /* This is the one and only location covering everything. */ + *startp = 0; + *endp = -1; + return 1; + } + + if (attr->form != DW_FORM_data16) + { + int error = INTUSE(dwarf_errno) (); + if (unlikely (error != DWARF_E_NO_BLOCK)) + { + __libdw_seterrno (error); + return -1; + } + } + + int result = is_constant_offset (attr, expr, exprlen); + if (result != 1) + { + if (result == 0) + { + /* This is the one and only location covering everything. */ + *startp = 0; + *endp = -1; + return 1; + } + return result; /* Something bad, dwarf_errno has been set. */ + } + + /* We must be looking at a true loclistptr, fetch the initial + base address and offset. */ + *basep = __libdw_cu_base_address (attr->cu); + if (*basep == (Dwarf_Addr) -1) + return -1; + + if (initial_offset (attr, &offset) != 0) + return -1; + } + + size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists; + const Elf_Data *d = attr->cu->dbg->sectiondata[secidx]; + + return getlocations_addr (attr, offset, basep, startp, endp, + (Dwarf_Word) -1, d, expr, exprlen); +} diff --git a/libdw/dwarf_getlocation_attr.c b/libdw/dwarf_getlocation_attr.c new file mode 100644 index 00000000..99bcc828 --- /dev/null +++ b/libdw/dwarf_getlocation_attr.c @@ -0,0 +1,162 @@ +/* Return DWARF attribute associated with a location expression op. + Copyright (C) 2013, 2014, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +static Dwarf_CU * +attr_form_cu (Dwarf_Attribute *attr) +{ + /* If the attribute has block/expr form the data comes from the + .debug_info from the same cu as the attr. Otherwise it comes from + the .debug_loc or .debug_loclists data section. */ + switch (attr->form) + { + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_block: + case DW_FORM_exprloc: + return attr->cu; + default: + return (attr->cu->version < 5 + ? attr->cu->dbg->fake_loc_cu + : attr->cu->dbg->fake_loclists_cu); + } +} + +static unsigned char * +addr_valp (Dwarf_CU *cu, Dwarf_Word index) +{ + Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr]; + if (debug_addr == NULL) + { + __libdw_seterrno (DWARF_E_NO_DEBUG_ADDR); + return NULL; + } + + Dwarf_Word offset = __libdw_cu_addr_base (cu) + (index * cu->address_size); + return (unsigned char *) debug_addr->d_buf + offset; +} + +int +dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribute *result) +{ + if (attr == NULL) + return -1; + + switch (op->atom) + { + case DW_OP_implicit_value: + result->code = DW_AT_const_value; + result->form = DW_FORM_block; + result->valp = (unsigned char *) (uintptr_t) op->number2; + result->cu = attr_form_cu (attr); + break; + + case DW_OP_entry_value: + case DW_OP_GNU_entry_value: + result->code = DW_AT_location; + result->form = DW_FORM_exprloc; + result->valp = (unsigned char *) (uintptr_t) op->number2; + result->cu = attr_form_cu (attr); + break; + + case DW_OP_const_type: + case DW_OP_GNU_const_type: + result->code = DW_AT_const_value; + result->form = DW_FORM_block1; + result->valp = (unsigned char *) (uintptr_t) op->number2; + result->cu = attr_form_cu (attr); + break; + + case DW_OP_GNU_const_index: + case DW_OP_constx: + result->code = DW_AT_const_value; + if (attr->cu->address_size == 4) + result->form = DW_FORM_data4; + else + result->form = DW_FORM_data8; + result->valp = addr_valp (attr->cu, op->number); + if (result->valp == NULL) + return -1; + result->cu = attr->cu->dbg->fake_addr_cu; + break; + + case DW_OP_GNU_addr_index: + case DW_OP_addrx: + result->code = DW_AT_low_pc; + result->form = DW_FORM_addr; + result->valp = addr_valp (attr->cu, op->number); + if (result->valp == NULL) + return -1; + result->cu = attr->cu->dbg->fake_addr_cu; + break; + + case DW_OP_call2: + case DW_OP_call4: + case DW_OP_call_ref: + { + Dwarf_Die die; + if (INTUSE(dwarf_getlocation_die) (attr, op, &die) != 0) + return -1; + if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL) + { + __libdw_empty_loc_attr (result); + return 0; + } + } + break; + + case DW_OP_implicit_pointer: + case DW_OP_GNU_implicit_pointer: + case DW_OP_GNU_variable_value: + { + Dwarf_Die die; + if (INTUSE(dwarf_getlocation_die) (attr, op, &die) != 0) + return -1; + if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL + && INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL) + { + __libdw_empty_loc_attr (result); + return 0; + } + } + break; + + default: + __libdw_seterrno (DWARF_E_INVALID_ACCESS); + return -1; + } + + return 0; +} diff --git a/libdw/dwarf_getlocation_die.c b/libdw/dwarf_getlocation_die.c new file mode 100644 index 00000000..673c61cf --- /dev/null +++ b/libdw/dwarf_getlocation_die.c @@ -0,0 +1,95 @@ +/* Return DIE associated with a location expression op. + Copyright (C) 2013, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +int +dwarf_getlocation_die (Dwarf_Attribute *attr, const Dwarf_Op *op, + Dwarf_Die *result) +{ + if (attr == NULL) + return -1; + + Dwarf_Off dieoff; + switch (op->atom) + { + case DW_OP_implicit_pointer: + case DW_OP_GNU_implicit_pointer: + case DW_OP_call_ref: + case DW_OP_GNU_variable_value: + dieoff = op->number; + break; + + case DW_OP_GNU_parameter_ref: + case DW_OP_convert: + case DW_OP_GNU_convert: + case DW_OP_reinterpret: + case DW_OP_GNU_reinterpret: + case DW_OP_const_type: + case DW_OP_GNU_const_type: + case DW_OP_call2: + case DW_OP_call4: + if (op->number > (attr->cu->end - attr->cu->start)) + { + invalid_offset: + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + dieoff = attr->cu->start + op->number; + break; + + case DW_OP_regval_type: + case DW_OP_GNU_regval_type: + case DW_OP_deref_type: + case DW_OP_GNU_deref_type: + if (op->number2 > (attr->cu->end - attr->cu->start)) + goto invalid_offset; + dieoff = attr->cu->start + op->number2; + break; + + case DW_OP_xderef_type: + dieoff = op->number2; + break; + + default: + __libdw_seterrno (DWARF_E_INVALID_ACCESS); + return -1; + } + + if (__libdw_offdie (attr->cu->dbg, dieoff, result, + ISV4TU(attr->cu)) == NULL) + return -1; + + return 0; +} +INTDEF(dwarf_getlocation_die); diff --git a/libdw/dwarf_getlocation_implicit_pointer.c b/libdw/dwarf_getlocation_implicit_pointer.c new file mode 100644 index 00000000..0c1cd00a --- /dev/null +++ b/libdw/dwarf_getlocation_implicit_pointer.c @@ -0,0 +1,78 @@ +/* Return associated attribute for DW_OP_GNU_implicit_pointer. + Copyright (C) 2010, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + + +static unsigned char empty_exprloc = 0; +static Dwarf_CU empty_cu = { .startp = &empty_exprloc, + .endp = &empty_exprloc + 1 }; + +void +internal_function +__libdw_empty_loc_attr (Dwarf_Attribute *attr) +{ + attr->code = DW_AT_location; + attr->form = DW_FORM_exprloc; + attr->valp = &empty_exprloc; + attr->cu = &empty_cu; +} + +int +dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr, const Dwarf_Op *op, + Dwarf_Attribute *result) +{ + if (attr == NULL) + return -1; + + if (unlikely (op->atom != DW_OP_implicit_pointer + && op->atom != DW_OP_GNU_implicit_pointer)) + { + __libdw_seterrno (DWARF_E_INVALID_ACCESS); + return -1; + } + + Dwarf_Die die; + if (__libdw_offdie (attr->cu->dbg, op->number, &die, + ISV4TU(attr->cu)) == NULL) + return -1; + + if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL + && INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL) + { + __libdw_empty_loc_attr (result); + return 0; + } + + return 0; +} diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c new file mode 100644 index 00000000..fd929669 --- /dev/null +++ b/libdw/dwarf_getmacros.c @@ -0,0 +1,593 @@ +/* Get macro information. + Copyright (C) 2002-2009, 2014, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +static int +get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp) +{ + /* Get the appropriate attribute. */ + Dwarf_Attribute attr; + if (INTUSE(dwarf_attr) (die, name, &attr) == NULL) + return -1; + + /* Offset into the corresponding section. */ + return INTUSE(dwarf_formudata) (&attr, retp); +} + +static int +macro_op_compare (const void *p1, const void *p2) +{ + const Dwarf_Macro_Op_Table *t1 = (const Dwarf_Macro_Op_Table *) p1; + const Dwarf_Macro_Op_Table *t2 = (const Dwarf_Macro_Op_Table *) p2; + + if (t1->offset < t2->offset) + return -1; + if (t1->offset > t2->offset) + return 1; + + if (t1->sec_index < t2->sec_index) + return -1; + if (t1->sec_index > t2->sec_index) + return 1; + + return 0; +} + +static void +build_table (Dwarf_Macro_Op_Table *table, + Dwarf_Macro_Op_Proto op_protos[static 255]) +{ + unsigned ct = 0; + for (unsigned i = 1; i < 256; ++i) + if (op_protos[i - 1].forms != NULL) + table->table[table->opcodes[i - 1] = ct++] = op_protos[i - 1]; + else + table->opcodes[i - 1] = 0xff; +} + +#define MACRO_PROTO(NAME, ...) \ + Dwarf_Macro_Op_Proto NAME = ({ \ + static const uint8_t proto[] = {__VA_ARGS__}; \ + (Dwarf_Macro_Op_Proto) {sizeof proto, proto}; \ + }) + +enum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) }; +static unsigned char macinfo_data[macinfo_data_size] + __attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table)))); + +static __attribute__ ((constructor)) void +init_macinfo_table (void) +{ + MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string); + MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata); + MACRO_PROTO (p_none); + + Dwarf_Macro_Op_Proto op_protos[255] = + { + [DW_MACINFO_define - 1] = p_udata_str, + [DW_MACINFO_undef - 1] = p_udata_str, + [DW_MACINFO_vendor_ext - 1] = p_udata_str, + [DW_MACINFO_start_file - 1] = p_udata_udata, + [DW_MACINFO_end_file - 1] = p_none, + /* If you are adding more elements to this array, increase + MACINFO_DATA_SIZE above. */ + }; + + Dwarf_Macro_Op_Table *macinfo_table = (void *) macinfo_data; + memset (macinfo_table, 0, sizeof macinfo_data); + build_table (macinfo_table, op_protos); + macinfo_table->sec_index = IDX_debug_macinfo; +} + +static Dwarf_Macro_Op_Table * +get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie) +{ + assert (cudie != NULL); + + Dwarf_Attribute attr_mem, *attr + = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem); + Dwarf_Off line_offset = (Dwarf_Off) -1; + if (attr != NULL) + if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0)) + return NULL; + + Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table, + macinfo_data_size, 1); + memcpy (table, macinfo_data, macinfo_data_size); + + table->offset = macoff; + table->sec_index = IDX_debug_macinfo; + table->line_offset = line_offset; + table->is_64bit = cudie->cu->address_size == 8; + table->comp_dir = __libdw_getcompdir (cudie); + + return table; +} + +static Dwarf_Macro_Op_Table * +get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff, + const unsigned char *readp, + const unsigned char *const endp, + Dwarf_Die *cudie) +{ + const unsigned char *startp = readp; + + /* Request at least 3 bytes for header. */ + if (readp + 3 > endp) + { + invalid_dwarf: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); + if (version != 4 && version != 5) + { + __libdw_seterrno (DWARF_E_INVALID_VERSION); + return NULL; + } + + uint8_t flags = *readp++; + bool is_64bit = (flags & 0x1) != 0; + + Dwarf_Off line_offset = (Dwarf_Off) -1; + if ((flags & 0x2) != 0) + { + line_offset = read_addr_unaligned_inc (is_64bit ? 8 : 4, dbg, readp); + if (readp > endp) + goto invalid_dwarf; + } + else if (cudie != NULL) + { + Dwarf_Attribute attr_mem, *attr + = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem); + if (attr != NULL) + if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0)) + return NULL; + } + + /* """The macinfo entry types defined in this standard may, but + might not, be described in the table""". + + I.e. these may be present. It's tempting to simply skip them, + but it's probably more correct to tolerate that a producer tweaks + the way certain opcodes are encoded, for whatever reasons. */ + + MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string); + MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp); + MACRO_PROTO (p_udata_strsup, DW_FORM_udata, DW_FORM_strp_sup); + MACRO_PROTO (p_udata_strx, DW_FORM_udata, DW_FORM_strx); + MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata); + MACRO_PROTO (p_secoffset, DW_FORM_sec_offset); + MACRO_PROTO (p_none); + + Dwarf_Macro_Op_Proto op_protos[255] = + { + [DW_MACRO_define - 1] = p_udata_str, + [DW_MACRO_undef - 1] = p_udata_str, + [DW_MACRO_define_strp - 1] = p_udata_strp, + [DW_MACRO_undef_strp - 1] = p_udata_strp, + [DW_MACRO_start_file - 1] = p_udata_udata, + [DW_MACRO_end_file - 1] = p_none, + [DW_MACRO_import - 1] = p_secoffset, + [DW_MACRO_define_sup - 1] = p_udata_strsup, + [DW_MACRO_undef_sup - 1] = p_udata_strsup, + [DW_MACRO_import_sup - 1] = p_secoffset, /* XXX - but in sup!. */ + [DW_MACRO_define_strx - 1] = p_udata_strx, + [DW_MACRO_undef_strx - 1] = p_udata_strx, + }; + + if ((flags & 0x4) != 0) + { + unsigned count = *readp++; + for (unsigned i = 0; i < count; ++i) + { + unsigned opcode = *readp++; + + Dwarf_Macro_Op_Proto e; + if (readp >= endp) + goto invalid; + get_uleb128 (e.nforms, readp, endp); + e.forms = readp; + op_protos[opcode - 1] = e; + + readp += e.nforms; + if (readp > endp) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + } + } + + size_t ct = 0; + for (unsigned i = 1; i < 256; ++i) + if (op_protos[i - 1].forms != NULL) + ++ct; + + /* We support at most 0xfe opcodes defined in the table, as 0xff is + a value that means that given opcode is not stored at all. But + that should be fine, as opcode 0 is not allocated. */ + assert (ct < 0xff); + + size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]); + + Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table, + macop_table_size, 1); + + *table = (Dwarf_Macro_Op_Table) { + .offset = macoff, + .sec_index = IDX_debug_macro, + .line_offset = line_offset, + .header_len = readp - startp, + .version = version, + .is_64bit = is_64bit, + + /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent. */ + .comp_dir = __libdw_getcompdir (cudie), + }; + build_table (table, op_protos); + + return table; +} + +static Dwarf_Macro_Op_Table * +cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff, + const unsigned char *startp, + const unsigned char *const endp, + Dwarf_Die *cudie) +{ + Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index }; + Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops, + macro_op_compare); + if (found != NULL) + return *found; + + Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro + ? get_table_for_offset (dbg, macoff, startp, endp, cudie) + : get_macinfo_table (dbg, macoff, cudie); + + if (table == NULL) + return NULL; + + Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops, + macro_op_compare); + if (unlikely (ret == NULL)) + { + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + return *ret; +} + +static ptrdiff_t +read_macros (Dwarf *dbg, int sec_index, + Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t offset, bool accept_0xff, + Dwarf_Die *cudie) +{ + Elf_Data *d = dbg->sectiondata[sec_index]; + if (unlikely (d == NULL || d->d_buf == NULL)) + { + __libdw_seterrno (DWARF_E_NO_ENTRY); + return -1; + } + + if (unlikely (macoff >= d->d_size)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + const unsigned char *const startp = d->d_buf + macoff; + const unsigned char *const endp = d->d_buf + d->d_size; + + Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff, + startp, endp, cudie); + if (table == NULL) + return -1; + + if (offset == 0) + offset = table->header_len; + + assert (offset >= 0); + assert (offset < endp - startp); + const unsigned char *readp = startp + offset; + + while (readp < endp) + { + unsigned int opcode = *readp++; + if (opcode == 0) + /* Nothing more to do. */ + return 0; + + if (unlikely (opcode == 0xff && ! accept_0xff)) + { + /* See comment below at dwarf_getmacros for explanation of + why we are doing this. */ + __libdw_seterrno (DWARF_E_INVALID_OPCODE); + return -1; + } + + unsigned int idx = table->opcodes[opcode - 1]; + if (idx == 0xff) + { + __libdw_seterrno (DWARF_E_INVALID_OPCODE); + return -1; + } + + Dwarf_Macro_Op_Proto *proto = &table->table[idx]; + + /* A fake CU with bare minimum data to fool dwarf_formX into + doing the right thing with the attributes that we put out. + We pretend it is the same version as the actual table. + Version 4 for the old GNU extension, version 5 for DWARF5. + To handle DW_FORM_strx[1234] we set the .str_offsets_base + from the given CU. + XXX We will need to deal with DW_MACRO_import_sup and change + out the dbg somehow for the DW_FORM_sec_offset to make sense. */ + Dwarf_CU fake_cu = { + .dbg = dbg, + .sec_idx = sec_index, + .version = table->version, + .offset_size = table->is_64bit ? 8 : 4, + .str_off_base = str_offsets_base_off (dbg, (cudie != NULL + ? cudie->cu: NULL)), + .startp = (void *) startp + offset, + .endp = (void *) endp, + }; + + Dwarf_Attribute *attributes; + Dwarf_Attribute *attributesp = NULL; + Dwarf_Attribute nattributes[8]; + if (unlikely (proto->nforms > 8)) + { + attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms); + if (attributesp == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + attributes = attributesp; + } + else + attributes = &nattributes[0]; + + for (Dwarf_Word i = 0; i < proto->nforms; ++i) + { + /* We pretend this is a DW_AT[_GNU]_macros attribute so that + DW_FORM_sec_offset forms get correctly interpreted as + offset into .debug_macro. XXX Deal with DW_MACRO_import_sup + (swap .dbg) for DW_FORM_sec_offset? */ + attributes[i].code = (fake_cu.version == 4 ? DW_AT_GNU_macros + : DW_AT_macros); + attributes[i].form = proto->forms[i]; + attributes[i].valp = (void *) readp; + attributes[i].cu = &fake_cu; + + /* We don't want forms that aren't allowed because they could + read from the "abbrev" like DW_FORM_implicit_const. */ + if (! libdw_valid_user_form (attributes[i].form)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + free (attributesp); + return -1; + } + + size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp); + if (unlikely (len == (size_t) -1)) + { + free (attributesp); + return -1; + } + + readp += len; + } + + Dwarf_Macro macro = { + .table = table, + .opcode = opcode, + .attributes = attributes, + }; + + int res = callback (¯o, arg); + if (unlikely (attributesp != NULL)) + free (attributesp); + + if (res != DWARF_CB_OK) + return readp - startp; + } + + return 0; +} + +/* Token layout: + + - The highest bit is used for distinguishing between callers that + know that opcode 0xff may have one of two incompatible meanings. + The mask that we use for selecting this bit is + DWARF_GETMACROS_START. + + - The rest of the token (31 or 63 bits) encodes address inside the + macro unit. + + Besides, token value of 0 signals end of iteration and -1 is + reserved for signaling errors. That means it's impossible to + represent maximum offset of a .debug_macro unit to new-style + callers (which in practice decreases the permissible macro unit + size by another 1 byte). */ + +static ptrdiff_t +token_from_offset (ptrdiff_t offset, bool accept_0xff) +{ + if (offset == -1 || offset == 0) + return offset; + + /* Make sure the offset didn't overflow into the flag bit. */ + if ((offset & DWARF_GETMACROS_START) != 0) + { + __libdw_seterrno (DWARF_E_TOO_BIG); + return -1; + } + + if (accept_0xff) + offset |= DWARF_GETMACROS_START; + + return offset; +} + +static ptrdiff_t +offset_from_token (ptrdiff_t token, bool *accept_0xffp) +{ + *accept_0xffp = (token & DWARF_GETMACROS_START) != 0; + token &= ~DWARF_GETMACROS_START; + + return token; +} + +static ptrdiff_t +gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, + int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t offset, bool accept_0xff, + Dwarf_Die *cudie) +{ + assert (offset >= 0); + + if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + + return read_macros (dbg, IDX_debug_macro, macoff, + callback, arg, offset, accept_0xff, cudie); +} + +static ptrdiff_t +macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, + int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t offset, Dwarf_Die *cudie) +{ + assert (offset >= 0); + + return read_macros (dbg, IDX_debug_macinfo, macoff, + callback, arg, offset, true, cudie); +} + +ptrdiff_t +dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, + int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t token) +{ + if (dbg == NULL) + { + __libdw_seterrno (DWARF_E_NO_DWARF); + return -1; + } + + bool accept_0xff; + ptrdiff_t offset = offset_from_token (token, &accept_0xff); + assert (accept_0xff); + + offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset, + accept_0xff, NULL); + + return token_from_offset (offset, accept_0xff); +} + +ptrdiff_t +dwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t token) +{ + if (cudie == NULL) + { + __libdw_seterrno (DWARF_E_NO_DWARF); + return -1; + } + + /* This function might be called from a code that expects to see + DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones. It is fine to + serve most DW_MACRO_{GNU_,}* opcodes to such code, because those + whose values are the same as DW_MACINFO_* ones also have the same + behavior. It is not very likely that a .debug_macro section + would only use the part of opcode space that it shares with + .debug_macinfo, but it is possible. Serving the opcodes that are + only valid in DW_MACRO_{GNU_,}* domain is OK as well, because + clients in general need to be ready that newer standards define + more opcodes, and have coping mechanisms for unfamiliar opcodes. + + The one exception to the above rule is opcode 0xff, which has + concrete semantics in .debug_macinfo, but falls into vendor block + in .debug_macro, and can be assigned to do whatever. There is + some small probability that the two opcodes would look + superficially similar enough that a client would be confused and + misbehave as a result. For this reason, we refuse to serve + through this interface 0xff's originating from .debug_macro + unless the TOKEN that we obtained indicates the call originates + from a new-style caller. See above for details on what + information is encoded into tokens. */ + + bool accept_0xff; + ptrdiff_t offset = offset_from_token (token, &accept_0xff); + + /* DW_AT_macro_info */ + if (dwarf_hasattr (cudie, DW_AT_macro_info)) + { + Dwarf_Word macoff; + if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0) + return -1; + offset = macro_info_getmacros_off (cudie->cu->dbg, macoff, + callback, arg, offset, cudie); + } + else + { + /* DW_AT_GNU_macros, DW_AT_macros */ + Dwarf_Word macoff; + if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0 + && get_offset_from (cudie, DW_AT_macros, &macoff) != 0) + return -1; + offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff, + callback, arg, offset, accept_0xff, + cudie); + } + + return token_from_offset (offset, accept_0xff); +} diff --git a/libdw/dwarf_getpubnames.c b/libdw/dwarf_getpubnames.c new file mode 100644 index 00000000..25600f33 --- /dev/null +++ b/libdw/dwarf_getpubnames.c @@ -0,0 +1,244 @@ +/* Get public symbol information. + Copyright (C) 2002, 2003, 2004, 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include +#include + + +static int +get_offsets (Dwarf *dbg) +{ + size_t allocated = 0; + size_t cnt = 0; + struct pubnames_s *mem = NULL; + const size_t entsize = sizeof (struct pubnames_s); + unsigned char *const startp = dbg->sectiondata[IDX_debug_pubnames]->d_buf; + unsigned char *readp = startp; + unsigned char *endp = readp + dbg->sectiondata[IDX_debug_pubnames]->d_size; + + while (readp + 14 < endp) + { + /* If necessary, allocate more entries. */ + if (cnt >= allocated) + { + allocated = MAX (10, 2 * allocated); + struct pubnames_s *newmem + = (struct pubnames_s *) realloc (mem, allocated * entsize); + if (newmem == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + err_return: + free (mem); + return -1; + } + + mem = newmem; + } + + /* Read the set header. */ + int len_bytes = 4; + Dwarf_Off len = read_4ubyte_unaligned_inc (dbg, readp); + if (len == DWARF3_LENGTH_64_BIT) + { + len = read_8ubyte_unaligned_inc (dbg, readp); + len_bytes = 8; + } + else if (unlikely (len >= DWARF3_LENGTH_MIN_ESCAPE_CODE + && len <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + goto err_return; + } + + /* Now we know the offset of the first offset/name pair. */ + mem[cnt].set_start = readp + 2 + 2 * len_bytes - startp; + mem[cnt].address_len = len_bytes; + size_t max_size = dbg->sectiondata[IDX_debug_pubnames]->d_size; + if (mem[cnt].set_start >= max_size + || len - (2 + 2 * len_bytes) > max_size - mem[cnt].set_start) + /* Something wrong, the first entry is beyond the end of + the section. Or the length of the whole unit is too big. */ + break; + + /* Read the version. It better be two for now. */ + uint16_t version = read_2ubyte_unaligned (dbg, readp); + if (unlikely (version != 2)) + { + __libdw_seterrno (DWARF_E_INVALID_VERSION); + goto err_return; + } + + /* Get the CU offset. */ + if (__libdw_read_offset (dbg, dbg, IDX_debug_pubnames, + readp + 2, len_bytes, + &mem[cnt].cu_offset, IDX_debug_info, 3)) + /* Error has been already set in reader. */ + goto err_return; + + /* Determine the size of the CU header. */ + unsigned char *infop + = ((unsigned char *) dbg->sectiondata[IDX_debug_info]->d_buf + + mem[cnt].cu_offset); + if (read_4ubyte_unaligned_noncvt (infop) == DWARF3_LENGTH_64_BIT) + mem[cnt].cu_header_size = 23; + else + mem[cnt].cu_header_size = 11; + + ++cnt; + + /* Advance to the next set. */ + readp += len; + } + + if (mem == NULL || cnt == 0) + { + free (mem); + __libdw_seterrno (DWARF_E_NO_ENTRY); + return -1; + } + + dbg->pubnames_sets = (struct pubnames_s *) realloc (mem, cnt * entsize); + dbg->pubnames_nsets = cnt; + + return 0; +} + + +ptrdiff_t +dwarf_getpubnames (Dwarf *dbg, + int (*callback) (Dwarf *, Dwarf_Global *, void *), + void *arg, ptrdiff_t offset) +{ + if (dbg == NULL) + return -1l; + + if (unlikely (offset < 0)) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1l; + } + + /* Make sure it is a valid offset. */ + if (unlikely (dbg->sectiondata[IDX_debug_pubnames] == NULL + || ((size_t) offset + >= dbg->sectiondata[IDX_debug_pubnames]->d_size))) + /* No (more) entry. */ + return 0; + + /* If necessary read the set information. */ + if (dbg->pubnames_nsets == 0 && unlikely (get_offsets (dbg) != 0)) + return -1l; + + /* Find the place where to start. */ + size_t cnt; + if (offset == 0) + { + cnt = 0; + offset = dbg->pubnames_sets[0].set_start; + } + else + { + for (cnt = 0; cnt + 1 < dbg->pubnames_nsets; ++cnt) + if ((Dwarf_Off) offset >= dbg->pubnames_sets[cnt].set_start) + { + assert ((Dwarf_Off) offset + < dbg->pubnames_sets[cnt + 1].set_start); + break; + } + assert (cnt + 1 < dbg->pubnames_nsets); + } + + unsigned char *startp + = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf; + unsigned char *endp + = startp + dbg->sectiondata[IDX_debug_pubnames]->d_size; + unsigned char *readp = startp + offset; + while (1) + { + Dwarf_Global gl; + + gl.cu_offset = (dbg->pubnames_sets[cnt].cu_offset + + dbg->pubnames_sets[cnt].cu_header_size); + + while (1) + { + /* READP points to the next offset/name pair. */ + if (readp + dbg->pubnames_sets[cnt].address_len > endp) + goto invalid_dwarf; + if (dbg->pubnames_sets[cnt].address_len == 4) + gl.die_offset = read_4ubyte_unaligned_inc (dbg, readp); + else + gl.die_offset = read_8ubyte_unaligned_inc (dbg, readp); + + /* If the offset is zero we reached the end of the set. */ + if (gl.die_offset == 0) + break; + + /* Add the CU offset. */ + gl.die_offset += dbg->pubnames_sets[cnt].cu_offset; + + gl.name = (char *) readp; + readp = (unsigned char *) memchr (gl.name, '\0', endp - readp); + if (unlikely (readp == NULL)) + { + invalid_dwarf: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1l; + } + readp++; + + /* We found name and DIE offset. Report it. */ + if (callback (dbg, &gl, arg) != DWARF_CB_OK) + { + /* The user wants us to stop. Return the offset of the + next entry. */ + return readp - startp; + } + } + + if (++cnt == dbg->pubnames_nsets) + /* This was the last set. */ + break; + + startp = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf; + readp = startp + dbg->pubnames_sets[cnt].set_start; + } + + /* We are done. No more entries. */ + return 0; +} diff --git a/libdw/dwarf_getscopes.c b/libdw/dwarf_getscopes.c new file mode 100644 index 00000000..5662eecf --- /dev/null +++ b/libdw/dwarf_getscopes.c @@ -0,0 +1,203 @@ +/* Return scope DIEs containing PC address. + Copyright (C) 2005, 2007, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" +#include + + +struct args +{ + Dwarf_Addr pc; + Dwarf_Die *scopes; + unsigned int inlined, nscopes; + Dwarf_Die inlined_origin; +}; + +/* Preorder visitor: prune the traversal if this DIE does not contain PC. */ +static int +pc_match (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg) +{ + struct args *a = arg; + + if (a->scopes != NULL) + die->prune = true; + else + { + /* dwarf_haspc returns an error if there are no appropriate attributes. + But we use it indiscriminantly instead of presuming which tags can + have PC attributes. So when it fails for that reason, treat it just + as a nonmatching return. */ + int result = INTUSE(dwarf_haspc) (&die->die, a->pc); + if (result < 0) + { + int error = INTUSE(dwarf_errno) (); + if (error != DWARF_E_NOERROR + && error != DWARF_E_NO_DEBUG_RANGES + && error != DWARF_E_NO_DEBUG_RNGLISTS) + { + __libdw_seterrno (error); + return -1; + } + result = 0; + } + if (result == 0) + die->prune = true; + + if (!die->prune + && INTUSE (dwarf_tag) (&die->die) == DW_TAG_inlined_subroutine) + a->inlined = depth; + } + + return 0; +} + +/* Preorder visitor for second partial traversal after finding a + concrete inlined instance. */ +static int +origin_match (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg) +{ + struct args *a = arg; + + if (die->die.addr != a->inlined_origin.addr) + return 0; + + /* We have a winner! This is the abstract definition of the inline + function of which A->scopes[A->nscopes - 1] is a concrete instance. + */ + + unsigned int nscopes = a->nscopes + depth; + Dwarf_Die *scopes = realloc (a->scopes, nscopes * sizeof scopes[0]); + if (scopes == NULL) + { + free (a->scopes); + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + + a->scopes = scopes; + do + { + die = die->parent; + scopes[a->nscopes++] = die->die; + } + while (a->nscopes < nscopes); + assert (die->parent == NULL); + return a->nscopes; +} + +/* Postorder visitor: first (innermost) call wins. */ +static int +pc_record (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg) +{ + struct args *a = arg; + + if (die->prune) + return 0; + + if (a->scopes == NULL) + { + /* We have hit the innermost DIE that contains the target PC. */ + + a->nscopes = depth + 1 - a->inlined; + a->scopes = malloc (a->nscopes * sizeof a->scopes[0]); + if (a->scopes == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + + for (unsigned int i = 0; i < a->nscopes; ++i) + { + a->scopes[i] = die->die; + die = die->parent; + } + + if (a->inlined == 0) + { + assert (die == NULL); + return a->nscopes; + } + + /* This is the concrete inlined instance itself. + Record its abstract_origin pointer. */ + Dwarf_Die *const inlinedie = &a->scopes[depth - a->inlined]; + + assert (INTUSE (dwarf_tag) (inlinedie) == DW_TAG_inlined_subroutine); + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE (dwarf_attr) (inlinedie, + DW_AT_abstract_origin, + &attr_mem); + if (INTUSE (dwarf_formref_die) (attr, &a->inlined_origin) == NULL) + return -1; + return 0; + } + + + /* We've recorded the scopes back to one that is a concrete inlined + instance. Now return out of the traversal back to the scope + containing that instance. */ + + assert (a->inlined); + if (depth >= a->inlined) + /* Not there yet. */ + return 0; + + /* Now we are in a scope that contains the concrete inlined instance. + Search it for the inline function's abstract definition. + If we don't find it, return to search the containing scope. + If we do find it, the nonzero return value will bail us out + of the postorder traversal. */ + return __libdw_visit_scopes (depth, die, NULL, &origin_match, NULL, a); +} + + +int +dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc, Dwarf_Die **scopes) +{ + if (cudie == NULL) + return -1; + + struct Dwarf_Die_Chain cu = { .parent = NULL, .die = *cudie }; + struct args a = { .pc = pc }; + + int result = __libdw_visit_scopes (0, &cu, NULL, &pc_match, &pc_record, &a); + + if (result == 0 && a.scopes != NULL) + result = __libdw_visit_scopes (0, &cu, NULL, &origin_match, NULL, &a); + + if (result > 0) + *scopes = a.scopes; + + return result; +} diff --git a/libdw/dwarf_getscopes_die.c b/libdw/dwarf_getscopes_die.c new file mode 100644 index 00000000..8e2e41db --- /dev/null +++ b/libdw/dwarf_getscopes_die.c @@ -0,0 +1,74 @@ +/* Return scope DIEs containing given DIE. + Copyright (C) 2005, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "libdwP.h" +#include +#include + +static int +scope_visitor (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg) +{ + if (die->die.addr != *(void **) arg) + return 0; + + Dwarf_Die *scopes = malloc (depth * sizeof scopes[0]); + if (scopes == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + + unsigned int i = 0; + do + { + scopes[i++] = die->die; + die = die->parent; + } + while (die != NULL); + assert (i == depth); + + *(void **) arg = scopes; + return depth; +} + +int +dwarf_getscopes_die (Dwarf_Die *die, Dwarf_Die **scopes) +{ + if (die == NULL) + return -1; + + struct Dwarf_Die_Chain cu = { .die = CUDIE (die->cu), .parent = NULL }; + void *info = die->addr; + int result = __libdw_visit_scopes (1, &cu, NULL, &scope_visitor, NULL, &info); + if (result > 0) + *scopes = info; + return result; +} diff --git a/libdw/dwarf_getscopevar.c b/libdw/dwarf_getscopevar.c new file mode 100644 index 00000000..7b1416f3 --- /dev/null +++ b/libdw/dwarf_getscopevar.c @@ -0,0 +1,159 @@ +/* Find a named variable or parameter within given scopes. + Copyright (C) 2005-2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" +#include + + +/* Find the containing CU's files. */ +static int +getfiles (Dwarf_Die *die, Dwarf_Files **files) +{ + return INTUSE(dwarf_getsrcfiles) (&CUDIE (die->cu), files, NULL); +} + +/* Fetch an attribute that should have a constant integer form. */ +static int +getattr (Dwarf_Die *die, int search_name, Dwarf_Word *value) +{ + Dwarf_Attribute attr_mem; + return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (die, search_name, + &attr_mem), value); +} + +static inline int +file_matches (const char *lastfile, + size_t match_file_len, const char *match_file, + Dwarf_Files *files, size_t idx, + bool *lastfile_matches) +{ + if (idx >= files->nfiles) + return false; + const char *file = files->info[idx].name; + if (file != lastfile) + { + size_t len = strlen (file); + *lastfile_matches = (len >= match_file_len + && !memcmp (match_file, file, match_file_len) + && (len == match_file_len + || file[len - match_file_len - 1] == '/')); + } + return *lastfile_matches; +} + +/* Search SCOPES[0..NSCOPES-1] for a variable called NAME. + Ignore the first SKIP_SHADOWS scopes that match the name. + If MATCH_FILE is not null, accept only declaration in that source file; + if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration + at that line and column. + + If successful, fill in *RESULT with the DIE of the variable found, + and return N where SCOPES[N] is the scope defining the variable. + Return -1 for errors or -2 for no matching variable found. */ + +int +dwarf_getscopevar (Dwarf_Die *scopes, int nscopes, + const char *name, int skip_shadows, + const char *match_file, int match_lineno, int match_linecol, + Dwarf_Die *result) +{ + /* Match against the given file name. */ + size_t match_file_len = match_file == NULL ? 0 : strlen (match_file); + bool lastfile_matches = false; + const char *lastfile = NULL; + + /* Start with the innermost scope and move out. */ + for (int out = 0; out < nscopes; ++out) + if (INTUSE(dwarf_haschildren) (&scopes[out])) + { + if (INTUSE(dwarf_child) (&scopes[out], result) != 0) + return -1; + do + { + switch (INTUSE(dwarf_tag) (result)) + { + case DW_TAG_variable: + case DW_TAG_formal_parameter: + break; + + default: + continue; + } + + /* Only get here for a variable or parameter. Check the name. */ + const char *diename = INTUSE(dwarf_diename) (result); + if (diename != NULL && !strcmp (name, diename)) + { + /* We have a matching name. */ + + if (skip_shadows > 0) + { + /* Punt this scope for the one it shadows. */ + --skip_shadows; + break; + } + + if (match_file != NULL) + { + /* Check its decl_file. */ + + Dwarf_Word i; + Dwarf_Files *files; + if (getattr (result, DW_AT_decl_file, &i) != 0 + || getfiles (&scopes[out], &files) != 0) + break; + + if (!file_matches (lastfile, match_file_len, match_file, + files, i, &lastfile_matches)) + break; + + if (match_lineno > 0 + && (getattr (result, DW_AT_decl_line, &i) != 0 + || (int) i != match_lineno)) + break; + if (match_linecol > 0 + && (getattr (result, DW_AT_decl_column, &i) != 0 + || (int) i != match_linecol)) + break; + } + + /* We have a winner! */ + return out; + } + } + while (INTUSE(dwarf_siblingof) (result, result) == 0); + } + + return -2; +} diff --git a/libdw/dwarf_getsrc_die.c b/libdw/dwarf_getsrc_die.c new file mode 100644 index 00000000..a95179ff --- /dev/null +++ b/libdw/dwarf_getsrc_die.c @@ -0,0 +1,74 @@ +/* Find line information for address. + Copyright (C) 2004, 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + + +Dwarf_Line * +dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr) +{ + Dwarf_Lines *lines; + size_t nlines; + + if (INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines) != 0) + return NULL; + + /* The lines are sorted by address, so we can use binary search. */ + if (nlines > 0) + { + size_t l = 0, u = nlines - 1; + while (l < u) + { + size_t idx = u - (u - l) / 2; + Dwarf_Line *line = &lines->info[idx]; + if (addr < line->addr) + u = idx - 1; + else + l = idx; + } + + /* This is guaranteed for us by libdw read_srclines. */ + assert (lines->info[nlines - 1].end_sequence); + + /* The last line which is less than or equal to addr is what we + want, unless it is the end_sequence which is after the + current line sequence. */ + Dwarf_Line *line = &lines->info[l]; + if (! line->end_sequence && line->addr <= addr) + return &lines->info[l]; + } + + __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE); + return NULL; +} diff --git a/libdw/dwarf_getsrc_file.c b/libdw/dwarf_getsrc_file.c new file mode 100644 index 00000000..5289c7da --- /dev/null +++ b/libdw/dwarf_getsrc_file.c @@ -0,0 +1,178 @@ +/* Find line information for given file/line/column triple. + Copyright (C) 2005-2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "libdwP.h" + + +int +dwarf_getsrc_file (Dwarf *dbg, const char *fname, int lineno, int column, + Dwarf_Line ***srcsp, size_t *nsrcs) +{ + if (dbg == NULL) + return -1; + + bool is_basename = strchr (fname, '/') == NULL; + + size_t max_match = *nsrcs ?: ~0u; + size_t act_match = *nsrcs; + size_t cur_match = 0; + Dwarf_Line **match = *nsrcs == 0 ? NULL : *srcsp; + + size_t cuhl; + Dwarf_Off noff; + for (Dwarf_Off off = 0; + INTUSE(dwarf_nextcu) (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0; + off = noff) + { + Dwarf_Die cudie_mem; + Dwarf_Die *cudie = INTUSE(dwarf_offdie) (dbg, off + cuhl, &cudie_mem); + if (cudie == NULL) + continue; + + /* Get the line number information for this file. */ + Dwarf_Lines *lines; + size_t nlines; + if (INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines) != 0) + { + /* Ignore a CU that just has no DW_AT_stmt_list at all. */ + int error = INTUSE(dwarf_errno) (); + if (error == 0) + continue; + __libdw_seterrno (error); + return -1; + } + + /* Search through all the line number records for a matching + file and line/column number. If any of the numbers is zero, + no match is performed. */ + unsigned int lastfile = UINT_MAX; + bool lastmatch = false; + for (size_t cnt = 0; cnt < nlines; ++cnt) + { + Dwarf_Line *line = &lines->info[cnt]; + + if (lastfile != line->file) + { + lastfile = line->file; + if (lastfile >= line->files->nfiles) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + /* Match the name with the name the user provided. */ + const char *fname2 = line->files->info[lastfile].name; + if (is_basename) + lastmatch = strcmp (basename (fname2), fname) == 0; + else + lastmatch = strcmp (fname2, fname) == 0; + } + if (!lastmatch) + continue; + + /* See whether line and possibly column match. */ + if (lineno != 0 + && (lineno > line->line + || (column != 0 && column > line->column))) + /* Cannot match. */ + continue; + + /* Determine whether this is the best match so far. */ + size_t inner; + for (inner = 0; inner < cur_match; ++inner) + if (match[inner]->files == line->files + && match[inner]->file == line->file) + break; + if (inner < cur_match + && (match[inner]->line != line->line + || match[inner]->line != lineno + || (column != 0 + && (match[inner]->column != line->column + || match[inner]->column != column)))) + { + /* We know about this file already. If this is a better + match for the line number, use it. */ + if (match[inner]->line >= line->line + && (match[inner]->line != line->line + || match[inner]->column >= line->column)) + /* Use the new line. Otherwise the old one. */ + match[inner] = line; + continue; + } + + if (cur_match < max_match) + { + if (cur_match == act_match) + { + /* Enlarge the array for the results. */ + act_match += 10; + Dwarf_Line **newp = realloc (match, + act_match + * sizeof (Dwarf_Line *)); + if (newp == NULL) + { + free (match); + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + match = newp; + } + + match[cur_match++] = line; + } + } + + /* If we managed to find as many matches as the user requested + already, there is no need to go on to the next CU. */ + if (cur_match == max_match) + break; + } + + if (cur_match > 0) + { + assert (*nsrcs == 0 || *srcsp == match); + + *nsrcs = cur_match; + *srcsp = match; + + return 0; + } + + __libdw_seterrno (DWARF_E_NO_MATCH); + return -1; +} diff --git a/libdw/dwarf_getsrcdirs.c b/libdw/dwarf_getsrcdirs.c new file mode 100644 index 00000000..8160ed30 --- /dev/null +++ b/libdw/dwarf_getsrcdirs.c @@ -0,0 +1,45 @@ +/* Find include directories in source file information. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_getsrcdirs (Dwarf_Files *files, const char *const **result, size_t *ndirs) +{ + if (files == NULL) + return -1; + + *result = (void *) &files->info[files->nfiles]; + *ndirs = files->ndirs; + return 0; +} diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c new file mode 100644 index 00000000..12fdabf2 --- /dev/null +++ b/libdw/dwarf_getsrcfiles.c @@ -0,0 +1,111 @@ +/* Return source file information of CU. + Copyright (C) 2004, 2005, 2013, 2015, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + + +int +dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles) +{ + if (cudie == NULL) + return -1; + if (! is_cudie (cudie)) + { + __libdw_seterrno (DWARF_E_NOT_CUDIE); + return -1; + } + + int res = -1; + + /* Get the information if it is not already known. */ + struct Dwarf_CU *const cu = cudie->cu; + if (cu->files == NULL) + { + /* For split units there might be a simple file table (without lines). + If not, use the one from the skeleton. */ + if (cu->unit_type == DW_UT_split_compile + || cu->unit_type == DW_UT_split_type) + { + /* We tried, assume we fail... */ + cu->files = (void *) -1; + + /* See if there is a .debug_line section, for split CUs + the table is at offset zero. */ + if (cu->dbg->sectiondata[IDX_debug_line] != NULL) + { + /* We are only interested in the files, the lines will + always come from the skeleton. */ + res = __libdw_getsrclines (cu->dbg, 0, + __libdw_getcompdir (cudie), + cu->address_size, NULL, + &cu->files); + } + else + { + Dwarf_CU *skel = __libdw_find_split_unit (cu); + if (skel != NULL) + { + Dwarf_Die skeldie = CUDIE (skel); + res = INTUSE(dwarf_getsrcfiles) (&skeldie, files, nfiles); + cu->files = skel->files; + } + } + } + else + { + Dwarf_Lines *lines; + size_t nlines; + + /* Let the more generic function do the work. It'll create more + data but that will be needed in an real program anyway. */ + res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines); + } + } + else if (cu->files != (void *) -1l) + /* We already have the information. */ + res = 0; + + if (likely (res == 0)) + { + assert (cu->files != NULL && cu->files != (void *) -1l); + *files = cu->files; + if (nfiles != NULL) + *nfiles = cu->files->nfiles; + } + + // XXX Eventually: unlocking here. + + return res; +} +INTDEF (dwarf_getsrcfiles) diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c new file mode 100644 index 00000000..d6a581ad --- /dev/null +++ b/libdw/dwarf_getsrclines.c @@ -0,0 +1,1228 @@ +/* Return line number information of CU. + Copyright (C) 2004-2010, 2013, 2014, 2015, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "dwarf.h" +#include "libdwP.h" + + +struct filelist +{ + Dwarf_Fileinfo info; + struct filelist *next; +}; + +struct linelist +{ + Dwarf_Line line; + struct linelist *next; + size_t sequence; +}; + + +/* Compare by Dwarf_Line.addr, given pointers into an array of pointers. */ +static int +compare_lines (const void *a, const void *b) +{ + struct linelist *const *p1 = a; + struct linelist *const *p2 = b; + struct linelist *list1 = *p1; + struct linelist *list2 = *p2; + Dwarf_Line *line1 = &list1->line; + Dwarf_Line *line2 = &list2->line; + + if (line1->addr != line2->addr) + return (line1->addr < line2->addr) ? -1 : 1; + + /* An end_sequence marker precedes a normal record at the same address. */ + if (line1->end_sequence != line2->end_sequence) + return line2->end_sequence - line1->end_sequence; + + /* Otherwise, the linelist sequence maintains a stable sort. */ + return (list1->sequence < list2->sequence) ? -1 + : (list1->sequence > list2->sequence) ? 1 + : 0; +} + +struct line_state +{ + Dwarf_Word addr; + unsigned int op_index; + unsigned int file; + int64_t line; + unsigned int column; + uint_fast8_t is_stmt; + bool basic_block; + bool prologue_end; + bool epilogue_begin; + unsigned int isa; + unsigned int discriminator; + struct linelist *linelist; + size_t nlinelist; + unsigned int end_sequence; +}; + +static inline void +run_advance_pc (struct line_state *state, unsigned int op_advance, + uint_fast8_t minimum_instr_len, uint_fast8_t max_ops_per_instr) +{ + state->addr += minimum_instr_len * ((state->op_index + op_advance) + / max_ops_per_instr); + state->op_index = (state->op_index + op_advance) % max_ops_per_instr; +} + +static inline bool +add_new_line (struct line_state *state, struct linelist *new_line) +{ + /* Set the line information. For some fields we use bitfields, + so we would lose information if the encoded values are too large. + Check just for paranoia, and call the data "invalid" if it + violates our assumptions on reasonable limits for the values. */ + new_line->next = state->linelist; + new_line->sequence = state->nlinelist; + state->linelist = new_line; + ++(state->nlinelist); + + /* Set the line information. For some fields we use bitfields, + so we would lose information if the encoded values are too large. + Check just for paranoia, and call the data "invalid" if it + violates our assumptions on reasonable limits for the values. */ +#define SET(field) \ + do { \ + new_line->line.field = state->field; \ + if (unlikely (new_line->line.field != state->field)) \ + return true; \ + } while (0) + + SET (addr); + SET (op_index); + SET (file); + SET (line); + SET (column); + SET (is_stmt); + SET (basic_block); + SET (end_sequence); + SET (prologue_end); + SET (epilogue_begin); + SET (isa); + SET (discriminator); + +#undef SET + + return false; +} + +static int +read_srclines (Dwarf *dbg, + const unsigned char *linep, const unsigned char *lineendp, + const char *comp_dir, unsigned address_size, + Dwarf_Lines **linesp, Dwarf_Files **filesp) +{ + int res = -1; + + struct filelist *filelist = NULL; + size_t nfilelist = 0; + size_t ndirlist = 0; + + /* If there are a large number of lines, files or dirs don't blow up + the stack. Stack allocate some entries, only dynamically malloc + when more than MAX. */ +#define MAX_STACK_ALLOC 4096 +#define MAX_STACK_LINES MAX_STACK_ALLOC +#define MAX_STACK_FILES (MAX_STACK_ALLOC / 4) +#define MAX_STACK_DIRS (MAX_STACK_ALLOC / 16) + + /* Initial statement program state (except for stmt_list, see below). */ + struct line_state state = + { + .linelist = NULL, + .nlinelist = 0, + .addr = 0, + .op_index = 0, + .file = 1, + /* We only store int but want to check for overflow (see SET above). */ + .line = 1, + .column = 0, + .basic_block = false, + .prologue_end = false, + .epilogue_begin = false, + .isa = 0, + .discriminator = 0 + }; + + /* The dirs normally go on the stack, but if there are too many + we alloc them all. Set up stack storage early, so we can check on + error if we need to free them or not. */ + struct dirlist + { + const char *dir; + size_t len; + }; + struct dirlist dirstack[MAX_STACK_DIRS]; + struct dirlist *dirarray = dirstack; + + if (unlikely (linep + 4 > lineendp)) + { + invalid_data: + __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE); + goto out; + } + + Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); + unsigned int length = 4; + if (unlikely (unit_length == DWARF3_LENGTH_64_BIT)) + { + if (unlikely (linep + 8 > lineendp)) + goto invalid_data; + unit_length = read_8ubyte_unaligned_inc (dbg, linep); + length = 8; + } + + /* Check whether we have enough room in the section. */ + if (unlikely (unit_length > (size_t) (lineendp - linep))) + goto invalid_data; + lineendp = linep + unit_length; + + /* The next element of the header is the version identifier. */ + if ((size_t) (lineendp - linep) < 2) + goto invalid_data; + uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); + if (unlikely (version < 2) || unlikely (version > 5)) + { + __libdw_seterrno (DWARF_E_VERSION); + goto out; + } + + /* DWARF5 explicitly lists address and segment_selector sizes. */ + if (version >= 5) + { + if ((size_t) (lineendp - linep) < 2) + goto invalid_data; + size_t line_address_size = *linep++; + size_t segment_selector_size = *linep++; + if (line_address_size != address_size || segment_selector_size != 0) + goto invalid_data; + } + + /* Next comes the header length. */ + Dwarf_Word header_length; + if (length == 4) + { + if ((size_t) (lineendp - linep) < 4) + goto invalid_data; + header_length = read_4ubyte_unaligned_inc (dbg, linep); + } + else + { + if ((size_t) (lineendp - linep) < 8) + goto invalid_data; + header_length = read_8ubyte_unaligned_inc (dbg, linep); + } + const unsigned char *header_start = linep; + + /* Next the minimum instruction length. */ + uint_fast8_t minimum_instr_len = *linep++; + + /* Next the maximum operations per instruction, in version 4 format. */ + uint_fast8_t max_ops_per_instr = 1; + if (version >= 4) + { + if (unlikely ((size_t) (lineendp - linep) < 1)) + goto invalid_data; + max_ops_per_instr = *linep++; + if (unlikely (max_ops_per_instr == 0)) + goto invalid_data; + } + + /* 4 more bytes, is_stmt, line_base, line_range and opcode_base. */ + if ((size_t) (lineendp - linep) < 4) + goto invalid_data; + + /* Then the flag determining the default value of the is_stmt + register. */ + uint_fast8_t default_is_stmt = *linep++; + + /* Now the line base. */ + int_fast8_t line_base = (int8_t) *linep++; + + /* And the line range. */ + uint_fast8_t line_range = *linep++; + + /* The opcode base. */ + uint_fast8_t opcode_base = *linep++; + + /* Remember array with the standard opcode length (-1 to account for + the opcode with value zero not being mentioned). */ + const uint8_t *standard_opcode_lengths = linep - 1; + if (unlikely (lineendp - linep < opcode_base - 1)) + goto invalid_data; + linep += opcode_base - 1; + + /* To read DWARF5 dir and file lists we need to know the forms. For + now we skip everything, except the DW_LNCT_path and + DW_LNCT_directory_index. */ + uint16_t forms[256]; + unsigned char nforms = 0; + unsigned char form_path = -1; /* Which forms is DW_LNCT_path. */ + unsigned char form_idx = -1; /* And which is DW_LNCT_directory_index. */ + + /* To read/skip form data. */ + Dwarf_CU fake_cu = { + .dbg = dbg, + .sec_idx = IDX_debug_line, + .version = 5, + .offset_size = length, + .address_size = address_size, + .startp = (void *) linep, + .endp = (void *) lineendp, + }; + + /* First count the entries. */ + size_t ndirs = 0; + if (version < 5) + { + const unsigned char *dirp = linep; + while (dirp < lineendp && *dirp != 0) + { + uint8_t *endp = memchr (dirp, '\0', lineendp - dirp); + if (endp == NULL) + goto invalid_data; + ++ndirs; + dirp = endp + 1; + } + if (dirp >= lineendp || *dirp != '\0') + goto invalid_data; + ndirs = ndirs + 1; /* There is always the "unknown" dir. */ + } + else + { + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + nforms = *linep++; + for (int i = 0; i < nforms; i++) + { + uint16_t desc, form; + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (desc, linep, lineendp); + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (form, linep, lineendp); + + if (! libdw_valid_user_form (form)) + goto invalid_data; + + forms[i] = form; + if (desc == DW_LNCT_path) + form_path = i; + } + + if (nforms > 0 && form_path == (unsigned char) -1) + goto invalid_data; + + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (ndirs, linep, lineendp); + + if (nforms == 0 && ndirs != 0) + goto invalid_data; + + /* Assume there is at least 1 byte needed per form to describe + the directory. Filters out insanely large ndirs. */ + if (nforms != 0 && ndirs > (size_t) (lineendp - linep) / nforms) + goto invalid_data; + } + + /* Arrange the list in array form. */ + ndirlist = ndirs; + if (ndirlist >= MAX_STACK_DIRS) + { + if (ndirlist > SIZE_MAX / sizeof (*dirarray)) + goto no_mem; + dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray)); + if (unlikely (dirarray == NULL)) + { + no_mem: + __libdw_seterrno (DWARF_E_NOMEM); + goto out; + } + } + + /* Entry zero is implicit for older versions, but explicit for 5+. */ + struct dirlist comp_dir_elem; + if (version < 5) + { + /* First comes the list of directories. Add the compilation + directory first since the index zero is used for it. */ + comp_dir_elem.dir = comp_dir; + comp_dir_elem.len = comp_dir ? strlen (comp_dir) : 0, + dirarray[0] = comp_dir_elem; + for (unsigned int n = 1; n < ndirlist; n++) + { + dirarray[n].dir = (char *) linep; + uint8_t *endp = memchr (linep, '\0', lineendp - linep); + assert (endp != NULL); // Checked above when calculating ndirlist. + dirarray[n].len = endp - linep; + linep = endp + 1; + } + /* Skip the final NUL byte. */ + assert (*linep == '\0'); // Checked above when calculating ndirlist. + ++linep; + } + else + { + Dwarf_Attribute attr; + attr.code = DW_AT_name; + attr.cu = &fake_cu; + for (unsigned int n = 0; n < ndirlist; n++) + { + const char *dir = NULL; + for (unsigned char m = 0; m < nforms; m++) + { + if (m == form_path) + { + attr.form = forms[m]; + attr.valp = (void *) linep; + dir = dwarf_formstring (&attr); + } + + size_t len = __libdw_form_val_len (&fake_cu, forms[m], linep); + if ((size_t) (lineendp - linep) < len) + goto invalid_data; + + linep += len; + } + + if (dir == NULL) + goto invalid_data; + + dirarray[n].dir = dir; + dirarray[n].len = strlen (dir); + } + } + + /* File index zero doesn't exist for DWARF < 5. Files are indexed + starting from 1. But for DWARF5 they are indexed starting from + zero, but the default index is still 1. In both cases the + "first" file is special and refers to the main compile unit file, + equal to the DW_AT_name of the DW_TAG_compile_unit. */ + struct filelist null_file = + { + .info = + { + .name = "???", + .mtime = 0, + .length = 0 + }, + .next = NULL + }; + filelist = &null_file; + nfilelist = 1; + + /* Allocate memory for a new file. For the first MAX_STACK_FILES + entries just return a slot in the preallocated stack array. + This is slightly complicated because in DWARF < 5 new files could + be defined with DW_LNE_define_file after the normal file list was + read. */ + struct filelist flstack[MAX_STACK_FILES]; +#define NEW_FILE() ({ \ + struct filelist *fl = (nfilelist < MAX_STACK_FILES \ + ? &flstack[nfilelist] \ + : malloc (sizeof (struct filelist))); \ + if (unlikely (fl == NULL)) \ + goto no_mem; \ + ++nfilelist; \ + fl->next = filelist; \ + filelist = fl; \ + fl; }) + + /* Now read the files. */ + if (version < 5) + { + if (unlikely (linep >= lineendp)) + goto invalid_data; + while (linep < lineendp && *linep != '\0') + { + struct filelist *new_file = NEW_FILE (); + + /* First comes the file name. */ + char *fname = (char *) linep; + uint8_t *endp = memchr (fname, '\0', lineendp - linep); + if (endp == NULL) + goto invalid_data; + size_t fnamelen = endp - (uint8_t *) fname; + linep = endp + 1; + + /* Then the index. */ + Dwarf_Word diridx; + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (diridx, linep, lineendp); + if (unlikely (diridx >= ndirlist)) + { + __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); + goto out; + } + + if (*fname == '/') + /* It's an absolute path. */ + new_file->info.name = fname; + else + { + new_file->info.name = libdw_alloc (dbg, char, 1, + dirarray[diridx].len + 1 + + fnamelen + 1); + char *cp = new_file->info.name; + + if (dirarray[diridx].dir != NULL) + { + /* This value could be NULL in case the DW_AT_comp_dir + was not present. We cannot do much in this case. + Just keep the file relative. */ + cp = stpcpy (cp, dirarray[diridx].dir); + *cp++ = '/'; + } + strcpy (cp, fname); + assert (strlen (new_file->info.name) + < dirarray[diridx].len + 1 + fnamelen + 1); + } + + /* Next comes the modification time. */ + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (new_file->info.mtime, linep, lineendp); + + /* Finally the length of the file. */ + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (new_file->info.length, linep, lineendp); + } + if (linep >= lineendp || *linep != '\0') + goto invalid_data; + /* Skip the final NUL byte. */ + ++linep; + } + else + { + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + nforms = *linep++; + form_path = form_idx = -1; + for (int i = 0; i < nforms; i++) + { + uint16_t desc, form; + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (desc, linep, lineendp); + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (form, linep, lineendp); + + if (! libdw_valid_user_form (form)) + goto invalid_data; + + forms[i] = form; + if (desc == DW_LNCT_path) + form_path = i; + else if (desc == DW_LNCT_directory_index) + form_idx = i; + } + + if (nforms > 0 && (form_path == (unsigned char) -1 + || form_idx == (unsigned char) -1)) + goto invalid_data; + + size_t nfiles; + get_uleb128 (nfiles, linep, lineendp); + + if (nforms == 0 && nfiles != 0) + goto invalid_data; + + /* Assume there is at least 1 byte needed per form to describe + the file. Filters out insanely large nfiles. */ + if (nforms != 0 && nfiles > (size_t) (lineendp - linep) / nforms) + goto invalid_data; + + Dwarf_Attribute attr; + attr.cu = &fake_cu; + for (unsigned int n = 0; n < nfiles; n++) + { + const char *fname = NULL; + Dwarf_Word diridx = (Dwarf_Word) -1; + for (unsigned char m = 0; m < nforms; m++) + { + if (m == form_path) + { + attr.code = DW_AT_name; + attr.form = forms[m]; + attr.valp = (void *) linep; + fname = dwarf_formstring (&attr); + } + else if (m == form_idx) + { + attr.code = DW_AT_decl_file; /* Close enough. */ + attr.form = forms[m]; + attr.valp = (void *) linep; + if (dwarf_formudata (&attr, &diridx) != 0) + diridx = (Dwarf_Word) -1; + } + + size_t len = __libdw_form_val_len (&fake_cu, forms[m], linep); + if ((size_t) (lineendp - linep) < len) + goto invalid_data; + + linep += len; + } + + if (fname == NULL || diridx == (Dwarf_Word) -1) + goto invalid_data; + + size_t fnamelen = strlen (fname); + + if (unlikely (diridx >= ndirlist)) + { + __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); + goto out; + } + + /* Yes, weird. Looks like an off-by-one in the spec. */ + struct filelist *new_file = n == 0 ? &null_file : NEW_FILE (); + + /* We follow the same rules as above for DWARF < 5, even + though the standard doesn't explicitly mention absolute + paths and ignoring the dir index. */ + if (*fname == '/') + /* It's an absolute path. */ + new_file->info.name = (char *) fname; + else + { + new_file->info.name = libdw_alloc (dbg, char, 1, + dirarray[diridx].len + 1 + + fnamelen + 1); + char *cp = new_file->info.name; + + /* In the DWARF >= 5 case, dir can never be NULL. */ + cp = stpcpy (cp, dirarray[diridx].dir); + *cp++ = '/'; + strcpy (cp, fname); + assert (strlen (new_file->info.name) + < dirarray[diridx].len + 1 + fnamelen + 1); + } + + /* For now we just ignore the modification time and file length. */ + new_file->info.mtime = 0; + new_file->info.length = 0; + } + } + + /* Consistency check. */ + if (unlikely (linep != header_start + header_length)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + goto out; + } + + /* We are about to process the statement program. Most state machine + registers have already been initialize above. Just add the is_stmt + default. See 6.2.2 in the v2.1 specification. */ + state.is_stmt = default_is_stmt; + + /* Apply the "operation advance" from a special opcode or + DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ +#define advance_pc(op_advance) \ + run_advance_pc (&state, op_advance, minimum_instr_len, max_ops_per_instr) + + /* Process the instructions. */ + + /* Adds a new line to the matrix. For the first MAX_STACK_LINES + entries just return a slot in the preallocated stack array. */ + struct linelist llstack[MAX_STACK_LINES]; +#define NEW_LINE(end_seq) \ + do { \ + struct linelist *ll = (state.nlinelist < MAX_STACK_LINES \ + ? &llstack[state.nlinelist] \ + : malloc (sizeof (struct linelist))); \ + if (unlikely (ll == NULL)) \ + goto no_mem; \ + state.end_sequence = end_seq; \ + if (unlikely (add_new_line (&state, ll))) \ + goto invalid_data; \ + } while (0) + + while (linep < lineendp) + { + unsigned int opcode; + unsigned int u128; + int s128; + + /* Read the opcode. */ + opcode = *linep++; + + /* Is this a special opcode? */ + if (likely (opcode >= opcode_base)) + { + if (unlikely (line_range == 0)) + goto invalid_data; + + /* Yes. Handling this is quite easy since the opcode value + is computed with + + opcode = (desired line increment - line_base) + + (line_range * address advance) + opcode_base + */ + int line_increment = (line_base + + (opcode - opcode_base) % line_range); + + /* Perform the increments. */ + state.line += line_increment; + advance_pc ((opcode - opcode_base) / line_range); + + /* Add a new line with the current state machine values. */ + NEW_LINE (0); + + /* Reset the flags. */ + state.basic_block = false; + state.prologue_end = false; + state.epilogue_begin = false; + state.discriminator = 0; + } + else if (opcode == 0) + { + /* This an extended opcode. */ + if (unlikely (lineendp - linep < 2)) + goto invalid_data; + + /* The length. */ + uint_fast8_t len = *linep++; + + if (unlikely ((size_t) (lineendp - linep) < len)) + goto invalid_data; + + /* The sub-opcode. */ + opcode = *linep++; + + switch (opcode) + { + case DW_LNE_end_sequence: + /* Add a new line with the current state machine values. + The is the end of the sequence. */ + NEW_LINE (1); + + /* Reset the registers. */ + state.addr = 0; + state.op_index = 0; + state.file = 1; + state.line = 1; + state.column = 0; + state.is_stmt = default_is_stmt; + state.basic_block = false; + state.prologue_end = false; + state.epilogue_begin = false; + state.isa = 0; + state.discriminator = 0; + break; + + case DW_LNE_set_address: + /* The value is an address. The size is defined as + appropriate for the target machine. We use the + address size field from the CU header. */ + state.op_index = 0; + if (unlikely (lineendp - linep < (uint8_t) address_size)) + goto invalid_data; + if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep, + address_size, &state.addr)) + goto out; + break; + + case DW_LNE_define_file: + { + char *fname = (char *) linep; + uint8_t *endp = memchr (linep, '\0', lineendp - linep); + if (endp == NULL) + goto invalid_data; + size_t fnamelen = endp - linep; + linep = endp + 1; + + unsigned int diridx; + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (diridx, linep, lineendp); + if (unlikely (diridx >= ndirlist)) + { + __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); + goto invalid_data; + } + Dwarf_Word mtime; + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (mtime, linep, lineendp); + Dwarf_Word filelength; + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (filelength, linep, lineendp); + + struct filelist *new_file = NEW_FILE (); + if (fname[0] == '/') + new_file->info.name = fname; + else + { + new_file->info.name = + libdw_alloc (dbg, char, 1, (dirarray[diridx].len + 1 + + fnamelen + 1)); + char *cp = new_file->info.name; + + if (dirarray[diridx].dir != NULL) + /* This value could be NULL in case the + DW_AT_comp_dir was not present. We + cannot do much in this case. Just + keep the file relative. */ + { + cp = stpcpy (cp, dirarray[diridx].dir); + *cp++ = '/'; + } + strcpy (cp, fname); + } + + new_file->info.mtime = mtime; + new_file->info.length = filelength; + } + break; + + case DW_LNE_set_discriminator: + /* Takes one ULEB128 parameter, the discriminator. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (state.discriminator, linep, lineendp); + break; + + default: + /* Unknown, ignore it. */ + if (unlikely ((size_t) (lineendp - (linep - 1)) < len)) + goto invalid_data; + linep += len - 1; + break; + } + } + else if (opcode <= DW_LNS_set_isa) + { + /* This is a known standard opcode. */ + switch (opcode) + { + case DW_LNS_copy: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + /* Add a new line with the current state machine values. */ + NEW_LINE (0); + + /* Reset the flags. */ + state.basic_block = false; + state.prologue_end = false; + state.epilogue_begin = false; + state.discriminator = 0; + break; + + case DW_LNS_advance_pc: + /* Takes one uleb128 parameter which is added to the + address. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (u128, linep, lineendp); + advance_pc (u128); + break; + + case DW_LNS_advance_line: + /* Takes one sleb128 parameter which is added to the + line. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_sleb128 (s128, linep, lineendp); + state.line += s128; + break; + + case DW_LNS_set_file: + /* Takes one uleb128 parameter which is stored in file. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (u128, linep, lineendp); + state.file = u128; + break; + + case DW_LNS_set_column: + /* Takes one uleb128 parameter which is stored in column. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (u128, linep, lineendp); + state.column = u128; + break; + + case DW_LNS_negate_stmt: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + state.is_stmt = 1 - state.is_stmt; + break; + + case DW_LNS_set_basic_block: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + state.basic_block = true; + break; + + case DW_LNS_const_add_pc: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + if (unlikely (line_range == 0)) + goto invalid_data; + + advance_pc ((255 - opcode_base) / line_range); + break; + + case DW_LNS_fixed_advance_pc: + /* Takes one 16 bit parameter which is added to the + address. */ + if (unlikely (standard_opcode_lengths[opcode] != 1) + || unlikely (lineendp - linep < 2)) + goto invalid_data; + + state.addr += read_2ubyte_unaligned_inc (dbg, linep); + state.op_index = 0; + break; + + case DW_LNS_set_prologue_end: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + state.prologue_end = true; + break; + + case DW_LNS_set_epilogue_begin: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + state.epilogue_begin = true; + break; + + case DW_LNS_set_isa: + /* Takes one uleb128 parameter which is stored in isa. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (state.isa, linep, lineendp); + break; + } + } + else + { + /* This is a new opcode the generator but not we know about. + Read the parameters associated with it but then discard + everything. Read all the parameters for this opcode. */ + for (int n = standard_opcode_lengths[opcode]; n > 0; --n) + { + if (unlikely (linep >= lineendp)) + goto invalid_data; + get_uleb128 (u128, linep, lineendp); + } + + /* Next round, ignore this opcode. */ + continue; + } + } + + /* Put all the files in an array. */ + Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files, + sizeof (Dwarf_Files) + + nfilelist * sizeof (Dwarf_Fileinfo) + + (ndirlist + 1) * sizeof (char *), + 1); + const char **dirs = (void *) &files->info[nfilelist]; + + struct filelist *fileslist = filelist; + files->nfiles = nfilelist; + for (size_t n = nfilelist; n > 0; n--) + { + files->info[n - 1] = fileslist->info; + fileslist = fileslist->next; + } + assert (fileslist == NULL); + + /* Put all the directory strings in an array. */ + files->ndirs = ndirlist; + for (unsigned int i = 0; i < ndirlist; ++i) + dirs[i] = dirarray[i].dir; + dirs[ndirlist] = NULL; + + /* Pass the file data structure to the caller. */ + if (filesp != NULL) + *filesp = files; + + size_t buf_size = (sizeof (Dwarf_Lines) + + (sizeof (Dwarf_Line) * state.nlinelist)); + void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1); + + /* First use the buffer for the pointers, and sort the entries. + We'll write the pointers in the end of the buffer, and then + copy into the buffer from the beginning so the overlap works. */ + assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *)); + struct linelist **sortlines = (buf + buf_size + - sizeof (struct linelist **) * state.nlinelist); + + /* The list is in LIFO order and usually they come in clumps with + ascending addresses. So fill from the back to probably start with + runs already in order before we sort. */ + struct linelist *lineslist = state.linelist; + for (size_t i = state.nlinelist; i-- > 0; ) + { + sortlines[i] = lineslist; + lineslist = lineslist->next; + } + assert (lineslist == NULL); + + /* Sort by ascending address. */ + qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines); + + /* Now that they are sorted, put them in the final array. + The buffers overlap, so we've clobbered the early elements + of SORTLINES by the time we're reading the later ones. */ + Dwarf_Lines *lines = buf; + lines->nlines = state.nlinelist; + for (size_t i = 0; i < state.nlinelist; ++i) + { + lines->info[i] = sortlines[i]->line; + lines->info[i].files = files; + } + + /* Make sure the highest address for the CU is marked as end_sequence. + This is required by the DWARF spec, but some compilers forget and + dwfl_module_getsrc depends on it. */ + if (state.nlinelist > 0) + lines->info[state.nlinelist - 1].end_sequence = 1; + + /* Pass the line structure back to the caller. */ + if (linesp != NULL) + *linesp = lines; + + /* Success. */ + res = 0; + + out: + /* Free malloced line records, if any. */ + for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++) + { + struct linelist *ll = state.linelist->next; + free (state.linelist); + state.linelist = ll; + } + if (dirarray != dirstack) + free (dirarray); + for (size_t i = MAX_STACK_FILES; i < nfilelist; i++) + { + struct filelist *fl = filelist->next; + free (filelist); + filelist = fl; + } + + return res; +} + +static int +files_lines_compare (const void *p1, const void *p2) +{ + const struct files_lines_s *t1 = p1; + const struct files_lines_s *t2 = p2; + + if (t1->debug_line_offset < t2->debug_line_offset) + return -1; + if (t1->debug_line_offset > t2->debug_line_offset) + return 1; + + return 0; +} + +int +internal_function +__libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, + const char *comp_dir, unsigned address_size, + Dwarf_Lines **linesp, Dwarf_Files **filesp) +{ + struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; + struct files_lines_s **found = tfind (&fake, &dbg->files_lines, + files_lines_compare); + if (found == NULL) + { + Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); + if (data == NULL + || __libdw_offset_in_section (dbg, IDX_debug_line, + debug_line_offset, 1) != 0) + return -1; + + const unsigned char *linep = data->d_buf + debug_line_offset; + const unsigned char *lineendp = data->d_buf + data->d_size; + + struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, + sizeof *node, 1); + + if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, + &node->lines, &node->files) != 0) + return -1; + + node->debug_line_offset = debug_line_offset; + + found = tsearch (node, &dbg->files_lines, files_lines_compare); + if (found == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + } + + if (linesp != NULL) + *linesp = (*found)->lines; + + if (filesp != NULL) + *filesp = (*found)->files; + + return 0; +} + +/* Get the compilation directory, if any is set. */ +const char * +__libdw_getcompdir (Dwarf_Die *cudie) +{ + Dwarf_Attribute compdir_attr_mem; + Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie, + DW_AT_comp_dir, + &compdir_attr_mem); + return INTUSE(dwarf_formstring) (compdir_attr); +} + +int +dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) +{ + if (cudie == NULL) + return -1; + if (! is_cudie (cudie)) + { + __libdw_seterrno (DWARF_E_NOT_CUDIE); + return -1; + } + + /* Get the information if it is not already known. */ + struct Dwarf_CU *const cu = cudie->cu; + if (cu->lines == NULL) + { + /* For split units always pick the lines from the skeleton. */ + if (cu->unit_type == DW_UT_split_compile + || cu->unit_type == DW_UT_split_type) + { + /* We tries, assume we fail... */ + cu->lines = (void *) -1l; + + Dwarf_CU *skel = __libdw_find_split_unit (cu); + if (skel != NULL) + { + Dwarf_Die skeldie = CUDIE (skel); + int res = INTUSE(dwarf_getsrclines) (&skeldie, lines, nlines); + if (res == 0) + { + cu->lines = skel->lines; + *lines = cu->lines; + *nlines = cu->lines->nlines; + } + return res; + } + + __libdw_seterrno (DWARF_E_NO_DEBUG_LINE); + return -1; + } + + /* Failsafe mode: no data found. */ + cu->lines = (void *) -1l; + cu->files = (void *) -1l; + + /* The die must have a statement list associated. */ + Dwarf_Attribute stmt_list_mem; + Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, + &stmt_list_mem); + + /* Get the offset into the .debug_line section. NB: this call + also checks whether the previous dwarf_attr call failed. */ + Dwarf_Off debug_line_offset; + if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE, + NULL, &debug_line_offset) == NULL) + return -1; + + if (__libdw_getsrclines (cu->dbg, debug_line_offset, + __libdw_getcompdir (cudie), + cu->address_size, &cu->lines, &cu->files) < 0) + return -1; + } + else if (cu->lines == (void *) -1l) + return -1; + + *lines = cu->lines; + *nlines = cu->lines->nlines; + + // XXX Eventually: unlocking here. + + return 0; +} +INTDEF(dwarf_getsrclines) diff --git a/libdw/dwarf_getstring.c b/libdw/dwarf_getstring.c new file mode 100644 index 00000000..5620cb07 --- /dev/null +++ b/libdw/dwarf_getstring.c @@ -0,0 +1,63 @@ +/* Get string. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +const char * +dwarf_getstring (Dwarf *dbg, Dwarf_Off offset, size_t *lenp) +{ + if (dbg == NULL) + return NULL; + + if (dbg->sectiondata[IDX_debug_str] == NULL + || offset >= dbg->sectiondata[IDX_debug_str]->d_size) + { + no_string: + __libdw_seterrno (DWARF_E_NO_STRING); + return NULL; + } + + const char *result = ((const char *) dbg->sectiondata[IDX_debug_str]->d_buf + + offset); + const char *endp = memchr (result, '\0', + dbg->sectiondata[IDX_debug_str]->d_size - offset); + if (endp == NULL) + goto no_string; + + if (lenp != NULL) + *lenp = endp - result; + + return result; +} diff --git a/libdw/dwarf_hasattr.c b/libdw/dwarf_hasattr.c new file mode 100644 index 00000000..eca08394 --- /dev/null +++ b/libdw/dwarf_hasattr.c @@ -0,0 +1,77 @@ +/* Check whether given DIE has specific attribute. + Copyright (C) 2003, 2005, 2014, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_hasattr (Dwarf_Die *die, unsigned int search_name) +{ + if (die == NULL) + return 0; + + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return 0; + } + + /* Search the name attribute. Dwarf_Abbrev was checked when created, + so we can read unchecked here. */ + const unsigned char *attrp = abbrevp->attrp; + while (1) + { + /* Get attribute name and form. */ + unsigned int attr_name; + get_uleb128_unchecked (attr_name, attrp); + unsigned int attr_form; + get_uleb128_unchecked (attr_form, attrp); + + /* We can stop if we found the end of the attribute list. */ + if (attr_name == 0 && attr_form == 0) + return 0; + + if (attr_name == search_name) + return 1; + + if (attr_form == DW_FORM_implicit_const) + { + int64_t attr_value __attribute__ ((unused)); + get_sleb128_unchecked (attr_value, attrp); + } + } +} +INTDEF (dwarf_hasattr) diff --git a/libdw/dwarf_hasattr_integrate.c b/libdw/dwarf_hasattr_integrate.c new file mode 100644 index 00000000..1d946280 --- /dev/null +++ b/libdw/dwarf_hasattr_integrate.c @@ -0,0 +1,73 @@ +/* Check whether DIE has specific attribute, integrating DW_AT_abstract_origin. + Copyright (C) 2005, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + +int +dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name) +{ + Dwarf_Die die_mem; + int chain = 16; /* Largest DIE ref chain we will follow. */ + do + { + if (INTUSE(dwarf_hasattr) (die, search_name)) + return 1; + + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin, + &attr_mem); + if (attr == NULL) + attr = INTUSE(dwarf_attr) (die, DW_AT_specification, &attr_mem); + if (attr == NULL) + break; + + die = INTUSE(dwarf_formref_die) (attr, &die_mem); + } + while (die != NULL && chain-- != 0); + + /* Not NULL if it didn't have abstract_origin and specification + attributes. If it is a split CU then see if the skeleton + has it. */ + if (die != NULL && is_cudie (die) + && die->cu->unit_type == DW_UT_split_compile) + { + Dwarf_CU *skel_cu = __libdw_find_split_unit (die->cu); + if (skel_cu != NULL) + { + Dwarf_Die skel_die = CUDIE (skel_cu); + return INTUSE(dwarf_hasattr) (&skel_die, search_name); + } + } + + return 0; +} diff --git a/libdw/dwarf_haschildren.c b/libdw/dwarf_haschildren.c new file mode 100644 index 00000000..03a81737 --- /dev/null +++ b/libdw/dwarf_haschildren.c @@ -0,0 +1,51 @@ +/* Return string associated with given attribute. + Copyright (C) 2003, 2005, 2008, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + + +int +dwarf_haschildren (Dwarf_Die *die) +{ + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + return abbrevp->has_children; +} +INTDEF (dwarf_haschildren) diff --git a/libdw/dwarf_hasform.c b/libdw/dwarf_hasform.c new file mode 100644 index 00000000..a0c32298 --- /dev/null +++ b/libdw/dwarf_hasform.c @@ -0,0 +1,45 @@ +/* Check whether given attribute has specific form. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form) +{ + if (attr == NULL) + return 0; + + return attr->form == search_form; +} diff --git a/libdw/dwarf_haspc.c b/libdw/dwarf_haspc.c new file mode 100644 index 00000000..47e2b055 --- /dev/null +++ b/libdw/dwarf_haspc.c @@ -0,0 +1,54 @@ +/* Determine whether a DIE covers a PC address. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + + +int +dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc) +{ + if (die == NULL) + return -1; + + Dwarf_Addr base; + Dwarf_Addr begin; + Dwarf_Addr end; + ptrdiff_t offset = 0; + while ((offset = INTUSE(dwarf_ranges) (die, offset, &base, + &begin, &end)) > 0) + if (pc >= begin && pc < end) + return 1; + + return offset; +} +INTDEF (dwarf_haspc) diff --git a/libdw/dwarf_highpc.c b/libdw/dwarf_highpc.c new file mode 100644 index 00000000..5b2f0fd6 --- /dev/null +++ b/libdw/dwarf_highpc.c @@ -0,0 +1,70 @@ +/* Return high PC attribute of DIE. + Copyright (C) 2003, 2005, 2012, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr) +{ + Dwarf_Attribute attr_high_mem; + Dwarf_Attribute *attr_high; + /* Split compile DIEs inherit high_pc from their skeleton DIE. */ + if (is_cudie (die) && die->cu->unit_type == DW_UT_split_compile) + attr_high = INTUSE(dwarf_attr_integrate) (die, DW_AT_high_pc, + &attr_high_mem); + else + attr_high = INTUSE(dwarf_attr) (die, DW_AT_high_pc, &attr_high_mem); + + if (attr_high == NULL) + goto no_addr; + + if (INTUSE(dwarf_formaddr) (attr_high, return_addr) == 0) + return 0; + + /* DWARF 4 allows high_pc to be a constant offset from low_pc. */ + if (INTUSE(dwarf_lowpc) (die, return_addr) == 0) + { + Dwarf_Word uval; + if (INTUSE(dwarf_formudata) (attr_high, &uval) == 0) + { + *return_addr += uval; + return 0; + } + } + +no_addr: + __libdw_seterrno (DWARF_E_NO_ADDR); + return -1; +} +INTDEF(dwarf_highpc) diff --git a/libdw/dwarf_line_file.c b/libdw/dwarf_line_file.c new file mode 100644 index 00000000..e2df642a --- /dev/null +++ b/libdw/dwarf_line_file.c @@ -0,0 +1,52 @@ +/* Find line information for address. + Copyright (C) 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_line_file (Dwarf_Line *line, Dwarf_Files **files, size_t *idx) +{ + if (line == NULL) + return -1; + + if (line->file >= line->files->nfiles) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + *files = line->files; + *idx = line->file; + + return 0; +} diff --git a/libdw/dwarf_lineaddr.c b/libdw/dwarf_lineaddr.c new file mode 100644 index 00000000..4e1952d3 --- /dev/null +++ b/libdw/dwarf_lineaddr.c @@ -0,0 +1,46 @@ +/* Return line address. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp) +{ + if (line == NULL) + return -1; + + *addrp = line->addr; + + return 0; +} diff --git a/libdw/dwarf_linebeginstatement.c b/libdw/dwarf_linebeginstatement.c new file mode 100644 index 00000000..4854c56b --- /dev/null +++ b/libdw/dwarf_linebeginstatement.c @@ -0,0 +1,46 @@ +/* Return true if record is for beginning of a statement. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->is_stmt; + + return 0; +} diff --git a/libdw/dwarf_lineblock.c b/libdw/dwarf_lineblock.c new file mode 100644 index 00000000..e3c7f41a --- /dev/null +++ b/libdw/dwarf_lineblock.c @@ -0,0 +1,46 @@ +/* Return true if record is for beginning of a basic block. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineblock (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->basic_block; + + return 0; +} diff --git a/libdw/dwarf_linecol.c b/libdw/dwarf_linecol.c new file mode 100644 index 00000000..c667b1b4 --- /dev/null +++ b/libdw/dwarf_linecol.c @@ -0,0 +1,46 @@ +/* Return column in line. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_linecol (Dwarf_Line *line, int *colp) +{ + if (line == NULL) + return -1; + + *colp = line->column; + + return 0; +} diff --git a/libdw/dwarf_linediscriminator.c b/libdw/dwarf_linediscriminator.c new file mode 100644 index 00000000..552205a7 --- /dev/null +++ b/libdw/dwarf_linediscriminator.c @@ -0,0 +1,45 @@ +/* Return code path discriminator in line record. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp) +{ + if (line == NULL) + return -1; + + *discp = line->discriminator; + + return 0; +} diff --git a/libdw/dwarf_lineendsequence.c b/libdw/dwarf_lineendsequence.c new file mode 100644 index 00000000..61bde935 --- /dev/null +++ b/libdw/dwarf_lineendsequence.c @@ -0,0 +1,46 @@ +/* Return true if record is for end of sequence. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineendsequence (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->end_sequence; + + return 0; +} diff --git a/libdw/dwarf_lineepiloguebegin.c b/libdw/dwarf_lineepiloguebegin.c new file mode 100644 index 00000000..b9147872 --- /dev/null +++ b/libdw/dwarf_lineepiloguebegin.c @@ -0,0 +1,46 @@ +/* Return true if record is for beginning of epilogue. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->epilogue_begin; + + return 0; +} diff --git a/libdw/dwarf_lineisa.c b/libdw/dwarf_lineisa.c new file mode 100644 index 00000000..30181fc5 --- /dev/null +++ b/libdw/dwarf_lineisa.c @@ -0,0 +1,45 @@ +/* Return ISA in line. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineisa (Dwarf_Line *line, unsigned int *isap) +{ + if (line == NULL) + return -1; + + *isap = line->isa; + + return 0; +} diff --git a/libdw/dwarf_lineno.c b/libdw/dwarf_lineno.c new file mode 100644 index 00000000..009999c2 --- /dev/null +++ b/libdw/dwarf_lineno.c @@ -0,0 +1,46 @@ +/* Return line number. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineno (Dwarf_Line *line, int *linep) +{ + if (line == NULL) + return -1; + + *linep = line->line; + + return 0; +} diff --git a/libdw/dwarf_lineop_index.c b/libdw/dwarf_lineop_index.c new file mode 100644 index 00000000..9ea4ef4d --- /dev/null +++ b/libdw/dwarf_lineop_index.c @@ -0,0 +1,45 @@ +/* Return line VLIW operation index. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineop_index (Dwarf_Line *line, unsigned int *idxp) +{ + if (line == NULL) + return -1; + + *idxp = line->op_index; + + return 0; +} diff --git a/libdw/dwarf_lineprologueend.c b/libdw/dwarf_lineprologueend.c new file mode 100644 index 00000000..6ba8be2f --- /dev/null +++ b/libdw/dwarf_lineprologueend.c @@ -0,0 +1,46 @@ +/* Return true if record is for end of prologue. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineprologueend (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->prologue_end; + + return 0; +} diff --git a/libdw/dwarf_linesrc.c b/libdw/dwarf_linesrc.c new file mode 100644 index 00000000..27b59903 --- /dev/null +++ b/libdw/dwarf_linesrc.c @@ -0,0 +1,56 @@ +/* Find line information for address. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +const char * +dwarf_linesrc (Dwarf_Line *line, Dwarf_Word *mtime, Dwarf_Word *length) +{ + if (line == NULL) + return NULL; + + if (line->file >= line->files->nfiles) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + if (mtime != NULL) + *mtime = line->files->info[line->file].mtime; + + if (length != NULL) + *length = line->files->info[line->file].length; + + return line->files->info[line->file].name; +} diff --git a/libdw/dwarf_lowpc.c b/libdw/dwarf_lowpc.c new file mode 100644 index 00000000..4d743a72 --- /dev/null +++ b/libdw/dwarf_lowpc.c @@ -0,0 +1,48 @@ +/* Return low PC attribute of DIE. + Copyright (C) 2003, 2005, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr) +{ + Dwarf_Attribute attr_mem, *attr; + /* Split compile DIEs inherit low_pc from their skeleton DIE. */ + if (is_cudie (die) && die->cu->unit_type == DW_UT_split_compile) + attr = INTUSE(dwarf_attr_integrate) (die, DW_AT_low_pc, &attr_mem); + else + attr = INTUSE(dwarf_attr) (die, DW_AT_low_pc, &attr_mem); + return INTUSE(dwarf_formaddr) (attr, return_addr); +} +INTDEF(dwarf_lowpc) diff --git a/libdw/dwarf_macro_getparamcnt.c b/libdw/dwarf_macro_getparamcnt.c new file mode 100644 index 00000000..e218eb1d --- /dev/null +++ b/libdw/dwarf_macro_getparamcnt.c @@ -0,0 +1,43 @@ +/* Return number of parameters of a macro. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + +int +dwarf_macro_getparamcnt (Dwarf_Macro *macro, size_t *paramcntp) +{ + if (macro == NULL) + return -1; + + *paramcntp = libdw_macro_nforms (macro); + return 0; +} diff --git a/libdw/dwarf_macro_getsrcfiles.c b/libdw/dwarf_macro_getsrcfiles.c new file mode 100644 index 00000000..3b1794b1 --- /dev/null +++ b/libdw/dwarf_macro_getsrcfiles.c @@ -0,0 +1,86 @@ +/* Find line information for a given macro. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + +int +dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro, + Dwarf_Files **files, size_t *nfiles) +{ + /* macro is declared NN */ + Dwarf_Macro_Op_Table *const table = macro->table; + if (table->files == NULL) + { + Dwarf_Off line_offset = table->line_offset; + if (line_offset == (Dwarf_Off) -1) + { + *files = NULL; + *nfiles = 0; + return 0; + } + + /* If TABLE->comp_dir is NULL that could mean any of the + following: + + - The macro unit is not bound to a CU. It's an auxiliary + unit used purely for import from other units. In that case + there's actually no COMP_DIR value that we could use. + + - The macro unit is bound to a CU, but there's no + DW_AT_comp_dir attribute at the CU DIE. + + - The macro unit is bound to a CU, but we don't know that, + likely because its iteration was requested through + dwarf_getmacros_off interface. This might be legitimate if + one macro unit imports another CU's macro unit, but that is + unlikely to happen in practice. Most probably this is not + legitimate use of the interfaces. + + So when the interfaces are used correctly, COMP_DIR value is + always right. That means that we can cache the parsed + .debug_line unit without fear that later on someone requests + the same unit through dwarf_getsrcfiles, and the file names + will be broken. */ + + if (__libdw_getsrclines (dbg, line_offset, table->comp_dir, + table->is_64bit ? 8 : 4, + NULL, &table->files) < 0) + table->files = (void *) -1; + } + + if (table->files == (void *) -1) + return -1; + + *files = table->files; + *nfiles = table->files->nfiles; + return 0; +} diff --git a/libdw/dwarf_macro_opcode.c b/libdw/dwarf_macro_opcode.c new file mode 100644 index 00000000..8607777f --- /dev/null +++ b/libdw/dwarf_macro_opcode.c @@ -0,0 +1,46 @@ +/* Return macro opcode. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_macro_opcode (Dwarf_Macro *macro, unsigned int *opcodep) +{ + if (macro == NULL) + return -1; + + *opcodep = macro->opcode; + + return 0; +} diff --git a/libdw/dwarf_macro_param.c b/libdw/dwarf_macro_param.c new file mode 100644 index 00000000..bd846a7f --- /dev/null +++ b/libdw/dwarf_macro_param.c @@ -0,0 +1,46 @@ +/* Return a given parameter of a macro. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + +int +dwarf_macro_param (Dwarf_Macro *macro, size_t idx, Dwarf_Attribute *ret) +{ + if (macro == NULL) + return -1; + + if (idx >= libdw_macro_nforms (macro)) + return -1; + + *ret = macro->attributes[idx]; + return 0; +} diff --git a/libdw/dwarf_macro_param1.c b/libdw/dwarf_macro_param1.c new file mode 100644 index 00000000..87ce0035 --- /dev/null +++ b/libdw/dwarf_macro_param1.c @@ -0,0 +1,48 @@ +/* Return first macro parameter. + Copyright (C) 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_macro_param1 (Dwarf_Macro *macro, Dwarf_Word *paramp) +{ + if (macro == NULL) + return -1; + + Dwarf_Attribute param; + if (dwarf_macro_param (macro, 0, ¶m) != 0) + return -1; + + return dwarf_formudata (¶m, paramp); +} diff --git a/libdw/dwarf_macro_param2.c b/libdw/dwarf_macro_param2.c new file mode 100644 index 00000000..cc902c99 --- /dev/null +++ b/libdw/dwarf_macro_param2.c @@ -0,0 +1,55 @@ +/* Return second macro parameter. + Copyright (C) 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_macro_param2 (Dwarf_Macro *macro, Dwarf_Word *paramp, const char **strp) +{ + if (macro == NULL) + return -1; + + Dwarf_Attribute param; + if (dwarf_macro_param (macro, 1, ¶m) != 0) + return -1; + + if (param.form == DW_FORM_string + || param.form == DW_FORM_strp) + { + *strp = dwarf_formstring (¶m); + return 0; + } + else + return dwarf_formudata (¶m, paramp); +} diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c new file mode 100644 index 00000000..fa28d99b --- /dev/null +++ b/libdw/dwarf_next_cfi.c @@ -0,0 +1,253 @@ +/* Advance to next CFI entry. + Copyright (C) 2009-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" +#include "encoded-value.h" + +#include + + +int +dwarf_next_cfi (const unsigned char e_ident[], + Elf_Data *data, + bool eh_frame_p, + Dwarf_Off off, + Dwarf_Off *next_off, + Dwarf_CFI_Entry *entry) +{ + /* Dummy struct for memory-access.h macros. */ + BYTE_ORDER_DUMMY (dw, e_ident); + + /* If we reached the end before don't do anything. */ + if (off == (Dwarf_Off) -1l + /* Make sure there is enough space in the .debug_frame section + for at least the initial word. We cannot test the rest since + we don't know yet whether this is a 64-bit object or not. */ + || unlikely (off + 4 >= data->d_size)) + { + done: + *next_off = (Dwarf_Off) -1l; + return 1; + } + + /* This points into the .debug_frame section at the start of the entry. */ + const uint8_t *bytes = data->d_buf + off; + const uint8_t *limit = data->d_buf + data->d_size; + + /* The format of a CFI entry is described in DWARF3 6.4.1: + */ + + uint64_t length = read_4ubyte_unaligned_inc (&dw, bytes); + size_t offset_size = 4; + if (length == DWARF3_LENGTH_64_BIT) + { + /* This is the 64-bit DWARF format. */ + offset_size = 8; + if (unlikely (limit - bytes < 8)) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + length = read_8ubyte_unaligned_inc (&dw, bytes); + } + + /* Not explicitly in the DWARF spec, but mentioned in the LSB exception + frames (.eh_frame) spec. If Length contains the value 0, then this + CIE shall be considered a terminator and processing shall end. */ + if (length == 0) + goto done; + + if (unlikely ((uint64_t) (limit - bytes) < length) + || unlikely (length < offset_size + 1)) + goto invalid; + + /* Now we know how large the entry is. Note the trick in the + computation. If the offset_size is 4 the '- 4' term undoes the + '2 *'. If offset_size is 8 this term computes the size of the + escape value plus the 8 byte offset. */ + *next_off = off + (2 * offset_size - 4) + length; + + limit = bytes + length; + + const uint8_t *const cie_pointer_start = bytes; + if (offset_size == 8) + entry->cie.CIE_id = read_8ubyte_unaligned_inc (&dw, bytes); + else + { + entry->cie.CIE_id = read_4ubyte_unaligned_inc (&dw, bytes); + /* Canonicalize the 32-bit CIE_ID value to 64 bits. */ + if (!eh_frame_p && entry->cie.CIE_id == DW_CIE_ID_32) + entry->cie.CIE_id = DW_CIE_ID_64; + } + if (eh_frame_p) + { + /* Canonicalize the .eh_frame CIE pointer to .debug_frame format. */ + if (entry->cie.CIE_id == 0) + entry->cie.CIE_id = DW_CIE_ID_64; + else + { + /* In .eh_frame format, a CIE pointer is the distance from where + it appears back to the beginning of the CIE. */ + ptrdiff_t pos = cie_pointer_start - (const uint8_t *) data->d_buf; + if (unlikely (entry->cie.CIE_id > (Dwarf_Off) pos) + || unlikely (pos <= (ptrdiff_t) offset_size)) + goto invalid; + entry->cie.CIE_id = pos - entry->cie.CIE_id; + } + } + + if (entry->cie.CIE_id == DW_CIE_ID_64) + { + /* Read the version stamp. Always an 8-bit value. */ + uint8_t version = *bytes++; + + if (version != 1 && (unlikely (version < 3) || unlikely (version > 4))) + goto invalid; + + entry->cie.augmentation = (const char *) bytes; + + bytes = memchr (bytes, '\0', limit - bytes); + if (unlikely (bytes == NULL)) + goto invalid; + ++bytes; + + /* The address size for CFI is implicit in the ELF class. */ + uint_fast8_t address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + uint_fast8_t segment_size = 0; + if (version >= 4) + { + if (unlikely (limit - bytes < 5)) + goto invalid; + /* XXX We don't actually support address_size not matching the class. + To do so, we'd have to return it here so that intern_new_cie + could use it choose a specific fde_encoding. */ + if (unlikely (*bytes != address_size)) + { + __libdw_seterrno (DWARF_E_VERSION); + return -1; + } + address_size = *bytes++; + segment_size = *bytes++; + /* We don't actually support segment selectors. We'd have to + roll this into the fde_encoding bits or something. */ + if (unlikely (segment_size != 0)) + { + __libdw_seterrno (DWARF_E_VERSION); + return -1; + } + } + + const char *ap = entry->cie.augmentation; + + /* g++ v2 "eh" has pointer immediately following augmentation string, + so it must be handled first. */ + if (unlikely (ap[0] == 'e' && ap[1] == 'h')) + { + ap += 2; + bytes += address_size; + } + + if (bytes >= limit) + goto invalid; + get_uleb128 (entry->cie.code_alignment_factor, bytes, limit); + + if (bytes >= limit) + goto invalid; + get_sleb128 (entry->cie.data_alignment_factor, bytes, limit); + + if (bytes >= limit) + goto invalid; + + if (version >= 3) /* DWARF 3+ */ + get_uleb128 (entry->cie.return_address_register, bytes, limit); + else /* DWARF 2 */ + entry->cie.return_address_register = *bytes++; + + /* If we have sized augmentation data, + we don't need to grok it all. */ + entry->cie.fde_augmentation_data_size = 0; + bool sized_augmentation = *ap == 'z'; + if (sized_augmentation) + { + if (bytes >= limit) + goto invalid; + get_uleb128 (entry->cie.augmentation_data_size, bytes, limit); + if ((Dwarf_Word) (limit - bytes) < entry->cie.augmentation_data_size) + goto invalid; + entry->cie.augmentation_data = bytes; + bytes += entry->cie.augmentation_data_size; + } + else + { + entry->cie.augmentation_data = bytes; + + for (; *ap != '\0'; ++ap) + { + uint8_t encoding; + switch (*ap) + { + case 'L': /* Skip LSDA pointer encoding byte. */ + case 'R': /* Skip FDE address encoding byte. */ + encoding = *bytes++; + entry->cie.fde_augmentation_data_size + += encoded_value_size (data, e_ident, encoding, NULL); + continue; + case 'P': /* Skip encoded personality routine pointer. */ + encoding = *bytes++; + bytes += encoded_value_size (data, e_ident, encoding, bytes); + continue; + case 'S': /* Skip signal-frame flag. */ + continue; + default: + /* Unknown augmentation string. initial_instructions might + actually start with some augmentation data. */ + break; + } + break; + } + entry->cie.augmentation_data_size + = bytes - entry->cie.augmentation_data; + } + + entry->cie.initial_instructions = bytes; + entry->cie.initial_instructions_end = limit; + } + else + { + entry->fde.start = bytes; + entry->fde.end = limit; + } + + return 0; +} +INTDEF (dwarf_next_cfi) diff --git a/libdw/dwarf_next_lines.c b/libdw/dwarf_next_lines.c new file mode 100644 index 00000000..9b76b47e --- /dev/null +++ b/libdw/dwarf_next_lines.c @@ -0,0 +1,197 @@ +/* Iterate through the debug line table. + Copyright (C) 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +dwarf_next_lines (Dwarf *dbg, Dwarf_Off off, + Dwarf_Off *next_off, Dwarf_CU **cu, + Dwarf_Files **srcfiles, size_t *nfiles, + Dwarf_Lines **srclines, size_t *nlines) +{ + /* Ignore existing errors. */ + if (dbg == NULL) + return -1; + + Elf_Data *lines = dbg->sectiondata[IDX_debug_line]; + if (lines == NULL) + { + __libdw_seterrno (DWARF_E_NO_DEBUG_LINE); + return -1; + } + + if (off == (Dwarf_Off) -1 + || lines->d_size < 4 + || off >= lines->d_size) + { + *next_off = (Dwarf_Off) -1; + return 1; + } + + /* Read enough of the header to know where the next table is and + whether we need to lookup the CU (version < 5). */ + const unsigned char *linep = lines->d_buf + off; + const unsigned char *lineendp = lines->d_buf + lines->d_size; + + if ((size_t) (lineendp - linep) < 4) + { + invalid_data: + __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE); + return -1; + } + + *next_off = off + 4; + Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); + if (unit_length == DWARF3_LENGTH_64_BIT) + { + if ((size_t) (lineendp - linep) < 8) + goto invalid_data; + unit_length = read_8ubyte_unaligned_inc (dbg, linep); + *next_off += 8; + } + + if (unit_length > (size_t) (lineendp - linep)) + goto invalid_data; + + *next_off += unit_length; + lineendp = linep + unit_length; + + if ((size_t) (lineendp - linep) < 2) + goto invalid_data; + uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); + + Dwarf_Die cudie; + if (version < 5) + { + /* We need to find the matching CU to get the comp_dir. Use the + given CU as hint where to start searching. Normally it will + be the next CU that has a statement list. */ + Dwarf_CU *given_cu = *cu; + Dwarf_CU *next_cu = given_cu; + bool found = false; + while (dwarf_get_units (dbg, next_cu, &next_cu, NULL, NULL, + &cudie, NULL) == 0) + { + if (dwarf_hasattr (&cudie, DW_AT_stmt_list)) + { + Dwarf_Attribute attr; + Dwarf_Word stmt_off; + if (dwarf_formudata (dwarf_attr (&cudie, DW_AT_stmt_list, &attr), + &stmt_off) == 0 + && stmt_off == off) + { + found = true; + break; + } + } + else if (off == 0 + && (next_cu->unit_type == DW_UT_split_compile + || next_cu->unit_type == DW_UT_split_type)) + { + /* For split units (in .dwo files) there is only one table + at offset zero (containing just the files, no lines). */ + found = true; + break; + } + } + + if (!found && given_cu != NULL) + { + /* The CUs might be in a different order from the line + tables. Need to do a linear search (but stop at the given + CU, since we already searched those. */ + next_cu = NULL; + while (dwarf_get_units (dbg, next_cu, &next_cu, NULL, NULL, + &cudie, NULL) == 0 + && next_cu != given_cu) + { + Dwarf_Attribute attr; + Dwarf_Word stmt_off; + if (dwarf_formudata (dwarf_attr (&cudie, DW_AT_stmt_list, &attr), + &stmt_off) == 0 + && stmt_off == off) + { + found = true; + break; + } + } + } + + if (found) + *cu = next_cu; + else + *cu = NULL; + } + else + *cu = NULL; + + const char *comp_dir; + unsigned address_size; + if (*cu != NULL) + { + comp_dir = __libdw_getcompdir (&cudie); + address_size = (*cu)->address_size; + } + else + { + comp_dir = NULL; + + size_t esize; + char *ident = elf_getident (dbg->elf, &esize); + if (ident == NULL || esize < EI_NIDENT) + goto invalid_data; + address_size = ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + } + + if (__libdw_getsrclines (dbg, off, comp_dir, address_size, + srclines, srcfiles) != 0) + return -1; + + if (nlines != NULL) + { + if (srclines != NULL && *srclines != NULL) + *nlines = (*srclines)->nlines; + else + *nlines = 0; + } + + if (nfiles != NULL) + { + if (srcfiles != NULL && *srcfiles != NULL) + *nfiles = (*srcfiles)->nfiles; + else + *nfiles = 0; + } + + return 0; +} diff --git a/libdw/dwarf_nextcu.c b/libdw/dwarf_nextcu.c new file mode 100644 index 00000000..67cec449 --- /dev/null +++ b/libdw/dwarf_nextcu.c @@ -0,0 +1,309 @@ +/* Advance to next CU header. + Copyright (C) 2002-2010, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +int +dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, + size_t *header_sizep, Dwarf_Half *versionp, + Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, + uint8_t *offset_sizep, uint64_t *v4_type_signaturep, + Dwarf_Off *v4_type_offsetp) +{ + const bool v4_debug_types = v4_type_signaturep != NULL; + return __libdw_next_unit (dwarf, v4_debug_types, off, next_off, + header_sizep, versionp, NULL, + abbrev_offsetp, address_sizep, offset_sizep, + v4_type_signaturep, v4_type_offsetp); +} +INTDEF(dwarf_next_unit) + +int +internal_function +__libdw_next_unit (Dwarf *dwarf, bool v4_debug_types, Dwarf_Off off, + Dwarf_Off *next_off, size_t *header_sizep, + Dwarf_Half *versionp, uint8_t *unit_typep, + Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, + uint8_t *offset_sizep, uint64_t *unit_id8p, + Dwarf_Off *subdie_offsetp) +{ + /* Note that debug_type units come from .debug_types in DWARF < 5 and + from .debug_info in DWARF >= 5. If the user requested the + v4_type_signature we return from .debug_types always. If no signature + is requested we return units (any type) from .debug_info. */ + const size_t sec_idx = v4_debug_types ? IDX_debug_types : IDX_debug_info; + + /* Maybe there has been an error before. */ + if (dwarf == NULL) + return -1; + + /* If we reached the end before don't do anything. */ + if (off == (Dwarf_Off) -1l + || unlikely (dwarf->sectiondata[sec_idx] == NULL) + /* Make sure there is enough space in the .debug_info section + for at least the initial word. We cannot test the rest since + we don't know yet whether this is a 64-bit object or not. */ + || unlikely (off + 4 >= dwarf->sectiondata[sec_idx]->d_size)) + { + *next_off = (Dwarf_Off) -1l; + return 1; + } + + /* This points into the .debug_info or .debug_types section to the + beginning of the CU entry. */ + const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf; + const unsigned char *bytes = data + off; + const unsigned char *bytes_end = data + dwarf->sectiondata[sec_idx]->d_size; + + /* The format of the CU header is described in dwarf2p1 7.5.1 and + changed in DWARFv5 (to include unit type, switch location of some + fields and add some optional fields). + + 1. A 4-byte or 12-byte unsigned integer representing the length + of the .debug_info contribution for that compilation unit, not + including the length field itself. In the 32-bit DWARF format, + this is a 4-byte unsigned integer (which must be less than + 0xfffffff0); in the 64-bit DWARF format, this consists of the + 4-byte value 0xffffffff followed by an 8-byte unsigned integer + that gives the actual length (see Section 7.2.2). This field + indicates whether this unit is 32-bit of 64-bit DWARF, which + affects all other offset fields in this header. + + 2. A 2-byte unsigned integer representing the version of the + DWARF information for that compilation unit. For DWARF Version + 2.1, the value in this field is 2 (3 for v3, 4 for v4, 5 for v5). + This fields determines the order of the next fields and whether + there are any optional fields in this header. + + 3. For DWARF 2, 3 and 4 (including v4 type units): + A 4-byte or 8-byte unsigned offset into the .debug_abbrev + section. This offset associates the compilation unit with a + particular set of debugging information entry abbreviations. In + the 32-bit DWARF format, this is a 4-byte unsigned length; in + the 64-bit DWARF format, this is an 8-byte unsigned length (see + Section 7.4). + + For DWARF 5: + A 1-byte unsigned integer representing the unit (header) type. + This field determines what the optional fields in the header + represent. If this is an unknown unit type then we cannot + assume anything about the rest of the unit (header). + + 4. For all DWARF versions (including v4 type units): + A 1-byte unsigned integer representing the size in bytes of + an address on the target architecture. If the system uses + segmented addressing, this value represents the size of the + offset portion of an address. This is the last field in the header + for DWARF versions 2, 3 and 4 (except for v4 type units). + + 5. For DWARF 5 only (this is field 3 for DWARF 2, 3, 4 and v4 types): + A 4-byte or 8-byte unsigned offset into the .debug_abbrev + section. This offset associates the compilation unit with a + particular set of debugging information entry abbreviations. In + the 32-bit DWARF format, this is a 4-byte unsigned length; in + the 64-bit DWARF format, this is an 8-byte unsigned length. + + 6. For v4 type units (this is really field 5 for v4 types) and + DWARF 5 optional (skeleton, split_compile, type and + split_type): An 8 byte (opaque) integer constant value. For + v4 and v5 type units this is the type signature. For skeleton + and split compile units this is the compilation ID. + + 7. For v4 type units (this is really field 6 for v4 types) and + DWARF 5 optional (type and split_type) and v4 type units: + A 4-byte or 8-byte unsigned offset. In the 32-bit DWARF format, + this is a 4-byte unsigned length; in the 64-bit DWARF format, + this is an 8-byte unsigned length. This is the type DIE offset + (which is not necessarily the first DIE in the unit). + */ + + uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes); + size_t offset_size = 4; + /* Lengths of 0xfffffff0 - 0xffffffff are escape codes. Oxffffffff is + used to indicate that 64-bit dwarf information is being used, the + other values are currently reserved. */ + if (length == DWARF3_LENGTH_64_BIT) + offset_size = 8; + else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE + && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + if (length == DWARF3_LENGTH_64_BIT) + { + /* This is a 64-bit DWARF format. */ + if (bytes_end - bytes < 8) + goto invalid; + length = read_8ubyte_unaligned_inc (dwarf, bytes); + } + + /* Read the version stamp. Always a 16-bit value. */ + if (bytes_end - bytes < 2) + goto invalid; + uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes); + + /* We keep unit_type at zero for older DWARF since we cannot + easily guess whether it is a compile or partial unit. */ + uint8_t unit_type = 0; + if (version >= 5) + { + if (bytes_end - bytes < 1) + goto invalid; + unit_type = *bytes++; + } + + /* All these are optional. */ + Dwarf_Off subdie_off = 0; + uint64_t sig_id = 0; + Dwarf_Off abbrev_offset = 0; + uint8_t address_size = 0; + + if (version < 2 || version > 5 + || (version == 5 && ! (unit_type == DW_UT_compile + || unit_type == DW_UT_partial + || unit_type == DW_UT_skeleton + || unit_type == DW_UT_split_compile + || unit_type == DW_UT_type + || unit_type == DW_UT_split_type))) + { + /* We cannot really know more about the header. Just report + the length of the unit, version and unit type. */ + goto done; + } + + /* We have to guess the unit_type. But we don't have a real CUDIE. */ + if (version < 5) + unit_type = v4_debug_types ? DW_UT_type : DW_UT_compile; + + /* Now we know how large the header is (should be). */ + if (unlikely (__libdw_first_die_from_cu_start (off, offset_size, version, + unit_type) + >= dwarf->sectiondata[sec_idx]->d_size)) + { + *next_off = -1; + return 1; + } + + /* The address size. Always an 8-bit value. + Comes after abbrev_offset for version < 5, otherwise unit type + and address size (if a known unit type) comes before abbrev_offset. */ + if (version >= 5) + address_size = *bytes++; + + /* Get offset in .debug_abbrev. Note that the size of the entry + depends on whether this is a 32-bit or 64-bit DWARF definition. */ + if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size, + &abbrev_offset, IDX_debug_abbrev, 0)) + return -1; + + if (version < 5) + address_size = *bytes++; + + /* Extra fields, signature/id and type offset/padding. */ + if (v4_debug_types + || (version >= 5 + && (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile + || unit_type == DW_UT_type || unit_type == DW_UT_split_type))) + { + sig_id = read_8ubyte_unaligned_inc (dwarf, bytes); + + if ((v4_debug_types + || unit_type == DW_UT_type || unit_type == DW_UT_split_type)) + { + if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size, + &subdie_off, sec_idx, 0)) + return -1; + + /* Validate that the TYPE_OFFSET points past the header. */ + if (unlikely (subdie_off < (size_t) (bytes - (data + off)))) + goto invalid; + } + } + + done: + if (unit_id8p != NULL) + *unit_id8p = sig_id; + + if (subdie_offsetp != NULL) + *subdie_offsetp = subdie_off; + + /* Store the header length. This is really how much we have read + from the header. If we didn't recognize the unit type the + header might actually be bigger. */ + if (header_sizep != NULL) + *header_sizep = bytes - (data + off); + + if (versionp != NULL) + *versionp = version; + + if (unit_typep != NULL) + *unit_typep = unit_type; + + if (abbrev_offsetp != NULL) + *abbrev_offsetp = abbrev_offset; + + if (address_sizep != NULL) + *address_sizep = address_size; + + /* Store the offset size. */ + if (offset_sizep != NULL) + *offset_sizep = offset_size; + + /* The length of the unit doesn't include the length field itself. + The length field is either, with offset == 4: 2 * 4 - 4 == 4, + or with offset == 8: 2 * 8 - 4 == 12. */ + *next_off = off + 2 * offset_size - 4 + length; + + /* This means that the length field is bogus, but return the CU anyway. + We just won't return anything after this. */ + if (*next_off <= off) + *next_off = (Dwarf_Off) -1; + + return 0; +} + +int +dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, + size_t *header_sizep, Dwarf_Off *abbrev_offsetp, + uint8_t *address_sizep, uint8_t *offset_sizep) +{ + return INTUSE(dwarf_next_unit) (dwarf, off, next_off, header_sizep, NULL, + abbrev_offsetp, address_sizep, offset_sizep, + NULL, NULL); +} +INTDEF(dwarf_nextcu) diff --git a/libdw/dwarf_offabbrev.c b/libdw/dwarf_offabbrev.c new file mode 100644 index 00000000..27cdad64 --- /dev/null +++ b/libdw/dwarf_offabbrev.c @@ -0,0 +1,51 @@ +/* Get abbreviation at given offset. + Copyright (C) 2004, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp, + Dwarf_Abbrev *abbrevp) +{ + if (dbg == NULL) + return -1; + + Dwarf_Abbrev *abbrev = __libdw_getabbrev (dbg, NULL, offset, lengthp, + abbrevp); + + if (abbrev == NULL) + return -1; + + return abbrev == DWARF_END_ABBREV ? 1 : 0; +} diff --git a/libdw/dwarf_offdie.c b/libdw/dwarf_offdie.c new file mode 100644 index 00000000..883720de --- /dev/null +++ b/libdw/dwarf_offdie.c @@ -0,0 +1,84 @@ +/* Return DIE at given offset. + Copyright (C) 2002-2010, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +Dwarf_Die * +internal_function +__libdw_offdie (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result, + bool debug_types) +{ + if (dbg == NULL) + return NULL; + + Elf_Data *const data = dbg->sectiondata[debug_types ? IDX_debug_types + : IDX_debug_info]; + if (data == NULL || offset >= data->d_size) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* Clear the entire DIE structure. This signals we have not yet + determined any of the information. */ + memset (result, '\0', sizeof (Dwarf_Die)); + + result->addr = (char *) data->d_buf + offset; + + /* Get the CU. */ + result->cu = __libdw_findcu (dbg, offset, debug_types); + if (result->cu == NULL) + { + /* This should never happen. The input file is malformed. */ + __libdw_seterrno (DWARF_E_INVALID_DWARF); + result = NULL; + } + + return result; +} + + +Dwarf_Die * +dwarf_offdie (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result) +{ + return __libdw_offdie (dbg, offset, result, false); +} +INTDEF(dwarf_offdie) + +Dwarf_Die * +dwarf_offdie_types (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result) +{ + return __libdw_offdie (dbg, offset, result, true); +} diff --git a/libdw/dwarf_onearange.c b/libdw/dwarf_onearange.c new file mode 100644 index 00000000..de49f6c1 --- /dev/null +++ b/libdw/dwarf_onearange.c @@ -0,0 +1,50 @@ +/* Return one of the address range entries. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +Dwarf_Arange * +dwarf_onearange (Dwarf_Aranges *aranges, size_t idx) +{ + if (aranges == NULL) + return NULL; + + if (idx >= aranges->naranges) + { + __libdw_seterrno (DWARF_E_INVALID_ARANGE_IDX); + return NULL; + } + + return &aranges->info[idx]; +} diff --git a/libdw/dwarf_onesrcline.c b/libdw/dwarf_onesrcline.c new file mode 100644 index 00000000..5d3c3ded --- /dev/null +++ b/libdw/dwarf_onesrcline.c @@ -0,0 +1,50 @@ +/* Return one of the sources lines of a CU. + Copyright (C) 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +Dwarf_Line * +dwarf_onesrcline (Dwarf_Lines *lines, size_t idx) +{ + if (lines == NULL) + return NULL; + + if (idx >= lines->nlines) + { + __libdw_seterrno (DWARF_E_INVALID_LINE_IDX); + return NULL; + } + + return &lines->info[idx]; +} diff --git a/libdw/dwarf_peel_type.c b/libdw/dwarf_peel_type.c new file mode 100644 index 00000000..59fc6f15 --- /dev/null +++ b/libdw/dwarf_peel_type.c @@ -0,0 +1,80 @@ +/* Peel type aliases and qualifier tags from a type DIE. + Copyright (C) 2014, 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include +#include + + +int +dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result) +{ + int tag; + + /* Ignore previous errors. */ + if (die == NULL) + return -1; + + *result = *die; + tag = INTUSE (dwarf_tag) (result); + +/* Stack 8 of all these modifiers, after that it gets silly. */ +#define MAX_DEPTH (8 * 8) + int max_depth = MAX_DEPTH; + while ((tag == DW_TAG_typedef + || tag == DW_TAG_const_type + || tag == DW_TAG_volatile_type + || tag == DW_TAG_restrict_type + || tag == DW_TAG_atomic_type + || tag == DW_TAG_immutable_type + || tag == DW_TAG_packed_type + || tag == DW_TAG_shared_type) + && max_depth-- > 0) + { + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (result, DW_AT_type, + &attr_mem); + if (attr == NULL) + return 1; + + if (INTUSE (dwarf_formref_die) (attr, result) == NULL) + return -1; + + tag = INTUSE (dwarf_tag) (result); + } + + if (tag == DW_TAG_invalid || max_depth <= 0) + return -1; + + return 0; +} +INTDEF(dwarf_peel_type) diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c new file mode 100644 index 00000000..520f9ffe --- /dev/null +++ b/libdw/dwarf_ranges.c @@ -0,0 +1,562 @@ +/* Enumerate the PC ranges covered by a DIE. + Copyright (C) 2005, 2007, 2009, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include +#include + +/* Read up begin/end pair and increment read pointer. + - If it's normal range record, set up `*beginp' and `*endp' and return 0. + - If it's a default location, set `*beginp' (0), `*endp' (-1) and return 0. + - If it's base address selection record, set up `*basep' and return 1. + - If it's end of rangelist, don't set anything and return 2 + - If an error occurs, don't set anything and return -1. */ +internal_function int +__libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index, + const unsigned char **addrp, + const unsigned char *addrend, + int width, + Dwarf_Addr *beginp, Dwarf_Addr *endp, + Dwarf_Addr *basep) +{ + Dwarf *dbg = cu->dbg; + if (sec_index == IDX_debug_loc + && cu->version < 5 + && cu->unit_type == DW_UT_split_compile) + { + /* GNU DebugFission. */ + const unsigned char *addr = *addrp; + if (addrend - addr < 1) + goto invalid; + + const char code = *addr++; + uint64_t begin = 0, end = 0, base = *basep, addr_idx; + switch (code) + { + case DW_LLE_GNU_end_of_list_entry: + *addrp = addr; + return 2; + + case DW_LLE_GNU_base_address_selection_entry: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &base) != 0) + return -1; + *basep = base; + *addrp = addr; + return 1; + + case DW_LLE_GNU_start_end_entry: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &begin) != 0) + return -1; + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &end) != 0) + return -1; + + *beginp = begin; + *endp = end; + *addrp = addr; + return 0; + + case DW_LLE_GNU_start_length_entry: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &begin) != 0) + return -1; + if (addrend - addr < 4) + goto invalid; + end = read_4ubyte_unaligned_inc (dbg, addr); + + *beginp = begin; + *endp = begin + end; + *addrp = addr; + return 0; + + default: + goto invalid; + } + } + else if (sec_index == IDX_debug_ranges || sec_index == IDX_debug_loc) + { + Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1 + : (Elf64_Addr) (Elf32_Addr) -1); + Dwarf_Addr begin; + Dwarf_Addr end; + + const unsigned char *addr = *addrp; + if (addrend - addr < width * 2) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address, + begin); + bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address, + end); + *addrp = addr; + + /* Unrelocated escape for begin means base address selection. */ + if (begin == escape && !begin_relocated) + { + if (unlikely (end == escape)) + goto invalid; + + *basep = end; + return 1; + } + + /* Unrelocated pair of zeroes means end of range list. */ + if (begin == 0 && end == 0 && !begin_relocated && !end_relocated) + return 2; + + /* Don't check for begin_relocated == end_relocated. Serve the data + to the client even though it may be buggy. */ + *beginp = begin + *basep; + *endp = end + *basep; + + return 0; + } + else if (sec_index == IDX_debug_rnglists) + { + const unsigned char *addr = *addrp; + if (addrend - addr < 1) + goto invalid; + + const char code = *addr++; + uint64_t begin = 0, end = 0, base = *basep, addr_idx; + switch (code) + { + case DW_RLE_end_of_list: + *addrp = addr; + return 2; + + case DW_RLE_base_addressx: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &base) != 0) + return -1; + + *basep = base; + *addrp = addr; + return 1; + + case DW_RLE_startx_endx: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &begin) != 0) + return -1; + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &end) != 0) + return -1; + + *beginp = begin; + *endp = end; + *addrp = addr; + return 0; + + case DW_RLE_startx_length: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &begin) != 0) + return -1; + if (addrend - addr < 1) + goto invalid; + get_uleb128 (end, addr, addrend); + + *beginp = begin; + *endp = begin + end; + *addrp = addr; + return 0; + + case DW_RLE_offset_pair: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (begin, addr, addrend); + if (addrend - addr < 1) + goto invalid; + get_uleb128 (end, addr, addrend); + + *beginp = begin + base; + *endp = end + base; + *addrp = addr; + return 0; + + case DW_RLE_base_address: + if (addrend - addr < width) + goto invalid; + __libdw_read_address_inc (dbg, sec_index, &addr, width, &base); + + *basep = base; + *addrp = addr; + return 1; + + case DW_RLE_start_end: + if (addrend - addr < 2 * width) + goto invalid; + __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin); + __libdw_read_address_inc (dbg, sec_index, &addr, width, &end); + + *beginp = begin; + *endp = end; + *addrp = addr; + return 0; + + case DW_RLE_start_length: + if (addrend - addr < width) + goto invalid; + __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin); + if (addrend - addr < 1) + goto invalid; + get_uleb128 (end, addr, addrend); + + *beginp = begin; + *endp = begin + end; + *addrp = addr; + return 0; + + default: + goto invalid; + } + } + else if (sec_index == IDX_debug_loclists) + { + const unsigned char *addr = *addrp; + if (addrend - addr < 1) + goto invalid; + + const char code = *addr++; + uint64_t begin = 0, end = 0, base = *basep, addr_idx; + switch (code) + { + case DW_LLE_end_of_list: + *addrp = addr; + return 2; + + case DW_LLE_base_addressx: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &base) != 0) + return -1; + + *basep = base; + *addrp = addr; + return 1; + + case DW_LLE_startx_endx: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &begin) != 0) + return -1; + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &end) != 0) + return -1; + + *beginp = begin; + *endp = end; + *addrp = addr; + return 0; + + case DW_LLE_startx_length: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (addr_idx, addr, addrend); + if (__libdw_addrx (cu, addr_idx, &begin) != 0) + return -1; + if (addrend - addr < 1) + goto invalid; + get_uleb128 (end, addr, addrend); + + *beginp = begin; + *endp = begin + end; + *addrp = addr; + return 0; + + case DW_LLE_offset_pair: + if (addrend - addr < 1) + goto invalid; + get_uleb128 (begin, addr, addrend); + if (addrend - addr < 1) + goto invalid; + get_uleb128 (end, addr, addrend); + + *beginp = begin + base; + *endp = end + base; + *addrp = addr; + return 0; + + case DW_LLE_default_location: + *beginp = 0; + *endp = (Dwarf_Addr) -1; + *addrp = addr; + return 0; + + case DW_LLE_base_address: + if (addrend - addr < width) + goto invalid; + __libdw_read_address_inc (dbg, sec_index, &addr, width, &base); + + *basep = base; + *addrp = addr; + return 1; + + case DW_LLE_start_end: + if (addrend - addr < 2 * width) + goto invalid; + __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin); + __libdw_read_address_inc (dbg, sec_index, &addr, width, &end); + + *beginp = begin; + *endp = end; + *addrp = addr; + return 0; + + case DW_LLE_start_length: + if (addrend - addr < width) + goto invalid; + __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin); + if (addrend - addr < 1) + goto invalid; + get_uleb128 (end, addr, addrend); + + *beginp = begin; + *endp = begin + end; + *addrp = addr; + return 0; + + default: + goto invalid; + } + } + else + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } +} + +static int +initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset) +{ + size_t secidx = (attr->cu->version < 5 + ? IDX_debug_ranges : IDX_debug_rnglists); + + Dwarf_Word start_offset; + if (attr->form == DW_FORM_rnglistx) + { + Dwarf_Word idx; + Dwarf_CU *cu = attr->cu; + const unsigned char *datap = attr->valp; + const unsigned char *endp = cu->endp; + if (datap >= endp) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + get_uleb128 (idx, datap, endp); + + Elf_Data *data = cu->dbg->sectiondata[secidx]; + if (data == NULL && cu->unit_type == DW_UT_split_compile) + { + cu = __libdw_find_split_unit (cu); + if (cu != NULL) + data = cu->dbg->sectiondata[secidx]; + } + + if (data == NULL) + { + __libdw_seterrno (secidx == IDX_debug_ranges + ? DWARF_E_NO_DEBUG_RANGES + : DWARF_E_NO_DEBUG_RNGLISTS); + return -1; + } + + Dwarf_Off range_base_off = __libdw_cu_ranges_base (cu); + + /* The section should at least contain room for one offset. */ + size_t sec_size = cu->dbg->sectiondata[secidx]->d_size; + size_t offset_size = cu->offset_size; + if (offset_size > sec_size) + { + invalid_offset: + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + + /* And the base offset should be at least inside the section. */ + if (range_base_off > (sec_size - offset_size)) + goto invalid_offset; + + size_t max_idx = (sec_size - offset_size - range_base_off) / offset_size; + if (idx > max_idx) + goto invalid_offset; + + datap = (cu->dbg->sectiondata[secidx]->d_buf + + range_base_off + (idx * offset_size)); + if (offset_size == 4) + start_offset = read_4ubyte_unaligned (cu->dbg, datap); + else + start_offset = read_8ubyte_unaligned (cu->dbg, datap); + + start_offset += range_base_off; + } + else + { + if (__libdw_formptr (attr, secidx, + (secidx == IDX_debug_ranges + ? DWARF_E_NO_DEBUG_RANGES + : DWARF_E_NO_DEBUG_RNGLISTS), + NULL, &start_offset) == NULL) + return -1; + } + + *offset = start_offset; + return 0; +} + +ptrdiff_t +dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, + Dwarf_Addr *startp, Dwarf_Addr *endp) +{ + if (die == NULL) + return -1; + + if (offset == 0 + /* Usually there is a single contiguous range. */ + && INTUSE(dwarf_highpc) (die, endp) == 0 + && INTUSE(dwarf_lowpc) (die, startp) == 0) + /* A offset into .debug_ranges will never be 1, it must be at least a + multiple of 4. So we can return 1 as a special case value to mark + there are no ranges to look for on the next call. */ + return 1; + + if (offset == 1) + return 0; + + /* We have to look for a noncontiguous range. */ + Dwarf_CU *cu = die->cu; + if (cu == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + size_t secidx = (cu->version < 5 ? IDX_debug_ranges : IDX_debug_rnglists); + const Elf_Data *d = cu->dbg->sectiondata[secidx]; + if (d == NULL && cu->unit_type == DW_UT_split_compile) + { + Dwarf_CU *skel = __libdw_find_split_unit (cu); + if (skel != NULL) + { + cu = skel; + d = cu->dbg->sectiondata[secidx]; + } + } + + const unsigned char *readp; + const unsigned char *readendp; + if (offset == 0) + { + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges, + &attr_mem); + /* Note that above we use dwarf_attr, not dwarf_attr_integrate. + The only case where the ranges can come from another DIE + attribute are the split CU case. In that case we also have a + different CU to check against. But that is already set up + above using __libdw_find_split_unit. */ + if (attr == NULL + && is_cudie (die) + && die->cu->unit_type == DW_UT_split_compile) + attr = INTUSE(dwarf_attr_integrate) (die, DW_AT_ranges, &attr_mem); + if (attr == NULL) + /* No PC attributes in this DIE at all, so an empty range list. */ + return 0; + + *basep = __libdw_cu_base_address (attr->cu); + if (*basep == (Dwarf_Addr) -1) + return -1; + + if (initial_offset (attr, &offset) != 0) + return -1; + } + else + { + if (__libdw_offset_in_section (cu->dbg, + secidx, offset, 1)) + return -1; + } + + readp = d->d_buf + offset; + readendp = d->d_buf + d->d_size; + + Dwarf_Addr begin; + Dwarf_Addr end; + + next: + switch (__libdw_read_begin_end_pair_inc (cu, secidx, + &readp, readendp, + cu->address_size, + &begin, &end, basep)) + { + case 0: + break; + case 1: + goto next; + case 2: + return 0; + default: + return -1; + } + + *startp = begin; + *endp = end; + return readp - (unsigned char *) d->d_buf; +} +INTDEF (dwarf_ranges) diff --git a/libdw/dwarf_setalt.c b/libdw/dwarf_setalt.c new file mode 100644 index 00000000..9051b8e0 --- /dev/null +++ b/libdw/dwarf_setalt.c @@ -0,0 +1,49 @@ +/* Provides the data referenced by the .gnu_debugaltlink section. + Copyright (C) 2014, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + +#include + +void +dwarf_setalt (Dwarf *main, Dwarf *alt) +{ + if (main->alt_fd != -1) + { + INTUSE(dwarf_end) (main->alt_dwarf); + close (main->alt_fd); + main->alt_fd = -1; + } + + main->alt_dwarf = alt; +} +INTDEF (dwarf_setalt) diff --git a/libdw/dwarf_siblingof.c b/libdw/dwarf_siblingof.c new file mode 100644 index 00000000..dbed9fa8 --- /dev/null +++ b/libdw/dwarf_siblingof.c @@ -0,0 +1,144 @@ +/* Return sibling of given DIE. + Copyright (C) 2003-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include +#include + + +int +dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result) +{ + /* Ignore previous errors. */ + if (die == NULL) + return -1; + + /* result is declared NN */ + + if (result != die) + result->addr = NULL; + + unsigned int level = 0; + + /* Copy of the current DIE. */ + Dwarf_Die this_die = *die; + /* Temporary attributes we create. */ + Dwarf_Attribute sibattr; + /* Copy of the CU in the request. */ + sibattr.cu = this_die.cu; + /* That's the address we start looking. */ + unsigned char *addr; + + /* Search for the beginning of the next die on this level. We + must not return the dies for children of the given die. */ + do + { + /* Find the end of the DIE or the sibling attribute. */ + addr = __libdw_find_attr (&this_die, DW_AT_sibling, &sibattr.code, + &sibattr.form); + if (addr != NULL && sibattr.code == DW_AT_sibling) + { + Dwarf_Off offset; + sibattr.valp = addr; + if (unlikely (__libdw_formref (&sibattr, &offset) != 0)) + /* Something went wrong. */ + return -1; + + /* The sibling attribute should point after this DIE in the CU. + But not after the end of the CU. */ + size_t size = sibattr.cu->endp - sibattr.cu->startp; + size_t die_off = this_die.addr - this_die.cu->startp; + if (unlikely (offset >= size || offset <= die_off)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + /* Compute the next address. */ + addr = sibattr.cu->startp + offset; + } + else if (unlikely (addr == NULL) + || unlikely (this_die.abbrev == DWARF_END_ABBREV)) + return -1; + else if (this_die.abbrev->has_children) + /* This abbreviation has children. */ + ++level; + + /* End of the buffer. */ + unsigned char *endp = sibattr.cu->endp; + + while (1) + { + /* Make sure we are still in range. Some producers might skip + the trailing NUL bytes. */ + if (addr >= endp) + return 1; + + if (*addr != '\0') + break; + + if (level-- == 0) + { + if (result != die) + result->addr = addr; + /* No more sibling at all. */ + return 1; + } + + ++addr; + } + + /* Initialize the 'current DIE'. */ + this_die.addr = addr; + this_die.abbrev = NULL; + } + while (level > 0); + + /* Maybe we reached the end of the CU. */ + unsigned char *endp = sibattr.cu->endp; + if (addr >= endp) + return 1; + + /* Clear the entire DIE structure. This signals we have not yet + determined any of the information. */ + memset (result, '\0', sizeof (Dwarf_Die)); + + /* We have the address. */ + result->addr = addr; + + /* Same CU as the parent. */ + result->cu = sibattr.cu; + + return 0; +} +INTDEF(dwarf_siblingof) diff --git a/libdw/dwarf_sig8_hash.c b/libdw/dwarf_sig8_hash.c new file mode 100644 index 00000000..777f9ebc --- /dev/null +++ b/libdw/dwarf_sig8_hash.c @@ -0,0 +1,41 @@ +/* Implementation of hash table for DWARF .debug_types section content. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define NO_UNDEF +#include "dwarf_sig8_hash.h" +#undef NO_UNDEF + +/* This is defined in dwarf_abbrev_hash.c, we can just use it here. */ +#define next_prime __libdwarf_next_prime +extern size_t next_prime (size_t) attribute_hidden; + +#include diff --git a/libdw/dwarf_sig8_hash.h b/libdw/dwarf_sig8_hash.h new file mode 100644 index 00000000..c399919a --- /dev/null +++ b/libdw/dwarf_sig8_hash.h @@ -0,0 +1,43 @@ +/* Hash table for DWARF .debug_types section content. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _DWARF_SIG8_HASH_H +#define _DWARF_SIG8_HASH_H 1 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdw.h" + +#define NAME Dwarf_Sig8_Hash +#define TYPE struct Dwarf_CU * + +#include + +#endif /* dwarf_sig8_hash.h */ diff --git a/libdw/dwarf_srclang.c b/libdw/dwarf_srclang.c new file mode 100644 index 00000000..f10e7642 --- /dev/null +++ b/libdw/dwarf_srclang.c @@ -0,0 +1,50 @@ +/* Return source language attribute of DIE. + Copyright (C) 2003-2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +int +dwarf_srclang (Dwarf_Die *die) +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate) + (die, DW_AT_language, &attr_mem), + &value) == 0 ? (int) value : -1; +} +INTDEF (dwarf_srclang) +OLD_VERSION (dwarf_srclang, ELFUTILS_0.122) +NEW_VERSION (dwarf_srclang, ELFUTILS_0.143) diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c new file mode 100644 index 00000000..d784970c --- /dev/null +++ b/libdw/dwarf_tag.c @@ -0,0 +1,94 @@ +/* Return tag of given DIE. + Copyright (C) 2003-2011, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +Dwarf_Abbrev * +internal_function +__libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code) +{ + Dwarf_Abbrev *abb; + + /* Abbreviation code can never have a value of 0. */ + if (unlikely (code == 0)) + return DWARF_END_ABBREV; + + /* See whether the entry is already in the hash table. */ + abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code); + if (abb == NULL) + while (cu->last_abbrev_offset != (size_t) -1l) + { + size_t length; + + /* Find the next entry. It gets automatically added to the + hash table. */ + abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length, + NULL); + if (abb == NULL || abb == DWARF_END_ABBREV) + { + /* Make sure we do not try to search for it again. */ + cu->last_abbrev_offset = (size_t) -1l; + return DWARF_END_ABBREV; + } + + cu->last_abbrev_offset += length; + + /* Is this the code we are looking for? */ + if (abb->code == code) + break; + } + + /* This is our second (or third, etc.) call to __libdw_findabbrev + and the code is invalid. */ + if (unlikely (abb == NULL)) + abb = DWARF_END_ABBREV; + + return abb; +} + + +int +dwarf_tag (Dwarf_Die *die) +{ + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return DW_TAG_invalid; + } + + return abbrevp->tag; +} +INTDEF(dwarf_tag) diff --git a/libdw/dwarf_whatattr.c b/libdw/dwarf_whatattr.c new file mode 100644 index 00000000..d664b021 --- /dev/null +++ b/libdw/dwarf_whatattr.c @@ -0,0 +1,42 @@ +/* Return attribute code of given attribute. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +unsigned int +dwarf_whatattr (Dwarf_Attribute *attr) +{ + return attr == NULL ? 0 : attr->code; +} diff --git a/libdw/dwarf_whatform.c b/libdw/dwarf_whatform.c new file mode 100644 index 00000000..dee29a9f --- /dev/null +++ b/libdw/dwarf_whatform.c @@ -0,0 +1,42 @@ +/* Return form code of given attribute. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libdwP.h" + + +unsigned int +dwarf_whatform (Dwarf_Attribute *attr) +{ + return attr == NULL ? 0 : attr->form; +} diff --git a/libdw/encoded-value.h b/libdw/encoded-value.h new file mode 100644 index 00000000..f0df4cec --- /dev/null +++ b/libdw/encoded-value.h @@ -0,0 +1,232 @@ +/* DW_EH_PE_* support for libdw unwinder. + Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _ENCODED_VALUE_H +#define _ENCODED_VALUE_H 1 + +#include +#include +#include "libdwP.h" +#include "../libelf/common.h" + + +/* Returns zero if the value is omitted, the encoding is unknown or + the (leb128) size cannot be determined. */ +static size_t __attribute__ ((unused)) +encoded_value_size (const Elf_Data *data, const unsigned char e_ident[], + uint8_t encoding, const uint8_t *p) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x07) + { + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + + case DW_EH_PE_absptr: + return e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + + case DW_EH_PE_uleb128: + if (p != NULL) + { + const uint8_t *end = p; + while (end < (uint8_t *) data->d_buf + data->d_size) + if (*end++ & 0x80u) + return end - p; + } + return 0; + + default: + return 0; + } +} + +/* Returns zero when value was read successfully, minus one otherwise. */ +static inline int __attribute__ ((unused)) +__libdw_cfi_read_address_inc (const Dwarf_CFI *cache, + const unsigned char **addrp, + int width, Dwarf_Addr *ret) +{ + width = width ?: cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + + if (cache->dbg != NULL) + return __libdw_read_address_inc (cache->dbg, IDX_debug_frame, + addrp, width, ret); + + /* Only .debug_frame might have relocation to consider. + Read plain values from .eh_frame data. */ + + const unsigned char *endp = cache->data->d.d_buf + cache->data->d.d_size; + Dwarf eh_dbg = { .other_byte_order = MY_ELFDATA != cache->e_ident[EI_DATA] }; + + if (width == 4) + { + if (unlikely (*addrp + 4 > endp)) + { + invalid_data: + __libdw_seterrno (DWARF_E_INVALID_CFI); + return -1; + } + *ret = read_4ubyte_unaligned_inc (&eh_dbg, *addrp); + } + else + { + if (unlikely (*addrp + 8 > endp)) + goto invalid_data; + *ret = read_8ubyte_unaligned_inc (&eh_dbg, *addrp); + } + return 0; +} + +/* Returns true on error, false otherwise. */ +static bool __attribute__ ((unused)) +read_encoded_value (const Dwarf_CFI *cache, uint8_t encoding, + const uint8_t **p, Dwarf_Addr *result) +{ + *result = 0; + switch (encoding & 0x70) + { + case DW_EH_PE_absptr: + break; + case DW_EH_PE_pcrel: + *result = (cache->frame_vaddr + + (*p - (const uint8_t *) cache->data->d.d_buf)); + break; + case DW_EH_PE_textrel: + // ia64: segrel + *result = cache->textrel; + break; + case DW_EH_PE_datarel: + // i386: GOTOFF + // ia64: gprel + *result = cache->datarel; + break; + case DW_EH_PE_funcrel: /* XXX */ + break; + case DW_EH_PE_aligned: + { + const size_t size = encoded_value_size (&cache->data->d, + cache->e_ident, + encoding, *p); + if (unlikely (size == 0)) + return true; + size_t align = ((cache->frame_vaddr + + (*p - (const uint8_t *) cache->data->d.d_buf)) + & (size - 1)); + if (align != 0) + *p += size - align; + break; + } + + default: + __libdw_seterrno (DWARF_E_INVALID_CFI); + return true; + } + + Dwarf_Addr value = 0; + const unsigned char *endp = cache->data->d.d_buf + cache->data->d.d_size; + switch (encoding & 0x0f) + { + case DW_EH_PE_udata2: + if (unlikely (*p + 2 > endp)) + { + invalid_data: + __libdw_seterrno (DWARF_E_INVALID_CFI); + return true; + } + value = read_2ubyte_unaligned_inc (cache, *p); + break; + + case DW_EH_PE_sdata2: + if (unlikely (*p + 2 > endp)) + goto invalid_data; + value = read_2sbyte_unaligned_inc (cache, *p); + break; + + case DW_EH_PE_udata4: + if (unlikely (__libdw_cfi_read_address_inc (cache, p, 4, &value) != 0)) + return true; + break; + + case DW_EH_PE_sdata4: + if (unlikely (__libdw_cfi_read_address_inc (cache, p, 4, &value) != 0)) + return true; + value = (Dwarf_Sword) (Elf32_Sword) value; /* Sign-extend. */ + break; + + case DW_EH_PE_udata8: + case DW_EH_PE_sdata8: + if (unlikely (__libdw_cfi_read_address_inc (cache, p, 8, &value) != 0)) + return true; + break; + + case DW_EH_PE_absptr: + if (unlikely (__libdw_cfi_read_address_inc (cache, p, 0, &value) != 0)) + return true; + break; + + case DW_EH_PE_uleb128: + get_uleb128 (value, *p, endp); + break; + + case DW_EH_PE_sleb128: + get_sleb128 (value, *p, endp); + break; + + default: + __libdw_seterrno (DWARF_E_INVALID_CFI); + return true; + } + + *result += value; + + if (encoding & DW_EH_PE_indirect) + { + if (unlikely (*result < cache->frame_vaddr)) + return true; + *result -= cache->frame_vaddr; + size_t ptrsize = encoded_value_size (NULL, cache->e_ident, + DW_EH_PE_absptr, NULL); + if (unlikely (cache->data->d.d_size < ptrsize + || *result > (cache->data->d.d_size - ptrsize))) + return true; + const uint8_t *ptr = cache->data->d.d_buf + *result; + if (unlikely (__libdw_cfi_read_address_inc (cache, &ptr, 0, result) + != 0)) + return true; + } + + return false; +} + +#endif /* encoded-value.h */ diff --git a/libdw/fde.c b/libdw/fde.c new file mode 100644 index 00000000..f5f6fbe1 --- /dev/null +++ b/libdw/fde.c @@ -0,0 +1,324 @@ +/* FDE reading. + Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" +#include +#include + +#include "encoded-value.h" + +static int +compare_fde (const void *a, const void *b) +{ + const struct dwarf_fde *fde1 = a; + const struct dwarf_fde *fde2 = b; + + /* Find out which of the two arguments is the search value. + It has end offset 0. */ + if (fde1->end == 0) + { + if (fde1->start < fde2->start) + return -1; + if (fde1->start >= fde2->end) + return 1; + } + else + { + if (fde2->start < fde1->start) + return 1; + if (fde2->start >= fde1->end) + return -1; + } + + return 0; +} + +static struct dwarf_fde * +intern_fde (Dwarf_CFI *cache, const Dwarf_FDE *entry) +{ + /* Look up the new entry's CIE. */ + struct dwarf_cie *cie = __libdw_find_cie (cache, entry->CIE_pointer); + if (cie == NULL) + return (void *) -1l; + + struct dwarf_fde *fde = malloc (sizeof (struct dwarf_fde)); + if (fde == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + fde->instructions = entry->start; + fde->instructions_end = entry->end; + if (unlikely (read_encoded_value (cache, cie->fde_encoding, + &fde->instructions, &fde->start)) + || unlikely (read_encoded_value (cache, cie->fde_encoding & 0x0f, + &fde->instructions, &fde->end))) + { + free (fde); + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + fde->end += fde->start; + + /* Make sure the fde actually covers a real code range. */ + if (fde->start >= fde->end) + { + free (fde); + return (void *) -1; + } + + fde->cie = cie; + + if (cie->sized_augmentation_data) + { + /* The CIE augmentation says the FDE has a DW_FORM_block + before its actual instruction stream. */ + Dwarf_Word len; + get_uleb128 (len, fde->instructions, fde->instructions_end); + if ((Dwarf_Word) (fde->instructions_end - fde->instructions) < len) + { + free (fde); + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + fde->instructions += len; + } + else + /* We had to understand all of the CIE augmentation string. + We've recorded the number of data bytes in FDEs. */ + fde->instructions += cie->fde_augmentation_data_size; + + /* Add the new entry to the search tree. */ + struct dwarf_fde **tres = tsearch (fde, &cache->fde_tree, &compare_fde); + if (tres == NULL) + { + free (fde); + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + else if (*tres != fde) + { + /* There is already an FDE in the cache that covers the same + address range. That is odd. Ignore this FDE. And just use + the one in the cache for consistency. */ + free (fde); + return *tres; + } + + return fde; +} + +struct dwarf_fde * +internal_function +__libdw_fde_by_offset (Dwarf_CFI *cache, Dwarf_Off offset) +{ + Dwarf_CFI_Entry entry; + Dwarf_Off next_offset; + int result = INTUSE(dwarf_next_cfi) (cache->e_ident, + &cache->data->d, CFI_IS_EH (cache), + offset, &next_offset, &entry); + if (result != 0) + { + if (result > 0) + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + if (unlikely (dwarf_cfi_cie_p (&entry))) + goto invalid; + + /* We have a new FDE to consider. */ + struct dwarf_fde *fde = intern_fde (cache, &entry.fde); + if (fde == (void *) -1l || fde == NULL) + return NULL; + + /* If this happened to be what we would have read next, notice it. */ + if (cache->next_offset == offset) + cache->next_offset = next_offset; + + return fde; +} + +/* Use a binary search table in .eh_frame_hdr format, yield an FDE offset. */ +static Dwarf_Off +binary_search_fde (Dwarf_CFI *cache, Dwarf_Addr address) +{ + const size_t size = 2 * encoded_value_size (&cache->data->d, cache->e_ident, + cache->search_table_encoding, + NULL); + if (unlikely (size == 0)) + return (Dwarf_Off) -1l; + + /* Dummy used by read_encoded_value. */ + Elf_Data_Scn dummy_cfi_hdr_data = + { + .d = { .d_buf = (void *) cache->search_table, + .d_size = cache->search_table_len } + }; + + Dwarf_CFI dummy_cfi = + { + .e_ident = cache->e_ident, + .datarel = cache->search_table_vaddr, + .frame_vaddr = cache->search_table_vaddr, + .data = &dummy_cfi_hdr_data + }; + + size_t l = 0, u = cache->search_table_entries; + while (l < u) + { + size_t idx = (l + u) / 2; + + /* Max idx * size is checked against search_table len when + loading eh_frame_hdr. */ + const uint8_t *p = &cache->search_table[idx * size]; + Dwarf_Addr start; + if (unlikely (read_encoded_value (&dummy_cfi, + cache->search_table_encoding, &p, + &start))) + break; + if (address < start) + u = idx; + else + { + l = idx + 1; + + Dwarf_Addr fde; + if (unlikely (read_encoded_value (&dummy_cfi, + cache->search_table_encoding, &p, + &fde))) + break; + + /* If this is the last entry, its upper bound is assumed to be + the end of the module. + XXX really should be end of containing PT_LOAD segment */ + if (l < cache->search_table_entries) + { + /* Look at the start address in the following entry. */ + Dwarf_Addr end; + if (unlikely (read_encoded_value + (&dummy_cfi, cache->search_table_encoding, &p, + &end))) + break; + if (address >= end) + continue; + } + + return fde - cache->frame_vaddr; + } + } + + return (Dwarf_Off) -1l; +} + +struct dwarf_fde * +internal_function +__libdw_find_fde (Dwarf_CFI *cache, Dwarf_Addr address) +{ + /* Look for a cached FDE covering this address. */ + + const struct dwarf_fde fde_key = { .start = address, .end = 0 }; + struct dwarf_fde **found = tfind (&fde_key, &cache->fde_tree, &compare_fde); + if (found != NULL) + return *found; + + /* Use .eh_frame_hdr binary search table if possible. */ + if (cache->search_table != NULL) + { + Dwarf_Off offset = binary_search_fde (cache, address); + if (offset == (Dwarf_Off) -1l) + goto no_match; + struct dwarf_fde *fde = __libdw_fde_by_offset (cache, offset); + if (likely (fde != NULL)) + { + /* Sanity check the address range. */ + if (unlikely (address < fde->start)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + /* .eh_frame_hdr does not indicate length covered by FDE. */ + if (unlikely (address >= fde->end)) + goto no_match; + } + return fde; + } + + /* It's not there. Read more CFI entries until we find it. */ + while (1) + { + Dwarf_Off last_offset = cache->next_offset; + Dwarf_CFI_Entry entry; + int result = INTUSE(dwarf_next_cfi) (cache->e_ident, + &cache->data->d, CFI_IS_EH (cache), + last_offset, &cache->next_offset, + &entry); + if (result > 0) + break; + if (result < 0) + { + if (cache->next_offset == last_offset) + /* We couldn't progress past the bogus FDE. */ + break; + /* Skip the loser and look at the next entry. */ + continue; + } + + if (dwarf_cfi_cie_p (&entry)) + { + /* This is a CIE, not an FDE. We eagerly intern these + because the next FDE will usually refer to this CIE. */ + __libdw_intern_cie (cache, last_offset, &entry.cie); + continue; + } + + /* We have a new FDE to consider. */ + struct dwarf_fde *fde = intern_fde (cache, &entry.fde); + + if (fde == (void *) -1l) /* Bad FDE, but we can keep looking. */ + continue; + + if (fde == NULL) /* Bad data. */ + return NULL; + + /* Is this the one we're looking for? */ + if (fde->start <= address && fde->end > address) + return fde; + } + + no_match: + /* We found no FDE covering this address. */ + __libdw_seterrno (DWARF_E_NO_MATCH); + return NULL; +} diff --git a/libdw/frame-cache.c b/libdw/frame-cache.c new file mode 100644 index 00000000..5b6afb5d --- /dev/null +++ b/libdw/frame-cache.c @@ -0,0 +1,70 @@ +/* Frame cache handling. + Copyright (C) 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "../libebl/libebl.h" +#include "cfi.h" +#include +#include + + +static void +free_cie (void *arg) +{ + struct dwarf_cie *cie = arg; + + free ((Dwarf_Frame *) cie->initial_state); + free (cie); +} + +#define free_fde free + +static void +free_expr (void *arg) +{ + struct loc_s *loc = arg; + + free (loc->loc); + free (loc); +} + +void +internal_function +__libdw_destroy_frame_cache (Dwarf_CFI *cache) +{ + /* Most of the data is in our two search trees. */ + tdestroy (cache->fde_tree, free_fde); + tdestroy (cache->cie_tree, free_cie); + tdestroy (cache->expr_tree, free_expr); + + if (cache->ebl != NULL && cache->ebl != (void *) -1l) + ebl_closebackend (cache->ebl); +} diff --git a/libdw/known-dwarf.h b/libdw/known-dwarf.h new file mode 100644 index 00000000..4b8a83c9 --- /dev/null +++ b/libdw/known-dwarf.h @@ -0,0 +1,782 @@ +/* Generated by config/known-dwarf.awk from libdw/dwarf.h contents. */ + +#define DWARF_ALL_KNOWN_DW_ACCESS \ + DWARF_ONE_KNOWN_DW_ACCESS (private, DW_ACCESS_private) \ + DWARF_ONE_KNOWN_DW_ACCESS (protected, DW_ACCESS_protected) \ + DWARF_ONE_KNOWN_DW_ACCESS (public, DW_ACCESS_public) \ + /* End of DW_ACCESS_*. */ + +#define DWARF_ALL_KNOWN_DW_AT \ + DWARF_ONE_KNOWN_DW_AT (GNU_addr_base, DW_AT_GNU_addr_base) \ + DWARF_ONE_KNOWN_DW_AT (GNU_all_call_sites, DW_AT_GNU_all_call_sites) \ + DWARF_ONE_KNOWN_DW_AT (GNU_all_source_call_sites, DW_AT_GNU_all_source_call_sites) \ + DWARF_ONE_KNOWN_DW_AT (GNU_all_tail_call_sites, DW_AT_GNU_all_tail_call_sites) \ + DWARF_ONE_KNOWN_DW_AT (GNU_bias, DW_AT_GNU_bias) \ + DWARF_ONE_KNOWN_DW_AT (GNU_call_site_data_value, DW_AT_GNU_call_site_data_value) \ + DWARF_ONE_KNOWN_DW_AT (GNU_call_site_target, DW_AT_GNU_call_site_target) \ + DWARF_ONE_KNOWN_DW_AT (GNU_call_site_target_clobbered, DW_AT_GNU_call_site_target_clobbered) \ + DWARF_ONE_KNOWN_DW_AT (GNU_call_site_value, DW_AT_GNU_call_site_value) \ + DWARF_ONE_KNOWN_DW_AT (GNU_deleted, DW_AT_GNU_deleted) \ + DWARF_ONE_KNOWN_DW_AT (GNU_denominator, DW_AT_GNU_denominator) \ + DWARF_ONE_KNOWN_DW_AT (GNU_dwo_id, DW_AT_GNU_dwo_id) \ + DWARF_ONE_KNOWN_DW_AT (GNU_dwo_name, DW_AT_GNU_dwo_name) \ + DWARF_ONE_KNOWN_DW_AT (GNU_entry_view, DW_AT_GNU_entry_view) \ + DWARF_ONE_KNOWN_DW_AT (GNU_exclusive_locks_required, DW_AT_GNU_exclusive_locks_required) \ + DWARF_ONE_KNOWN_DW_AT (GNU_guarded, DW_AT_GNU_guarded) \ + DWARF_ONE_KNOWN_DW_AT (GNU_guarded_by, DW_AT_GNU_guarded_by) \ + DWARF_ONE_KNOWN_DW_AT (GNU_locks_excluded, DW_AT_GNU_locks_excluded) \ + DWARF_ONE_KNOWN_DW_AT (GNU_locviews, DW_AT_GNU_locviews) \ + DWARF_ONE_KNOWN_DW_AT (GNU_macros, DW_AT_GNU_macros) \ + DWARF_ONE_KNOWN_DW_AT (GNU_numerator, DW_AT_GNU_numerator) \ + DWARF_ONE_KNOWN_DW_AT (GNU_odr_signature, DW_AT_GNU_odr_signature) \ + DWARF_ONE_KNOWN_DW_AT (GNU_pt_guarded, DW_AT_GNU_pt_guarded) \ + DWARF_ONE_KNOWN_DW_AT (GNU_pt_guarded_by, DW_AT_GNU_pt_guarded_by) \ + DWARF_ONE_KNOWN_DW_AT (GNU_pubnames, DW_AT_GNU_pubnames) \ + DWARF_ONE_KNOWN_DW_AT (GNU_pubtypes, DW_AT_GNU_pubtypes) \ + DWARF_ONE_KNOWN_DW_AT (GNU_ranges_base, DW_AT_GNU_ranges_base) \ + DWARF_ONE_KNOWN_DW_AT (GNU_shared_locks_required, DW_AT_GNU_shared_locks_required) \ + DWARF_ONE_KNOWN_DW_AT (GNU_tail_call, DW_AT_GNU_tail_call) \ + DWARF_ONE_KNOWN_DW_AT (GNU_template_name, DW_AT_GNU_template_name) \ + DWARF_ONE_KNOWN_DW_AT (GNU_vector, DW_AT_GNU_vector) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_abstract_name, DW_AT_MIPS_abstract_name) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_allocatable_dopetype, DW_AT_MIPS_allocatable_dopetype) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_assumed_shape_dopetype, DW_AT_MIPS_assumed_shape_dopetype) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_assumed_size, DW_AT_MIPS_assumed_size) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_clone_origin, DW_AT_MIPS_clone_origin) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_epilog_begin, DW_AT_MIPS_epilog_begin) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_fde, DW_AT_MIPS_fde) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_has_inlines, DW_AT_MIPS_has_inlines) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_linkage_name, DW_AT_MIPS_linkage_name) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_loop_begin, DW_AT_MIPS_loop_begin) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_loop_unroll_factor, DW_AT_MIPS_loop_unroll_factor) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_ptr_dopetype, DW_AT_MIPS_ptr_dopetype) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_software_pipeline_depth, DW_AT_MIPS_software_pipeline_depth) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_stride, DW_AT_MIPS_stride) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_stride_byte, DW_AT_MIPS_stride_byte) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_stride_elem, DW_AT_MIPS_stride_elem) \ + DWARF_ONE_KNOWN_DW_AT (MIPS_tail_loop_begin, DW_AT_MIPS_tail_loop_begin) \ + DWARF_ONE_KNOWN_DW_AT (abstract_origin, DW_AT_abstract_origin) \ + DWARF_ONE_KNOWN_DW_AT (accessibility, DW_AT_accessibility) \ + DWARF_ONE_KNOWN_DW_AT (addr_base, DW_AT_addr_base) \ + DWARF_ONE_KNOWN_DW_AT (address_class, DW_AT_address_class) \ + DWARF_ONE_KNOWN_DW_AT (alignment, DW_AT_alignment) \ + DWARF_ONE_KNOWN_DW_AT (allocated, DW_AT_allocated) \ + DWARF_ONE_KNOWN_DW_AT (artificial, DW_AT_artificial) \ + DWARF_ONE_KNOWN_DW_AT (associated, DW_AT_associated) \ + DWARF_ONE_KNOWN_DW_AT (base_types, DW_AT_base_types) \ + DWARF_ONE_KNOWN_DW_AT (binary_scale, DW_AT_binary_scale) \ + DWARF_ONE_KNOWN_DW_AT (bit_offset, DW_AT_bit_offset) \ + DWARF_ONE_KNOWN_DW_AT (bit_size, DW_AT_bit_size) \ + DWARF_ONE_KNOWN_DW_AT (bit_stride, DW_AT_bit_stride) \ + DWARF_ONE_KNOWN_DW_AT (body_begin, DW_AT_body_begin) \ + DWARF_ONE_KNOWN_DW_AT (body_end, DW_AT_body_end) \ + DWARF_ONE_KNOWN_DW_AT (byte_size, DW_AT_byte_size) \ + DWARF_ONE_KNOWN_DW_AT (byte_stride, DW_AT_byte_stride) \ + DWARF_ONE_KNOWN_DW_AT (call_all_calls, DW_AT_call_all_calls) \ + DWARF_ONE_KNOWN_DW_AT (call_all_source_calls, DW_AT_call_all_source_calls) \ + DWARF_ONE_KNOWN_DW_AT (call_all_tail_calls, DW_AT_call_all_tail_calls) \ + DWARF_ONE_KNOWN_DW_AT (call_column, DW_AT_call_column) \ + DWARF_ONE_KNOWN_DW_AT (call_data_location, DW_AT_call_data_location) \ + DWARF_ONE_KNOWN_DW_AT (call_data_value, DW_AT_call_data_value) \ + DWARF_ONE_KNOWN_DW_AT (call_file, DW_AT_call_file) \ + DWARF_ONE_KNOWN_DW_AT (call_line, DW_AT_call_line) \ + DWARF_ONE_KNOWN_DW_AT (call_origin, DW_AT_call_origin) \ + DWARF_ONE_KNOWN_DW_AT (call_parameter, DW_AT_call_parameter) \ + DWARF_ONE_KNOWN_DW_AT (call_pc, DW_AT_call_pc) \ + DWARF_ONE_KNOWN_DW_AT (call_return_pc, DW_AT_call_return_pc) \ + DWARF_ONE_KNOWN_DW_AT (call_tail_call, DW_AT_call_tail_call) \ + DWARF_ONE_KNOWN_DW_AT (call_target, DW_AT_call_target) \ + DWARF_ONE_KNOWN_DW_AT (call_target_clobbered, DW_AT_call_target_clobbered) \ + DWARF_ONE_KNOWN_DW_AT (call_value, DW_AT_call_value) \ + DWARF_ONE_KNOWN_DW_AT (calling_convention, DW_AT_calling_convention) \ + DWARF_ONE_KNOWN_DW_AT (common_reference, DW_AT_common_reference) \ + DWARF_ONE_KNOWN_DW_AT (comp_dir, DW_AT_comp_dir) \ + DWARF_ONE_KNOWN_DW_AT (const_expr, DW_AT_const_expr) \ + DWARF_ONE_KNOWN_DW_AT (const_value, DW_AT_const_value) \ + DWARF_ONE_KNOWN_DW_AT (containing_type, DW_AT_containing_type) \ + DWARF_ONE_KNOWN_DW_AT (count, DW_AT_count) \ + DWARF_ONE_KNOWN_DW_AT (data_bit_offset, DW_AT_data_bit_offset) \ + DWARF_ONE_KNOWN_DW_AT (data_location, DW_AT_data_location) \ + DWARF_ONE_KNOWN_DW_AT (data_member_location, DW_AT_data_member_location) \ + DWARF_ONE_KNOWN_DW_AT (decimal_scale, DW_AT_decimal_scale) \ + DWARF_ONE_KNOWN_DW_AT (decimal_sign, DW_AT_decimal_sign) \ + DWARF_ONE_KNOWN_DW_AT (decl_column, DW_AT_decl_column) \ + DWARF_ONE_KNOWN_DW_AT (decl_file, DW_AT_decl_file) \ + DWARF_ONE_KNOWN_DW_AT (decl_line, DW_AT_decl_line) \ + DWARF_ONE_KNOWN_DW_AT (declaration, DW_AT_declaration) \ + DWARF_ONE_KNOWN_DW_AT (default_value, DW_AT_default_value) \ + DWARF_ONE_KNOWN_DW_AT (defaulted, DW_AT_defaulted) \ + DWARF_ONE_KNOWN_DW_AT (deleted, DW_AT_deleted) \ + DWARF_ONE_KNOWN_DW_AT (description, DW_AT_description) \ + DWARF_ONE_KNOWN_DW_AT (digit_count, DW_AT_digit_count) \ + DWARF_ONE_KNOWN_DW_AT (discr, DW_AT_discr) \ + DWARF_ONE_KNOWN_DW_AT (discr_list, DW_AT_discr_list) \ + DWARF_ONE_KNOWN_DW_AT (discr_value, DW_AT_discr_value) \ + DWARF_ONE_KNOWN_DW_AT (dwo_name, DW_AT_dwo_name) \ + DWARF_ONE_KNOWN_DW_AT (elemental, DW_AT_elemental) \ + DWARF_ONE_KNOWN_DW_AT (encoding, DW_AT_encoding) \ + DWARF_ONE_KNOWN_DW_AT (endianity, DW_AT_endianity) \ + DWARF_ONE_KNOWN_DW_AT (entry_pc, DW_AT_entry_pc) \ + DWARF_ONE_KNOWN_DW_AT (enum_class, DW_AT_enum_class) \ + DWARF_ONE_KNOWN_DW_AT (explicit, DW_AT_explicit) \ + DWARF_ONE_KNOWN_DW_AT (export_symbols, DW_AT_export_symbols) \ + DWARF_ONE_KNOWN_DW_AT (extension, DW_AT_extension) \ + DWARF_ONE_KNOWN_DW_AT (external, DW_AT_external) \ + DWARF_ONE_KNOWN_DW_AT (frame_base, DW_AT_frame_base) \ + DWARF_ONE_KNOWN_DW_AT (friend, DW_AT_friend) \ + DWARF_ONE_KNOWN_DW_AT (high_pc, DW_AT_high_pc) \ + DWARF_ONE_KNOWN_DW_AT (identifier_case, DW_AT_identifier_case) \ + DWARF_ONE_KNOWN_DW_AT (import, DW_AT_import) \ + DWARF_ONE_KNOWN_DW_AT (inline, DW_AT_inline) \ + DWARF_ONE_KNOWN_DW_AT (is_optional, DW_AT_is_optional) \ + DWARF_ONE_KNOWN_DW_AT (language, DW_AT_language) \ + DWARF_ONE_KNOWN_DW_AT (linkage_name, DW_AT_linkage_name) \ + DWARF_ONE_KNOWN_DW_AT (location, DW_AT_location) \ + DWARF_ONE_KNOWN_DW_AT (loclists_base, DW_AT_loclists_base) \ + DWARF_ONE_KNOWN_DW_AT (low_pc, DW_AT_low_pc) \ + DWARF_ONE_KNOWN_DW_AT (lower_bound, DW_AT_lower_bound) \ + DWARF_ONE_KNOWN_DW_AT (mac_info, DW_AT_mac_info) \ + DWARF_ONE_KNOWN_DW_AT (macro_info, DW_AT_macro_info) \ + DWARF_ONE_KNOWN_DW_AT (macros, DW_AT_macros) \ + DWARF_ONE_KNOWN_DW_AT (main_subprogram, DW_AT_main_subprogram) \ + DWARF_ONE_KNOWN_DW_AT (mutable, DW_AT_mutable) \ + DWARF_ONE_KNOWN_DW_AT (name, DW_AT_name) \ + DWARF_ONE_KNOWN_DW_AT (namelist_item, DW_AT_namelist_item) \ + DWARF_ONE_KNOWN_DW_AT (noreturn, DW_AT_noreturn) \ + DWARF_ONE_KNOWN_DW_AT (object_pointer, DW_AT_object_pointer) \ + DWARF_ONE_KNOWN_DW_AT (ordering, DW_AT_ordering) \ + DWARF_ONE_KNOWN_DW_AT (picture_string, DW_AT_picture_string) \ + DWARF_ONE_KNOWN_DW_AT (priority, DW_AT_priority) \ + DWARF_ONE_KNOWN_DW_AT (producer, DW_AT_producer) \ + DWARF_ONE_KNOWN_DW_AT (prototyped, DW_AT_prototyped) \ + DWARF_ONE_KNOWN_DW_AT (pure, DW_AT_pure) \ + DWARF_ONE_KNOWN_DW_AT (ranges, DW_AT_ranges) \ + DWARF_ONE_KNOWN_DW_AT (rank, DW_AT_rank) \ + DWARF_ONE_KNOWN_DW_AT (recursive, DW_AT_recursive) \ + DWARF_ONE_KNOWN_DW_AT (reference, DW_AT_reference) \ + DWARF_ONE_KNOWN_DW_AT (return_addr, DW_AT_return_addr) \ + DWARF_ONE_KNOWN_DW_AT (rnglists_base, DW_AT_rnglists_base) \ + DWARF_ONE_KNOWN_DW_AT (rvalue_reference, DW_AT_rvalue_reference) \ + DWARF_ONE_KNOWN_DW_AT (segment, DW_AT_segment) \ + DWARF_ONE_KNOWN_DW_AT (sf_names, DW_AT_sf_names) \ + DWARF_ONE_KNOWN_DW_AT (sibling, DW_AT_sibling) \ + DWARF_ONE_KNOWN_DW_AT (signature, DW_AT_signature) \ + DWARF_ONE_KNOWN_DW_AT (small, DW_AT_small) \ + DWARF_ONE_KNOWN_DW_AT (specification, DW_AT_specification) \ + DWARF_ONE_KNOWN_DW_AT (src_coords, DW_AT_src_coords) \ + DWARF_ONE_KNOWN_DW_AT (src_info, DW_AT_src_info) \ + DWARF_ONE_KNOWN_DW_AT (start_scope, DW_AT_start_scope) \ + DWARF_ONE_KNOWN_DW_AT (static_link, DW_AT_static_link) \ + DWARF_ONE_KNOWN_DW_AT (stmt_list, DW_AT_stmt_list) \ + DWARF_ONE_KNOWN_DW_AT (str_offsets_base, DW_AT_str_offsets_base) \ + DWARF_ONE_KNOWN_DW_AT (string_length, DW_AT_string_length) \ + DWARF_ONE_KNOWN_DW_AT (string_length_bit_size, DW_AT_string_length_bit_size) \ + DWARF_ONE_KNOWN_DW_AT (string_length_byte_size, DW_AT_string_length_byte_size) \ + DWARF_ONE_KNOWN_DW_AT (threads_scaled, DW_AT_threads_scaled) \ + DWARF_ONE_KNOWN_DW_AT (trampoline, DW_AT_trampoline) \ + DWARF_ONE_KNOWN_DW_AT (type, DW_AT_type) \ + DWARF_ONE_KNOWN_DW_AT (upper_bound, DW_AT_upper_bound) \ + DWARF_ONE_KNOWN_DW_AT (use_UTF8, DW_AT_use_UTF8) \ + DWARF_ONE_KNOWN_DW_AT (use_location, DW_AT_use_location) \ + DWARF_ONE_KNOWN_DW_AT (variable_parameter, DW_AT_variable_parameter) \ + DWARF_ONE_KNOWN_DW_AT (virtuality, DW_AT_virtuality) \ + DWARF_ONE_KNOWN_DW_AT (visibility, DW_AT_visibility) \ + DWARF_ONE_KNOWN_DW_AT (vtable_elem_location, DW_AT_vtable_elem_location) \ + /* End of DW_AT_*. */ + +#define DWARF_ALL_KNOWN_DW_ATE \ + DWARF_ONE_KNOWN_DW_ATE (ASCII, DW_ATE_ASCII) \ + DWARF_ONE_KNOWN_DW_ATE (UCS, DW_ATE_UCS) \ + DWARF_ONE_KNOWN_DW_ATE (UTF, DW_ATE_UTF) \ + DWARF_ONE_KNOWN_DW_ATE (address, DW_ATE_address) \ + DWARF_ONE_KNOWN_DW_ATE (boolean, DW_ATE_boolean) \ + DWARF_ONE_KNOWN_DW_ATE (complex_float, DW_ATE_complex_float) \ + DWARF_ONE_KNOWN_DW_ATE (decimal_float, DW_ATE_decimal_float) \ + DWARF_ONE_KNOWN_DW_ATE (edited, DW_ATE_edited) \ + DWARF_ONE_KNOWN_DW_ATE (float, DW_ATE_float) \ + DWARF_ONE_KNOWN_DW_ATE (imaginary_float, DW_ATE_imaginary_float) \ + DWARF_ONE_KNOWN_DW_ATE (numeric_string, DW_ATE_numeric_string) \ + DWARF_ONE_KNOWN_DW_ATE (packed_decimal, DW_ATE_packed_decimal) \ + DWARF_ONE_KNOWN_DW_ATE (signed, DW_ATE_signed) \ + DWARF_ONE_KNOWN_DW_ATE (signed_char, DW_ATE_signed_char) \ + DWARF_ONE_KNOWN_DW_ATE (signed_fixed, DW_ATE_signed_fixed) \ + DWARF_ONE_KNOWN_DW_ATE (unsigned, DW_ATE_unsigned) \ + DWARF_ONE_KNOWN_DW_ATE (unsigned_char, DW_ATE_unsigned_char) \ + DWARF_ONE_KNOWN_DW_ATE (unsigned_fixed, DW_ATE_unsigned_fixed) \ + DWARF_ONE_KNOWN_DW_ATE (void, DW_ATE_void) \ + /* End of DW_ATE_*. */ + +#define DWARF_ALL_KNOWN_DW_CC \ + DWARF_ONE_KNOWN_DW_CC (nocall, DW_CC_nocall) \ + DWARF_ONE_KNOWN_DW_CC (normal, DW_CC_normal) \ + DWARF_ONE_KNOWN_DW_CC (pass_by_reference, DW_CC_pass_by_reference) \ + DWARF_ONE_KNOWN_DW_CC (pass_by_value, DW_CC_pass_by_value) \ + DWARF_ONE_KNOWN_DW_CC (program, DW_CC_program) \ + /* End of DW_CC_*. */ + +#define DWARF_ALL_KNOWN_DW_CFA \ + DWARF_ONE_KNOWN_DW_CFA (AARCH64_negate_ra_state, DW_CFA_AARCH64_negate_ra_state) \ + DWARF_ONE_KNOWN_DW_CFA (GNU_args_size, DW_CFA_GNU_args_size) \ + DWARF_ONE_KNOWN_DW_CFA (GNU_negative_offset_extended, DW_CFA_GNU_negative_offset_extended) \ + DWARF_ONE_KNOWN_DW_CFA (GNU_window_save, DW_CFA_GNU_window_save) \ + DWARF_ONE_KNOWN_DW_CFA (MIPS_advance_loc8, DW_CFA_MIPS_advance_loc8) \ + DWARF_ONE_KNOWN_DW_CFA (advance_loc, DW_CFA_advance_loc) \ + DWARF_ONE_KNOWN_DW_CFA (advance_loc1, DW_CFA_advance_loc1) \ + DWARF_ONE_KNOWN_DW_CFA (advance_loc2, DW_CFA_advance_loc2) \ + DWARF_ONE_KNOWN_DW_CFA (advance_loc4, DW_CFA_advance_loc4) \ + DWARF_ONE_KNOWN_DW_CFA (def_cfa, DW_CFA_def_cfa) \ + DWARF_ONE_KNOWN_DW_CFA (def_cfa_expression, DW_CFA_def_cfa_expression) \ + DWARF_ONE_KNOWN_DW_CFA (def_cfa_offset, DW_CFA_def_cfa_offset) \ + DWARF_ONE_KNOWN_DW_CFA (def_cfa_offset_sf, DW_CFA_def_cfa_offset_sf) \ + DWARF_ONE_KNOWN_DW_CFA (def_cfa_register, DW_CFA_def_cfa_register) \ + DWARF_ONE_KNOWN_DW_CFA (def_cfa_sf, DW_CFA_def_cfa_sf) \ + DWARF_ONE_KNOWN_DW_CFA (expression, DW_CFA_expression) \ + DWARF_ONE_KNOWN_DW_CFA (extended, DW_CFA_extended) \ + DWARF_ONE_KNOWN_DW_CFA (nop, DW_CFA_nop) \ + DWARF_ONE_KNOWN_DW_CFA (offset, DW_CFA_offset) \ + DWARF_ONE_KNOWN_DW_CFA (offset_extended, DW_CFA_offset_extended) \ + DWARF_ONE_KNOWN_DW_CFA (offset_extended_sf, DW_CFA_offset_extended_sf) \ + DWARF_ONE_KNOWN_DW_CFA (register, DW_CFA_register) \ + DWARF_ONE_KNOWN_DW_CFA (remember_state, DW_CFA_remember_state) \ + DWARF_ONE_KNOWN_DW_CFA (restore, DW_CFA_restore) \ + DWARF_ONE_KNOWN_DW_CFA (restore_extended, DW_CFA_restore_extended) \ + DWARF_ONE_KNOWN_DW_CFA (restore_state, DW_CFA_restore_state) \ + DWARF_ONE_KNOWN_DW_CFA (same_value, DW_CFA_same_value) \ + DWARF_ONE_KNOWN_DW_CFA (set_loc, DW_CFA_set_loc) \ + DWARF_ONE_KNOWN_DW_CFA (undefined, DW_CFA_undefined) \ + DWARF_ONE_KNOWN_DW_CFA (val_expression, DW_CFA_val_expression) \ + DWARF_ONE_KNOWN_DW_CFA (val_offset, DW_CFA_val_offset) \ + DWARF_ONE_KNOWN_DW_CFA (val_offset_sf, DW_CFA_val_offset_sf) \ + /* End of DW_CFA_*. */ + +#define DWARF_ALL_KNOWN_DW_CHILDREN \ + DWARF_ONE_KNOWN_DW_CHILDREN (no, DW_CHILDREN_no) \ + DWARF_ONE_KNOWN_DW_CHILDREN (yes, DW_CHILDREN_yes) \ + /* End of DW_CHILDREN_*. */ + +#define DWARF_ALL_KNOWN_DW_CIE_ID \ + DWARF_ONE_KNOWN_DW_CIE_ID (32, DW_CIE_ID_32) \ + DWARF_ONE_KNOWN_DW_CIE_ID (64, DW_CIE_ID_64) \ + /* End of DW_CIE_ID_*. */ + +#define DWARF_ALL_KNOWN_DW_DEFAULTED \ + DWARF_ONE_KNOWN_DW_DEFAULTED (in_class, DW_DEFAULTED_in_class) \ + DWARF_ONE_KNOWN_DW_DEFAULTED (no, DW_DEFAULTED_no) \ + DWARF_ONE_KNOWN_DW_DEFAULTED (out_of_class, DW_DEFAULTED_out_of_class) \ + /* End of DW_DEFAULTED_*. */ + +#define DWARF_ALL_KNOWN_DW_DS \ + DWARF_ONE_KNOWN_DW_DS (leading_overpunch, DW_DS_leading_overpunch) \ + DWARF_ONE_KNOWN_DW_DS (leading_separate, DW_DS_leading_separate) \ + DWARF_ONE_KNOWN_DW_DS (trailing_overpunch, DW_DS_trailing_overpunch) \ + DWARF_ONE_KNOWN_DW_DS (trailing_separate, DW_DS_trailing_separate) \ + DWARF_ONE_KNOWN_DW_DS (unsigned, DW_DS_unsigned) \ + /* End of DW_DS_*. */ + +#define DWARF_ALL_KNOWN_DW_DSC \ + DWARF_ONE_KNOWN_DW_DSC (label, DW_DSC_label) \ + DWARF_ONE_KNOWN_DW_DSC (range, DW_DSC_range) \ + /* End of DW_DSC_*. */ + +#define DWARF_ALL_KNOWN_DW_EH_PE \ + DWARF_ONE_KNOWN_DW_EH_PE (absptr, DW_EH_PE_absptr) \ + DWARF_ONE_KNOWN_DW_EH_PE (aligned, DW_EH_PE_aligned) \ + DWARF_ONE_KNOWN_DW_EH_PE (datarel, DW_EH_PE_datarel) \ + DWARF_ONE_KNOWN_DW_EH_PE (funcrel, DW_EH_PE_funcrel) \ + DWARF_ONE_KNOWN_DW_EH_PE (indirect, DW_EH_PE_indirect) \ + DWARF_ONE_KNOWN_DW_EH_PE (omit, DW_EH_PE_omit) \ + DWARF_ONE_KNOWN_DW_EH_PE (pcrel, DW_EH_PE_pcrel) \ + DWARF_ONE_KNOWN_DW_EH_PE (sdata2, DW_EH_PE_sdata2) \ + DWARF_ONE_KNOWN_DW_EH_PE (sdata4, DW_EH_PE_sdata4) \ + DWARF_ONE_KNOWN_DW_EH_PE (sdata8, DW_EH_PE_sdata8) \ + DWARF_ONE_KNOWN_DW_EH_PE (signed, DW_EH_PE_signed) \ + DWARF_ONE_KNOWN_DW_EH_PE (sleb128, DW_EH_PE_sleb128) \ + DWARF_ONE_KNOWN_DW_EH_PE (textrel, DW_EH_PE_textrel) \ + DWARF_ONE_KNOWN_DW_EH_PE (udata2, DW_EH_PE_udata2) \ + DWARF_ONE_KNOWN_DW_EH_PE (udata4, DW_EH_PE_udata4) \ + DWARF_ONE_KNOWN_DW_EH_PE (udata8, DW_EH_PE_udata8) \ + DWARF_ONE_KNOWN_DW_EH_PE (uleb128, DW_EH_PE_uleb128) \ + /* End of DW_EH_PE_*. */ + +#define DWARF_ALL_KNOWN_DW_END \ + DWARF_ONE_KNOWN_DW_END (big, DW_END_big) \ + DWARF_ONE_KNOWN_DW_END (default, DW_END_default) \ + DWARF_ONE_KNOWN_DW_END (little, DW_END_little) \ + /* End of DW_END_*. */ + +#define DWARF_ALL_KNOWN_DW_FORM \ + DWARF_ONE_KNOWN_DW_FORM (GNU_addr_index, DW_FORM_GNU_addr_index) \ + DWARF_ONE_KNOWN_DW_FORM (GNU_ref_alt, DW_FORM_GNU_ref_alt) \ + DWARF_ONE_KNOWN_DW_FORM (GNU_str_index, DW_FORM_GNU_str_index) \ + DWARF_ONE_KNOWN_DW_FORM (GNU_strp_alt, DW_FORM_GNU_strp_alt) \ + DWARF_ONE_KNOWN_DW_FORM (addr, DW_FORM_addr) \ + DWARF_ONE_KNOWN_DW_FORM (addrx, DW_FORM_addrx) \ + DWARF_ONE_KNOWN_DW_FORM (addrx1, DW_FORM_addrx1) \ + DWARF_ONE_KNOWN_DW_FORM (addrx2, DW_FORM_addrx2) \ + DWARF_ONE_KNOWN_DW_FORM (addrx3, DW_FORM_addrx3) \ + DWARF_ONE_KNOWN_DW_FORM (addrx4, DW_FORM_addrx4) \ + DWARF_ONE_KNOWN_DW_FORM (block, DW_FORM_block) \ + DWARF_ONE_KNOWN_DW_FORM (block1, DW_FORM_block1) \ + DWARF_ONE_KNOWN_DW_FORM (block2, DW_FORM_block2) \ + DWARF_ONE_KNOWN_DW_FORM (block4, DW_FORM_block4) \ + DWARF_ONE_KNOWN_DW_FORM (data1, DW_FORM_data1) \ + DWARF_ONE_KNOWN_DW_FORM (data16, DW_FORM_data16) \ + DWARF_ONE_KNOWN_DW_FORM (data2, DW_FORM_data2) \ + DWARF_ONE_KNOWN_DW_FORM (data4, DW_FORM_data4) \ + DWARF_ONE_KNOWN_DW_FORM (data8, DW_FORM_data8) \ + DWARF_ONE_KNOWN_DW_FORM (exprloc, DW_FORM_exprloc) \ + DWARF_ONE_KNOWN_DW_FORM (flag, DW_FORM_flag) \ + DWARF_ONE_KNOWN_DW_FORM (flag_present, DW_FORM_flag_present) \ + DWARF_ONE_KNOWN_DW_FORM (implicit_const, DW_FORM_implicit_const) \ + DWARF_ONE_KNOWN_DW_FORM (indirect, DW_FORM_indirect) \ + DWARF_ONE_KNOWN_DW_FORM (line_strp, DW_FORM_line_strp) \ + DWARF_ONE_KNOWN_DW_FORM (loclistx, DW_FORM_loclistx) \ + DWARF_ONE_KNOWN_DW_FORM (ref1, DW_FORM_ref1) \ + DWARF_ONE_KNOWN_DW_FORM (ref2, DW_FORM_ref2) \ + DWARF_ONE_KNOWN_DW_FORM (ref4, DW_FORM_ref4) \ + DWARF_ONE_KNOWN_DW_FORM (ref8, DW_FORM_ref8) \ + DWARF_ONE_KNOWN_DW_FORM (ref_addr, DW_FORM_ref_addr) \ + DWARF_ONE_KNOWN_DW_FORM (ref_sig8, DW_FORM_ref_sig8) \ + DWARF_ONE_KNOWN_DW_FORM (ref_sup4, DW_FORM_ref_sup4) \ + DWARF_ONE_KNOWN_DW_FORM (ref_sup8, DW_FORM_ref_sup8) \ + DWARF_ONE_KNOWN_DW_FORM (ref_udata, DW_FORM_ref_udata) \ + DWARF_ONE_KNOWN_DW_FORM (rnglistx, DW_FORM_rnglistx) \ + DWARF_ONE_KNOWN_DW_FORM (sdata, DW_FORM_sdata) \ + DWARF_ONE_KNOWN_DW_FORM (sec_offset, DW_FORM_sec_offset) \ + DWARF_ONE_KNOWN_DW_FORM (string, DW_FORM_string) \ + DWARF_ONE_KNOWN_DW_FORM (strp, DW_FORM_strp) \ + DWARF_ONE_KNOWN_DW_FORM (strp_sup, DW_FORM_strp_sup) \ + DWARF_ONE_KNOWN_DW_FORM (strx, DW_FORM_strx) \ + DWARF_ONE_KNOWN_DW_FORM (strx1, DW_FORM_strx1) \ + DWARF_ONE_KNOWN_DW_FORM (strx2, DW_FORM_strx2) \ + DWARF_ONE_KNOWN_DW_FORM (strx3, DW_FORM_strx3) \ + DWARF_ONE_KNOWN_DW_FORM (strx4, DW_FORM_strx4) \ + DWARF_ONE_KNOWN_DW_FORM (udata, DW_FORM_udata) \ + /* End of DW_FORM_*. */ + +#define DWARF_ALL_KNOWN_DW_ID \ + DWARF_ONE_KNOWN_DW_ID (case_insensitive, DW_ID_case_insensitive) \ + DWARF_ONE_KNOWN_DW_ID (case_sensitive, DW_ID_case_sensitive) \ + DWARF_ONE_KNOWN_DW_ID (down_case, DW_ID_down_case) \ + DWARF_ONE_KNOWN_DW_ID (up_case, DW_ID_up_case) \ + /* End of DW_ID_*. */ + +#define DWARF_ALL_KNOWN_DW_INL \ + DWARF_ONE_KNOWN_DW_INL (declared_inlined, DW_INL_declared_inlined) \ + DWARF_ONE_KNOWN_DW_INL (declared_not_inlined, DW_INL_declared_not_inlined) \ + DWARF_ONE_KNOWN_DW_INL (inlined, DW_INL_inlined) \ + DWARF_ONE_KNOWN_DW_INL (not_inlined, DW_INL_not_inlined) \ + /* End of DW_INL_*. */ + +#define DWARF_ALL_KNOWN_DW_LANG \ + DWARF_ONE_KNOWN_DW_LANG (Ada83, DW_LANG_Ada83) \ + DWARF_ONE_KNOWN_DW_LANG (Ada95, DW_LANG_Ada95) \ + DWARF_ONE_KNOWN_DW_LANG (BLISS, DW_LANG_BLISS) \ + DWARF_ONE_KNOWN_DW_LANG (C, DW_LANG_C) \ + DWARF_ONE_KNOWN_DW_LANG (C11, DW_LANG_C11) \ + DWARF_ONE_KNOWN_DW_LANG (C89, DW_LANG_C89) \ + DWARF_ONE_KNOWN_DW_LANG (C99, DW_LANG_C99) \ + DWARF_ONE_KNOWN_DW_LANG (C_plus_plus, DW_LANG_C_plus_plus) \ + DWARF_ONE_KNOWN_DW_LANG (C_plus_plus_03, DW_LANG_C_plus_plus_03) \ + DWARF_ONE_KNOWN_DW_LANG (C_plus_plus_11, DW_LANG_C_plus_plus_11) \ + DWARF_ONE_KNOWN_DW_LANG (C_plus_plus_14, DW_LANG_C_plus_plus_14) \ + DWARF_ONE_KNOWN_DW_LANG (Cobol74, DW_LANG_Cobol74) \ + DWARF_ONE_KNOWN_DW_LANG (Cobol85, DW_LANG_Cobol85) \ + DWARF_ONE_KNOWN_DW_LANG (D, DW_LANG_D) \ + DWARF_ONE_KNOWN_DW_LANG (Dylan, DW_LANG_Dylan) \ + DWARF_ONE_KNOWN_DW_LANG (Fortran03, DW_LANG_Fortran03) \ + DWARF_ONE_KNOWN_DW_LANG (Fortran08, DW_LANG_Fortran08) \ + DWARF_ONE_KNOWN_DW_LANG (Fortran77, DW_LANG_Fortran77) \ + DWARF_ONE_KNOWN_DW_LANG (Fortran90, DW_LANG_Fortran90) \ + DWARF_ONE_KNOWN_DW_LANG (Fortran95, DW_LANG_Fortran95) \ + DWARF_ONE_KNOWN_DW_LANG (Go, DW_LANG_Go) \ + DWARF_ONE_KNOWN_DW_LANG (Haskell, DW_LANG_Haskell) \ + DWARF_ONE_KNOWN_DW_LANG (Java, DW_LANG_Java) \ + DWARF_ONE_KNOWN_DW_LANG (Julia, DW_LANG_Julia) \ + DWARF_ONE_KNOWN_DW_LANG (Mips_Assembler, DW_LANG_Mips_Assembler) \ + DWARF_ONE_KNOWN_DW_LANG (Modula2, DW_LANG_Modula2) \ + DWARF_ONE_KNOWN_DW_LANG (Modula3, DW_LANG_Modula3) \ + DWARF_ONE_KNOWN_DW_LANG (OCaml, DW_LANG_OCaml) \ + DWARF_ONE_KNOWN_DW_LANG (ObjC, DW_LANG_ObjC) \ + DWARF_ONE_KNOWN_DW_LANG (ObjC_plus_plus, DW_LANG_ObjC_plus_plus) \ + DWARF_ONE_KNOWN_DW_LANG (OpenCL, DW_LANG_OpenCL) \ + DWARF_ONE_KNOWN_DW_LANG (PLI, DW_LANG_PLI) \ + DWARF_ONE_KNOWN_DW_LANG (Pascal83, DW_LANG_Pascal83) \ + DWARF_ONE_KNOWN_DW_LANG (Python, DW_LANG_Python) \ + DWARF_ONE_KNOWN_DW_LANG (RenderScript, DW_LANG_RenderScript) \ + DWARF_ONE_KNOWN_DW_LANG (Rust, DW_LANG_Rust) \ + DWARF_ONE_KNOWN_DW_LANG (Swift, DW_LANG_Swift) \ + DWARF_ONE_KNOWN_DW_LANG (UPC, DW_LANG_UPC) \ + /* End of DW_LANG_*. */ + +#define DWARF_ALL_KNOWN_DW_LLE \ + DWARF_ONE_KNOWN_DW_LLE (base_address, DW_LLE_base_address) \ + DWARF_ONE_KNOWN_DW_LLE (base_addressx, DW_LLE_base_addressx) \ + DWARF_ONE_KNOWN_DW_LLE (default_location, DW_LLE_default_location) \ + DWARF_ONE_KNOWN_DW_LLE (end_of_list, DW_LLE_end_of_list) \ + DWARF_ONE_KNOWN_DW_LLE (offset_pair, DW_LLE_offset_pair) \ + DWARF_ONE_KNOWN_DW_LLE (start_end, DW_LLE_start_end) \ + DWARF_ONE_KNOWN_DW_LLE (start_length, DW_LLE_start_length) \ + DWARF_ONE_KNOWN_DW_LLE (startx_endx, DW_LLE_startx_endx) \ + DWARF_ONE_KNOWN_DW_LLE (startx_length, DW_LLE_startx_length) \ + /* End of DW_LLE_*. */ + +#define DWARF_ALL_KNOWN_DW_LLE_GNU \ + DWARF_ONE_KNOWN_DW_LLE_GNU (base_address_selection_entry, DW_LLE_GNU_base_address_selection_entry) \ + DWARF_ONE_KNOWN_DW_LLE_GNU (end_of_list_entry, DW_LLE_GNU_end_of_list_entry) \ + DWARF_ONE_KNOWN_DW_LLE_GNU (start_end_entry, DW_LLE_GNU_start_end_entry) \ + DWARF_ONE_KNOWN_DW_LLE_GNU (start_length_entry, DW_LLE_GNU_start_length_entry) \ + /* End of DW_LLE_GNU_*. */ + +#define DWARF_ALL_KNOWN_DW_LNCT \ + DWARF_ONE_KNOWN_DW_LNCT (MD5, DW_LNCT_MD5) \ + DWARF_ONE_KNOWN_DW_LNCT (directory_index, DW_LNCT_directory_index) \ + DWARF_ONE_KNOWN_DW_LNCT (path, DW_LNCT_path) \ + DWARF_ONE_KNOWN_DW_LNCT (size, DW_LNCT_size) \ + DWARF_ONE_KNOWN_DW_LNCT (timestamp, DW_LNCT_timestamp) \ + /* End of DW_LNCT_*. */ + +#define DWARF_ALL_KNOWN_DW_LNE \ + DWARF_ONE_KNOWN_DW_LNE (define_file, DW_LNE_define_file) \ + DWARF_ONE_KNOWN_DW_LNE (end_sequence, DW_LNE_end_sequence) \ + DWARF_ONE_KNOWN_DW_LNE (set_address, DW_LNE_set_address) \ + DWARF_ONE_KNOWN_DW_LNE (set_discriminator, DW_LNE_set_discriminator) \ + /* End of DW_LNE_*. */ + +#define DWARF_ALL_KNOWN_DW_LNS \ + DWARF_ONE_KNOWN_DW_LNS (advance_line, DW_LNS_advance_line) \ + DWARF_ONE_KNOWN_DW_LNS (advance_pc, DW_LNS_advance_pc) \ + DWARF_ONE_KNOWN_DW_LNS (const_add_pc, DW_LNS_const_add_pc) \ + DWARF_ONE_KNOWN_DW_LNS (copy, DW_LNS_copy) \ + DWARF_ONE_KNOWN_DW_LNS (fixed_advance_pc, DW_LNS_fixed_advance_pc) \ + DWARF_ONE_KNOWN_DW_LNS (negate_stmt, DW_LNS_negate_stmt) \ + DWARF_ONE_KNOWN_DW_LNS (set_basic_block, DW_LNS_set_basic_block) \ + DWARF_ONE_KNOWN_DW_LNS (set_column, DW_LNS_set_column) \ + DWARF_ONE_KNOWN_DW_LNS (set_epilogue_begin, DW_LNS_set_epilogue_begin) \ + DWARF_ONE_KNOWN_DW_LNS (set_file, DW_LNS_set_file) \ + DWARF_ONE_KNOWN_DW_LNS (set_isa, DW_LNS_set_isa) \ + DWARF_ONE_KNOWN_DW_LNS (set_prologue_end, DW_LNS_set_prologue_end) \ + /* End of DW_LNS_*. */ + +#define DWARF_ALL_KNOWN_DW_MACINFO \ + DWARF_ONE_KNOWN_DW_MACINFO (define, DW_MACINFO_define) \ + DWARF_ONE_KNOWN_DW_MACINFO (end_file, DW_MACINFO_end_file) \ + DWARF_ONE_KNOWN_DW_MACINFO (start_file, DW_MACINFO_start_file) \ + DWARF_ONE_KNOWN_DW_MACINFO (undef, DW_MACINFO_undef) \ + DWARF_ONE_KNOWN_DW_MACINFO (vendor_ext, DW_MACINFO_vendor_ext) \ + /* End of DW_MACINFO_*. */ + +#define DWARF_ALL_KNOWN_DW_MACRO \ + DWARF_ONE_KNOWN_DW_MACRO (define, DW_MACRO_define) \ + DWARF_ONE_KNOWN_DW_MACRO (define_strp, DW_MACRO_define_strp) \ + DWARF_ONE_KNOWN_DW_MACRO (define_strx, DW_MACRO_define_strx) \ + DWARF_ONE_KNOWN_DW_MACRO (define_sup, DW_MACRO_define_sup) \ + DWARF_ONE_KNOWN_DW_MACRO (end_file, DW_MACRO_end_file) \ + DWARF_ONE_KNOWN_DW_MACRO (import, DW_MACRO_import) \ + DWARF_ONE_KNOWN_DW_MACRO (import_sup, DW_MACRO_import_sup) \ + DWARF_ONE_KNOWN_DW_MACRO (start_file, DW_MACRO_start_file) \ + DWARF_ONE_KNOWN_DW_MACRO (undef, DW_MACRO_undef) \ + DWARF_ONE_KNOWN_DW_MACRO (undef_strp, DW_MACRO_undef_strp) \ + DWARF_ONE_KNOWN_DW_MACRO (undef_strx, DW_MACRO_undef_strx) \ + DWARF_ONE_KNOWN_DW_MACRO (undef_sup, DW_MACRO_undef_sup) \ + /* End of DW_MACRO_*. */ + +#define DWARF_ALL_KNOWN_DW_OP \ + DWARF_ONE_KNOWN_DW_OP (GNU_addr_index, DW_OP_GNU_addr_index) \ + DWARF_ONE_KNOWN_DW_OP (GNU_const_index, DW_OP_GNU_const_index) \ + DWARF_ONE_KNOWN_DW_OP (GNU_const_type, DW_OP_GNU_const_type) \ + DWARF_ONE_KNOWN_DW_OP (GNU_convert, DW_OP_GNU_convert) \ + DWARF_ONE_KNOWN_DW_OP (GNU_deref_type, DW_OP_GNU_deref_type) \ + DWARF_ONE_KNOWN_DW_OP (GNU_encoded_addr, DW_OP_GNU_encoded_addr) \ + DWARF_ONE_KNOWN_DW_OP (GNU_entry_value, DW_OP_GNU_entry_value) \ + DWARF_ONE_KNOWN_DW_OP (GNU_implicit_pointer, DW_OP_GNU_implicit_pointer) \ + DWARF_ONE_KNOWN_DW_OP (GNU_parameter_ref, DW_OP_GNU_parameter_ref) \ + DWARF_ONE_KNOWN_DW_OP (GNU_push_tls_address, DW_OP_GNU_push_tls_address) \ + DWARF_ONE_KNOWN_DW_OP (GNU_regval_type, DW_OP_GNU_regval_type) \ + DWARF_ONE_KNOWN_DW_OP (GNU_reinterpret, DW_OP_GNU_reinterpret) \ + DWARF_ONE_KNOWN_DW_OP (GNU_uninit, DW_OP_GNU_uninit) \ + DWARF_ONE_KNOWN_DW_OP (GNU_variable_value, DW_OP_GNU_variable_value) \ + DWARF_ONE_KNOWN_DW_OP (abs, DW_OP_abs) \ + DWARF_ONE_KNOWN_DW_OP (addr, DW_OP_addr) \ + DWARF_ONE_KNOWN_DW_OP (addrx, DW_OP_addrx) \ + DWARF_ONE_KNOWN_DW_OP (and, DW_OP_and) \ + DWARF_ONE_KNOWN_DW_OP (bit_piece, DW_OP_bit_piece) \ + DWARF_ONE_KNOWN_DW_OP (bra, DW_OP_bra) \ + DWARF_ONE_KNOWN_DW_OP (breg0, DW_OP_breg0) \ + DWARF_ONE_KNOWN_DW_OP (breg1, DW_OP_breg1) \ + DWARF_ONE_KNOWN_DW_OP (breg10, DW_OP_breg10) \ + DWARF_ONE_KNOWN_DW_OP (breg11, DW_OP_breg11) \ + DWARF_ONE_KNOWN_DW_OP (breg12, DW_OP_breg12) \ + DWARF_ONE_KNOWN_DW_OP (breg13, DW_OP_breg13) \ + DWARF_ONE_KNOWN_DW_OP (breg14, DW_OP_breg14) \ + DWARF_ONE_KNOWN_DW_OP (breg15, DW_OP_breg15) \ + DWARF_ONE_KNOWN_DW_OP (breg16, DW_OP_breg16) \ + DWARF_ONE_KNOWN_DW_OP (breg17, DW_OP_breg17) \ + DWARF_ONE_KNOWN_DW_OP (breg18, DW_OP_breg18) \ + DWARF_ONE_KNOWN_DW_OP (breg19, DW_OP_breg19) \ + DWARF_ONE_KNOWN_DW_OP (breg2, DW_OP_breg2) \ + DWARF_ONE_KNOWN_DW_OP (breg20, DW_OP_breg20) \ + DWARF_ONE_KNOWN_DW_OP (breg21, DW_OP_breg21) \ + DWARF_ONE_KNOWN_DW_OP (breg22, DW_OP_breg22) \ + DWARF_ONE_KNOWN_DW_OP (breg23, DW_OP_breg23) \ + DWARF_ONE_KNOWN_DW_OP (breg24, DW_OP_breg24) \ + DWARF_ONE_KNOWN_DW_OP (breg25, DW_OP_breg25) \ + DWARF_ONE_KNOWN_DW_OP (breg26, DW_OP_breg26) \ + DWARF_ONE_KNOWN_DW_OP (breg27, DW_OP_breg27) \ + DWARF_ONE_KNOWN_DW_OP (breg28, DW_OP_breg28) \ + DWARF_ONE_KNOWN_DW_OP (breg29, DW_OP_breg29) \ + DWARF_ONE_KNOWN_DW_OP (breg3, DW_OP_breg3) \ + DWARF_ONE_KNOWN_DW_OP (breg30, DW_OP_breg30) \ + DWARF_ONE_KNOWN_DW_OP (breg31, DW_OP_breg31) \ + DWARF_ONE_KNOWN_DW_OP (breg4, DW_OP_breg4) \ + DWARF_ONE_KNOWN_DW_OP (breg5, DW_OP_breg5) \ + DWARF_ONE_KNOWN_DW_OP (breg6, DW_OP_breg6) \ + DWARF_ONE_KNOWN_DW_OP (breg7, DW_OP_breg7) \ + DWARF_ONE_KNOWN_DW_OP (breg8, DW_OP_breg8) \ + DWARF_ONE_KNOWN_DW_OP (breg9, DW_OP_breg9) \ + DWARF_ONE_KNOWN_DW_OP (bregx, DW_OP_bregx) \ + DWARF_ONE_KNOWN_DW_OP (call2, DW_OP_call2) \ + DWARF_ONE_KNOWN_DW_OP (call4, DW_OP_call4) \ + DWARF_ONE_KNOWN_DW_OP (call_frame_cfa, DW_OP_call_frame_cfa) \ + DWARF_ONE_KNOWN_DW_OP (call_ref, DW_OP_call_ref) \ + DWARF_ONE_KNOWN_DW_OP (const1s, DW_OP_const1s) \ + DWARF_ONE_KNOWN_DW_OP (const1u, DW_OP_const1u) \ + DWARF_ONE_KNOWN_DW_OP (const2s, DW_OP_const2s) \ + DWARF_ONE_KNOWN_DW_OP (const2u, DW_OP_const2u) \ + DWARF_ONE_KNOWN_DW_OP (const4s, DW_OP_const4s) \ + DWARF_ONE_KNOWN_DW_OP (const4u, DW_OP_const4u) \ + DWARF_ONE_KNOWN_DW_OP (const8s, DW_OP_const8s) \ + DWARF_ONE_KNOWN_DW_OP (const8u, DW_OP_const8u) \ + DWARF_ONE_KNOWN_DW_OP (const_type, DW_OP_const_type) \ + DWARF_ONE_KNOWN_DW_OP (consts, DW_OP_consts) \ + DWARF_ONE_KNOWN_DW_OP (constu, DW_OP_constu) \ + DWARF_ONE_KNOWN_DW_OP (constx, DW_OP_constx) \ + DWARF_ONE_KNOWN_DW_OP (convert, DW_OP_convert) \ + DWARF_ONE_KNOWN_DW_OP (deref, DW_OP_deref) \ + DWARF_ONE_KNOWN_DW_OP (deref_size, DW_OP_deref_size) \ + DWARF_ONE_KNOWN_DW_OP (deref_type, DW_OP_deref_type) \ + DWARF_ONE_KNOWN_DW_OP (div, DW_OP_div) \ + DWARF_ONE_KNOWN_DW_OP (drop, DW_OP_drop) \ + DWARF_ONE_KNOWN_DW_OP (dup, DW_OP_dup) \ + DWARF_ONE_KNOWN_DW_OP (entry_value, DW_OP_entry_value) \ + DWARF_ONE_KNOWN_DW_OP (eq, DW_OP_eq) \ + DWARF_ONE_KNOWN_DW_OP (fbreg, DW_OP_fbreg) \ + DWARF_ONE_KNOWN_DW_OP (form_tls_address, DW_OP_form_tls_address) \ + DWARF_ONE_KNOWN_DW_OP (ge, DW_OP_ge) \ + DWARF_ONE_KNOWN_DW_OP (gt, DW_OP_gt) \ + DWARF_ONE_KNOWN_DW_OP (implicit_pointer, DW_OP_implicit_pointer) \ + DWARF_ONE_KNOWN_DW_OP (implicit_value, DW_OP_implicit_value) \ + DWARF_ONE_KNOWN_DW_OP (le, DW_OP_le) \ + DWARF_ONE_KNOWN_DW_OP (lit0, DW_OP_lit0) \ + DWARF_ONE_KNOWN_DW_OP (lit1, DW_OP_lit1) \ + DWARF_ONE_KNOWN_DW_OP (lit10, DW_OP_lit10) \ + DWARF_ONE_KNOWN_DW_OP (lit11, DW_OP_lit11) \ + DWARF_ONE_KNOWN_DW_OP (lit12, DW_OP_lit12) \ + DWARF_ONE_KNOWN_DW_OP (lit13, DW_OP_lit13) \ + DWARF_ONE_KNOWN_DW_OP (lit14, DW_OP_lit14) \ + DWARF_ONE_KNOWN_DW_OP (lit15, DW_OP_lit15) \ + DWARF_ONE_KNOWN_DW_OP (lit16, DW_OP_lit16) \ + DWARF_ONE_KNOWN_DW_OP (lit17, DW_OP_lit17) \ + DWARF_ONE_KNOWN_DW_OP (lit18, DW_OP_lit18) \ + DWARF_ONE_KNOWN_DW_OP (lit19, DW_OP_lit19) \ + DWARF_ONE_KNOWN_DW_OP (lit2, DW_OP_lit2) \ + DWARF_ONE_KNOWN_DW_OP (lit20, DW_OP_lit20) \ + DWARF_ONE_KNOWN_DW_OP (lit21, DW_OP_lit21) \ + DWARF_ONE_KNOWN_DW_OP (lit22, DW_OP_lit22) \ + DWARF_ONE_KNOWN_DW_OP (lit23, DW_OP_lit23) \ + DWARF_ONE_KNOWN_DW_OP (lit24, DW_OP_lit24) \ + DWARF_ONE_KNOWN_DW_OP (lit25, DW_OP_lit25) \ + DWARF_ONE_KNOWN_DW_OP (lit26, DW_OP_lit26) \ + DWARF_ONE_KNOWN_DW_OP (lit27, DW_OP_lit27) \ + DWARF_ONE_KNOWN_DW_OP (lit28, DW_OP_lit28) \ + DWARF_ONE_KNOWN_DW_OP (lit29, DW_OP_lit29) \ + DWARF_ONE_KNOWN_DW_OP (lit3, DW_OP_lit3) \ + DWARF_ONE_KNOWN_DW_OP (lit30, DW_OP_lit30) \ + DWARF_ONE_KNOWN_DW_OP (lit31, DW_OP_lit31) \ + DWARF_ONE_KNOWN_DW_OP (lit4, DW_OP_lit4) \ + DWARF_ONE_KNOWN_DW_OP (lit5, DW_OP_lit5) \ + DWARF_ONE_KNOWN_DW_OP (lit6, DW_OP_lit6) \ + DWARF_ONE_KNOWN_DW_OP (lit7, DW_OP_lit7) \ + DWARF_ONE_KNOWN_DW_OP (lit8, DW_OP_lit8) \ + DWARF_ONE_KNOWN_DW_OP (lit9, DW_OP_lit9) \ + DWARF_ONE_KNOWN_DW_OP (lt, DW_OP_lt) \ + DWARF_ONE_KNOWN_DW_OP (minus, DW_OP_minus) \ + DWARF_ONE_KNOWN_DW_OP (mod, DW_OP_mod) \ + DWARF_ONE_KNOWN_DW_OP (mul, DW_OP_mul) \ + DWARF_ONE_KNOWN_DW_OP (ne, DW_OP_ne) \ + DWARF_ONE_KNOWN_DW_OP (neg, DW_OP_neg) \ + DWARF_ONE_KNOWN_DW_OP (nop, DW_OP_nop) \ + DWARF_ONE_KNOWN_DW_OP (not, DW_OP_not) \ + DWARF_ONE_KNOWN_DW_OP (or, DW_OP_or) \ + DWARF_ONE_KNOWN_DW_OP (over, DW_OP_over) \ + DWARF_ONE_KNOWN_DW_OP (pick, DW_OP_pick) \ + DWARF_ONE_KNOWN_DW_OP (piece, DW_OP_piece) \ + DWARF_ONE_KNOWN_DW_OP (plus, DW_OP_plus) \ + DWARF_ONE_KNOWN_DW_OP (plus_uconst, DW_OP_plus_uconst) \ + DWARF_ONE_KNOWN_DW_OP (push_object_address, DW_OP_push_object_address) \ + DWARF_ONE_KNOWN_DW_OP (reg0, DW_OP_reg0) \ + DWARF_ONE_KNOWN_DW_OP (reg1, DW_OP_reg1) \ + DWARF_ONE_KNOWN_DW_OP (reg10, DW_OP_reg10) \ + DWARF_ONE_KNOWN_DW_OP (reg11, DW_OP_reg11) \ + DWARF_ONE_KNOWN_DW_OP (reg12, DW_OP_reg12) \ + DWARF_ONE_KNOWN_DW_OP (reg13, DW_OP_reg13) \ + DWARF_ONE_KNOWN_DW_OP (reg14, DW_OP_reg14) \ + DWARF_ONE_KNOWN_DW_OP (reg15, DW_OP_reg15) \ + DWARF_ONE_KNOWN_DW_OP (reg16, DW_OP_reg16) \ + DWARF_ONE_KNOWN_DW_OP (reg17, DW_OP_reg17) \ + DWARF_ONE_KNOWN_DW_OP (reg18, DW_OP_reg18) \ + DWARF_ONE_KNOWN_DW_OP (reg19, DW_OP_reg19) \ + DWARF_ONE_KNOWN_DW_OP (reg2, DW_OP_reg2) \ + DWARF_ONE_KNOWN_DW_OP (reg20, DW_OP_reg20) \ + DWARF_ONE_KNOWN_DW_OP (reg21, DW_OP_reg21) \ + DWARF_ONE_KNOWN_DW_OP (reg22, DW_OP_reg22) \ + DWARF_ONE_KNOWN_DW_OP (reg23, DW_OP_reg23) \ + DWARF_ONE_KNOWN_DW_OP (reg24, DW_OP_reg24) \ + DWARF_ONE_KNOWN_DW_OP (reg25, DW_OP_reg25) \ + DWARF_ONE_KNOWN_DW_OP (reg26, DW_OP_reg26) \ + DWARF_ONE_KNOWN_DW_OP (reg27, DW_OP_reg27) \ + DWARF_ONE_KNOWN_DW_OP (reg28, DW_OP_reg28) \ + DWARF_ONE_KNOWN_DW_OP (reg29, DW_OP_reg29) \ + DWARF_ONE_KNOWN_DW_OP (reg3, DW_OP_reg3) \ + DWARF_ONE_KNOWN_DW_OP (reg30, DW_OP_reg30) \ + DWARF_ONE_KNOWN_DW_OP (reg31, DW_OP_reg31) \ + DWARF_ONE_KNOWN_DW_OP (reg4, DW_OP_reg4) \ + DWARF_ONE_KNOWN_DW_OP (reg5, DW_OP_reg5) \ + DWARF_ONE_KNOWN_DW_OP (reg6, DW_OP_reg6) \ + DWARF_ONE_KNOWN_DW_OP (reg7, DW_OP_reg7) \ + DWARF_ONE_KNOWN_DW_OP (reg8, DW_OP_reg8) \ + DWARF_ONE_KNOWN_DW_OP (reg9, DW_OP_reg9) \ + DWARF_ONE_KNOWN_DW_OP (regval_type, DW_OP_regval_type) \ + DWARF_ONE_KNOWN_DW_OP (regx, DW_OP_regx) \ + DWARF_ONE_KNOWN_DW_OP (reinterpret, DW_OP_reinterpret) \ + DWARF_ONE_KNOWN_DW_OP (rot, DW_OP_rot) \ + DWARF_ONE_KNOWN_DW_OP (shl, DW_OP_shl) \ + DWARF_ONE_KNOWN_DW_OP (shr, DW_OP_shr) \ + DWARF_ONE_KNOWN_DW_OP (shra, DW_OP_shra) \ + DWARF_ONE_KNOWN_DW_OP (skip, DW_OP_skip) \ + DWARF_ONE_KNOWN_DW_OP (stack_value, DW_OP_stack_value) \ + DWARF_ONE_KNOWN_DW_OP (swap, DW_OP_swap) \ + DWARF_ONE_KNOWN_DW_OP (xderef, DW_OP_xderef) \ + DWARF_ONE_KNOWN_DW_OP (xderef_size, DW_OP_xderef_size) \ + DWARF_ONE_KNOWN_DW_OP (xderef_type, DW_OP_xderef_type) \ + DWARF_ONE_KNOWN_DW_OP (xor, DW_OP_xor) \ + /* End of DW_OP_*. */ + +#define DWARF_ALL_KNOWN_DW_ORD \ + DWARF_ONE_KNOWN_DW_ORD (col_major, DW_ORD_col_major) \ + DWARF_ONE_KNOWN_DW_ORD (row_major, DW_ORD_row_major) \ + /* End of DW_ORD_*. */ + +#define DWARF_ALL_KNOWN_DW_RLE \ + DWARF_ONE_KNOWN_DW_RLE (base_address, DW_RLE_base_address) \ + DWARF_ONE_KNOWN_DW_RLE (base_addressx, DW_RLE_base_addressx) \ + DWARF_ONE_KNOWN_DW_RLE (end_of_list, DW_RLE_end_of_list) \ + DWARF_ONE_KNOWN_DW_RLE (offset_pair, DW_RLE_offset_pair) \ + DWARF_ONE_KNOWN_DW_RLE (start_end, DW_RLE_start_end) \ + DWARF_ONE_KNOWN_DW_RLE (start_length, DW_RLE_start_length) \ + DWARF_ONE_KNOWN_DW_RLE (startx_endx, DW_RLE_startx_endx) \ + DWARF_ONE_KNOWN_DW_RLE (startx_length, DW_RLE_startx_length) \ + /* End of DW_RLE_*. */ + +#define DWARF_ALL_KNOWN_DW_TAG \ + DWARF_ONE_KNOWN_DW_TAG (GNU_BINCL, DW_TAG_GNU_BINCL) \ + DWARF_ONE_KNOWN_DW_TAG (GNU_EINCL, DW_TAG_GNU_EINCL) \ + DWARF_ONE_KNOWN_DW_TAG (GNU_call_site, DW_TAG_GNU_call_site) \ + DWARF_ONE_KNOWN_DW_TAG (GNU_call_site_parameter, DW_TAG_GNU_call_site_parameter) \ + DWARF_ONE_KNOWN_DW_TAG (GNU_formal_parameter_pack, DW_TAG_GNU_formal_parameter_pack) \ + DWARF_ONE_KNOWN_DW_TAG (GNU_template_parameter_pack, DW_TAG_GNU_template_parameter_pack) \ + DWARF_ONE_KNOWN_DW_TAG (GNU_template_template_param, DW_TAG_GNU_template_template_param) \ + DWARF_ONE_KNOWN_DW_TAG (MIPS_loop, DW_TAG_MIPS_loop) \ + DWARF_ONE_KNOWN_DW_TAG (access_declaration, DW_TAG_access_declaration) \ + DWARF_ONE_KNOWN_DW_TAG (array_type, DW_TAG_array_type) \ + DWARF_ONE_KNOWN_DW_TAG (atomic_type, DW_TAG_atomic_type) \ + DWARF_ONE_KNOWN_DW_TAG (base_type, DW_TAG_base_type) \ + DWARF_ONE_KNOWN_DW_TAG (call_site, DW_TAG_call_site) \ + DWARF_ONE_KNOWN_DW_TAG (call_site_parameter, DW_TAG_call_site_parameter) \ + DWARF_ONE_KNOWN_DW_TAG (catch_block, DW_TAG_catch_block) \ + DWARF_ONE_KNOWN_DW_TAG (class_template, DW_TAG_class_template) \ + DWARF_ONE_KNOWN_DW_TAG (class_type, DW_TAG_class_type) \ + DWARF_ONE_KNOWN_DW_TAG (coarray_type, DW_TAG_coarray_type) \ + DWARF_ONE_KNOWN_DW_TAG (common_block, DW_TAG_common_block) \ + DWARF_ONE_KNOWN_DW_TAG (common_inclusion, DW_TAG_common_inclusion) \ + DWARF_ONE_KNOWN_DW_TAG (compile_unit, DW_TAG_compile_unit) \ + DWARF_ONE_KNOWN_DW_TAG (condition, DW_TAG_condition) \ + DWARF_ONE_KNOWN_DW_TAG (const_type, DW_TAG_const_type) \ + DWARF_ONE_KNOWN_DW_TAG (constant, DW_TAG_constant) \ + DWARF_ONE_KNOWN_DW_TAG (dwarf_procedure, DW_TAG_dwarf_procedure) \ + DWARF_ONE_KNOWN_DW_TAG (dynamic_type, DW_TAG_dynamic_type) \ + DWARF_ONE_KNOWN_DW_TAG (entry_point, DW_TAG_entry_point) \ + DWARF_ONE_KNOWN_DW_TAG (enumeration_type, DW_TAG_enumeration_type) \ + DWARF_ONE_KNOWN_DW_TAG (enumerator, DW_TAG_enumerator) \ + DWARF_ONE_KNOWN_DW_TAG (file_type, DW_TAG_file_type) \ + DWARF_ONE_KNOWN_DW_TAG (formal_parameter, DW_TAG_formal_parameter) \ + DWARF_ONE_KNOWN_DW_TAG (format_label, DW_TAG_format_label) \ + DWARF_ONE_KNOWN_DW_TAG (friend, DW_TAG_friend) \ + DWARF_ONE_KNOWN_DW_TAG (function_template, DW_TAG_function_template) \ + DWARF_ONE_KNOWN_DW_TAG (generic_subrange, DW_TAG_generic_subrange) \ + DWARF_ONE_KNOWN_DW_TAG (immutable_type, DW_TAG_immutable_type) \ + DWARF_ONE_KNOWN_DW_TAG (imported_declaration, DW_TAG_imported_declaration) \ + DWARF_ONE_KNOWN_DW_TAG (imported_module, DW_TAG_imported_module) \ + DWARF_ONE_KNOWN_DW_TAG (imported_unit, DW_TAG_imported_unit) \ + DWARF_ONE_KNOWN_DW_TAG (inheritance, DW_TAG_inheritance) \ + DWARF_ONE_KNOWN_DW_TAG (inlined_subroutine, DW_TAG_inlined_subroutine) \ + DWARF_ONE_KNOWN_DW_TAG (interface_type, DW_TAG_interface_type) \ + DWARF_ONE_KNOWN_DW_TAG (label, DW_TAG_label) \ + DWARF_ONE_KNOWN_DW_TAG (lexical_block, DW_TAG_lexical_block) \ + DWARF_ONE_KNOWN_DW_TAG (member, DW_TAG_member) \ + DWARF_ONE_KNOWN_DW_TAG (module, DW_TAG_module) \ + DWARF_ONE_KNOWN_DW_TAG (namelist, DW_TAG_namelist) \ + DWARF_ONE_KNOWN_DW_TAG (namelist_item, DW_TAG_namelist_item) \ + DWARF_ONE_KNOWN_DW_TAG (namespace, DW_TAG_namespace) \ + DWARF_ONE_KNOWN_DW_TAG (packed_type, DW_TAG_packed_type) \ + DWARF_ONE_KNOWN_DW_TAG (partial_unit, DW_TAG_partial_unit) \ + DWARF_ONE_KNOWN_DW_TAG (pointer_type, DW_TAG_pointer_type) \ + DWARF_ONE_KNOWN_DW_TAG (ptr_to_member_type, DW_TAG_ptr_to_member_type) \ + DWARF_ONE_KNOWN_DW_TAG (reference_type, DW_TAG_reference_type) \ + DWARF_ONE_KNOWN_DW_TAG (restrict_type, DW_TAG_restrict_type) \ + DWARF_ONE_KNOWN_DW_TAG (rvalue_reference_type, DW_TAG_rvalue_reference_type) \ + DWARF_ONE_KNOWN_DW_TAG (set_type, DW_TAG_set_type) \ + DWARF_ONE_KNOWN_DW_TAG (shared_type, DW_TAG_shared_type) \ + DWARF_ONE_KNOWN_DW_TAG (skeleton_unit, DW_TAG_skeleton_unit) \ + DWARF_ONE_KNOWN_DW_TAG (string_type, DW_TAG_string_type) \ + DWARF_ONE_KNOWN_DW_TAG (structure_type, DW_TAG_structure_type) \ + DWARF_ONE_KNOWN_DW_TAG (subprogram, DW_TAG_subprogram) \ + DWARF_ONE_KNOWN_DW_TAG (subrange_type, DW_TAG_subrange_type) \ + DWARF_ONE_KNOWN_DW_TAG (subroutine_type, DW_TAG_subroutine_type) \ + DWARF_ONE_KNOWN_DW_TAG (template_alias, DW_TAG_template_alias) \ + DWARF_ONE_KNOWN_DW_TAG (template_type_parameter, DW_TAG_template_type_parameter) \ + DWARF_ONE_KNOWN_DW_TAG (template_value_parameter, DW_TAG_template_value_parameter) \ + DWARF_ONE_KNOWN_DW_TAG (thrown_type, DW_TAG_thrown_type) \ + DWARF_ONE_KNOWN_DW_TAG (try_block, DW_TAG_try_block) \ + DWARF_ONE_KNOWN_DW_TAG (type_unit, DW_TAG_type_unit) \ + DWARF_ONE_KNOWN_DW_TAG (typedef, DW_TAG_typedef) \ + DWARF_ONE_KNOWN_DW_TAG (union_type, DW_TAG_union_type) \ + DWARF_ONE_KNOWN_DW_TAG (unspecified_parameters, DW_TAG_unspecified_parameters) \ + DWARF_ONE_KNOWN_DW_TAG (unspecified_type, DW_TAG_unspecified_type) \ + DWARF_ONE_KNOWN_DW_TAG (variable, DW_TAG_variable) \ + DWARF_ONE_KNOWN_DW_TAG (variant, DW_TAG_variant) \ + DWARF_ONE_KNOWN_DW_TAG (variant_part, DW_TAG_variant_part) \ + DWARF_ONE_KNOWN_DW_TAG (volatile_type, DW_TAG_volatile_type) \ + DWARF_ONE_KNOWN_DW_TAG (with_stmt, DW_TAG_with_stmt) \ + /* End of DW_TAG_*. */ + +#define DWARF_ALL_KNOWN_DW_UT \ + DWARF_ONE_KNOWN_DW_UT (compile, DW_UT_compile) \ + DWARF_ONE_KNOWN_DW_UT (partial, DW_UT_partial) \ + DWARF_ONE_KNOWN_DW_UT (skeleton, DW_UT_skeleton) \ + DWARF_ONE_KNOWN_DW_UT (split_compile, DW_UT_split_compile) \ + DWARF_ONE_KNOWN_DW_UT (split_type, DW_UT_split_type) \ + DWARF_ONE_KNOWN_DW_UT (type, DW_UT_type) \ + /* End of DW_UT_*. */ + +#define DWARF_ALL_KNOWN_DW_VIRTUALITY \ + DWARF_ONE_KNOWN_DW_VIRTUALITY (none, DW_VIRTUALITY_none) \ + DWARF_ONE_KNOWN_DW_VIRTUALITY (pure_virtual, DW_VIRTUALITY_pure_virtual) \ + DWARF_ONE_KNOWN_DW_VIRTUALITY (virtual, DW_VIRTUALITY_virtual) \ + /* End of DW_VIRTUALITY_*. */ + +#define DWARF_ALL_KNOWN_DW_VIS \ + DWARF_ONE_KNOWN_DW_VIS (exported, DW_VIS_exported) \ + DWARF_ONE_KNOWN_DW_VIS (local, DW_VIS_local) \ + DWARF_ONE_KNOWN_DW_VIS (qualified, DW_VIS_qualified) \ + /* End of DW_VIS_*. */ diff --git a/libdw/libdw.h b/libdw/libdw.h new file mode 100644 index 00000000..77174d28 --- /dev/null +++ b/libdw/libdw.h @@ -0,0 +1,1111 @@ +/* Interfaces for libdw. + Copyright (C) 2002-2010, 2013, 2014, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBDW_H +#define _LIBDW_H 1 + +#include +#include +#include +#include + +/* Mode for the session. */ +typedef enum + { + DWARF_C_READ, /* Read .. */ + DWARF_C_RDWR, /* Read and write .. */ + DWARF_C_WRITE, /* Write .. */ + } +Dwarf_Cmd; + + +/* Callback results. */ +enum +{ + DWARF_CB_OK = 0, + DWARF_CB_ABORT +}; + + +/* Error values. */ +enum + { + DW_TAG_invalid = 0 +#define DW_TAG_invalid DW_TAG_invalid + }; + + +/* Type for offset in DWARF file. */ +typedef GElf_Off Dwarf_Off; + +/* Type for address in DWARF file. */ +typedef GElf_Addr Dwarf_Addr; + +/* Integer types. Big enough to hold any numeric value. */ +typedef GElf_Xword Dwarf_Word; +typedef GElf_Sxword Dwarf_Sword; +/* For the times we know we do not need that much. */ +typedef GElf_Half Dwarf_Half; + + +/* DWARF abbreviation record. */ +typedef struct Dwarf_Abbrev Dwarf_Abbrev; + +/* Returned to show the last DIE has be returned. */ +#define DWARF_END_ABBREV ((Dwarf_Abbrev *) -1l) + +/* Source code line information for CU. */ +typedef struct Dwarf_Lines_s Dwarf_Lines; + +/* One source code line information. */ +typedef struct Dwarf_Line_s Dwarf_Line; + +/* Source file information. */ +typedef struct Dwarf_Files_s Dwarf_Files; + +/* One address range record. */ +typedef struct Dwarf_Arange_s Dwarf_Arange; + +/* Address ranges of a file. */ +typedef struct Dwarf_Aranges_s Dwarf_Aranges; + +/* CU representation. */ +struct Dwarf_CU; +typedef struct Dwarf_CU Dwarf_CU; + +/* Macro information. */ +typedef struct Dwarf_Macro_s Dwarf_Macro; + +/* Attribute representation. */ +typedef struct +{ + unsigned int code; + unsigned int form; + unsigned char *valp; + struct Dwarf_CU *cu; +} Dwarf_Attribute; + + +/* Data block representation. */ +typedef struct +{ + Dwarf_Word length; + unsigned char *data; +} Dwarf_Block; + + +/* DIE information. */ +typedef struct +{ + /* The offset can be computed from the address. */ + void *addr; + struct Dwarf_CU *cu; + Dwarf_Abbrev *abbrev; + // XXX We'll see what other information will be needed. + long int padding__; +} Dwarf_Die; + +/* Returned to show the last DIE has be returned. */ +#define DWARF_END_DIE ((Dwarf_Die *) -1l) + + +/* Global symbol information. */ +typedef struct +{ + Dwarf_Off cu_offset; + Dwarf_Off die_offset; + const char *name; +} Dwarf_Global; + + +/* One operation in a DWARF location expression. + A location expression is an array of these. */ +typedef struct +{ + uint8_t atom; /* Operation */ + Dwarf_Word number; /* Operand */ + Dwarf_Word number2; /* Possible second operand */ + Dwarf_Word offset; /* Offset in location expression */ +} Dwarf_Op; + + +/* This describes one Common Information Entry read from a CFI section. + Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi. */ +typedef struct +{ + Dwarf_Off CIE_id; /* Always DW_CIE_ID_64 in Dwarf_CIE structures. */ + + /* Instruction stream describing initial state used by FDEs. If + we did not understand the whole augmentation string and it did + not use 'z', then there might be more augmentation data here + (and in FDEs) before the actual instructions. */ + const uint8_t *initial_instructions; + const uint8_t *initial_instructions_end; + + Dwarf_Word code_alignment_factor; + Dwarf_Sword data_alignment_factor; + Dwarf_Word return_address_register; + + const char *augmentation; /* Augmentation string. */ + + /* Augmentation data, might be NULL. The size is correct only if + we understood the augmentation string sufficiently. */ + const uint8_t *augmentation_data; + size_t augmentation_data_size; + size_t fde_augmentation_data_size; +} Dwarf_CIE; + +/* This describes one Frame Description Entry read from a CFI section. + Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi. */ +typedef struct +{ + /* Section offset of CIE this FDE refers to. This will never be + DW_CIE_ID_64 in an FDE. If this value is DW_CIE_ID_64, this is + actually a Dwarf_CIE structure. */ + Dwarf_Off CIE_pointer; + + /* We can't really decode anything further without looking up the CIE + and checking its augmentation string. Here follows the encoded + initial_location and address_range, then any augmentation data, + then the instruction stream. This FDE describes PC locations in + the byte range [initial_location, initial_location+address_range). + When the CIE augmentation string uses 'z', the augmentation data is + a DW_FORM_block (self-sized). Otherwise, when we understand the + augmentation string completely, fde_augmentation_data_size gives + the number of bytes of augmentation data before the instructions. */ + const uint8_t *start; + const uint8_t *end; +} Dwarf_FDE; + +/* Each entry in a CFI section is either a CIE described by Dwarf_CIE or + an FDE described by Dward_FDE. Check CIE_id to see which you have. */ +typedef union +{ + Dwarf_Off CIE_id; /* Always DW_CIE_ID_64 in Dwarf_CIE structures. */ + Dwarf_CIE cie; + Dwarf_FDE fde; +} Dwarf_CFI_Entry; + +/* Same as DW_CIE_ID_64 from dwarf.h to keep libdw.h independent. */ +#define LIBDW_CIE_ID 0xffffffffffffffffULL +#define dwarf_cfi_cie_p(entry) ((entry)->cie.CIE_id == LIBDW_CIE_ID) + +/* Opaque type representing a frame state described by CFI. */ +typedef struct Dwarf_Frame_s Dwarf_Frame; + +/* Opaque type representing a CFI section found in a DWARF or ELF file. */ +typedef struct Dwarf_CFI_s Dwarf_CFI; + + +/* Handle for debug sessions. */ +typedef struct Dwarf Dwarf; + + +/* Out-Of-Memory handler. */ +typedef void (*__noreturn_attribute__ Dwarf_OOM) (void); + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create a handle for a new debug session. */ +extern Dwarf *dwarf_begin (int fildes, Dwarf_Cmd cmd); + +/* Create a handle for a new debug session for an ELF file. */ +extern Dwarf *dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp); + +/* Retrieve ELF descriptor used for DWARF access. */ +extern Elf *dwarf_getelf (Dwarf *dwarf); + +/* Retrieve DWARF descriptor used for a Dwarf_Die or Dwarf_Attribute. + A Dwarf_Die or a Dwarf_Attribute is associated with a particular + Dwarf_CU handle. This function returns the DWARF descriptor for + that Dwarf_CU. */ +extern Dwarf *dwarf_cu_getdwarf (Dwarf_CU *cu); + +/* Retrieves the DWARF descriptor for debugaltlink data. Returns NULL + if no alternate debug data has been supplied yet. libdw will try + to set the alt file on first use of an alt FORM if not yet explicitly + provided by dwarf_setalt. */ +extern Dwarf *dwarf_getalt (Dwarf *main); + +/* Provides the data referenced by the .gnu_debugaltlink section. The + caller should check that MAIN and ALT match (i.e., they have the + same build ID). It is the responsibility of the caller to ensure + that the data referenced by ALT stays valid while it is used by + MAIN, until dwarf_setalt is called on MAIN with a different + descriptor, or dwarf_end. Must be called before inspecting DIEs + that might have alt FORMs. Otherwise libdw will try to set the + alt file itself on first use. */ +extern void dwarf_setalt (Dwarf *main, Dwarf *alt); + +/* Release debugging handling context. */ +extern int dwarf_end (Dwarf *dwarf); + + +/* Read the header for the DWARF CU. */ +extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, + size_t *header_sizep, Dwarf_Off *abbrev_offsetp, + uint8_t *address_sizep, uint8_t *offset_sizep) + __nonnull_attribute__ (3); + +/* Read the header of a DWARF CU or type unit. If TYPE_SIGNATUREP is not + null, this reads a type unit from the .debug_types section; otherwise + this reads a CU from the .debug_info section. */ +extern int dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, + size_t *header_sizep, Dwarf_Half *versionp, + Dwarf_Off *abbrev_offsetp, + uint8_t *address_sizep, uint8_t *offset_sizep, + uint64_t *type_signaturep, Dwarf_Off *type_offsetp) + __nonnull_attribute__ (3); + + +/* Gets the next Dwarf_CU (unit), version, unit type and if available + the CU DIE and sub (type) DIE of the unit. Returns 0 on success, + -1 on error or 1 if there are no more units. To start iterating + provide NULL for CU. If version < 5 the unit type is set from the + CU DIE if available (DW_UT_compile for DW_TAG_compile_unit, + DW_UT_type for DW_TAG_type_unit or DW_UT_partial for + DW_TAG_partial_unit), otherwise it is set to zero. If unavailable + (the version or unit type is unknown) the CU DIE is cleared. + Likewise if the sub DIE isn't isn't available (the unit type is not + DW_UT_type or DW_UT_split_type) the sub DIE tag is cleared. */ +extern int dwarf_get_units (Dwarf *dwarf, Dwarf_CU *cu, Dwarf_CU **next_cu, + Dwarf_Half *version, uint8_t *unit_type, + Dwarf_Die *cudie, Dwarf_Die *subdie) + __nonnull_attribute__ (3); + +/* Provides information and DIEs associated with the given Dwarf_CU + unit. Returns -1 on error, zero on success. Arguments not needed + may be NULL. If they are NULL and aren't known yet, they won't be + looked up. If the subdie doesn't exist for this unit_type it will + be cleared. If there is no unit_id for this unit type it will be + set to zero. */ +extern int dwarf_cu_info (Dwarf_CU *cu, + Dwarf_Half *version, uint8_t *unit_type, + Dwarf_Die *cudie, Dwarf_Die *subdie, + uint64_t *unit_id, + uint8_t *address_size, uint8_t *offset_size); + +/* Decode one DWARF CFI entry (CIE or FDE) from the raw section data. + The E_IDENT from the originating ELF file indicates the address + size and byte order used in the CFI section contained in DATA; + EH_FRAME_P should be true for .eh_frame format and false for + .debug_frame format. OFFSET is the byte position in the section + to start at; on return *NEXT_OFFSET is filled in with the byte + position immediately after this entry. + + On success, returns 0 and fills in *ENTRY; use dwarf_cfi_cie_p to + see whether ENTRY->cie or ENTRY->fde is valid. + + On errors, returns -1. Some format errors will permit safely + skipping to the next CFI entry though the current one is unusable. + In that case, *NEXT_OFF will be updated before a -1 return. + + If there are no more CFI entries left in the section, + returns 1 and sets *NEXT_OFFSET to (Dwarf_Off) -1. */ +extern int dwarf_next_cfi (const unsigned char e_ident[], + Elf_Data *data, bool eh_frame_p, + Dwarf_Off offset, Dwarf_Off *next_offset, + Dwarf_CFI_Entry *entry) + __nonnull_attribute__ (1, 2, 5, 6); + +/* Use the CFI in the DWARF .debug_frame section. + Returns NULL if there is no such section (not an error). + The pointer returned can be used until dwarf_end is called on DWARF, + and must not be passed to dwarf_cfi_end. + Calling this more than once returns the same pointer. */ +extern Dwarf_CFI *dwarf_getcfi (Dwarf *dwarf); + +/* Use the CFI in the ELF file's exception-handling data. + Returns NULL if there is no such data. + The pointer returned can be used until elf_end is called on ELF, + and must be passed to dwarf_cfi_end before then. + Calling this more than once allocates independent data structures. */ +extern Dwarf_CFI *dwarf_getcfi_elf (Elf *elf); + +/* Release resources allocated by dwarf_getcfi_elf. */ +extern int dwarf_cfi_end (Dwarf_CFI *cache); + + +/* Return DIE at given offset in .debug_info section. */ +extern Dwarf_Die *dwarf_offdie (Dwarf *dbg, Dwarf_Off offset, + Dwarf_Die *result) __nonnull_attribute__ (3); + +/* Return DIE at given offset in .debug_types section. */ +extern Dwarf_Die *dwarf_offdie_types (Dwarf *dbg, Dwarf_Off offset, + Dwarf_Die *result) + __nonnull_attribute__ (3); + +/* Return offset of DIE. */ +extern Dwarf_Off dwarf_dieoffset (Dwarf_Die *die); + +/* Return offset of DIE in CU. */ +extern Dwarf_Off dwarf_cuoffset (Dwarf_Die *die); + +/* Return CU DIE containing given DIE. */ +extern Dwarf_Die *dwarf_diecu (Dwarf_Die *die, Dwarf_Die *result, + uint8_t *address_sizep, uint8_t *offset_sizep) + __nonnull_attribute__ (2); + +/* Given a Dwarf_Die addr returns a (reconstructed) Dwarf_Die, or NULL + if the given addr didn't come from a valid Dwarf_Die. In particular + it will make sure that the correct Dwarf_CU pointer is set for the + Dwarf_Die, the Dwarf_Abbrev pointer will not be set up yet (it will + only be once the Dwarf_Die is used to read attributes, children or + siblings). This functions can be used to keep a reference to a + Dwarf_Die which you want to refer to later. The addr, and the result + of this function, is only valid while the associated Dwarf is valid. */ +extern Dwarf_Die *dwarf_die_addr_die (Dwarf *dbg, void *addr, + Dwarf_Die *result) + __nonnull_attribute__ (3); + +/* Return the CU DIE and the header info associated with a Dwarf_Die + or Dwarf_Attribute. A Dwarf_Die or a Dwarf_Attribute is associated + with a particular Dwarf_CU handle. This function returns the CU or + type unit DIE and header information for that Dwarf_CU. The + returned DIE is either a compile_unit, partial_unit or type_unit. + If it is a type_unit, then the type signature and type offset are + also provided, otherwise type_offset will be set to zero. See also + dwarf_diecu and dwarf_next_unit. */ +extern Dwarf_Die *dwarf_cu_die (Dwarf_CU *cu, Dwarf_Die *result, + Dwarf_Half *versionp, + Dwarf_Off *abbrev_offsetp, + uint8_t *address_sizep, + uint8_t *offset_sizep, + uint64_t *type_signaturep, + Dwarf_Off *type_offsetp) + __nonnull_attribute__ (2); + +/* Return CU DIE containing given address. */ +extern Dwarf_Die *dwarf_addrdie (Dwarf *dbg, Dwarf_Addr addr, + Dwarf_Die *result) __nonnull_attribute__ (3); + +/* Return child of current DIE. */ +extern int dwarf_child (Dwarf_Die *die, Dwarf_Die *result) + __nonnull_attribute__ (2); + +/* Locates the first sibling of DIE and places it in RESULT. + Returns 0 if a sibling was found, -1 if something went wrong. + Returns 1 if no sibling could be found and, if RESULT is not + the same as DIE, it sets RESULT->addr to the address of the + (non-sibling) DIE that follows this one, or NULL if this DIE + was the last one in the compilation unit. */ +extern int dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result) + __nonnull_attribute__ (2); + +/* For type aliases and qualifier type DIEs, which don't modify or + change the structural layout of the underlying type, follow the + DW_AT_type attribute (recursively) and return the underlying type + Dwarf_Die. + + Returns 0 when RESULT contains a Dwarf_Die (possibly equal to the + given DIE) that isn't a type alias or qualifier type. Returns 1 + when RESULT contains a type alias or qualifier Dwarf_Die that + couldn't be peeled further (it doesn't have a DW_TAG_type + attribute). Returns -1 when an error occurred. + + The current DWARF specification defines one type alias tag + (DW_TAG_typedef) and seven modifier/qualifier type tags + (DW_TAG_const_type, DW_TAG_volatile_type, DW_TAG_restrict_type, + DW_TAG_atomic_type, DW_TAG_immutable_type, DW_TAG_packed_type and + DW_TAG_shared_type). This function won't peel modifier type + tags that change the way the underlying type is accessed such + as the pointer or reference type tags (DW_TAG_pointer_type, + DW_TAG_reference_type or DW_TAG_rvalue_reference_type). + + A future version of this function might peel other alias or + qualifier type tags if a future DWARF version or GNU extension + defines other type aliases or qualifier type tags that don't modify, + change the structural layout or the way to access the underlying type. */ +extern int dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result) + __nonnull_attribute__ (2); + +/* Check whether the DIE has children. */ +extern int dwarf_haschildren (Dwarf_Die *die) __nonnull_attribute__ (1); + +/* Walks the attributes of DIE, starting at the one OFFSET bytes in, + calling the CALLBACK function for each one. Stops if the callback + function ever returns a value other than DWARF_CB_OK and returns the + offset of the offending attribute. If the end of the attributes + is reached 1 is returned. If something goes wrong -1 is returned and + the dwarf error number is set. */ +extern ptrdiff_t dwarf_getattrs (Dwarf_Die *die, + int (*callback) (Dwarf_Attribute *, void *), + void *arg, ptrdiff_t offset) + __nonnull_attribute__ (2); + +/* Return tag of given DIE. */ +extern int dwarf_tag (Dwarf_Die *die) __nonnull_attribute__ (1); + + +/* Return specific attribute of DIE. */ +extern Dwarf_Attribute *dwarf_attr (Dwarf_Die *die, unsigned int search_name, + Dwarf_Attribute *result) + __nonnull_attribute__ (3); + +/* Check whether given DIE has specific attribute. */ +extern int dwarf_hasattr (Dwarf_Die *die, unsigned int search_name); + +/* These are the same as dwarf_attr and dwarf_hasattr, respectively, + but they resolve an indirect attribute through + DW_AT_abstract_origin, DW_AT_specification or, if the DIE is a + top-level split CU, the skeleton DIE. Note that the attribute + might come from a DIE in a different CU (possibly from a different + Dwarf file). In that case all attribute information needs to be + resolved through the CU associated with the returned + Dwarf_Attribute. The dwarf_form functions already do this + automatically. */ +extern Dwarf_Attribute *dwarf_attr_integrate (Dwarf_Die *die, + unsigned int search_name, + Dwarf_Attribute *result) + __nonnull_attribute__ (3); +extern int dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name); + + + + +/* Check whether given attribute has specific form. */ +extern int dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form); + +/* Return attribute code of given attribute. */ +extern unsigned int dwarf_whatattr (Dwarf_Attribute *attr); + +/* Return form code of given attribute. */ +extern unsigned int dwarf_whatform (Dwarf_Attribute *attr); + + +/* Return string associated with given attribute. */ +extern const char *dwarf_formstring (Dwarf_Attribute *attrp); + +/* Return unsigned constant represented by attribute. */ +extern int dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval) + __nonnull_attribute__ (2); + +/* Return signed constant represented by attribute. */ +extern int dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_uval) + __nonnull_attribute__ (2); + +/* Return address represented by attribute. */ +extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* This function is deprecated. Always use dwarf_formref_die instead. + Return reference offset represented by attribute. */ +extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) + __nonnull_attribute__ (2) __deprecated_attribute__; + +/* Look up the DIE in a reference-form attribute. */ +extern Dwarf_Die *dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *die_mem) + __nonnull_attribute__ (2); + +/* Return block represented by attribute. */ +extern int dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block) + __nonnull_attribute__ (2); + +/* Return flag represented by attribute. */ +extern int dwarf_formflag (Dwarf_Attribute *attr, bool *return_bool) + __nonnull_attribute__ (2); + + +/* Simplified attribute value access functions. */ + +/* Return string in name attribute of DIE. */ +extern const char *dwarf_diename (Dwarf_Die *die); + +/* Return high PC attribute of DIE. */ +extern int dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* Return low PC attribute of DIE. */ +extern int dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* Return entry_pc or low_pc attribute of DIE. */ +extern int dwarf_entrypc (Dwarf_Die *die, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* Return 1 if DIE's lowpc/highpc or ranges attributes match the PC address, + 0 if not, or -1 for errors. */ +extern int dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc); + +/* Enumerate the PC address ranges covered by this DIE, covering all + addresses where dwarf_haspc returns true. In the first call OFFSET + should be zero and *BASEP need not be initialized. Returns -1 for + errors, zero when there are no more address ranges to report, or a + nonzero OFFSET value to pass to the next call. Each subsequent call + must preserve *BASEP from the prior call. Successful calls fill in + *STARTP and *ENDP with a contiguous address range. */ +extern ptrdiff_t dwarf_ranges (Dwarf_Die *die, + ptrdiff_t offset, Dwarf_Addr *basep, + Dwarf_Addr *startp, Dwarf_Addr *endp); + + +/* Return byte size attribute of DIE. */ +extern int dwarf_bytesize (Dwarf_Die *die); + +/* Return bit size attribute of DIE. */ +extern int dwarf_bitsize (Dwarf_Die *die); + +/* Return bit offset attribute of DIE. */ +extern int dwarf_bitoffset (Dwarf_Die *die); + +/* Return array order attribute of DIE. */ +extern int dwarf_arrayorder (Dwarf_Die *die); + +/* Return source language attribute of DIE. */ +extern int dwarf_srclang (Dwarf_Die *die); + + +/* Get abbreviation at given offset for given DIE. */ +extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, + size_t *lengthp); + +/* Get abbreviation at given offset in .debug_abbrev section. */ +extern int dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp, + Dwarf_Abbrev *abbrevp) + __nonnull_attribute__ (4); + +/* Get abbreviation code. */ +extern unsigned int dwarf_getabbrevcode (Dwarf_Abbrev *abbrev); + +/* Get abbreviation tag. */ +extern unsigned int dwarf_getabbrevtag (Dwarf_Abbrev *abbrev); + +/* Return true if abbreviation is children flag set. */ +extern int dwarf_abbrevhaschildren (Dwarf_Abbrev *abbrev); + +/* Get number of attributes of abbreviation. */ +extern int dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp) + __nonnull_attribute__ (2); + +/* Get specific attribute of abbreviation. */ +extern int dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx, + unsigned int *namep, unsigned int *formp, + Dwarf_Off *offset); + +/* Get specific attribute of abbreviation and any data encoded with it. + Specifically for DW_FORM_implicit_const data will be set to the + constant value associated. */ +extern int dwarf_getabbrevattr_data (Dwarf_Abbrev *abbrev, size_t idx, + unsigned int *namep, unsigned int *formp, + Dwarf_Sword *datap, Dwarf_Off *offset); + +/* Get string from-debug_str section. */ +extern const char *dwarf_getstring (Dwarf *dbg, Dwarf_Off offset, + size_t *lenp); + + +/* Get public symbol information. */ +extern ptrdiff_t dwarf_getpubnames (Dwarf *dbg, + int (*callback) (Dwarf *, Dwarf_Global *, + void *), + void *arg, ptrdiff_t offset) + __nonnull_attribute__ (2); + + +/* Get source file information for CU. */ +extern int dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, + size_t *nlines) __nonnull_attribute__ (2, 3); + +/* Return one of the source lines of the CU. */ +extern Dwarf_Line *dwarf_onesrcline (Dwarf_Lines *lines, size_t idx); + +/* Get the file source files used in the CU. */ +extern int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, + size_t *nfiles) + __nonnull_attribute__ (2); + + +/* Get source for address in CU. */ +extern Dwarf_Line *dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr); + +/* Get source for file and line number. */ +extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col, + Dwarf_Line ***srcsp, size_t *nsrcs) + __nonnull_attribute__ (2, 5, 6); + + +/* Return line address. */ +extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp); + +/* Return line VLIW operation index. */ +extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp); + +/* Return line number. */ +extern int dwarf_lineno (Dwarf_Line *line, int *linep) + __nonnull_attribute__ (2); + +/* Return column in line. */ +extern int dwarf_linecol (Dwarf_Line *line, int *colp) + __nonnull_attribute__ (2); + +/* Return true if record is for beginning of a statement. */ +extern int dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for end of sequence. */ +extern int dwarf_lineendsequence (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for beginning of a basic block. */ +extern int dwarf_lineblock (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for end of prologue. */ +extern int dwarf_lineprologueend (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for beginning of epilogue. */ +extern int dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return instruction-set architecture in this record. */ +extern int dwarf_lineisa (Dwarf_Line *line, unsigned int *isap) + __nonnull_attribute__ (2); + +/* Return code path discriminator in this record. */ +extern int dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp) + __nonnull_attribute__ (2); + + +/* Find line information for address. The returned string is NULL when + an error occurred, or the file path. The file path is either absolute + or relative to the compilation directory. See dwarf_decl_file. */ +extern const char *dwarf_linesrc (Dwarf_Line *line, + Dwarf_Word *mtime, Dwarf_Word *length); + +/* Return file information. The returned string is NULL when + an error occurred, or the file path. The file path is either absolute + or relative to the compilation directory. See dwarf_decl_file. */ +extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx, + Dwarf_Word *mtime, Dwarf_Word *length); + +/* Return the Dwarf_Files and index associated with the given Dwarf_Line. */ +extern int dwarf_line_file (Dwarf_Line *line, + Dwarf_Files **files, size_t *idx) + __nonnull_attribute__ (2, 3); + +/* Return the directory list used in the file information extracted. + (*RESULT)[0] is the CU's DW_AT_comp_dir value, and may be null. + (*RESULT)[0..*NDIRS-1] are the compile-time include directory path + encoded by the compiler. */ +extern int dwarf_getsrcdirs (Dwarf_Files *files, + const char *const **result, size_t *ndirs) + __nonnull_attribute__ (2, 3); + +/* Iterates through the debug line units. Returns 0 on success, -1 on + error or 1 if there are no more units. To start iterating use zero + for OFF and set *CU to NULL. On success NEXT_OFF will be set to + the next offset to use. The *CU will be set if this line table + needed a specific CU and needs to be given when calling + dwarf_next_lines again (to help dwarf_next_lines quickly find the + next CU). *CU might be set to NULL when it couldn't be found (the + compilation directory entry will be the empty string in that case) + or for DWARF 5 or later tables, which are self contained. SRCFILES + and SRCLINES may be NULL if the caller is not interested in the + actual line or file table. On success and when not NULL, NFILES + and NLINES will be set to the number of files in the file table and + number of lines in the line table. */ +extern int dwarf_next_lines (Dwarf *dwarf, Dwarf_Off off, + Dwarf_Off *next_off, Dwarf_CU **cu, + Dwarf_Files **srcfiles, size_t *nfiles, + Dwarf_Lines **srclines, size_t *nlines) + __nonnull_attribute__ (3,4); + +/* Return location expression, decoded as a list of operations. */ +extern int dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **expr, + size_t *exprlen) __nonnull_attribute__ (2, 3); + +/* Return location expressions. If the attribute uses a location list, + ADDRESS selects the relevant location expressions from the list. + There can be multiple matches, resulting in multiple expressions to + return. EXPRS and EXPRLENS are parallel arrays of NLOCS slots to + fill in. Returns the number of locations filled in, or -1 for + errors. If EXPRS is a null pointer, stores nothing and returns the + total number of locations. A return value of zero means that the + location list indicated no value is accessible. */ +extern int dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address, + Dwarf_Op **exprs, size_t *exprlens, + size_t nlocs); + +/* Enumerate the locations ranges and descriptions covered by the + given attribute. In the first call OFFSET should be zero and + *BASEP need not be initialized. Returns -1 for errors, zero when + there are no more locations to report, or a nonzero OFFSET + value to pass to the next call. Each subsequent call must preserve + *BASEP from the prior call. Successful calls fill in *STARTP and + *ENDP with a contiguous address range and *EXPR with a pointer to + an array of operations with length *EXPRLEN. If the attribute + describes a single location description and not a location list the + first call (with OFFSET zero) will return the location description + in *EXPR with *STARTP set to zero and *ENDP set to minus one. */ +extern ptrdiff_t dwarf_getlocations (Dwarf_Attribute *attr, + ptrdiff_t offset, Dwarf_Addr *basep, + Dwarf_Addr *startp, Dwarf_Addr *endp, + Dwarf_Op **expr, size_t *exprlen); + +/* Return the block associated with a DW_OP_implicit_value operation. + The OP pointer must point into an expression that dwarf_getlocation + or dwarf_getlocation_addr has returned given the same ATTR. */ +extern int dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, + const Dwarf_Op *op, + Dwarf_Block *return_block) + __nonnull_attribute__ (2, 3); + +/* Return the attribute indicated by a DW_OP_GNU_implicit_pointer operation. + The OP pointer must point into an expression that dwarf_getlocation + or dwarf_getlocation_addr has returned given the same ATTR. + The result is the DW_AT_location or DW_AT_const_value attribute + of the OP->number DIE. */ +extern int dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr, + const Dwarf_Op *op, + Dwarf_Attribute *result) + __nonnull_attribute__ (2, 3); + +/* Return the DIE associated with an operation such as + DW_OP_GNU_implicit_pointer, DW_OP_GNU_parameter_ref, DW_OP_GNU_convert, + DW_OP_GNU_reinterpret, DW_OP_GNU_const_type, DW_OP_GNU_regval_type or + DW_OP_GNU_deref_type. The OP pointer must point into an expression that + dwarf_getlocation or dwarf_getlocation_addr has returned given the same + ATTR. The RESULT is a DIE that expresses a type or value needed by the + given OP. */ +extern int dwarf_getlocation_die (Dwarf_Attribute *attr, + const Dwarf_Op *op, + Dwarf_Die *result) + __nonnull_attribute__ (2, 3); + +/* Return the attribute expressing a value associated with an operation such + as DW_OP_implicit_value, DW_OP_GNU_entry_value or DW_OP_GNU_const_type. + The OP pointer must point into an expression that dwarf_getlocation + or dwarf_getlocation_addr has returned given the same ATTR. + The RESULT is a value expressed by an attribute such as DW_AT_location + or DW_AT_const_value. */ +extern int dwarf_getlocation_attr (Dwarf_Attribute *attr, + const Dwarf_Op *op, + Dwarf_Attribute *result) + __nonnull_attribute__ (2, 3); + + +/* Compute the byte-size of a type DIE according to DWARF rules. + For most types, this is just DW_AT_byte_size. + For DW_TAG_array_type it can apply much more complex rules. */ +extern int dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size); + +/* Given a language code, as returned by dwarf_srclan, get the default + lower bound for a subrange type without a lower bound attribute. + Returns zero on success or -1 on failure when the given language + wasn't recognized. */ +extern int dwarf_default_lower_bound (int lang, Dwarf_Sword *result) + __nonnull_attribute__ (2); + +/* Return scope DIEs containing PC address. + Sets *SCOPES to a malloc'd array of Dwarf_Die structures, + and returns the number of elements in the array. + (*SCOPES)[0] is the DIE for the innermost scope containing PC, + (*SCOPES)[1] is the DIE for the scope containing that scope, and so on. + Returns -1 for errors or 0 if no scopes match PC. */ +extern int dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc, + Dwarf_Die **scopes); + +/* Return scope DIEs containing the given DIE. + Sets *SCOPES to a malloc'd array of Dwarf_Die structures, + and returns the number of elements in the array. + (*SCOPES)[0] is a copy of DIE. + (*SCOPES)[1] is the DIE for the scope containing that scope, and so on. + Returns -1 for errors or 0 if DIE is not found in any scope entry. */ +extern int dwarf_getscopes_die (Dwarf_Die *die, Dwarf_Die **scopes); + + +/* Search SCOPES[0..NSCOPES-1] for a variable called NAME. + Ignore the first SKIP_SHADOWS scopes that match the name. + If MATCH_FILE is not null, accept only declaration in that source file; + if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration + at that line and column. + + If successful, fill in *RESULT with the DIE of the variable found, + and return N where SCOPES[N] is the scope defining the variable. + Return -1 for errors or -2 for no matching variable found. */ +extern int dwarf_getscopevar (Dwarf_Die *scopes, int nscopes, + const char *name, int skip_shadows, + const char *match_file, + int match_lineno, int match_linecol, + Dwarf_Die *result); + + + +/* Return list address ranges. */ +extern int dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, + size_t *naranges) + __nonnull_attribute__ (2); + +/* Return one of the address range entries. */ +extern Dwarf_Arange *dwarf_onearange (Dwarf_Aranges *aranges, size_t idx); + +/* Return information in address range record. */ +extern int dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp, + Dwarf_Word *lengthp, Dwarf_Off *offsetp); + +/* Get address range which includes given address. */ +extern Dwarf_Arange *dwarf_getarange_addr (Dwarf_Aranges *aranges, + Dwarf_Addr addr); + + + +/* Get functions in CUDIE. The given callback will be called for all + defining DW_TAG_subprograms in the CU DIE tree. If the callback + returns DWARF_CB_ABORT the return value can be used as offset argument + to resume the function to find all remaining functions (this is not + really recommended, since it needs to rewalk the CU DIE tree first till + that offset is found again). If the callback returns DWARF_CB_OK + dwarf_getfuncs will not return but keep calling the callback for each + function DIE it finds. Pass zero for offset on the first call to walk + the full CU DIE tree. If no more functions can be found and the callback + returned DWARF_CB_OK then the function returns zero. */ +extern ptrdiff_t dwarf_getfuncs (Dwarf_Die *cudie, + int (*callback) (Dwarf_Die *, void *), + void *arg, ptrdiff_t offset); + + +/* Return file name containing definition of the given declaration. + Of the DECL has an (indirect, see dwarf_attr_integrate) decl_file + attribute. The returned file path is either absolute, or relative + to the compilation directory. Given the decl DIE, the compilation + directory can be retrieved through: + dwarf_formstring (dwarf_attr (dwarf_diecu (decl, &cudie, NULL, NULL), + DW_AT_comp_dir, &attr)); + Returns NULL if no decl_file could be found or an error occurred. */ +extern const char *dwarf_decl_file (Dwarf_Die *decl); + +/* Get line number of beginning of given declaration. */ +extern int dwarf_decl_line (Dwarf_Die *decl, int *linep) + __nonnull_attribute__ (2); + +/* Get column number of beginning of given declaration. */ +extern int dwarf_decl_column (Dwarf_Die *decl, int *colp) + __nonnull_attribute__ (2); + + +/* Return nonzero if given function is an abstract inline definition. */ +extern int dwarf_func_inline (Dwarf_Die *func); + +/* Find each concrete inlined instance of the abstract inline definition. */ +extern int dwarf_func_inline_instances (Dwarf_Die *func, + int (*callback) (Dwarf_Die *, void *), + void *arg); + + +/* Find the appropriate PC location or locations for function entry + breakpoints for the given DW_TAG_subprogram DIE. Returns -1 for errors. + On success, returns the number of breakpoint locations (never zero) + and sets *BKPTS to a malloc'd vector of addresses. */ +extern int dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts); + + +/* Iterate through the macro unit referenced by CUDIE and call + CALLBACK for each macro information entry. To start the iteration, + one would pass DWARF_GETMACROS_START for TOKEN. + + The iteration continues while CALLBACK returns DWARF_CB_OK. If the + callback returns DWARF_CB_ABORT, the iteration stops and a + continuation token is returned, which can be used to restart the + iteration at the point where it ended. Returns -1 for errors or 0 + if there are no more macro entries. + + Note that the Dwarf_Macro pointer passed to the callback is only + valid for the duration of the callback invocation. + + For backward compatibility, a token of 0 is accepted for starting + the iteration as well, but in that case this interface will refuse + to serve opcode 0xff from .debug_macro sections. Such opcode would + be considered invalid and would cause dwarf_getmacros to return + with error. */ +#define DWARF_GETMACROS_START PTRDIFF_MIN +extern ptrdiff_t dwarf_getmacros (Dwarf_Die *cudie, + int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t token) + __nonnull_attribute__ (2); + +/* This is similar in operation to dwarf_getmacros, but selects the + unit to iterate through by offset instead of by CU, and always + iterates .debug_macro. This can be used for handling + DW_MACRO_GNU_transparent_include's or similar opcodes. + + TOKEN value of DWARF_GETMACROS_START can be used to start the + iteration. + + It is not appropriate to obtain macro unit offset by hand from a CU + DIE and then request iteration through this interface. The reason + for this is that if a dwarf_macro_getsrcfiles is later called, + there would be no way to figure out what DW_AT_comp_dir was present + on the CU DIE, and file names referenced in either the macro unit + itself, or the .debug_line unit that it references, might be wrong. + Use dwarf_getmacros. */ +extern ptrdiff_t dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, + int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t token) + __nonnull_attribute__ (3); + +/* Get the source files used by the macro entry. You shouldn't assume + that Dwarf_Files references will remain valid after MACRO becomes + invalid. (Which is to say it's only valid within the + dwarf_getmacros* callback.) Returns 0 for success or a negative + value in case of an error. */ +extern int dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro, + Dwarf_Files **files, size_t *nfiles) + __nonnull_attribute__ (2, 3, 4); + +/* Return macro opcode. That's a constant that can be either from + DW_MACINFO_* domain or DW_MACRO_GNU_* domain. The two domains have + compatible values, so it's OK to use either of them for + comparisons. The only differences is 0xff, which could be either + DW_MACINFO_vendor_ext or a vendor-defined DW_MACRO_* constant. One + would need to look if the CU DIE which the iteration was requested + for has attribute DW_AT_macro_info, or either of DW_AT_GNU_macros + or DW_AT_macros to differentiate the two interpretations. */ +extern int dwarf_macro_opcode (Dwarf_Macro *macro, unsigned int *opcodep) + __nonnull_attribute__ (2); + +/* Get number of parameters of MACRO and store it to *PARAMCNTP. */ +extern int dwarf_macro_getparamcnt (Dwarf_Macro *macro, size_t *paramcntp); + +/* Get IDX-th parameter of MACRO (numbered from zero), and stores it + to *ATTRIBUTE. Returns 0 on success or -1 for errors. + + After a successful call, you can query ATTRIBUTE by dwarf_whatform + to determine which of the dwarf_formX calls to make to get actual + value out of ATTRIBUTE. Note that calling dwarf_whatattr is not + meaningful for pseudo-attributes formed this way. */ +extern int dwarf_macro_param (Dwarf_Macro *macro, size_t idx, + Dwarf_Attribute *attribute); + +/* Return macro parameter with index 0. This will return -1 if the + parameter is not an integral value. Use dwarf_macro_param for more + general access. */ +extern int dwarf_macro_param1 (Dwarf_Macro *macro, Dwarf_Word *paramp) + __nonnull_attribute__ (2); + +/* Return macro parameter with index 1. This will return -1 if the + parameter is not an integral or string value. Use + dwarf_macro_param for more general access. */ +extern int dwarf_macro_param2 (Dwarf_Macro *macro, Dwarf_Word *paramp, + const char **strp); + +/* Compute what's known about a call frame when the PC is at ADDRESS. + Returns 0 for success or -1 for errors. + On success, *FRAME is a malloc'd pointer. */ +extern int dwarf_cfi_addrframe (Dwarf_CFI *cache, + Dwarf_Addr address, Dwarf_Frame **frame) + __nonnull_attribute__ (3); + +/* Return the DWARF register number used in FRAME to denote + the return address in FRAME's caller frame. The remaining + arguments can be non-null to fill in more information. + + Fill [*START, *END) with the PC range to which FRAME's information applies. + Fill in *SIGNALP to indicate whether this is a signal-handling frame. + If true, this is the implicit call frame that calls a signal handler. + This frame's "caller" is actually the interrupted state, not a call; + its return address is an exact PC, not a PC after a call instruction. */ +extern int dwarf_frame_info (Dwarf_Frame *frame, + Dwarf_Addr *start, Dwarf_Addr *end, bool *signalp); + +/* Return a DWARF expression that yields the Canonical Frame Address at + this frame state. Returns -1 for errors, or zero for success, with + *NOPS set to the number of operations stored at *OPS. That pointer + can be used only as long as FRAME is alive and unchanged. *NOPS is + zero if the CFA cannot be determined here. Note that if nonempty, + *OPS is a DWARF expression, not a location description--append + DW_OP_stack_value to a get a location description for the CFA. */ +extern int dwarf_frame_cfa (Dwarf_Frame *frame, Dwarf_Op **ops, size_t *nops) + __nonnull_attribute__ (2); + +/* Deliver a DWARF location description that yields the location or + value of DWARF register number REGNO in the state described by FRAME. + + Returns -1 for errors or zero for success, setting *NOPS to the + number of operations in the array stored at *OPS. Note the last + operation is DW_OP_stack_value if there is no mutable location but + only a computable value. + + *NOPS zero with *OPS set to OPS_MEM means CFI says the caller's + REGNO is "undefined", i.e. it's call-clobbered and cannot be recovered. + + *NOPS zero with *OPS set to a null pointer means CFI says the + caller's REGNO is "same_value", i.e. this frame did not change it; + ask the caller frame where to find it. + + For common simple expressions *OPS is OPS_MEM (which is a caller + owned array for at least 3 Dwarf_Ops). For arbitrary DWARF + expressions in the CFI, *OPS is an internal pointer that can be + used as long as the Dwarf_CFI used to create FRAME remains + alive. */ +extern int dwarf_frame_register (Dwarf_Frame *frame, int regno, + Dwarf_Op ops_mem[3], + Dwarf_Op **ops, size_t *nops) + __nonnull_attribute__ (3, 4, 5); + + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int dwarf_errno (void); + +/* Return error string for ERROR. If ERROR is zero, return error string + for most recent error or NULL is none occurred. If ERROR is -1 the + behaviour is similar to the last case except that not NULL but a legal + string is returned. */ +extern const char *dwarf_errmsg (int err); + + +/* Register new Out-Of-Memory handler. The old handler is returned. */ +extern Dwarf_OOM dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler); + + +/* Inline optimizations. */ +#ifdef __OPTIMIZE__ +/* Return attribute code of given attribute. */ +__libdw_extern_inline unsigned int +dwarf_whatattr (Dwarf_Attribute *attr) +{ + return attr == NULL ? 0 : attr->code; +} + +/* Return attribute code of given attribute. */ +__libdw_extern_inline unsigned int +dwarf_whatform (Dwarf_Attribute *attr) +{ + return attr == NULL ? 0 : attr->form; +} +#endif /* Optimize. */ + +#ifdef __cplusplus +} +#endif + +#endif /* libdw.h */ diff --git a/libdw/libdw.map b/libdw/libdw.map new file mode 100644 index 00000000..8ab0a2a0 --- /dev/null +++ b/libdw/libdw.map @@ -0,0 +1,362 @@ +ELFUTILS_0 { }; +ELFUTILS_0.122 { + global: + dwarf_abbrevhaschildren; + dwarf_addrdie; + dwarf_arrayorder; + dwarf_attr; + dwarf_attr_integrate; + dwarf_begin; + dwarf_begin_elf; + dwarf_bitoffset; + dwarf_bitsize; + dwarf_bytesize; + dwarf_child; + dwarf_cuoffset; + dwarf_decl_column; + dwarf_decl_file; + dwarf_decl_line; + dwarf_diecu; + dwarf_diename; + dwarf_dieoffset; + dwarf_end; + dwarf_entry_breakpoints; + dwarf_entrypc; + dwarf_errmsg; + dwarf_errno; + dwarf_filesrc; + dwarf_formaddr; + dwarf_formblock; + dwarf_formflag; + dwarf_formref; + dwarf_formref_die; + dwarf_formsdata; + dwarf_formstring; + dwarf_formudata; + dwarf_func_inline; + dwarf_func_inline_instances; + dwarf_getabbrev; + dwarf_getabbrevattr; + dwarf_getabbrevcode; + dwarf_getabbrevtag; + dwarf_getarange_addr; + dwarf_getarangeinfo; + dwarf_getaranges; + dwarf_getattrcnt; + dwarf_getattrs; + dwarf_getfuncs; + dwarf_getlocation; + dwarf_getlocation_addr; + dwarf_getmacros; + dwarf_getpubnames; + dwarf_getscopes; + dwarf_getscopes_die; + dwarf_getscopevar; + dwarf_getsrc_die; + dwarf_getsrc_file; + dwarf_getsrcfiles; + dwarf_getsrclines; + dwarf_getstring; + dwarf_hasattr; + dwarf_hasattr_integrate; + dwarf_haschildren; + dwarf_hasform; + dwarf_haspc; + dwarf_highpc; + dwarf_lineaddr; + dwarf_linebeginstatement; + dwarf_lineblock; + dwarf_linecol; + dwarf_lineendsequence; + dwarf_lineepiloguebegin; + dwarf_lineno; + dwarf_lineprologueend; + dwarf_linesrc; + dwarf_lowpc; + dwarf_macro_opcode; + dwarf_macro_param1; + dwarf_macro_param2; + dwarf_new_oom_handler; + dwarf_nextcu; + dwarf_offabbrev; + dwarf_offdie; + dwarf_onearange; + dwarf_onesrcline; + dwarf_ranges; + dwarf_siblingof; + dwarf_srclang; + dwarf_tag; + dwarf_whatattr; + dwarf_whatform; + + # libdwfl_pic.a contributes these symbols. + dwfl_addrdie; + dwfl_addrdwarf; + dwfl_addrmodule; + dwfl_begin; + dwfl_cumodule; + dwfl_end; + dwfl_errmsg; + dwfl_errno; + dwfl_getdwarf; + dwfl_getmodules; + dwfl_getsrc; + dwfl_getsrclines; + dwfl_line_comp_dir; + dwfl_linecu; + dwfl_lineinfo; + dwfl_linemodule; + dwfl_linux_kernel_find_elf; + dwfl_linux_kernel_module_section_address; + dwfl_linux_kernel_report_kernel; + dwfl_linux_kernel_report_modules; + dwfl_linux_kernel_report_offline; + dwfl_linux_proc_find_elf; + dwfl_linux_proc_maps_report; + dwfl_linux_proc_report; + dwfl_module_addrdie; + dwfl_module_addrname; + dwfl_module_getdwarf; + dwfl_module_getelf; + dwfl_module_getsrc; + dwfl_module_getsrc_file; + dwfl_module_getsym; + dwfl_module_getsymtab; + dwfl_module_info; + dwfl_module_nextcu; + dwfl_module_register_names; + dwfl_module_relocate_address; + dwfl_module_relocation_info; + dwfl_module_relocations; + dwfl_module_return_value_location; + dwfl_nextcu; + dwfl_offline_section_address; + dwfl_onesrcline; + dwfl_report_begin; + dwfl_report_elf; + dwfl_report_end; + dwfl_report_module; + dwfl_report_offline; + dwfl_standard_argp; + dwfl_standard_find_debuginfo; + dwfl_version; + + local: + *; +} ELFUTILS_0; + +ELFUTILS_0.126 { + global: + dwarf_getelf; + +} ELFUTILS_0.122; + +ELFUTILS_0.127 { + global: + dwarf_getsrcdirs; + + dwfl_module_addrsym; + dwfl_report_begin_add; + dwfl_module_address_section; + +} ELFUTILS_0.126; + +ELFUTILS_0.130 { + global: + dwfl_build_id_find_elf; + dwfl_build_id_find_debuginfo; + dwfl_module_build_id; + dwfl_module_report_build_id; + +} ELFUTILS_0.127; + +ELFUTILS_0.136 { + global: + dwfl_addrsegment; + dwfl_report_segment; + +} ELFUTILS_0.130; + +ELFUTILS_0.138 { + global: + # Replaced ELFUTILS_0.130 version, which has bug-compatibility wrapper. + dwfl_module_build_id; + +} ELFUTILS_0.136; + +ELFUTILS_0.142 { + global: + dwarf_next_cfi; + dwarf_getcfi; + dwarf_getcfi_elf; + dwarf_cfi_addrframe; + dwarf_cfi_end; + dwarf_frame_cfa; + dwarf_frame_register; + dwarf_frame_info; + + dwfl_module_dwarf_cfi; + dwfl_module_eh_cfi; +} ELFUTILS_0.138; + +ELFUTILS_0.143 { + global: + dwarf_getlocation_implicit_value; + + # Replaced ELFUTILS_0.122 versions. Both versions point to the + # same implementation, but users of the new symbol version can + # presume that they use dwarf_attr_integrate properly. + dwarf_arrayorder; + dwarf_bitoffset; + dwarf_bitsize; + dwarf_bytesize; + dwarf_decl_column; + dwarf_decl_file; + dwarf_decl_line; + dwarf_srclang; + +} ELFUTILS_0.142; + +ELFUTILS_0.144 { + global: + dwarf_aggregate_size; +} ELFUTILS_0.143; + +ELFUTILS_0.146 { + global: + dwfl_core_file_report; +} ELFUTILS_0.144; + +ELFUTILS_0.148 { + global: + dwarf_lineisa; + dwarf_linediscriminator; + dwarf_lineop_index; + + dwarf_next_unit; + dwarf_offdie_types; +} ELFUTILS_0.146; + +ELFUTILS_0.149 { + global: + dwarf_getlocation_implicit_pointer; + + dwfl_dwarf_line; +} ELFUTILS_0.148; + +ELFUTILS_0.156 { + global: + # Replaced ELFUTILS_0.122 version, which has a wrapper without add_p_vaddr. + dwfl_report_elf; +} ELFUTILS_0.149; + +ELFUTILS_0.157 { + global: + dwarf_getlocations; + dwarf_getlocation_die; + dwarf_getlocation_attr; +} ELFUTILS_0.156; + +ELFUTILS_0.158 { + global: + # Replaced ELFUTILS_0.146 version, which has a wrapper without executable. + dwfl_core_file_report; + + dwfl_attach_state; + dwfl_pid; + dwfl_thread_dwfl; + dwfl_thread_tid; + dwfl_frame_thread; + dwfl_thread_state_registers; + dwfl_thread_state_register_pc; + dwfl_getthread_frames; + dwfl_getthreads; + dwfl_thread_getframes; + dwfl_frame_pc; + + dwfl_module_getsymtab_first_global; + dwfl_module_addrinfo; + dwfl_module_getsym_info; + + dwfl_core_file_attach; + dwfl_linux_proc_attach; +} ELFUTILS_0.157; + +ELFUTILS_0.159 { + global: + dwarf_getalt; + dwarf_setalt; + dwelf_dwarf_gnu_debugaltlink; + dwelf_elf_gnu_debuglink; + dwelf_elf_gnu_build_id; +} ELFUTILS_0.158; + +ELFUTILS_0.160 { + global: + dwarf_cu_getdwarf; + dwarf_cu_die; +} ELFUTILS_0.159; + +ELFUTILS_0.161 { + global: + dwarf_peel_type; + + # Replaced ELFUTILS_0.144 version. Both versions point to the + # same implementation, but users of the new symbol version can + # presume that it uses dwarf_peel_type. + dwarf_aggregate_size; + + dwarf_getmacros_off; + dwarf_macro_getsrcfiles; + dwarf_macro_getparamcnt; + dwarf_macro_param; +} ELFUTILS_0.160; + +ELFUTILS_0.165 { + global: + dwelf_scn_gnu_compressed_size; +} ELFUTILS_0.161; + +ELFUTILS_0.167 { + global: + dwelf_strtab_init; + dwelf_strtab_add; + dwelf_strtab_add_len; + dwelf_strtab_finalize; + dwelf_strent_off; + dwelf_strent_str; + dwelf_strtab_free; +} ELFUTILS_0.165; + +ELFUTILS_0.170 { + global: + dwarf_default_lower_bound; + dwarf_line_file; +} ELFUTILS_0.167; + +ELFUTILS_0.171 { + global: + dwarf_die_addr_die; + dwarf_get_units; + dwarf_getabbrevattr_data; + dwarf_cu_info; +} ELFUTILS_0.170; + +ELFUTILS_0.173 { + global: + dwarf_next_lines; +} ELFUTILS_0.171; + +ELFUTILS_0.175 { + global: + dwelf_elf_begin; +} ELFUTILS_0.173; + +ELFUTILS_0.177 { + global: + dwelf_elf_e_machine_string; + # Replaced ELFUTILS_0.175 versions. Both versions point to the + # same implementation, but users of the new symbol version can + # presume that NULL is only returned on error (otherwise ELF_K_NONE). + dwelf_elf_begin; +} ELFUTILS_0.175; diff --git a/libdw/libdwP.h b/libdw/libdwP.h new file mode 100644 index 00000000..7174ea93 --- /dev/null +++ b/libdw/libdwP.h @@ -0,0 +1,1389 @@ +/* Internal definitions for libdw. + Copyright (C) 2002-2011, 2013-2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBDWP_H +#define _LIBDWP_H 1 + +#include +#include +#include + +#include +#include +#include "atomics.h" + + +/* Known location expressions already decoded. */ +struct loc_s +{ + void *addr; + Dwarf_Op *loc; + size_t nloc; +}; + +/* Known DW_OP_implicit_value blocks already decoded. + This overlaps struct loc_s exactly, but only the + first member really has to match. */ +struct loc_block_s +{ + void *addr; + unsigned char *data; + size_t length; +}; + +/* Already decoded .debug_line units. */ +struct files_lines_s +{ + Dwarf_Off debug_line_offset; + Dwarf_Files *files; + Dwarf_Lines *lines; +}; + +/* Valid indices for the section data. */ +enum + { + IDX_debug_info = 0, + IDX_debug_types, + IDX_debug_abbrev, + IDX_debug_aranges, + IDX_debug_addr, + IDX_debug_line, + IDX_debug_line_str, + IDX_debug_frame, + IDX_debug_loc, + IDX_debug_loclists, + IDX_debug_pubnames, + IDX_debug_str, + IDX_debug_str_offsets, + IDX_debug_macinfo, + IDX_debug_macro, + IDX_debug_ranges, + IDX_debug_rnglists, + IDX_gnu_debugaltlink, + IDX_last + }; + + +/* Error values. */ +enum +{ + DWARF_E_NOERROR = 0, + DWARF_E_UNKNOWN_ERROR, + DWARF_E_INVALID_ACCESS, + DWARF_E_NO_REGFILE, + DWARF_E_IO_ERROR, + DWARF_E_INVALID_ELF, + DWARF_E_NO_DWARF, + DWARF_E_COMPRESSED_ERROR, + DWARF_E_NOELF, + DWARF_E_GETEHDR_ERROR, + DWARF_E_NOMEM, + DWARF_E_UNIMPL, + DWARF_E_INVALID_CMD, + DWARF_E_INVALID_VERSION, + DWARF_E_INVALID_FILE, + DWARF_E_NO_ENTRY, + DWARF_E_INVALID_DWARF, + DWARF_E_NO_STRING, + DWARF_E_NO_DEBUG_STR, + DWARF_E_NO_DEBUG_LINE_STR, + DWARF_E_NO_STR_OFFSETS, + DWARF_E_NO_ADDR, + DWARF_E_NO_CONSTANT, + DWARF_E_NO_REFERENCE, + DWARF_E_INVALID_REFERENCE, + DWARF_E_NO_DEBUG_LINE, + DWARF_E_INVALID_DEBUG_LINE, + DWARF_E_TOO_BIG, + DWARF_E_VERSION, + DWARF_E_INVALID_DIR_IDX, + DWARF_E_ADDR_OUTOFRANGE, + DWARF_E_NO_DEBUG_LOC, + DWARF_E_NO_DEBUG_LOCLISTS, + DWARF_E_NO_LOC_VALUE, + DWARF_E_NO_BLOCK, + DWARF_E_INVALID_LINE_IDX, + DWARF_E_INVALID_ARANGE_IDX, + DWARF_E_NO_MATCH, + DWARF_E_NO_FLAG, + DWARF_E_INVALID_OFFSET, + DWARF_E_NO_DEBUG_RANGES, + DWARF_E_NO_DEBUG_RNGLISTS, + DWARF_E_INVALID_CFI, + DWARF_E_NO_ALT_DEBUGLINK, + DWARF_E_INVALID_OPCODE, + DWARF_E_NOT_CUDIE, + DWARF_E_UNKNOWN_LANGUAGE, + DWARF_E_NO_DEBUG_ADDR, +}; + + +#include "dwarf_sig8_hash.h" + +/* This is the structure representing the debugging state. */ +struct Dwarf +{ + /* The underlying ELF file. */ + Elf *elf; + + /* The (absolute) path to the ELF dir, if known. To help locating + alt and dwo files. */ + char *debugdir; + + /* dwz alternate DWARF file. */ + Dwarf *alt_dwarf; + + /* The section data. */ + Elf_Data *sectiondata[IDX_last]; + + /* True if the file has a byte order different from the host. */ + bool other_byte_order; + + /* If true, we allocated the ELF descriptor ourselves. */ + bool free_elf; + + /* If >= 0, we allocated the alt_dwarf ourselves and must end it and + close this file descriptor. */ + int alt_fd; + + /* Information for traversing the .debug_pubnames section. This is + an array and separately allocated with malloc. */ + struct pubnames_s + { + Dwarf_Off cu_offset; + Dwarf_Off set_start; + unsigned int cu_header_size; + int address_len; + } *pubnames_sets; + size_t pubnames_nsets; + + /* Search tree for the CUs. */ + void *cu_tree; + Dwarf_Off next_cu_offset; + + /* Search tree and sig8 hash table for .debug_types type units. */ + void *tu_tree; + Dwarf_Off next_tu_offset; + Dwarf_Sig8_Hash sig8_hash; + + /* Search tree for split Dwarf associated with CUs in this debug. */ + void *split_tree; + + /* Search tree for .debug_macro operator tables. */ + void *macro_ops; + + /* Search tree for decoded .debug_line units. */ + void *files_lines; + + /* Address ranges. */ + Dwarf_Aranges *aranges; + + /* Cached info from the CFI section. */ + struct Dwarf_CFI_s *cfi; + + /* Fake loc CU. Used when synthesizing attributes for Dwarf_Ops that + came from a location list entry in dwarf_getlocation_attr. + Depending on version this is the .debug_loc or .debug_loclists + section (could be both if mixing CUs with different DWARF versions). */ + struct Dwarf_CU *fake_loc_cu; + struct Dwarf_CU *fake_loclists_cu; + + /* Similar for addrx/constx, which will come from .debug_addr section. */ + struct Dwarf_CU *fake_addr_cu; + + /* Supporting lock for internal memory handling. Ensures threads that have + an entry in the mem_tails array are not disturbed by new threads doing + allocations for this Dwarf. */ + pthread_rwlock_t mem_rwl; + + /* Internal memory handling. This is basically a simplified thread-local + reimplementation of obstacks. Unfortunately the standard obstack + implementation is not usable in libraries. */ + size_t mem_stacks; + struct libdw_memblock + { + size_t size; + size_t remaining; + struct libdw_memblock *prev; + char mem[0]; + } **mem_tails; + + /* Default size of allocated memory blocks. */ + size_t mem_default_size; + + /* Registered OOM handler. */ + Dwarf_OOM oom_handler; +}; + + +/* Abbreviation representation. */ +struct Dwarf_Abbrev +{ + Dwarf_Off offset; /* Offset to start of abbrev into .debug_abbrev. */ + unsigned char *attrp; /* Pointer to start of attribute name/form pairs. */ + bool has_children : 1; /* Whether or not the DIE has children. */ + unsigned int code : 31; /* The (unique) abbrev code. */ + unsigned int tag; /* The tag of the DIE. */ +} attribute_packed; + +#include "dwarf_abbrev_hash.h" + + +/* Files in line information records. */ +struct Dwarf_Files_s + { + unsigned int ndirs; + unsigned int nfiles; + struct Dwarf_Fileinfo_s + { + char *name; + Dwarf_Word mtime; + Dwarf_Word length; + } info[0]; + /* nfiles of those, followed by char *[ndirs]. */ + }; +typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; + + +/* Representation of a row in the line table. */ + +struct Dwarf_Line_s +{ + Dwarf_Files *files; + + Dwarf_Addr addr; + unsigned int file; + int line; + unsigned short int column; + unsigned int is_stmt:1; + unsigned int basic_block:1; + unsigned int end_sequence:1; + unsigned int prologue_end:1; + unsigned int epilogue_begin:1; + /* The remaining bit fields are not flags, but hold values presumed to be + small. All the flags and other bit fields should add up to 48 bits + to give the whole struct a nice round size. */ + unsigned int op_index:8; + unsigned int isa:8; + unsigned int discriminator:24; +}; + +struct Dwarf_Lines_s +{ + size_t nlines; + struct Dwarf_Line_s info[0]; +}; + +/* Representation of address ranges. */ +struct Dwarf_Aranges_s +{ + Dwarf *dbg; + size_t naranges; + + struct Dwarf_Arange_s + { + Dwarf_Addr addr; + Dwarf_Word length; + Dwarf_Off offset; + } info[0]; +}; + + +/* CU representation. */ +struct Dwarf_CU +{ + Dwarf *dbg; + Dwarf_Off start; + Dwarf_Off end; + uint8_t address_size; + uint8_t offset_size; + uint16_t version; + + size_t sec_idx; /* Normally .debug_info, could be .debug_type or "fake". */ + + /* The unit type if version >= 5. Otherwise 0 for normal CUs (from + .debug_info) or 1 for v4 type units (from .debug_types). */ + uint8_t unit_type; + + /* Zero if the unit type doesn't support a die/type offset and/or id/sig. + Nonzero if it is a v4 type unit or for DWARFv5 units depending on + unit_type. */ + size_t subdie_offset; + uint64_t unit_id8; + + /* If this is a skeleton unit this points to the split compile unit. + Or the other way around if this is a split compile unit. Set to -1 + if not yet searched. Always use __libdw_find_split_unit to access + this field. */ + struct Dwarf_CU *split; + + /* Hash table for the abbreviations. */ + Dwarf_Abbrev_Hash abbrev_hash; + /* Offset of the first abbreviation. */ + size_t orig_abbrev_offset; + /* Offset past last read abbreviation. */ + size_t last_abbrev_offset; + + /* The srcline information. */ + Dwarf_Lines *lines; + + /* The source file information. */ + Dwarf_Files *files; + + /* Known location lists. */ + void *locs; + + /* Base address for use with ranges and locs. + Don't access directly, call __libdw_cu_base_address. */ + Dwarf_Addr base_address; + + /* The offset into the .debug_addr section where index zero begins. + Don't access directly, call __libdw_cu_addr_base. */ + Dwarf_Off addr_base; + + /* The offset into the .debug_str_offsets section where index zero begins. + Don't access directly, call __libdw_cu_str_off_base. */ + Dwarf_Off str_off_base; + + /* The offset into the .debug_ranges section to use for GNU + DebugFission split units. Don't access directly, call + __libdw_cu_ranges_base. */ + Dwarf_Off ranges_base; + + /* The start of the offset table in .debug_loclists. + Don't access directly, call __libdw_cu_locs_base. */ + Dwarf_Off locs_base; + + /* Memory boundaries of this CU. */ + void *startp; + void *endp; +}; + +#define ISV4TU(cu) ((cu)->version == 4 && (cu)->sec_idx == IDX_debug_types) + +/* Compute the offset of a CU's first DIE from the CU offset. + CU must be a valid/known version/unit_type. */ +static inline Dwarf_Off +__libdw_first_die_from_cu_start (Dwarf_Off cu_start, + uint8_t offset_size, + uint16_t version, + uint8_t unit_type) +{ +/* + assert (offset_size == 4 || offset_size == 8); + assert (version >= 2 && version <= 5); + assert (unit_type == DW_UT_compile + || unit_type == DW_UT_partial + || unit_type == DW_UT_skeleton + || unit_type == DW_UT_split_compile + || unit_type == DW_UT_type + || unit_type == DW_UT_split_type); +*/ + + Dwarf_Off off = cu_start; + if (version < 5) + { + /* + LEN VER OFFSET ADDR + 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf + 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf + or in .debug_types, SIGNATURE TYPE-OFFSET + 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit + 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit + + Note the trick in the computation. If the offset_size is 4 + the '- 4' term changes the '3 *' (or '4 *') into a '2 *' (or '3 *). + If the offset_size is 8 it accounts for the 4-byte escape value + used at the start of the length. */ + if (unit_type != DW_UT_type) + off += 3 * offset_size - 4 + 3; + else + off += 4 * offset_size - 4 + 3 + 8; + } + else + { + /* + LEN VER TYPE ADDR OFFSET SIGNATURE TYPE-OFFSET + 4-bytes + 2-bytes + 1-byte + 1-byte + 4-bytes + 8-bytes + 4-bytes 32-bit + 12-bytes + 2-bytes + 1-byte + 1-byte + 8-bytes + 8-bytes + 8-bytes 64-bit + Both signature and type offset are optional. + + Note same 4/8 offset size trick as above. + We explicitly ignore unknown unit types (see asserts above). */ + off += 3 * offset_size - 4 + 4; + if (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile + || unit_type == DW_UT_type || unit_type == DW_UT_split_type) + { + off += 8; + if (unit_type == DW_UT_type || unit_type == DW_UT_split_type) + off += offset_size; + } + } + + return off; +} + +static inline Dwarf_Off +__libdw_first_die_off_from_cu (struct Dwarf_CU *cu) +{ + return __libdw_first_die_from_cu_start (cu->start, + cu->offset_size, + cu->version, + cu->unit_type); +} + +#define CUDIE(fromcu) \ + ((Dwarf_Die) \ + { \ + .cu = (fromcu), \ + .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ + + __libdw_first_die_off_from_cu (fromcu)) \ + }) + +#define SUBDIE(fromcu) \ + ((Dwarf_Die) \ + { \ + .cu = (fromcu), \ + .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ + + (fromcu)->start + (fromcu)->subdie_offset) \ + }) + + +/* Prototype of a single .debug_macro operator. */ +typedef struct +{ + Dwarf_Word nforms; + unsigned char const *forms; +} Dwarf_Macro_Op_Proto; + +/* Prototype table. */ +typedef struct +{ + /* Offset of .debug_macro section. */ + Dwarf_Off offset; + + /* Offset of associated .debug_line section. */ + Dwarf_Off line_offset; + + /* The source file information. */ + Dwarf_Files *files; + + /* If this macro unit was opened through dwarf_getmacros or + dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if + present. */ + const char *comp_dir; + + /* Header length. */ + Dwarf_Half header_len; + + uint16_t version; + bool is_64bit; + uint8_t sec_index; /* IDX_debug_macro or IDX_debug_macinfo. */ + + /* Shows where in TABLE each opcode is defined. Since opcode 0 is + never used, it stores index of opcode X in X-1'th element. The + value of 0xff means not stored at all. */ + unsigned char opcodes[255]; + + /* Individual opcode prototypes. */ + Dwarf_Macro_Op_Proto table[]; +} Dwarf_Macro_Op_Table; + +struct Dwarf_Macro_s +{ + Dwarf_Macro_Op_Table *table; + Dwarf_Attribute *attributes; + uint8_t opcode; +}; + +static inline Dwarf_Word +libdw_macro_nforms (Dwarf_Macro *macro) +{ + return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms; +} + +/* Returns true for any allowed FORM in the opcode_operands_table as + mentioned in the DWARF5 spec (6.3.1 Macro Information Header). + Or those mentioned in DWARF5 spec (6.2.4.2 Vendor-defined Content + Descriptions) for the directory/file table (plus DW_FORM_strp_sup). */ +static inline bool +libdw_valid_user_form (int form) +{ + switch (form) + { + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_data16: + case DW_FORM_flag: + case DW_FORM_line_strp: + case DW_FORM_sdata: + case DW_FORM_sec_offset: + case DW_FORM_string: + case DW_FORM_strp: + case DW_FORM_strp_sup: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + case DW_FORM_udata: + return true; + default: + return false; + } +} + + +/* We have to include the file at this point because the inline + functions access internals of the Dwarf structure. */ +#include "memory-access.h" + + +/* Set error value. */ +extern void __libdw_seterrno (int value) internal_function; + + +/* Memory handling, the easy parts. */ +#define libdw_alloc(dbg, type, tsize, cnt) \ + ({ struct libdw_memblock *_tail = __libdw_alloc_tail(dbg); \ + size_t _required = (tsize) * (cnt); \ + type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\ + size_t _padding = ((__alignof (type) \ + - ((uintptr_t) _result & (__alignof (type) - 1))) \ + & (__alignof (type) - 1)); \ + if (unlikely (_tail->remaining < _required + _padding)) \ + _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\ + else \ + { \ + _required += _padding; \ + _result = (type *) ((char *) _result + _padding); \ + _tail->remaining -= _required; \ + } \ + _result; }) + +#define libdw_typed_alloc(dbg, type) \ + libdw_alloc (dbg, type, sizeof (type), 1) + +/* Can only be used to undo the last libdw_alloc. */ +#define libdw_unalloc(dbg, type, tsize, cnt) \ + ({ struct libdw_memblock *_tail = __libdw_thread_tail (dbg); \ + size_t _required = (tsize) * (cnt); \ + /* We cannot know the padding, it is lost. */ \ + _tail->remaining += _required; }) \ + +#define libdw_typed_unalloc(dbg, type) \ + libdw_unalloc (dbg, type, sizeof (type), 1) + +/* Callback to choose a thread-local memory allocation stack. */ +extern struct libdw_memblock *__libdw_alloc_tail (Dwarf* dbg) + __nonnull_attribute__ (1); + +extern struct libdw_memblock *__libdw_thread_tail (Dwarf* dbg) + __nonnull_attribute__ (1); + +/* Callback to allocate more. */ +extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) + __attribute__ ((__malloc__)) __nonnull_attribute__ (1); + +/* Default OOM handler. */ +extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden; + +/* Read next unit (or v4 debug type) and return next offset. Doesn't + create an actual Dwarf_CU just provides necessary header fields. */ +extern int +internal_function +__libdw_next_unit (Dwarf *dbg, bool v4_debug_types, Dwarf_Off off, + Dwarf_Off *next_off, size_t *header_sizep, + Dwarf_Half *versionp, uint8_t *unit_typep, + Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, + uint8_t *offset_sizep, uint64_t *unit_id8p, + Dwarf_Off *subdie_offsetp) + __nonnull_attribute__ (4) internal_function; + +/* Allocate the internal data for a unit not seen before. */ +extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types) + __nonnull_attribute__ (1) internal_function; + +/* Find CU for given offset. */ +extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu) + __nonnull_attribute__ (1) internal_function; + +/* Find CU for given DIE address. */ +extern struct Dwarf_CU *__libdw_findcu_addr (Dwarf *dbg, void *addr) + __nonnull_attribute__ (1) internal_function; + +/* Find split Dwarf for given DIE address. */ +extern struct Dwarf *__libdw_find_split_dbg_addr (Dwarf *dbg, void *addr) + __nonnull_attribute__ (1) internal_function; + +/* Find the split (or skeleton) unit. */ +extern struct Dwarf_CU *__libdw_find_split_unit (Dwarf_CU *cu) + internal_function; + +/* Get abbreviation with given code. */ +extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, + unsigned int code) + __nonnull_attribute__ (1) internal_function; + +/* Get abbreviation at given offset. */ +extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, + Dwarf_Off offset, size_t *lengthp, + Dwarf_Abbrev *result) + __nonnull_attribute__ (1) internal_function; + +/* Get abbreviation of given DIE, and optionally set *READP to the DIE memory + just past the abbreviation code. */ +static inline Dwarf_Abbrev * +__nonnull_attribute__ (1) +__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) +{ + /* Do we need to get the abbreviation, or need to read after the code? */ + if (die->abbrev == NULL || readp != NULL) + { + /* Get the abbreviation code. */ + unsigned int code; + const unsigned char *addr = die->addr; + if (unlikely (die->cu == NULL + || addr >= (const unsigned char *) die->cu->endp)) + return die->abbrev = DWARF_END_ABBREV; + get_uleb128 (code, addr, die->cu->endp); + if (readp != NULL) + *readp = addr; + + /* Find the abbreviation. */ + if (die->abbrev == NULL) + die->abbrev = __libdw_findabbrev (die->cu, code); + } + return die->abbrev; +} + +/* Helper functions for form handling. */ +extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu, + unsigned int form, + const unsigned char *valp) + __nonnull_attribute__ (1, 3) internal_function; + +/* Find the length of a form attribute in DIE/info data. */ +static inline size_t +__nonnull_attribute__ (1, 3) +__libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form, + const unsigned char *valp) +{ + /* Small lookup table of forms with fixed lengths. Absent indexes are + initialized 0, so any truly desired 0 is set to 0x80 and masked. */ + static const uint8_t form_lengths[] = + { + [DW_FORM_flag_present] = 0x80, + [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info. */ + + [DW_FORM_flag] = 1, + [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, + [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1, + + [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2, + [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2, + + [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3, + + [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4, + [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4, + + [DW_FORM_ref_sig8] = 8, + [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8, + + [DW_FORM_data16] = 16, + }; + + /* Return immediately for forms with fixed lengths. */ + if (form < sizeof form_lengths / sizeof form_lengths[0]) + { + uint8_t len = form_lengths[form]; + if (len != 0) + { + const unsigned char *endp = cu->endp; + len &= 0x7f; /* Mask to allow 0x80 -> 0. */ + if (unlikely (len > (size_t) (endp - valp))) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + return len; + } + } + + /* Other forms require some computation. */ + return __libdw_form_val_compute_len (cu, form, valp); +} + +/* Helper function for DW_FORM_ref* handling. */ +extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) + __nonnull_attribute__ (1, 2) internal_function; + + +/* Helper function to locate attribute. */ +extern unsigned char *__libdw_find_attr (Dwarf_Die *die, + unsigned int search_name, + unsigned int *codep, + unsigned int *formp) + __nonnull_attribute__ (1) internal_function; + +/* Helper function to access integer attribute. */ +extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval) + __nonnull_attribute__ (1, 2) internal_function; + +/* Helper function to walk scopes. */ +struct Dwarf_Die_Chain +{ + Dwarf_Die die; + struct Dwarf_Die_Chain *parent; + bool prune; /* The PREVISIT function can set this. */ +}; +extern int __libdw_visit_scopes (unsigned int depth, + struct Dwarf_Die_Chain *root, + struct Dwarf_Die_Chain *imports, + int (*previsit) (unsigned int depth, + struct Dwarf_Die_Chain *, + void *arg), + int (*postvisit) (unsigned int depth, + struct Dwarf_Die_Chain *, + void *arg), + void *arg) + __nonnull_attribute__ (2, 4) internal_function; + +/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's, + and cache the result (via tsearch). */ +extern int __libdw_intern_expression (Dwarf *dbg, + bool other_byte_order, + unsigned int address_size, + unsigned int ref_size, + void **cache, const Dwarf_Block *block, + bool cfap, bool valuep, + Dwarf_Op **llbuf, size_t *listlen, + int sec_index) + __nonnull_attribute__ (5, 6, 9, 10) internal_function; + +extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset, + Dwarf_Die *result, bool debug_types) + internal_function; + + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int __dwarf_errno_internal (void); + + +/* Reader hooks. */ + +/* Relocation hooks return -1 on error (in that case the error code + must already have been set), 0 if there is no relocation and 1 if a + relocation was present.*/ + +static inline int +__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)), + int sec_index __attribute__ ((unused)), + const void *addr __attribute__ ((unused)), + int width __attribute__ ((unused)), + Dwarf_Addr *val __attribute__ ((unused))) +{ + return 0; +} + +static inline int +__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)), + int sec_index __attribute__ ((unused)), + const void *addr __attribute__ ((unused)), + int width __attribute__ ((unused)), + Dwarf_Off *val __attribute__ ((unused))) +{ + return 0; +} + +static inline Elf_Data * +__libdw_checked_get_data (Dwarf *dbg, int sec_index) +{ + Elf_Data *data = dbg->sectiondata[sec_index]; + if (unlikely (data == NULL) + || unlikely (data->d_buf == NULL)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + return data; +} + +static inline int +__libdw_offset_in_section (Dwarf *dbg, int sec_index, + Dwarf_Off offset, size_t size) +{ + Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); + if (data == NULL) + return -1; + if (unlikely (offset > data->d_size) + || unlikely (data->d_size < size) + || unlikely (offset > data->d_size - size)) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1; + } + + return 0; +} + +static inline bool +__libdw_in_section (Dwarf *dbg, int sec_index, + const void *addr, size_t size) +{ + Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); + if (data == NULL) + return false; + if (unlikely (addr < data->d_buf) + || unlikely (data->d_size < size) + || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size)) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return false; + } + + return true; +} + +#define READ_AND_RELOCATE(RELOC_HOOK, VAL) \ + ({ \ + if (!__libdw_in_section (dbg, sec_index, addr, width)) \ + return -1; \ + \ + const unsigned char *orig_addr = addr; \ + if (width == 4) \ + VAL = read_4ubyte_unaligned_inc (dbg, addr); \ + else \ + VAL = read_8ubyte_unaligned_inc (dbg, addr); \ + \ + int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \ + if (status < 0) \ + return status; \ + status > 0; \ + }) + +static inline int +__libdw_read_address_inc (Dwarf *dbg, + int sec_index, const unsigned char **addrp, + int width, Dwarf_Addr *ret) +{ + const unsigned char *addr = *addrp; + READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); + *addrp = addr; + return 0; +} + +static inline int +__libdw_read_address (Dwarf *dbg, + int sec_index, const unsigned char *addr, + int width, Dwarf_Addr *ret) +{ + READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); + return 0; +} + +static inline int +__libdw_read_offset_inc (Dwarf *dbg, + int sec_index, const unsigned char **addrp, + int width, Dwarf_Off *ret, int sec_ret, + size_t size) +{ + const unsigned char *addr = *addrp; + READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); + *addrp = addr; + return __libdw_offset_in_section (dbg, sec_ret, *ret, size); +} + +static inline int +__libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret, + int sec_index, const unsigned char *addr, + int width, Dwarf_Off *ret, int sec_ret, + size_t size) +{ + READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); + return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size); +} + +static inline size_t +cu_sec_idx (struct Dwarf_CU *cu) +{ + return cu->sec_idx; +} + +static inline bool +is_cudie (Dwarf_Die *cudie) +{ + return cudie->cu != NULL && CUDIE (cudie->cu).addr == cudie->addr; +} + +/* Read up begin/end pair and increment read pointer. + - If it's normal range record, set up *BEGINP and *ENDP and return 0. + - If it's base address selection record, set up *BASEP and return 1. + - If it's end of rangelist, don't set anything and return 2 + - If an error occurs, don't set anything and return <0. */ +int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index, + const unsigned char **readp, + const unsigned char *readend, + int width, + Dwarf_Addr *beginp, Dwarf_Addr *endp, + Dwarf_Addr *basep) + internal_function; + +const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, + int err_nodata, + const unsigned char **endpp, + Dwarf_Off *offsetp) + internal_function; + +/* Fills in the given attribute to point at an empty location expression. */ +void __libdw_empty_loc_attr (Dwarf_Attribute *attr) + internal_function; + +/* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of + DW_AT_comp_dir or NULL if that attribute is not available. Caches + the loaded unit and optionally set *LINESP and/or *FILESP (if not + NULL) with loaded information. Returns 0 for success or a negative + value for failure. */ +int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, + const char *comp_dir, unsigned address_size, + Dwarf_Lines **linesp, Dwarf_Files **filesp) + internal_function + __nonnull_attribute__ (1); + +/* Load and return value of DW_AT_comp_dir from CUDIE. */ +const char *__libdw_getcompdir (Dwarf_Die *cudie); + +/* Get the base address for the CU, fetches it when not yet set. + This is used as initial base address for ranges and loclists. */ +Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu); + +/* Get the address base for the CU, fetches it when not yet set. */ +static inline Dwarf_Off +__libdw_cu_addr_base (Dwarf_CU *cu) +{ + if (cu->addr_base == (Dwarf_Off) -1) + { + Dwarf_Die cu_die = CUDIE(cu); + Dwarf_Attribute attr; + Dwarf_Off offset = 0; + if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL + || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL) + { + Dwarf_Word off; + if (dwarf_formudata (&attr, &off) == 0) + offset = off; + } + cu->addr_base = offset; + } + + return cu->addr_base; +} + +/* Gets the .debug_str_offsets base offset to use. static inline to + be shared between libdw and eu-readelf. */ +static inline Dwarf_Off +str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu) +{ + /* If we don't have a CU, then find and use the first one in the + debug file (when we support .dwp files, we must actually find the + one matching our "caller" - aka macro or line). If we (now) have + a cu and str_offsets_base attribute, just use that. Otherwise + use the first offset. But we might have to parse the header + first, but only if this is version 5. Assume if all else fails, + this is version 4, without header. */ + + if (cu == NULL && dbg != NULL) + { + Dwarf_CU *first_cu; + if (dwarf_get_units (dbg, NULL, &first_cu, + NULL, NULL, NULL, NULL) == 0) + cu = first_cu; + } + + if (cu != NULL) + { + if (cu->str_off_base == (Dwarf_Off) -1) + { + Dwarf_Die cu_die = CUDIE(cu); + Dwarf_Attribute attr; + if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL) + { + Dwarf_Word off; + if (dwarf_formudata (&attr, &off) == 0) + { + cu->str_off_base = off; + return cu->str_off_base; + } + } + /* For older DWARF simply assume zero (no header). */ + if (cu->version < 5) + { + cu->str_off_base = 0; + return cu->str_off_base; + } + + if (dbg == NULL) + dbg = cu->dbg; + } + else + return cu->str_off_base; + } + + /* No str_offsets_base attribute, we have to assume "zero". + But there could be a header first. */ + Dwarf_Off off = 0; + if (dbg == NULL) + goto no_header; + + Elf_Data *data = dbg->sectiondata[IDX_debug_str_offsets]; + if (data == NULL) + goto no_header; + + const unsigned char *start; + const unsigned char *readp; + const unsigned char *readendp; + start = readp = (const unsigned char *) data->d_buf; + readendp = (const unsigned char *) data->d_buf + data->d_size; + + uint64_t unit_length; + uint16_t version; + + unit_length = read_4ubyte_unaligned_inc (dbg, readp); + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readendp - readp < 8)) + goto no_header; + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + /* In theory the offset size could be different + between CU and str_offsets unit. But we just + ignore that here. */ + } + + /* We need at least 2-bytes (version) + 2-bytes (padding) = + 4 bytes to complete the header. And this unit cannot go + beyond the section data. */ + if (readendp - readp < 4 + || unit_length < 4 + || (uint64_t) (readendp - readp) < unit_length) + goto no_header; + + version = read_2ubyte_unaligned_inc (dbg, readp); + if (version != 5) + goto no_header; + /* padding */ + read_2ubyte_unaligned_inc (dbg, readp); + + off = (Dwarf_Off) (readp - start); + + no_header: + if (cu != NULL) + cu->str_off_base = off; + + return off; +} + + +/* Get the string offsets base for the CU, fetches it when not yet set. */ +static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu) +{ + return str_offsets_base_off (NULL, cu); +} + + +/* Either a direct offset into .debug_ranges for version < 5, or the + start of the offset table in .debug_rnglists for version > 5. */ +static inline Dwarf_Off +__libdw_cu_ranges_base (Dwarf_CU *cu) +{ + if (cu->ranges_base == (Dwarf_Off) -1) + { + Dwarf_Off offset = 0; + Dwarf_Die cu_die = CUDIE(cu); + Dwarf_Attribute attr; + if (cu->version < 5) + { + if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL) + { + Dwarf_Word off; + if (dwarf_formudata (&attr, &off) == 0) + offset = off; + } + } + else + { + if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL) + { + Dwarf_Word off; + if (dwarf_formudata (&attr, &off) == 0) + offset = off; + } + + /* There wasn't an rnglists_base, if the Dwarf does have a + .debug_rnglists section, then it might be we need the + base after the first header. */ + Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists]; + if (offset == 0 && data != NULL) + { + Dwarf *dbg = cu->dbg; + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend + = (unsigned char *) data->d_buf + data->d_size; + + uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int offset_size = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp > dataend - 8)) + goto no_header; + + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + offset_size = 8; + } + + if (readp > dataend - 8 + || unit_length < 8 + || unit_length > (uint64_t) (dataend - readp)) + goto no_header; + + uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); + if (version != 5) + goto no_header; + + uint8_t address_size = *readp++; + if (address_size != 4 && address_size != 8) + goto no_header; + + uint8_t segment_size = *readp++; + if (segment_size != 0) + goto no_header; + + uint32_t offset_entry_count; + offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp); + + const unsigned char *offset_array_start = readp; + if (offset_entry_count <= 0) + goto no_header; + + uint64_t needed = offset_entry_count * offset_size; + if (unit_length - 8 < needed) + goto no_header; + + offset = (Dwarf_Off) (offset_array_start + - (unsigned char *) data->d_buf); + } + } + no_header: + cu->ranges_base = offset; + } + + return cu->ranges_base; +} + + +/* The start of the offset table in .debug_loclists for DWARF5. */ +static inline Dwarf_Off +__libdw_cu_locs_base (Dwarf_CU *cu) +{ + if (cu->locs_base == (Dwarf_Off) -1) + { + Dwarf_Off offset = 0; + Dwarf_Die cu_die = CUDIE(cu); + Dwarf_Attribute attr; + if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL) + { + Dwarf_Word off; + if (dwarf_formudata (&attr, &off) == 0) + offset = off; + } + + /* There wasn't an loclists_base, if the Dwarf does have a + .debug_loclists section, then it might be we need the + base after the first header. */ + Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists]; + if (offset == 0 && data != NULL) + { + Dwarf *dbg = cu->dbg; + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend + = (unsigned char *) data->d_buf + data->d_size; + + uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int offset_size = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp > dataend - 8)) + goto no_header; + + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + offset_size = 8; + } + + if (readp > dataend - 8 + || unit_length < 8 + || unit_length > (uint64_t) (dataend - readp)) + goto no_header; + + uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); + if (version != 5) + goto no_header; + + uint8_t address_size = *readp++; + if (address_size != 4 && address_size != 8) + goto no_header; + + uint8_t segment_size = *readp++; + if (segment_size != 0) + goto no_header; + + uint32_t offset_entry_count; + offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp); + + const unsigned char *offset_array_start = readp; + if (offset_entry_count <= 0) + goto no_header; + + uint64_t needed = offset_entry_count * offset_size; + if (unit_length - 8 < needed) + goto no_header; + + offset = (Dwarf_Off) (offset_array_start + - (unsigned char *) data->d_buf); + } + + no_header: + cu->locs_base = offset; + } + + return cu->locs_base; +} + +/* Helper function for tsearch/tfind split_tree Dwarf. */ +int __libdw_finddbg_cb (const void *arg1, const void *arg2); + +/* Link skeleton and split compile units. */ +static inline void +__libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split) +{ + skel->split = split; + split->split = skel; + + /* Get .debug_addr and addr_base greedy. + We also need it for the fake addr cu. + There is only one per split debug. */ + Dwarf *dbg = skel->dbg; + Dwarf *sdbg = split->dbg; + if (sdbg->sectiondata[IDX_debug_addr] == NULL + && dbg->sectiondata[IDX_debug_addr] != NULL) + { + sdbg->sectiondata[IDX_debug_addr] + = dbg->sectiondata[IDX_debug_addr]; + split->addr_base = __libdw_cu_addr_base (skel); + sdbg->fake_addr_cu = dbg->fake_addr_cu; + } +} + + +/* Given an address index for a CU return the address. + Returns -1 and sets libdw_errno if an error occurs. */ +int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr); + + +/* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf + and libdwfl process_file. */ +char * __libdw_debugdir (int fd); + + +/* Given the directory of a debug file, an absolute or relative dir + to look in, and file returns a full path. + + If the file is absolute (starts with a /) a copy of file is returned. + the file isn't absolute, but dir is absolute, then a path that is + the concatenation of dir and file is returned. If neither file, + nor dir is absolute, the path will be constructed using dir (if not + NULL) and file relative to the debugdir (if valid). + + The debugdir and the dir may be NULL (in which case they aren't used). + If file is NULL, or no full path can be constructed NULL is returned. + + The caller is responsible for freeing the result if not NULL. */ +char * __libdw_filepath (const char *debugdir, const char *dir, + const char *file) + internal_function; + + +/* Aliases to avoid PLTs. */ +INTDECL (dwarf_aggregate_size) +INTDECL (dwarf_attr) +INTDECL (dwarf_attr_integrate) +INTDECL (dwarf_begin) +INTDECL (dwarf_begin_elf) +INTDECL (dwarf_child) +INTDECL (dwarf_default_lower_bound) +INTDECL (dwarf_dieoffset) +INTDECL (dwarf_diename) +INTDECL (dwarf_end) +INTDECL (dwarf_entrypc) +INTDECL (dwarf_errmsg) +INTDECL (dwarf_formaddr) +INTDECL (dwarf_formblock) +INTDECL (dwarf_formref_die) +INTDECL (dwarf_formsdata) +INTDECL (dwarf_formstring) +INTDECL (dwarf_formudata) +INTDECL (dwarf_getabbrevattr_data) +INTDECL (dwarf_getalt) +INTDECL (dwarf_getarange_addr) +INTDECL (dwarf_getarangeinfo) +INTDECL (dwarf_getaranges) +INTDECL (dwarf_getlocation_die) +INTDECL (dwarf_getsrcfiles) +INTDECL (dwarf_getsrclines) +INTDECL (dwarf_hasattr) +INTDECL (dwarf_haschildren) +INTDECL (dwarf_haspc) +INTDECL (dwarf_highpc) +INTDECL (dwarf_lowpc) +INTDECL (dwarf_nextcu) +INTDECL (dwarf_next_unit) +INTDECL (dwarf_offdie) +INTDECL (dwarf_peel_type) +INTDECL (dwarf_ranges) +INTDECL (dwarf_setalt) +INTDECL (dwarf_siblingof) +INTDECL (dwarf_srclang) +INTDECL (dwarf_tag) + +#endif /* libdwP.h */ diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c new file mode 100644 index 00000000..b3e53343 --- /dev/null +++ b/libdw/libdw_alloc.c @@ -0,0 +1,156 @@ +/* Memory handling for libdw. + Copyright (C) 2003, 2004, 2006 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" +#include "system.h" +#include "atomics.h" +#if USE_VG_ANNOTATIONS == 1 +#include +#else +#define ANNOTATE_HAPPENS_BEFORE(X) +#define ANNOTATE_HAPPENS_AFTER(X) +#endif + +#define THREAD_ID_UNSET ((size_t) -1) +static __thread size_t thread_id = THREAD_ID_UNSET; +static atomic_size_t next_id = ATOMIC_VAR_INIT(0); + +struct libdw_memblock * +__libdw_alloc_tail (Dwarf *dbg) +{ + if (thread_id == THREAD_ID_UNSET) + thread_id = atomic_fetch_add (&next_id, 1); + + pthread_rwlock_rdlock (&dbg->mem_rwl); + if (thread_id >= dbg->mem_stacks) + { + pthread_rwlock_unlock (&dbg->mem_rwl); + pthread_rwlock_wrlock (&dbg->mem_rwl); + + /* Another thread may have already reallocated. In theory using an + atomic would be faster, but given that this only happens once per + thread per Dwarf, some minor slowdown should be fine. */ + if (thread_id >= dbg->mem_stacks) + { + dbg->mem_tails = realloc (dbg->mem_tails, (thread_id+1) + * sizeof (struct libdw_memblock *)); + if (dbg->mem_tails == NULL) + { + pthread_rwlock_unlock (&dbg->mem_rwl); + dbg->oom_handler(); + } + for (size_t i = dbg->mem_stacks; i <= thread_id; i++) + dbg->mem_tails[i] = NULL; + dbg->mem_stacks = thread_id + 1; + ANNOTATE_HAPPENS_BEFORE (&dbg->mem_tails); + } + + pthread_rwlock_unlock (&dbg->mem_rwl); + pthread_rwlock_rdlock (&dbg->mem_rwl); + } + + /* At this point, we have an entry in the tail array. */ + ANNOTATE_HAPPENS_AFTER (&dbg->mem_tails); + struct libdw_memblock *result = dbg->mem_tails[thread_id]; + if (result == NULL) + { + result = malloc (dbg->mem_default_size); + if (result == NULL) + { + pthread_rwlock_unlock (&dbg->mem_rwl); + dbg->oom_handler(); + } + result->size = dbg->mem_default_size + - offsetof (struct libdw_memblock, mem); + result->remaining = result->size; + result->prev = NULL; + dbg->mem_tails[thread_id] = result; + } + pthread_rwlock_unlock (&dbg->mem_rwl); + return result; +} + +/* Can only be called after a allocation for this thread has already + been done, to possibly undo it. */ +struct libdw_memblock * +__libdw_thread_tail (Dwarf *dbg) +{ + struct libdw_memblock *result; + pthread_rwlock_rdlock (&dbg->mem_rwl); + result = dbg->mem_tails[thread_id]; + pthread_rwlock_unlock (&dbg->mem_rwl); + return result; +} + +void * +__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) +{ + size_t size = MAX (dbg->mem_default_size, + (align - 1 + + 2 * minsize + offsetof (struct libdw_memblock, mem))); + struct libdw_memblock *newp = malloc (size); + if (newp == NULL) + dbg->oom_handler (); + + uintptr_t result = ((uintptr_t) newp->mem + align - 1) & ~(align - 1); + + newp->size = size - offsetof (struct libdw_memblock, mem); + newp->remaining = (uintptr_t) newp + size - (result + minsize); + + pthread_rwlock_rdlock (&dbg->mem_rwl); + newp->prev = dbg->mem_tails[thread_id]; + dbg->mem_tails[thread_id] = newp; + pthread_rwlock_unlock (&dbg->mem_rwl); + + return (void *) result; +} + + +Dwarf_OOM +dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler) +{ + Dwarf_OOM old = dbg->oom_handler; + dbg->oom_handler = handler; + return old; +} + + +void +__attribute ((noreturn)) attribute_hidden +__libdw_oom (void) +{ + while (1) + error (EXIT_FAILURE, ENOMEM, "libdw"); +} diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c new file mode 100644 index 00000000..da039e50 --- /dev/null +++ b/libdw/libdw_find_split_unit.c @@ -0,0 +1,147 @@ +/* Find the split (or skeleton) unit for a given unit. + Copyright (C) 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include "libelfP.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +void +try_split_file (Dwarf_CU *cu, const char *dwo_path) +{ + int split_fd = open (dwo_path, O_RDONLY); + if (split_fd != -1) + { + Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ); + if (split_dwarf != NULL) + { + Dwarf_CU *split = NULL; + while (dwarf_get_units (split_dwarf, split, &split, + NULL, NULL, NULL, NULL) == 0) + { + if (split->unit_type == DW_UT_split_compile + && cu->unit_id8 == split->unit_id8) + { + if (tsearch (split->dbg, &cu->dbg->split_tree, + __libdw_finddbg_cb) == NULL) + { + /* Something went wrong. Don't link. */ + __libdw_seterrno (DWARF_E_NOMEM); + break; + } + + /* Link skeleton and split compile units. */ + __libdw_link_skel_split (cu, split); + + /* We have everything we need from this ELF + file. And we are going to close the fd to + not run out of file descriptors. */ + elf_cntl (split_dwarf->elf, ELF_C_FDDONE); + break; + } + } + if (cu->split == (Dwarf_CU *) -1) + dwarf_end (split_dwarf); + } + /* Always close, because we don't want to run out of file + descriptors. See also the elf_fcntl ELF_C_FDDONE call + above. */ + close (split_fd); + } +} + +Dwarf_CU * +internal_function +__libdw_find_split_unit (Dwarf_CU *cu) +{ + /* Only try once. */ + if (cu->split != (Dwarf_CU *) -1) + return cu->split; + + /* We need a skeleton unit with a comp_dir and [GNU_]dwo_name attributes. + The split unit will be the first in the dwo file and should have the + same id as the skeleton. */ + if (cu->unit_type == DW_UT_skeleton) + { + Dwarf_Die cudie = CUDIE (cu); + Dwarf_Attribute dwo_name; + /* It is fine if dwo_dir doesn't exists, but then dwo_name needs + to be an absolute path. */ + if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL + || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL) + { + /* First try the dwo file name in the same directory + as we found the skeleton file. */ + const char *dwo_file = dwarf_formstring (&dwo_name); + const char *debugdir = cu->dbg->debugdir; + char *dwo_path = __libdw_filepath (debugdir, NULL, dwo_file); + if (dwo_path != NULL) + { + try_split_file (cu, dwo_path); + free (dwo_path); + } + + if (cu->split == (Dwarf_CU *) -1) + { + /* Try compdir plus dwo_name. */ + Dwarf_Attribute compdir; + dwarf_attr (&cudie, DW_AT_comp_dir, &compdir); + const char *dwo_dir = dwarf_formstring (&compdir); + if (dwo_dir != NULL) + { + dwo_path = __libdw_filepath (debugdir, dwo_dir, dwo_file); + if (dwo_path != NULL) + { + try_split_file (cu, dwo_path); + free (dwo_path); + } + } + } + /* XXX If still not found we could try stripping dirs from the + comp_dir and adding them from the comp_dir, assuming + someone moved a whole build tree around. */ + } + } + + /* If we found nothing, make sure we don't try again. */ + if (cu->split == (Dwarf_CU *) -1) + cu->split = NULL; + + return cu->split; +} diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c new file mode 100644 index 00000000..ed744231 --- /dev/null +++ b/libdw/libdw_findcu.c @@ -0,0 +1,307 @@ +/* Find CU for given offset. + Copyright (C) 2003-2010, 2014, 2016, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libdwP.h" + +static int +findcu_cb (const void *arg1, const void *arg2) +{ + struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1; + struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2; + + /* Find out which of the two arguments is the search value. It has + end offset 0. */ + if (cu1->end == 0) + { + if (cu1->start < cu2->start) + return -1; + if (cu1->start >= cu2->end) + return 1; + } + else + { + if (cu2->start < cu1->start) + return 1; + if (cu2->start >= cu1->end) + return -1; + } + + return 0; +} + +int +__libdw_finddbg_cb (const void *arg1, const void *arg2) +{ + Dwarf *dbg1 = (Dwarf *) arg1; + Dwarf *dbg2 = (Dwarf *) arg2; + + Elf_Data *dbg1_data = dbg1->sectiondata[IDX_debug_info]; + unsigned char *dbg1_start = dbg1_data->d_buf; + size_t dbg1_size = dbg1_data->d_size; + + Elf_Data *dbg2_data = dbg2->sectiondata[IDX_debug_info]; + unsigned char *dbg2_start = dbg2_data->d_buf; + size_t dbg2_size = dbg2_data->d_size; + + /* Find out which of the two arguments is the search value. It has + a size of 0. */ + if (dbg1_size == 0) + { + if (dbg1_start < dbg2_start) + return -1; + if (dbg1_start >= dbg2_start + dbg2_size) + return 1; + } + else + { + if (dbg2_start < dbg1_start) + return 1; + if (dbg2_start >= dbg1_start + dbg1_size) + return -1; + } + + return 0; +} + +struct Dwarf_CU * +internal_function +__libdw_intern_next_unit (Dwarf *dbg, bool debug_types) +{ + Dwarf_Off *const offsetp + = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset; + void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree; + + Dwarf_Off oldoff = *offsetp; + uint16_t version; + uint8_t unit_type; + uint8_t address_size; + uint8_t offset_size; + Dwarf_Off abbrev_offset; + uint64_t unit_id8; + Dwarf_Off subdie_offset; + + if (__libdw_next_unit (dbg, debug_types, oldoff, offsetp, NULL, + &version, &unit_type, &abbrev_offset, + &address_size, &offset_size, + &unit_id8, &subdie_offset) != 0) + /* No more entries. */ + return NULL; + + /* We only know how to handle the DWARF version 2 through 5 formats. + For v4 debug types we only handle version 4. */ + if (unlikely (version < 2) || unlikely (version > 5) + || (debug_types && unlikely (version != 4))) + { + __libdw_seterrno (DWARF_E_VERSION); + return NULL; + } + + /* We only handle 32 or 64 bit (4 or 8 byte) addresses and offsets. + Just assume we are dealing with 64bit in case the size is "unknown". + Too much code assumes if it isn't 4 then it is 8 (or the other way + around). */ + if (unlikely (address_size != 4 && address_size != 8)) + address_size = 8; + if (unlikely (offset_size != 4 && offset_size != 8)) + offset_size = 8; + + /* Invalid or truncated debug section data? */ + size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info; + Elf_Data *data = dbg->sectiondata[sec_idx]; + if (unlikely (*offsetp > data->d_size)) + *offsetp = data->d_size; + + /* Create an entry for this CU. */ + struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU); + + newp->dbg = dbg; + newp->sec_idx = sec_idx; + newp->start = oldoff; + newp->end = *offsetp; + newp->address_size = address_size; + newp->offset_size = offset_size; + newp->version = version; + newp->unit_id8 = unit_id8; + newp->subdie_offset = subdie_offset; + Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41); + newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; + newp->files = NULL; + newp->lines = NULL; + newp->locs = NULL; + newp->split = (Dwarf_CU *) -1; + newp->base_address = (Dwarf_Addr) -1; + newp->addr_base = (Dwarf_Off) -1; + newp->str_off_base = (Dwarf_Off) -1; + newp->ranges_base = (Dwarf_Off) -1; + newp->locs_base = (Dwarf_Off) -1; + + newp->startp = data->d_buf + newp->start; + newp->endp = data->d_buf + newp->end; + + /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ + if (debug_types) + newp->unit_type = DW_UT_type; + else if (version < 5) + { + /* This is a reasonable guess (and needed to get the CUDIE). */ + newp->unit_type = DW_UT_compile; + + /* But set it correctly from the actual CUDIE tag. */ + Dwarf_Die cudie = CUDIE (newp); + int tag = INTUSE(dwarf_tag) (&cudie); + if (tag == DW_TAG_compile_unit) + { + Dwarf_Attribute dwo_id; + if (INTUSE(dwarf_attr) (&cudie, DW_AT_GNU_dwo_id, &dwo_id) != NULL) + { + Dwarf_Word id8; + if (INTUSE(dwarf_formudata) (&dwo_id, &id8) == 0) + { + if (INTUSE(dwarf_haschildren) (&cudie) == 0 + && INTUSE(dwarf_hasattr) (&cudie, + DW_AT_GNU_dwo_name) == 1) + newp->unit_type = DW_UT_skeleton; + else + newp->unit_type = DW_UT_split_compile; + + newp->unit_id8 = id8; + } + } + } + else if (tag == DW_TAG_partial_unit) + newp->unit_type = DW_UT_partial; + else if (tag == DW_TAG_type_unit) + newp->unit_type = DW_UT_type; + } + else + newp->unit_type = unit_type; + + /* Store a reference to any type unit ids in the hash for quick lookup. */ + if (unit_type == DW_UT_type || unit_type == DW_UT_split_type) + Dwarf_Sig8_Hash_insert (&dbg->sig8_hash, unit_id8, newp); + + /* Add the new entry to the search tree. */ + if (tsearch (newp, tree, findcu_cb) == NULL) + { + /* Something went wrong. Undo the operation. */ + *offsetp = oldoff; + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + return newp; +} + +struct Dwarf_CU * +internal_function +__libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types) +{ + void **tree = v4_debug_types ? &dbg->tu_tree : &dbg->cu_tree; + Dwarf_Off *next_offset + = v4_debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset; + + /* Maybe we already know that CU. */ + struct Dwarf_CU fake = { .start = start, .end = 0 }; + struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb); + if (found != NULL) + return *found; + + if (start < *next_offset) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* No. Then read more CUs. */ + while (1) + { + struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, v4_debug_types); + if (newp == NULL) + return NULL; + + /* Is this the one we are looking for? */ + if (start < *next_offset || start == newp->start) + return newp; + } + /* NOTREACHED */ +} + +struct Dwarf_CU * +internal_function +__libdw_findcu_addr (Dwarf *dbg, void *addr) +{ + void **tree; + Dwarf_Off start; + if (addr >= dbg->sectiondata[IDX_debug_info]->d_buf + && addr < (dbg->sectiondata[IDX_debug_info]->d_buf + + dbg->sectiondata[IDX_debug_info]->d_size)) + { + tree = &dbg->cu_tree; + start = addr - dbg->sectiondata[IDX_debug_info]->d_buf; + } + else if (dbg->sectiondata[IDX_debug_types] != NULL + && addr >= dbg->sectiondata[IDX_debug_types]->d_buf + && addr < (dbg->sectiondata[IDX_debug_types]->d_buf + + dbg->sectiondata[IDX_debug_types]->d_size)) + { + tree = &dbg->tu_tree; + start = addr - dbg->sectiondata[IDX_debug_types]->d_buf; + } + else + return NULL; + + struct Dwarf_CU fake = { .start = start, .end = 0 }; + struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb); + + if (found != NULL) + return *found; + + return NULL; +} + +Dwarf * +internal_function +__libdw_find_split_dbg_addr (Dwarf *dbg, void *addr) +{ + /* XXX Assumes split DWARF only has CUs in main IDX_debug_info. */ + Elf_Data fake_data = { .d_buf = addr, .d_size = 0 }; + Dwarf fake = { .sectiondata[IDX_debug_info] = &fake_data }; + Dwarf **found = tfind (&fake, &dbg->split_tree, __libdw_finddbg_cb); + + if (found != NULL) + return *found; + + return NULL; +} diff --git a/libdw/libdw_form.c b/libdw/libdw_form.c new file mode 100644 index 00000000..c83dfb39 --- /dev/null +++ b/libdw/libdw_form.c @@ -0,0 +1,144 @@ +/* Helper functions for form handling. + Copyright (C) 2003-2009, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libdwP.h" + + +size_t +internal_function +__libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form, + const unsigned char *valp) +{ + const unsigned char *startp = valp; + const unsigned char *endp = cu->endp; + Dwarf_Word u128; + size_t result; + + /* NB: This doesn't cover constant form lengths, which are + already handled by the inlined __libdw_form_val_len. */ + switch (form) + { + case DW_FORM_addr: + result = cu->address_size; + break; + + case DW_FORM_ref_addr: + result = cu->version == 2 ? cu->address_size : cu->offset_size; + break; + + case DW_FORM_strp: + case DW_FORM_strp_sup: + case DW_FORM_line_strp: + case DW_FORM_sec_offset: + case DW_FORM_GNU_ref_alt: + case DW_FORM_GNU_strp_alt: + result = cu->offset_size; + break; + + case DW_FORM_block1: + if (unlikely ((size_t) (endp - startp) < 1)) + goto invalid; + result = *valp + 1; + break; + + case DW_FORM_block2: + if (unlikely ((size_t) (endp - startp) < 2)) + goto invalid; + result = read_2ubyte_unaligned (cu->dbg, valp) + 2; + break; + + case DW_FORM_block4: + if (unlikely ((size_t) (endp - startp) < 4)) + goto invalid; + result = read_4ubyte_unaligned (cu->dbg, valp) + 4; + break; + + case DW_FORM_block: + case DW_FORM_exprloc: + get_uleb128 (u128, valp, endp); + result = u128 + (valp - startp); + break; + + case DW_FORM_string: + { + const unsigned char *endstrp = memchr (valp, '\0', + (size_t) (endp - startp)); + if (unlikely (endstrp == NULL)) + goto invalid; + result = (size_t) (endstrp - startp) + 1; + break; + } + + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_addrx: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: + case DW_FORM_strx: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + get_uleb128 (u128, valp, endp); + result = valp - startp; + break; + + case DW_FORM_indirect: + /* The amount of data to skip in the DIE is the size of the actual + FORM data (which is __libdw_form_val_len) plus the size of the + uleb128 encoding that FORM (which is valp - startp). */ + get_uleb128 (u128, valp, endp); + if (*valp == DW_FORM_indirect || *valp == DW_FORM_implicit_const) + return (size_t) -1; + result = __libdw_form_val_len (cu, u128, valp); + if (result != (size_t) -1) + result += valp - startp; + else + return (size_t) -1; + break; + + default: + goto invalid; + } + + if (unlikely (result > (size_t) (endp - startp))) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + result = (size_t) -1; + } + + return result; +} diff --git a/libdw/libdw_visit_scopes.c b/libdw/libdw_visit_scopes.c new file mode 100644 index 00000000..7dfa5f6b --- /dev/null +++ b/libdw/libdw_visit_scopes.c @@ -0,0 +1,192 @@ +/* Helper functions to descend DWARF scope trees. + Copyright (C) 2005,2006,2007,2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + + +static bool +may_have_scopes (Dwarf_Die *die) +{ + switch (INTUSE(dwarf_tag) (die)) + { + /* DIEs with addresses we can try to match. */ + case DW_TAG_compile_unit: + case DW_TAG_module: + case DW_TAG_lexical_block: + case DW_TAG_with_stmt: + case DW_TAG_catch_block: + case DW_TAG_try_block: + case DW_TAG_entry_point: + case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: + return true; + + /* DIEs without addresses that can own DIEs with addresses. */ + case DW_TAG_namespace: + case DW_TAG_class_type: + case DW_TAG_structure_type: + return true; + + /* Other DIEs we have no reason to descend. */ + default: + break; + } + return false; +} + +struct walk_children_state +{ + /* Parameters of __libdw_visit_scopes. */ + unsigned int depth; + struct Dwarf_Die_Chain *imports; + int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *); + int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *); + void *arg; + /* Extra local variables for the walker. */ + struct Dwarf_Die_Chain child; +}; + +static inline int +walk_children (struct walk_children_state *state); + +int +internal_function +__libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root, + struct Dwarf_Die_Chain *imports, + int (*previsit) (unsigned int, + struct Dwarf_Die_Chain *, + void *), + int (*postvisit) (unsigned int, + struct Dwarf_Die_Chain *, + void *), + void *arg) +{ + struct walk_children_state state = + { + .depth = depth, + .imports = imports, + .previsit = previsit, + .postvisit = postvisit, + .arg = arg + }; + + state.child.parent = root; + int ret; + if ((ret = INTUSE(dwarf_child) (&root->die, &state.child.die)) != 0) + return ret < 0 ? -1 : 0; // Having zero children is legal. + + return walk_children (&state); +} + +static inline int +walk_children (struct walk_children_state *state) +{ + int ret; + do + { + /* For an imported unit, it is logically as if the children of + that unit are siblings of the other children. So don't do + a full recursion into the imported unit, but just walk the + children in place before moving to the next real child. */ + while (INTUSE(dwarf_tag) (&state->child.die) == DW_TAG_imported_unit) + { + Dwarf_Die orig_child_die = state->child.die; + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&state->child.die, + DW_AT_import, + &attr_mem); + /* Some gcc -flto versions imported other top-level compile units, + skip those. */ + if (INTUSE(dwarf_formref_die) (attr, &state->child.die) != NULL + && INTUSE(dwarf_tag) (&state->child.die) != DW_TAG_compile_unit + && (INTUSE(dwarf_child) (&state->child.die, &state->child.die) + == 0)) + { + /* Checks the given DIE hasn't been imported yet + to prevent cycles. */ + bool imported = false; + for (struct Dwarf_Die_Chain *import = state->imports; import != NULL; + import = import->parent) + if (import->die.addr == orig_child_die.addr) + { + imported = true; + break; + } + if (imported) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + struct Dwarf_Die_Chain *orig_imports = state->imports; + struct Dwarf_Die_Chain import = { .die = orig_child_die, + .parent = orig_imports }; + state->imports = &import; + int result = walk_children (state); + state->imports = orig_imports; + if (result != DWARF_CB_OK) + return result; + } + + /* Any "real" children left? */ + if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die, + &state->child.die)) != 0) + return ret < 0 ? -1 : 0; + }; + + state->child.prune = false; + + /* previsit is declared NN */ + int result = (*state->previsit) (state->depth + 1, &state->child, state->arg); + if (result != DWARF_CB_OK) + return result; + + if (!state->child.prune && may_have_scopes (&state->child.die) + && INTUSE(dwarf_haschildren) (&state->child.die)) + { + result = __libdw_visit_scopes (state->depth + 1, &state->child, state->imports, + state->previsit, state->postvisit, state->arg); + if (result != DWARF_CB_OK) + return result; + } + + if (state->postvisit != NULL) + { + result = (*state->postvisit) (state->depth + 1, &state->child, state->arg); + if (result != DWARF_CB_OK) + return result; + } + } + while ((ret = INTUSE(dwarf_siblingof) (&state->child.die, &state->child.die)) == 0); + + return ret < 0 ? -1 : 0; +} diff --git a/libdw/memory-access.h b/libdw/memory-access.h new file mode 100644 index 00000000..8b2386ee --- /dev/null +++ b/libdw/memory-access.h @@ -0,0 +1,407 @@ +/* Unaligned memory access functionality. + Copyright (C) 2000-2014, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _MEMORY_ACCESS_H +#define _MEMORY_ACCESS_H 1 + +#include +#include +#include +#include + + +/* Number decoding macros. See 7.6 Variable Length Data. */ + +#define len_leb128(var) ((8 * sizeof (var) + 6) / 7) + +static inline size_t +__libdw_max_len_leb128 (const size_t type_len, + const unsigned char *addr, const unsigned char *end) +{ + const size_t pointer_len = likely (addr < end) ? end - addr : 0; + return likely (type_len <= pointer_len) ? type_len : pointer_len; +} + +static inline size_t +__libdw_max_len_uleb128 (const unsigned char *addr, const unsigned char *end) +{ + const size_t type_len = len_leb128 (uint64_t); + return __libdw_max_len_leb128 (type_len, addr, end); +} + +static inline size_t +__libdw_max_len_sleb128 (const unsigned char *addr, const unsigned char *end) +{ + /* Subtract one step, so we don't shift into sign bit. */ + const size_t type_len = len_leb128 (int64_t) - 1; + return __libdw_max_len_leb128 (type_len, addr, end); +} + +#define get_uleb128_step(var, addr, nth) \ + do { \ + unsigned char __b = *(addr)++; \ + (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \ + if (likely ((__b & 0x80) == 0)) \ + return (var); \ + } while (0) + +static inline uint64_t +__libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end) +{ + uint64_t acc = 0; + + /* Unroll the first step to help the compiler optimize + for the common single-byte case. */ + get_uleb128_step (acc, *addrp, 0); + + const size_t max = __libdw_max_len_uleb128 (*addrp - 1, end); + for (size_t i = 1; i < max; ++i) + get_uleb128_step (acc, *addrp, i); + /* Other implementations set VALUE to UINT_MAX in this + case. So we better do this as well. */ + return UINT64_MAX; +} + +static inline uint64_t +__libdw_get_uleb128_unchecked (const unsigned char **addrp) +{ + uint64_t acc = 0; + + /* Unroll the first step to help the compiler optimize + for the common single-byte case. */ + get_uleb128_step (acc, *addrp, 0); + + const size_t max = len_leb128 (uint64_t); + for (size_t i = 1; i < max; ++i) + get_uleb128_step (acc, *addrp, i); + /* Other implementations set VALUE to UINT_MAX in this + case. So we better do this as well. */ + return UINT64_MAX; +} + +/* Note, addr needs to me smaller than end. */ +#define get_uleb128(var, addr, end) ((var) = __libdw_get_uleb128 (&(addr), end)) +#define get_uleb128_unchecked(var, addr) ((var) = __libdw_get_uleb128_unchecked (&(addr))) + +/* The signed case is similar, but we sign-extend the result. */ + +#define get_sleb128_step(var, addr, nth) \ + do { \ + unsigned char __b = *(addr)++; \ + (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \ + if (likely ((__b & 0x80) == 0)) \ + { \ + if ((__b & 0x40) != 0) \ + (var) |= - ((typeof (var)) 1 << (((nth) + 1) * 7)); \ + return (var); \ + } \ + } while (0) + +static inline int64_t +__libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end) +{ + /* Do the work in an unsigned type, but use implementation-defined + behavior to cast to signed on return. This avoids some undefined + behavior when shifting. */ + uint64_t acc = 0; + + /* Unroll the first step to help the compiler optimize + for the common single-byte case. */ + get_sleb128_step (acc, *addrp, 0); + + const size_t max = __libdw_max_len_sleb128 (*addrp - 1, end); + for (size_t i = 1; i < max; ++i) + get_sleb128_step (acc, *addrp, i); + if (*addrp == end) + return INT64_MAX; + + /* There might be one extra byte. */ + unsigned char b = **addrp; + ++*addrp; + if (likely ((b & 0x80) == 0)) + { + /* We only need the low bit of the final byte, and as it is the + sign bit, we don't need to do anything else here. */ + acc |= ((typeof (acc)) b) << 7 * max; + return acc; + } + + /* Other implementations set VALUE to INT_MAX in this + case. So we better do this as well. */ + return INT64_MAX; +} + +static inline int64_t +__libdw_get_sleb128_unchecked (const unsigned char **addrp) +{ + /* Do the work in an unsigned type, but use implementation-defined + behavior to cast to signed on return. This avoids some undefined + behavior when shifting. */ + uint64_t acc = 0; + + /* Unroll the first step to help the compiler optimize + for the common single-byte case. */ + get_sleb128_step (acc, *addrp, 0); + + /* Subtract one step, so we don't shift into sign bit. */ + const size_t max = len_leb128 (int64_t) - 1; + for (size_t i = 1; i < max; ++i) + get_sleb128_step (acc, *addrp, i); + + /* There might be one extra byte. */ + unsigned char b = **addrp; + ++*addrp; + if (likely ((b & 0x80) == 0)) + { + /* We only need the low bit of the final byte, and as it is the + sign bit, we don't need to do anything else here. */ + acc |= ((typeof (acc)) b) << 7 * max; + return acc; + } + + /* Other implementations set VALUE to INT_MAX in this + case. So we better do this as well. */ + return INT64_MAX; +} + +#define get_sleb128(var, addr, end) ((var) = __libdw_get_sleb128 (&(addr), end)) +#define get_sleb128_unchecked(var, addr) ((var) = __libdw_get_sleb128_unchecked (&(addr))) + + +/* We use simple memory access functions in case the hardware allows it. + The caller has to make sure we don't have alias problems. */ +#if ALLOW_UNALIGNED + +# define read_2ubyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_16 (*((const uint16_t *) (Addr))) \ + : *((const uint16_t *) (Addr))) +# define read_2sbyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? (int16_t) bswap_16 (*((const int16_t *) (Addr))) \ + : *((const int16_t *) (Addr))) + +# define read_4ubyte_unaligned_noncvt(Addr) \ + *((const uint32_t *) (Addr)) +# define read_4ubyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_32 (*((const uint32_t *) (Addr))) \ + : *((const uint32_t *) (Addr))) +# define read_4sbyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? (int32_t) bswap_32 (*((const int32_t *) (Addr))) \ + : *((const int32_t *) (Addr))) + +# define read_8ubyte_unaligned_noncvt(Addr) \ + *((const uint64_t *) (Addr)) +# define read_8ubyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_64 (*((const uint64_t *) (Addr))) \ + : *((const uint64_t *) (Addr))) +# define read_8sbyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? (int64_t) bswap_64 (*((const int64_t *) (Addr))) \ + : *((const int64_t *) (Addr))) + +#else + +union unaligned + { + void *p; + uint16_t u2; + uint32_t u4; + uint64_t u8; + int16_t s2; + int32_t s4; + int64_t s8; + } attribute_packed; + +# define read_2ubyte_unaligned(Dbg, Addr) \ + read_2ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr)) +# define read_2sbyte_unaligned(Dbg, Addr) \ + read_2sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr)) +# define read_4ubyte_unaligned(Dbg, Addr) \ + read_4ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr)) +# define read_4sbyte_unaligned(Dbg, Addr) \ + read_4sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr)) +# define read_8ubyte_unaligned(Dbg, Addr) \ + read_8ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr)) +# define read_8sbyte_unaligned(Dbg, Addr) \ + read_8sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr)) + +static inline uint16_t +read_2ubyte_unaligned_1 (bool other_byte_order, const void *p) +{ + const union unaligned *up = p; + if (unlikely (other_byte_order)) + return bswap_16 (up->u2); + return up->u2; +} +static inline int16_t +read_2sbyte_unaligned_1 (bool other_byte_order, const void *p) +{ + const union unaligned *up = p; + if (unlikely (other_byte_order)) + return (int16_t) bswap_16 (up->u2); + return up->s2; +} + +static inline uint32_t +read_4ubyte_unaligned_noncvt (const void *p) +{ + const union unaligned *up = p; + return up->u4; +} +static inline uint32_t +read_4ubyte_unaligned_1 (bool other_byte_order, const void *p) +{ + const union unaligned *up = p; + if (unlikely (other_byte_order)) + return bswap_32 (up->u4); + return up->u4; +} +static inline int32_t +read_4sbyte_unaligned_1 (bool other_byte_order, const void *p) +{ + const union unaligned *up = p; + if (unlikely (other_byte_order)) + return (int32_t) bswap_32 (up->u4); + return up->s4; +} + +static inline uint64_t +read_8ubyte_unaligned_noncvt (const void *p) +{ + const union unaligned *up = p; + return up->u8; +} +static inline uint64_t +read_8ubyte_unaligned_1 (bool other_byte_order, const void *p) +{ + const union unaligned *up = p; + if (unlikely (other_byte_order)) + return bswap_64 (up->u8); + return up->u8; +} +static inline int64_t +read_8sbyte_unaligned_1 (bool other_byte_order, const void *p) +{ + const union unaligned *up = p; + if (unlikely (other_byte_order)) + return (int64_t) bswap_64 (up->u8); + return up->s8; +} + +#endif /* allow unaligned */ + + +#define read_2ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint16_t t_ = read_2ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \ + t_; }) +#define read_2sbyte_unaligned_inc(Dbg, Addr) \ + ({ int16_t t_ = read_2sbyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \ + t_; }) + +#define read_4ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint32_t t_ = read_4ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \ + t_; }) +#define read_4sbyte_unaligned_inc(Dbg, Addr) \ + ({ int32_t t_ = read_4sbyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \ + t_; }) + +#define read_8ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint64_t t_ = read_8ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \ + t_; }) +#define read_8sbyte_unaligned_inc(Dbg, Addr) \ + ({ int64_t t_ = read_8sbyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \ + t_; }) + +/* 3ubyte reads are only used for DW_FORM_addrx3 and DW_FORM_strx3. + And are probably very rare. They are not optimized. They are + handled as if reading a 4byte value with the first (for big endian) + or last (for little endian) byte zero. */ + +static inline int +file_byte_order (bool other_byte_order) +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + return other_byte_order ? __BIG_ENDIAN : __LITTLE_ENDIAN; +#else + return other_byte_order ? __LITTLE_ENDIAN : __BIG_ENDIAN; +#endif +} + +static inline uint32_t +read_3ubyte_unaligned (Dwarf *dbg, const unsigned char *p) +{ + union + { + uint32_t u4; + unsigned char c[4]; + } d; + bool other_byte_order = dbg->other_byte_order; + + if (file_byte_order (other_byte_order) == __BIG_ENDIAN) + { + d.c[0] = 0x00; + d.c[1] = p[0]; + d.c[2] = p[1]; + d.c[3] = p[2]; + } + else + { + d.c[0] = p[0]; + d.c[1] = p[1]; + d.c[2] = p[2]; + d.c[3] = 0x00; + } + + if (other_byte_order) + return bswap_32 (d.u4); + else + return d.u4; +} + + +#define read_3ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint32_t t_ = read_3ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 3); \ + t_; }) + +#define read_addr_unaligned_inc(Nbytes, Dbg, Addr) \ + (assert ((Nbytes) == 4 || (Nbytes) == 8), \ + ((Nbytes) == 4 ? read_4ubyte_unaligned_inc (Dbg, Addr) \ + : read_8ubyte_unaligned_inc (Dbg, Addr))) + +#endif /* memory-access.h */ diff --git a/libdwelf/ChangeLog b/libdwelf/ChangeLog new file mode 100644 index 00000000..a0ff9f4f --- /dev/null +++ b/libdwelf/ChangeLog @@ -0,0 +1,95 @@ +2020-12-12 Dmitry V. Levin + + * libdwelf.h: Fix spelling typos in comments. + * dwelf_strtab.c (newstring): Likewise. + + * dwelf_elf_e_machine_string.c (dwelf_elf_e_machine_string): Fix + spelling typos in returned strings. + +2020-06-04 Mark Wielaard + + * dwelf_elf_e_machine_string.c (dwelf_elf_e_machine_string): + Rename EM_ARC_COMPACT2 to EM_ARCV2. + +2019-08-12 Mark Wielaard + + * libdwelf.h (dwelf_elf_begin): Update documentation. + * dwelf_elf_begin.c (dwelf_elf_begin): Don't suppress ELF_K_NONE. + Mark old and new version. + +2019-06-28 Mark Wielaard + + * Makefile.am (libdwelf_a_SOURCES): Add dwelf_elf_e_machine_string.c. + * libdwelf.h (dwelf_elf_e_machine_string): Define new function. + * dwelf_elf_e_machine_string.c: New file. + +2018-10-21 Mark Wielaard + + * libdwelf.h (dwelf_elf_begin): Add function declaration. + * dwelf_elf_begin.c: New file. + * Makefile.am (libdwelf_a_SOURCES): Add dwelf_elf_begin.c. + +2018-10-18 Mark Wielaard + + * dwelf_elf_gnu_build_id.c (find_elf_build_id): Check p_align to + set ELF type. + +2016-10-11 Akihiko Odaki + + * dwelf_strtab.c: Remove sys/param.h include. + (MIN): Remove definition. + +2016-07-08 Mark Wielaard + + * Makefile.am (libdwelf_a_SOURCES): Add dwelf_strtab.c. + * dwelf_strtab.c: New file. + * libdwelf.h (Dwelf_Strtab): New typedef. + (Dwelf_Strent): Likewise. + (dwelf_strtab_init): New function. + (dwelf_strtab_add): Likewise. + (dwelf_strtab_add_len): Likewise. + (dwelf_strtab_finalize): Likewise. + (dwelf_strent_off): Likewise. + (dwelf_strent_str): Likewise. + (dwelf_strtab_free): Likewise. + +2015-10-28 Mark Wielaard + + * Makefile.am (libdwelf_a_SOURCES): Add + dwelf_scn_gnu_compressed_size.c. + * dwelf_scn_gnu_compressed_size.c: Likewise. + * libdwelf.h (dwelf_scn_gnu_compressed_size): New declaration. + +2015-10-14 Chih-Hung Hsieh + + * dwelf_elf_gnu_build_id.c (find_elf_build_id): Move nested function + 'check_notes' to file scope. + +2014-11-14 Mark Wielaard + + * dwelf_elf_gnu_debuglink.c (dwelf_elf_gnu_debuglink): Check d_buf + is not NULL. + +2014-04-30 Mark Wielaard + + * Makefile.am (AM_CPPFLAGS): Add libdwfl and libebl include dirs. + (libdwelf_a_SOURCES): Add dwelf_elf_gnu_build_id.c + * dwelf_elf_gnu_build_id.c: New file. Moved libdwfl function + __libdwfl_find_elf_build_id here. + * libdwelf.h (dwelf_elf_gnu_build_id): Declare new function. + * libdwelfP.h (dwelf_elf_gnu_build_id): Add internal declaration. + +2014-04-24 Florian Weimer + + * dwelf_dwarf_gnu_debugaltlink.c: New file. + * Makefile.am (libdwelf_a_SOURCES): Add it. + * libdwelf.h (dwelf_dwarf_gnu_debugaltlink): Declare new function. + * libdwelfP.h (dwelf_dwarf_gnu_debugaltlink): Add internal + declaration. + +2014-04-11 Mark Wielaard + + * Makefile.am: New file. + * libdwelf.h: Likewise. + * libdwelfP.h: Likewise. + * dwelf_elf_gnu_debuglink.c: Likewise. diff --git a/libdwelf/Makefile.am b/libdwelf/Makefile.am new file mode 100644 index 00000000..a35a2873 --- /dev/null +++ b/libdwelf/Makefile.am @@ -0,0 +1,57 @@ +## Makefile.am for libdwelf library subdirectory in elfutils. +## +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2014, 2015 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw \ + -I$(srcdir)/../libdwfl -I$(srcdir)/../libebl +VERSION = 1 + +noinst_LIBRARIES = libdwelf.a libdwelf_pic.a + +pkginclude_HEADERS = libdwelf.h +noinst_HEADERS = libdwelfP.h + +libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \ + dwelf_elf_gnu_build_id.c dwelf_scn_gnu_compressed_size.c \ + dwelf_strtab.c dwelf_elf_begin.c \ + dwelf_elf_e_machine_string.c + +libdwelf = $(libdw) + +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +libebl = ../libebl/libebl.a +libeu = ../lib/libeu.a + +libdwelf_pic_a_SOURCES = +am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os) + +CLEANFILES += $(am_libdwelf_pic_a_OBJECTS) diff --git a/libdwelf/Makefile.in b/libdwelf/Makefile.in new file mode 100644 index 00000000..1dadc878 --- /dev/null +++ b/libdwelf/Makefile.in @@ -0,0 +1,794 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +subdir = libdwelf +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(pkginclude_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libdwelf_a_AR = $(AR) $(ARFLAGS) +libdwelf_a_LIBADD = +am_libdwelf_a_OBJECTS = dwelf_elf_gnu_debuglink.$(OBJEXT) \ + dwelf_dwarf_gnu_debugaltlink.$(OBJEXT) \ + dwelf_elf_gnu_build_id.$(OBJEXT) \ + dwelf_scn_gnu_compressed_size.$(OBJEXT) dwelf_strtab.$(OBJEXT) \ + dwelf_elf_begin.$(OBJEXT) dwelf_elf_e_machine_string.$(OBJEXT) +libdwelf_a_OBJECTS = $(am_libdwelf_a_OBJECTS) +libdwelf_pic_a_AR = $(AR) $(ARFLAGS) +libdwelf_pic_a_LIBADD = +libdwelf_pic_a_OBJECTS = $(am_libdwelf_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/dwelf_dwarf_gnu_debugaltlink.Po \ + ./$(DEPDIR)/dwelf_elf_begin.Po \ + ./$(DEPDIR)/dwelf_elf_e_machine_string.Po \ + ./$(DEPDIR)/dwelf_elf_gnu_build_id.Po \ + ./$(DEPDIR)/dwelf_elf_gnu_debuglink.Po \ + ./$(DEPDIR)/dwelf_scn_gnu_compressed_size.Po \ + ./$(DEPDIR)/dwelf_strtab.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdwelf_a_SOURCES) $(libdwelf_pic_a_SOURCES) +DIST_SOURCES = $(libdwelf_a_SOURCES) $(libdwelf_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgincludedir)" +HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(srcdir)/../libelf -I$(srcdir)/../libdw \ + -I$(srcdir)/../libdwfl -I$(srcdir)/../libebl + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda $(am_libdwelf_pic_a_OBJECTS) +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +noinst_LIBRARIES = libdwelf.a libdwelf_pic.a +pkginclude_HEADERS = libdwelf.h +noinst_HEADERS = libdwelfP.h +libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \ + dwelf_elf_gnu_build_id.c dwelf_scn_gnu_compressed_size.c \ + dwelf_strtab.c dwelf_elf_begin.c \ + dwelf_elf_e_machine_string.c + +libdwelf = $(libdw) +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +libebl = ../libebl/libebl.a +libeu = ../lib/libeu.a +libdwelf_pic_a_SOURCES = +am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdwelf/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libdwelf/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libdwelf.a: $(libdwelf_a_OBJECTS) $(libdwelf_a_DEPENDENCIES) $(EXTRA_libdwelf_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdwelf.a + $(AM_V_AR)$(libdwelf_a_AR) libdwelf.a $(libdwelf_a_OBJECTS) $(libdwelf_a_LIBADD) + $(AM_V_at)$(RANLIB) libdwelf.a + +libdwelf_pic.a: $(libdwelf_pic_a_OBJECTS) $(libdwelf_pic_a_DEPENDENCIES) $(EXTRA_libdwelf_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdwelf_pic.a + $(AM_V_AR)$(libdwelf_pic_a_AR) libdwelf_pic.a $(libdwelf_pic_a_OBJECTS) $(libdwelf_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libdwelf_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_dwarf_gnu_debugaltlink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_elf_begin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_elf_e_machine_string.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_elf_gnu_build_id.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_elf_gnu_debuglink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_scn_gnu_compressed_size.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_strtab.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/dwelf_dwarf_gnu_debugaltlink.Po + -rm -f ./$(DEPDIR)/dwelf_elf_begin.Po + -rm -f ./$(DEPDIR)/dwelf_elf_e_machine_string.Po + -rm -f ./$(DEPDIR)/dwelf_elf_gnu_build_id.Po + -rm -f ./$(DEPDIR)/dwelf_elf_gnu_debuglink.Po + -rm -f ./$(DEPDIR)/dwelf_scn_gnu_compressed_size.Po + -rm -f ./$(DEPDIR)/dwelf_strtab.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/dwelf_dwarf_gnu_debugaltlink.Po + -rm -f ./$(DEPDIR)/dwelf_elf_begin.Po + -rm -f ./$(DEPDIR)/dwelf_elf_e_machine_string.Po + -rm -f ./$(DEPDIR)/dwelf_elf_gnu_build_id.Po + -rm -f ./$(DEPDIR)/dwelf_elf_gnu_debuglink.Po + -rm -f ./$(DEPDIR)/dwelf_scn_gnu_compressed_size.Po + -rm -f ./$(DEPDIR)/dwelf_strtab.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgincludeHEADERS \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libdwelf/dwelf_dwarf_gnu_debugaltlink.c b/libdwelf/dwelf_dwarf_gnu_debugaltlink.c new file mode 100644 index 00000000..b8285d09 --- /dev/null +++ b/libdwelf/dwelf_dwarf_gnu_debugaltlink.c @@ -0,0 +1,62 @@ +/* Returns the file name and build ID stored in the .gnu_altdebuglink if found. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwelfP.h" + +ssize_t +dwelf_dwarf_gnu_debugaltlink (Dwarf *dwarf, + const char **name_p, + const void **build_idp) +{ + Elf_Data *data = dwarf->sectiondata[IDX_gnu_debugaltlink]; + if (data == NULL) + { + return 0; + } + + const void *ptr = memchr (data->d_buf, '\0', data->d_size); + if (ptr == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_ELF); + return -1; + } + size_t build_id_len = data->d_size - (ptr - data->d_buf + 1); + if (build_id_len == 0 || (size_t) (ssize_t) build_id_len != build_id_len) + { + __libdw_seterrno (DWARF_E_INVALID_ELF); + return -1; + } + *name_p = data->d_buf; + *build_idp = ptr + 1; + return build_id_len; +} +INTDEF(dwelf_dwarf_gnu_debugaltlink) diff --git a/libdwelf/dwelf_elf_begin.c b/libdwelf/dwelf_elf_begin.c new file mode 100644 index 00000000..c7d63a1c --- /dev/null +++ b/libdwelf/dwelf_elf_begin.c @@ -0,0 +1,64 @@ +/* Creates an ELF handle from a possibly compressed file descriptor. + Copyright (C) 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwelfP.h" +#include "libdwflP.h" +#include "libelfP.h" + +#include + +Elf * +dwelf_elf_begin (int fd) +{ + Elf *elf = NULL; + Dwfl_Error e = __libdw_open_elf (fd, &elf); + if (e == DWFL_E_NOERROR) + return elf; + + /* Elf wasn't usable. Make sure there is a proper elf error + message. This is probably not the real error, because there is + no good way to propagate errnos or decompression errors, but + better than nothing. */ + + if (e != DWFL_E_LIBELF) + { + /* Force a bad ELF error. */ + char badelf[EI_NIDENT] = { }; + Elf *belf = elf_memory (badelf, EI_NIDENT); + elf32_getehdr (belf); + elf_end (belf); + } + + return NULL; +} +OLD_VERSION (dwelf_elf_begin, ELFUTILS_0.175) +NEW_VERSION (dwelf_elf_begin, ELFUTILS_0.177) diff --git a/libdwelf/dwelf_elf_e_machine_string.c b/libdwelf/dwelf_elf_e_machine_string.c new file mode 100644 index 00000000..387648e2 --- /dev/null +++ b/libdwelf/dwelf_elf_e_machine_string.c @@ -0,0 +1,406 @@ +/* Returns a human readable description of an ELF header e_machine value. + Copyright (C) 2019 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwelf.h" + + +const char * +dwelf_elf_e_machine_string (int machine) +{ + switch (machine) + { + case EM_NONE: + return "None"; + case EM_M32: + return "WE32100"; + case EM_SPARC: + return "SPARC"; + case EM_386: + return "Intel 80386"; + case EM_68K: + return "M68K"; + case EM_88K: + return "M88K"; + case EM_IAMCU: + return "Intel MCU"; + case EM_860: + return "Intel 80860"; + case EM_MIPS: + return "MIPS R3000"; + case EM_S370: + return "IBM System/370"; + case EM_MIPS_RS3_LE: + return "MIPS R3000"; + case EM_PARISC: + return "HPPA"; + case EM_VPP500: + return "Fujitsu VPP500"; + case EM_SPARC32PLUS: + return "SPARC v8+"; + case EM_960: + return "Intel 80960"; + case EM_PPC: + return "PowerPC"; + case EM_PPC64: + return "PowerPC64"; + case EM_S390: + return "IBM S/390"; + case EM_SPU: + return "IBM SPU/SPC"; + case EM_V800: + return "NEC V800"; + case EM_FR20: + return "Fujitsu FR20"; + case EM_RH32: + return "TRW RH-32"; + case EM_RCE: + return "Motorola RCE"; + case EM_ARM: + return "ARM"; + case EM_FAKE_ALPHA: + return "Digital Alpha"; + case EM_SH: + return "SH"; + case EM_SPARCV9: + return "SPARC v9"; + case EM_TRICORE: + return "Siemens Tricore"; + case EM_ARC: + return "ARC"; + case EM_H8_300: + return "H8/300"; + case EM_H8_300H: + return "H8/300H"; + case EM_H8S: + return "H8S"; + case EM_H8_500: + return "H8/500"; + case EM_IA_64: + return "Intel IA-64"; + case EM_MIPS_X: + return "Stanford MIPS-X"; + case EM_COLDFIRE: + return "Motorola Coldfire"; + case EM_68HC12: + return "Motorola M68HC12"; + case EM_MMA: + return "Fujitsu MMA Multimedia Accelerator"; + case EM_PCP: + return "Siemens PCP"; + case EM_NCPU: + return "Sony nCPU embedded RISC"; + case EM_NDR1: + return "Denso NDR1 microprocessor"; + case EM_STARCORE: + return "Motorola Star*Core processor"; + case EM_ME16: + return "Toyota ME16 processor"; + case EM_ST100: + return "STMicroelectronic ST100"; + case EM_TINYJ: + return "Advanced Logic Corporation Tinyj"; + case EM_X86_64: + return "AMD x86-64"; + case EM_PDSP: + return "Sony DSP Processor"; + case EM_PDP10: + return "Digital PDP-10"; + case EM_PDP11: + return "Digital PDP-11"; + case EM_FX66: + return "Siemens FX66 microcontroller"; + case EM_ST9PLUS: + return "STMicroelectronics ST9+"; + case EM_ST7: + return "STMicroelectronics ST7"; + case EM_68HC16: + return "Motorola MC68HC16 microcontroller"; + case EM_68HC11: + return "Motorola MC68HC11 microcontroller"; + case EM_68HC08: + return "Motorola MC68HC08 microcontroller"; + case EM_68HC05: + return "Motorola MC68HC05 microcontroller"; + case EM_SVX: + return "Silicon Graphics SVx"; + case EM_ST19: + return "STMicroelectronics ST19"; + case EM_VAX: + return "Digital VAX"; + case EM_CRIS: + return "Axis Communications 32-bit embedded processor"; + case EM_JAVELIN: + return "Infineon Technologies 32-bit embedded processor"; + case EM_FIREPATH: + return "Element 14 64-bit DSP Processor"; + case EM_ZSP: + return "LSI Logic 16-bit DSP Processor"; + case EM_MMIX: + return "Donald Knuth's educational 64-bit processor"; + case EM_HUANY: + return "Harvard University machine-independent object"; + case EM_PRISM: + return "SiTera Prism"; + case EM_AVR: + return "Atmel AVR 8-bit microcontroller"; + case EM_FR30: + return "Fujitsu FR30"; + case EM_D10V: + return "Mitsubishi D10V"; + case EM_D30V: + return "Mitsubishi D30V"; + case EM_V850: + return "NEC v850"; + case EM_M32R: + return "Mitsubishi M32R"; + case EM_MN10300: + return "Matsushita MN10300"; + case EM_MN10200: + return "Matsushita MN10200"; + case EM_PJ: + return "picoJava"; + case EM_OPENRISC: + return "OpenRISC"; + case EM_ARC_COMPACT: + return "ARC International ARCompact"; + case EM_XTENSA: + return "Tensilica Xtensa Architecture"; + case EM_VIDEOCORE: + return "Alphamosaic VideoCore"; + case EM_TMM_GPP: + return "Thompson Multimedia General Purpose Processor"; + case EM_NS32K: + return "National Semiconductor 32000"; + case EM_TPC: + return "Tenor Network TPC"; + case EM_SNP1K: + return "Trebia SNP 1000"; + case EM_ST200: + return "STMicroelectronics ST200"; + case EM_IP2K: + return "Ubicom IP2xxx"; + case EM_MAX: + return "MAX processor"; + case EM_CR: + return "National Semiconductor CompactRISC"; + case EM_F2MC16: + return "Fujitsu F2MC16"; + case EM_MSP430: + return "Texas Instruments msp430"; + case EM_BLACKFIN: + return "Analog Devices Blackfin DSP"; + case EM_SE_C33: + return "Seiko Epson S1C33"; + case EM_SEP: + return "Sharp embedded microprocessor"; + case EM_ARCA: + return "Arca RISC"; + case EM_UNICORE: + return "Unicore"; + case EM_EXCESS: + return "eXcess configurable CPU"; + case EM_DXP: + return "Icera Semiconductor Deep Execution Processor"; + case EM_ALTERA_NIOS2: + return "Altera Nios II"; + case EM_CRX: + return "National Semiconductor CompactRISC CRX"; + case EM_XGATE: + return "Motorola XGATE"; + case EM_C166: + return "Infineon C16x/XC16x"; + case EM_M16C: + return "Renesas M16C"; + case EM_DSPIC30F: + return "Microchip Technology dsPIC30F"; + case EM_CE: + return "Freescale Communication Engine RISC"; + case EM_M32C: + return "Renesas M32C"; + case EM_TSK3000: + return "Altium TSK3000"; + case EM_RS08: + return "Freescale RS08"; + case EM_SHARC: + return "Analog Devices SHARC"; + case EM_ECOG2: + return "Cyan Technology eCOG2"; + case EM_SCORE7: + return "Sunplus S+core7 RISC"; + case EM_DSP24: + return "New Japan Radio (NJR) 24-bit DSP"; + case EM_VIDEOCORE3: + return "Broadcom VideoCore III"; + case EM_LATTICEMICO32: + return "RISC for Lattice FPGA"; + case EM_SE_C17: + return "Seiko Epson C17"; + case EM_TI_C6000: + return "Texas Instruments TMS320C6000 DSP"; + case EM_TI_C2000: + return "Texas Instruments TMS320C2000 DSP"; + case EM_TI_C5500: + return "Texas Instruments TMS320C55x DSP"; + case EM_TI_ARP32: + return "Texas Instruments Application Specific RISC"; + case EM_TI_PRU: + return "Texas Instruments Programmable Realtime Unit"; + case EM_MMDSP_PLUS: + return "STMicroelectronics 64bit VLIW DSP"; + case EM_CYPRESS_M8C: + return "Cypress M8C"; + case EM_R32C: + return "Renesas R32C"; + case EM_TRIMEDIA: + return "NXP Semiconductors TriMedia"; + case EM_QDSP6: + return "QUALCOMM DSP6"; + case EM_8051: + return "Intel 8051 and variants"; + case EM_STXP7X: + return "STMicroelectronics STxP7x"; + case EM_NDS32: + return "Andes Technology compact code size embedded RISC"; + case EM_ECOG1X: + return "Cyan Technology eCOG1X"; + case EM_MAXQ30: + return "Dallas Semiconductor MAXQ30"; + case EM_XIMO16: + return "New Japan Radio (NJR) 16-bit DSP"; + case EM_MANIK: + return "M2000 Reconfigurable RISC"; + case EM_CRAYNV2: + return "Cray NV2 vector architecture"; + case EM_RX: + return "Renesas RX"; + case EM_METAG: + return "Imagination Technologies META"; + case EM_MCST_ELBRUS: + return "MCST Elbrus"; + case EM_ECOG16: + return "Cyan Technology eCOG16"; + case EM_CR16: + return "National Semiconductor CompactRISC"; + case EM_ETPU: + return "Freescale Extended Time Processing Unit"; + case EM_SLE9X: + return "Infineon Technologies SLE9X"; + case EM_L10M: + return "Intel L10M"; + case EM_K10M: + return "Intel K10M"; + case EM_AARCH64: + return "AARCH64"; + case EM_AVR32: + return "Amtel AVR32"; + case EM_STM8: + return "STMicroelectronics STM8"; + case EM_TILE64: + return "Tilera TILE64"; + case EM_TILEPRO: + return "Tilera TILEPro"; + case EM_MICROBLAZE: + return "Xilinx MicroBlaze"; + case EM_CUDA: + return "NVIDIA CUDA"; + case EM_TILEGX: + return "Tilera TILE-Gx"; + case EM_CLOUDSHIELD: + return "CloudShield"; + case EM_COREA_1ST: + return "KIPO-KAIST Core-A 1st gen"; + case EM_COREA_2ND: + return "KIPO-KAIST Core-A 2nd gen"; + case EM_ARCV2: + return "Synopsys ARCv2 ISA"; + case EM_OPEN8: + return "Open8 RISC"; + case EM_RL78: + return "Renesas RL78"; + case EM_VIDEOCORE5: + return "Broadcom VideoCore V"; + case EM_78KOR: + return "Renesas 78KOR"; + case EM_56800EX: + return "Freescale 56800EX DSC"; + case EM_BA1: + return "Beyond BA1"; + case EM_BA2: + return "Beyond BA2"; + case EM_XCORE: + return "XMOS xCORE"; + case EM_MCHP_PIC: + return "Microchip 8-bit PIC"; + case EM_KM32: + return "KM211 KM32"; + case EM_KMX32: + return "KM211 KMX32"; + case EM_EMX16: + return "KM211 KMX16"; + case EM_EMX8: + return "KM211 KMX8"; + case EM_KVARC: + return "KM211 KVARC"; + case EM_CDP: + return "Paneve CDP"; + case EM_COGE: + return "Cognitive Smart Memory Processor"; + case EM_COOL: + return "Bluechip CoolEngine"; + case EM_NORC: + return "Nanoradio Optimized RISC"; + case EM_CSR_KALIMBA: + return "CSR Kalimba"; + case EM_Z80: + return "Zilog Z80"; + case EM_VISIUM: + return "CDS VISIUMcore"; + case EM_FT32: + return "FTDI Chip FT32"; + case EM_MOXIE: + return "Moxie"; + case EM_AMDGPU: + return "AMD GPU"; + case EM_RISCV: + return "RISC-V"; + case EM_BPF: + return "BPF"; + case EM_CSKY: + return "C-SKY"; + + case EM_ALPHA: + return "Alpha"; + + default: + return NULL; + } +} diff --git a/libdwelf/dwelf_elf_gnu_build_id.c b/libdwelf/dwelf_elf_gnu_build_id.c new file mode 100644 index 00000000..dbcfc829 --- /dev/null +++ b/libdwelf/dwelf_elf_gnu_build_id.c @@ -0,0 +1,158 @@ +/* Returns the build id if found in a NT_GNU_BUILD_ID note. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwelfP.h" +#include "libdwflP.h" + +#define NO_VADDR ((GElf_Addr) -1l) + +static int +check_notes (Elf_Data *data, GElf_Addr data_elfaddr, + const void **build_id_bits, GElf_Addr *build_id_elfaddr, + int *build_id_len) +{ + size_t pos = 0; + GElf_Nhdr nhdr; + size_t name_pos; + size_t desc_pos; + while ((pos = gelf_getnote (data, pos, &nhdr, &name_pos, &desc_pos)) > 0) + if (nhdr.n_type == NT_GNU_BUILD_ID + && nhdr.n_namesz == sizeof "GNU" + && !memcmp (data->d_buf + name_pos, "GNU", sizeof "GNU")) + { + *build_id_bits = data->d_buf + desc_pos; + *build_id_elfaddr = (data_elfaddr == NO_VADDR + ? 0 : data_elfaddr + desc_pos); + *build_id_len = nhdr.n_descsz; + return 1; + } + return 0; +} + +/* Defined here for reuse. The dwelf interface doesn't care about the + address of the note, but libdwfl does. */ +static int +find_elf_build_id (Dwfl_Module *mod, int e_type, Elf *elf, + const void **build_id_bits, GElf_Addr *build_id_elfaddr, + int *build_id_len) +{ + size_t shstrndx = SHN_UNDEF; + int result = 0; + + Elf_Scn *scn = elf_nextscn (elf, NULL); + + if (scn == NULL) + { + /* No sections, have to look for phdrs. */ + size_t phnum; + if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) + { + if (mod != NULL) + __libdwfl_seterrno (DWFL_E_LIBELF); + return -1; + } + for (size_t i = 0; result == 0 && i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (likely (phdr != NULL) && phdr->p_type == PT_NOTE) + result = check_notes (elf_getdata_rawchunk (elf, + phdr->p_offset, + phdr->p_filesz, + (phdr->p_align == 8 + ? ELF_T_NHDR8 + : ELF_T_NHDR)), + phdr->p_vaddr, + build_id_bits, + build_id_elfaddr, + build_id_len); + } + } + else + do + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (likely (shdr != NULL) && shdr->sh_type == SHT_NOTE) + { + /* Determine the right sh_addr in this module. */ + GElf_Addr vaddr = 0; + if (!(shdr->sh_flags & SHF_ALLOC)) + vaddr = NO_VADDR; + else if (mod == NULL || e_type != ET_REL) + vaddr = shdr->sh_addr; + else if (__libdwfl_relocate_value (mod, elf, &shstrndx, + elf_ndxscn (scn), &vaddr)) + vaddr = NO_VADDR; + result = check_notes (elf_getdata (scn, NULL), vaddr, + build_id_bits, + build_id_elfaddr, + build_id_len); + } + } + while (result == 0 && (scn = elf_nextscn (elf, scn)) != NULL); + + return result; +} + +int +internal_function +__libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf, + const void **build_id_bits, + GElf_Addr *build_id_elfaddr, int *build_id_len) +{ + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (unlikely (ehdr == NULL)) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return -1; + } + // MOD->E_TYPE is zero here. + assert (ehdr->e_type != ET_REL || mod != NULL); + + return find_elf_build_id (mod, ehdr->e_type, elf, + build_id_bits, build_id_elfaddr, build_id_len); +} + +ssize_t +dwelf_elf_gnu_build_id (Elf *elf, const void **build_idp) +{ + GElf_Addr build_id_elfaddr; + int build_id_len; + int result = find_elf_build_id (NULL, ET_NONE, elf, build_idp, + &build_id_elfaddr, &build_id_len); + if (result > 0) + return build_id_len; + + return result; +} +INTDEF(dwelf_elf_gnu_build_id) diff --git a/libdwelf/dwelf_elf_gnu_debuglink.c b/libdwelf/dwelf_elf_gnu_debuglink.c new file mode 100644 index 00000000..6e22cf67 --- /dev/null +++ b/libdwelf/dwelf_elf_gnu_debuglink.c @@ -0,0 +1,99 @@ +/* Returns the file name and crc stored in the .gnu_debuglink if found. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwelfP.h" + +const char * +dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc) +{ + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) < 0) + return NULL; + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + return NULL; + + const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (name == NULL) + return NULL; + + if (!strcmp (name, ".gnu_debuglink")) + break; + } + + if (scn == NULL) + return NULL; + + /* Found the .gnu_debuglink section. Extract its contents. */ + Elf_Data *rawdata = elf_rawdata (scn, NULL); + if (rawdata == NULL || rawdata->d_buf == NULL) + return NULL; + + /* The CRC comes after the zero-terminated file name, + (aligned up to 4 bytes) at the end of the section data. */ + if (rawdata->d_size <= sizeof *crc + || memchr (rawdata->d_buf, '\0', rawdata->d_size - sizeof *crc) == NULL) + return NULL; + + Elf_Data crcdata = + { + .d_type = ELF_T_WORD, + .d_buf = crc, + .d_size = sizeof *crc, + .d_version = EV_CURRENT, + }; + Elf_Data conv = + { + .d_type = ELF_T_WORD, + .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc, + .d_size = sizeof *crc, + .d_version = EV_CURRENT, + }; + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + return NULL; + + Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]); + if (d == NULL) + return NULL; + assert (d == &crcdata); + + return rawdata->d_buf; +} +INTDEF(dwelf_elf_gnu_debuglink) diff --git a/libdwelf/dwelf_scn_gnu_compressed_size.c b/libdwelf/dwelf_scn_gnu_compressed_size.c new file mode 100644 index 00000000..d39b702a --- /dev/null +++ b/libdwelf/dwelf_scn_gnu_compressed_size.c @@ -0,0 +1,77 @@ +/* Return size of GNU compressed section. + Copyright (C) 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwelfP.h" +#include "libelfP.h" + +ssize_t +dwelf_scn_gnu_compressed_size (Elf_Scn *scn) +{ + if (scn == NULL) + return -1; + + GElf_Shdr shdr; + if (gelf_getshdr (scn, &shdr) == NULL) + return -1; + + /* Allocated or no bits sections can never be compressed. */ + if ((shdr.sh_flags & SHF_ALLOC) != 0 + || shdr.sh_type == SHT_NULL + || shdr.sh_type == SHT_NOBITS) + return -1; + + Elf_Data *d = elf_rawdata (scn, NULL); + if (d == NULL) + return -1; + + if (d->d_size >= 4 + 8 + && memcmp (d->d_buf, "ZLIB", 4) == 0) + { + /* There is a 12-byte header of "ZLIB" followed by + an 8-byte big-endian size. There is only one type and + alignment isn't preserved separately. */ + uint64_t size; + memcpy (&size, d->d_buf + 4, sizeof size); + size = be64toh (size); + + /* One more sanity check, size should be bigger than original + data size plus some overhead (4 chars ZLIB + 8 bytes size + 6 + bytes zlib stream overhead + 5 bytes overhead max for one 16K + block) and should fit into a size_t. */ + if (size + 4 + 8 + 6 + 5 < d->d_size || size > SIZE_MAX) + return -1; + + return size; + } + + return -1; +} diff --git a/libdwelf/dwelf_strtab.c b/libdwelf/dwelf_strtab.c new file mode 100644 index 00000000..c6ae7cdf --- /dev/null +++ b/libdwelf/dwelf_strtab.c @@ -0,0 +1,360 @@ +/* ELF/DWARF string table handling. + Copyright (C) 2000, 2001, 2002, 2005, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "libdwelfP.h" +#include + + +struct Dwelf_Strent +{ + const char *string; + size_t len; + struct Dwelf_Strent *next; + struct Dwelf_Strent *left; + struct Dwelf_Strent *right; + size_t offset; + char reverse[0]; +}; + + +struct memoryblock +{ + struct memoryblock *next; + char memory[0]; +}; + + +struct Dwelf_Strtab +{ + struct Dwelf_Strent *root; + struct memoryblock *memory; + char *backp; + size_t left; + size_t total; + bool nullstr; + + struct Dwelf_Strent null; +}; + + +/* Cache for the pagesize. */ +static size_t ps; +/* We correct this value a bit so that `malloc' is not allocating more + than a page. */ +#define MALLOC_OVERHEAD (2 * sizeof (void *)) + + +Dwelf_Strtab * +dwelf_strtab_init (bool nullstr) +{ + if (ps == 0) + { + ps = sysconf (_SC_PAGESIZE); + assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD); + } + + Dwelf_Strtab *ret + = (Dwelf_Strtab *) calloc (1, sizeof (struct Dwelf_Strtab)); + if (ret != NULL) + { + ret->nullstr = nullstr; + + if (nullstr) + { + ret->null.len = 1; + ret->null.string = ""; + } + } + + return ret; +} + + +static int +morememory (Dwelf_Strtab *st, size_t len) +{ + size_t overhead = offsetof (struct memoryblock, memory); + len += overhead + MALLOC_OVERHEAD; + + /* Allocate nearest multiple of pagesize >= len. */ + len = ((len / ps) + (len % ps != 0)) * ps - MALLOC_OVERHEAD; + + struct memoryblock *newmem = (struct memoryblock *) malloc (len); + if (newmem == NULL) + return 1; + + newmem->next = st->memory; + st->memory = newmem; + st->backp = newmem->memory; + st->left = len - overhead; + + return 0; +} + + +void +dwelf_strtab_free (Dwelf_Strtab *st) +{ + struct memoryblock *mb = st->memory; + + while (mb != NULL) + { + void *old = mb; + mb = mb->next; + free (old); + } + + free (st); +} + + +static Dwelf_Strent * +newstring (Dwelf_Strtab *st, const char *str, size_t len) +{ + /* Compute the amount of padding needed to make the structure aligned. */ + size_t align = ((__alignof__ (struct Dwelf_Strent) + - (((uintptr_t) st->backp) + & (__alignof__ (struct Dwelf_Strent) - 1))) + & (__alignof__ (struct Dwelf_Strent) - 1)); + + /* Make sure there is enough room in the memory block. */ + if (st->left < align + sizeof (struct Dwelf_Strent) + len) + { + if (morememory (st, sizeof (struct Dwelf_Strent) + len)) + return NULL; + + align = 0; + } + + /* Create the reserved string. */ + Dwelf_Strent *newstr = (Dwelf_Strent *) (st->backp + align); + newstr->string = str; + newstr->len = len; + newstr->next = NULL; + newstr->left = NULL; + newstr->right = NULL; + newstr->offset = 0; + for (int i = len - 2; i >= 0; --i) + newstr->reverse[i] = str[len - 2 - i]; + newstr->reverse[len - 1] = '\0'; + st->backp += align + sizeof (struct Dwelf_Strent) + len; + st->left -= align + sizeof (struct Dwelf_Strent) + len; + + return newstr; +} + + +/* XXX This function should definitely be rewritten to use a balancing + tree algorithm (AVL, red-black trees). For now a simple, correct + implementation is enough. */ +static Dwelf_Strent ** +searchstring (Dwelf_Strent **sep, Dwelf_Strent *newstr) +{ + /* More strings? */ + if (*sep == NULL) + { + *sep = newstr; + return sep; + } + + /* Compare the strings. */ + int cmpres = memcmp ((*sep)->reverse, newstr->reverse, + MIN ((*sep)->len, newstr->len) - 1); + if (cmpres == 0) + /* We found a matching string. */ + return sep; + else if (cmpres > 0) + return searchstring (&(*sep)->left, newstr); + else + return searchstring (&(*sep)->right, newstr); +} + + +/* Add new string. The actual string is assumed to be permanent. */ +static Dwelf_Strent * +strtab_add (Dwelf_Strtab *st, const char *str, size_t len) +{ + /* Make sure all "" strings get offset 0 but only if the table was + created with a special null entry in mind. */ + if (len == 1 && st->null.string != NULL) + return &st->null; + + /* Allocate memory for the new string and its associated information. */ + Dwelf_Strent *newstr = newstring (st, str, len); + if (newstr == NULL) + return NULL; + + /* Search in the array for the place to insert the string. If there + is no string with matching prefix and no string with matching + leading substring, create a new entry. */ + Dwelf_Strent **sep = searchstring (&st->root, newstr); + if (*sep != newstr) + { + /* This is not the same entry. This means we have a prefix match. */ + if ((*sep)->len > newstr->len) + { + /* Check whether we already know this string. */ + for (Dwelf_Strent *subs = (*sep)->next; subs != NULL; + subs = subs->next) + if (subs->len == newstr->len) + { + /* We have an exact match with a substring. Free the memory + we allocated. */ + st->left += st->backp - (char *) newstr; + st->backp = (char *) newstr; + + return subs; + } + + /* We have a new substring. This means we don't need the reverse + string of this entry anymore. */ + st->backp -= newstr->len; + st->left += newstr->len; + + newstr->next = (*sep)->next; + (*sep)->next = newstr; + } + else if ((*sep)->len != newstr->len) + { + /* When we get here it means that the string we are about to + add has a common prefix with a string we already have but + it is longer. In this case we have to put it first. */ + st->total += newstr->len - (*sep)->len; + newstr->next = *sep; + newstr->left = (*sep)->left; + newstr->right = (*sep)->right; + *sep = newstr; + } + else + { + /* We have an exact match. Free the memory we allocated. */ + st->left += st->backp - (char *) newstr; + st->backp = (char *) newstr; + + newstr = *sep; + } + } + else + st->total += newstr->len; + + return newstr; +} + +Dwelf_Strent * +dwelf_strtab_add (Dwelf_Strtab *st, const char *str) +{ + return strtab_add (st, str, strlen (str) + 1); +} + +Dwelf_Strent * +dwelf_strtab_add_len (Dwelf_Strtab *st, const char *str, size_t len) +{ + return strtab_add (st, str, len); +} + +static void +copystrings (Dwelf_Strent *nodep, char **freep, size_t *offsetp) +{ + if (nodep->left != NULL) + copystrings (nodep->left, freep, offsetp); + + /* Process the current node. */ + nodep->offset = *offsetp; + *freep = (char *) mempcpy (*freep, nodep->string, nodep->len); + *offsetp += nodep->len; + + for (Dwelf_Strent *subs = nodep->next; subs != NULL; subs = subs->next) + { + assert (subs->len < nodep->len); + subs->offset = nodep->offset + nodep->len - subs->len; + assert (subs->offset != 0 || subs->string[0] == '\0'); + } + + if (nodep->right != NULL) + copystrings (nodep->right, freep, offsetp); +} + + +Elf_Data * +dwelf_strtab_finalize (Dwelf_Strtab *st, Elf_Data *data) +{ + size_t nulllen = st->nullstr ? 1 : 0; + + /* Fill in the information. */ + data->d_buf = malloc (st->total + nulllen); + if (data->d_buf == NULL) + return NULL; + + /* The first byte must always be zero if we created the table with a + null string. */ + if (st->nullstr) + *((char *) data->d_buf) = '\0'; + + data->d_type = ELF_T_BYTE; + data->d_size = st->total + nulllen; + data->d_off = 0; + data->d_align = 1; + data->d_version = EV_CURRENT; + + /* Now run through the tree and add all the string while also updating + the offset members of the elfstrent records. */ + char *endp = (char *) data->d_buf + nulllen; + size_t copylen = nulllen; + if (st->root) + copystrings (st->root, &endp, ©len); + assert (copylen == st->total + nulllen); + + return data; +} + + +size_t +dwelf_strent_off (Dwelf_Strent *se) +{ + return se->offset; +} + + +const char * +dwelf_strent_str (Dwelf_Strent *se) +{ + return se->string; +} diff --git a/libdwelf/libdwelf.h b/libdwelf/libdwelf.h new file mode 100644 index 00000000..263ca60e --- /dev/null +++ b/libdwelf/libdwelf.h @@ -0,0 +1,147 @@ +/* Interfaces for libdwelf. DWARF ELF Low-level Functions. + Copyright (C) 2014, 2015, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBDWELF_H +#define _LIBDWELF_H 1 + +#include "libdw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* DWARF ELF Low-level Functions (dwelf). + Functions starting with dwelf_elf will take a (libelf) Elf object as + first argument and might set elf_errno on error. Functions starting + with dwelf_dwarf will take a (libdw) Dwarf object as first argument + and might set dwarf_errno on error. */ + +/* Returns the name and the CRC32 of the separate debug file from the + .gnu_debuglink section if found in the ELF. Return NULL if the ELF + file didn't have a .gnu_debuglink section, had malformed data in the + section or some other error occurred. */ +extern const char *dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc); + +/* Returns the name and build ID from the .gnu_debugaltlink section if + found in the ELF. On success, pointers to the name and build ID + are written to *NAMEP and *BUILDID_P, and the positive length of + the build ID is returned. Returns 0 if the ELF lacks a + .gnu_debugaltlink section. Returns -1 in case of malformed data or + other errors. */ +extern ssize_t dwelf_dwarf_gnu_debugaltlink (Dwarf *dwarf, + const char **namep, + const void **build_idp); + +/* Returns the build ID as found in a NT_GNU_BUILD_ID note from either + a SHT_NOTE section or from a PT_NOTE segment if the ELF file + doesn't contain any section headers. On success a pointer to the + build ID is written to *BUILDID_P, and the positive length of the + build ID is returned. Returns 0 if the ELF lacks a NT_GNU_BUILD_ID + note. Returns -1 in case of malformed data or other errors. */ +extern ssize_t dwelf_elf_gnu_build_id (Elf *elf, const void **build_idp); + +/* Returns the size of the uncompressed data of a GNU compressed + section. The section name should start with .zdebug (but this + isn't checked by this function). If the section isn't compressed + (the section data doesn't start with ZLIB) -1 is returned. If an + error occurred -1 is returned and elf_errno is set. */ +extern ssize_t dwelf_scn_gnu_compressed_size (Elf_Scn *scn); + +/* ELF/DWARF string table handling. */ +typedef struct Dwelf_Strtab Dwelf_Strtab; +typedef struct Dwelf_Strent Dwelf_Strent; + +/* Create a new ELF/DWARF string table object in memory. ELF string + tables have a required zero length null string at offset zero. + DWARF string tables don't require such a null entry (unless they + are shared with an ELF string table). If NULLSTR is true then a + null entry is always created (even if the string table is empty + otherwise). */ +extern Dwelf_Strtab *dwelf_strtab_init (bool nullstr); + +/* Add string STR to string table ST. Returns NULL if no memory could + be allocated. The given STR is owned by the called and must be + valid till dwelf_strtab_free is called. dwelf_strtab_finalize + might copy the string into the final table and dwelf_strent_str + might return it, or a reference to an identical copy/substring + added to the string table. */ +extern Dwelf_Strent *dwelf_strtab_add (Dwelf_Strtab *st, const char *str) + __nonnull_attribute__ (1, 2); + +/* This is an optimized version of dwelf_strtab_add if the length of + the string is already known. LEN is the length of STR including + zero terminator. Calling dwelf_strtab_add (st, str) is similar to + calling dwelf_strtab_len (st, str, strlen (str) + 1). */ +extern Dwelf_Strent *dwelf_strtab_add_len (Dwelf_Strtab *st, + const char *str, size_t len) + __nonnull_attribute__ (1, 2); + +/* Finalize string table ST and store size and memory location + information in DATA d_size and d_buf. DATA d_type will be set to + ELF_T_BYTE, d_off will be zero, d_align will be 1 and d_version + will be set to EV_CURRENT. If no memory could be allocated NULL is + returned and DATA->d_buf will be set to NULL. Otherwise DATA will + be returned. */ +extern Elf_Data *dwelf_strtab_finalize (Dwelf_Strtab *st, + Elf_Data *data) + __nonnull_attribute__ (1, 2); + +/* Get offset in string table for string associated with entry. Only + valid after dwelf_strtab_finalize has been called. */ +extern size_t dwelf_strent_off (Dwelf_Strent *se) + __nonnull_attribute__ (1); + +/* Return the string associated with the entry. */ +extern const char *dwelf_strent_str (Dwelf_Strent *se) + __nonnull_attribute__ (1); + +/* Free resources allocated for the string table. This invalidates + any Dwelf_Strent references returned earlier. */ +extern void dwelf_strtab_free (Dwelf_Strtab *st) + __nonnull_attribute__ (1); + +/* Creates a read-only Elf handle from the given file handle. The + file may be compressed and/or contain a linux kernel image header, + in which case it is eagerly decompressed in full and the Elf handle + is created as if created with elf_memory (). On decompression or + file errors NULL is returned (and elf_errno will be set). If there + was no error, but the file is not an ELF file, then an ELF_K_NONE + Elf handle is returned (just like with elf_begin). The Elf handle + should be closed with elf_end (). The file handle will not be + closed. */ +extern Elf *dwelf_elf_begin (int fd); + +/* Returns a human readable string for the given ELF header e_machine + value, or NULL if the given number isn't currently known. */ +extern const char *dwelf_elf_e_machine_string (int machine); + +#ifdef __cplusplus +} +#endif + +#endif /* libdwelf.h */ diff --git a/libdwelf/libdwelfP.h b/libdwelf/libdwelfP.h new file mode 100644 index 00000000..d83c759a --- /dev/null +++ b/libdwelf/libdwelfP.h @@ -0,0 +1,42 @@ +/* Internal definitions for libdwelf. DWARF ELF Low-level Functions. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBDWELFP_H +#define _LIBDWELFP_H 1 + +#include +#include "../libdw/libdwP.h" /* We need its INTDECLs. */ +#include +#include + +/* Avoid PLT entries. */ +INTDECL (dwelf_elf_gnu_debuglink) +INTDECL (dwelf_dwarf_gnu_debugaltlink) +INTDECL (dwelf_elf_gnu_build_id) + +#endif /* libdwelfP.h */ diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog new file mode 100644 index 00000000..fedf65a4 --- /dev/null +++ b/libdwfl/ChangeLog @@ -0,0 +1,3310 @@ +2021-04-19 Martin Liska + + * dwfl_frame.c (dwfl_attach_state): Use startswith. + * dwfl_module_getdwarf.c (find_symtab): Likewise. + * linux-kernel-modules.c: Likewise. + * linux-pid-attach.c (linux_proc_pid_is_stopped): Likewise. + (dwfl_linux_proc_attach): Likewise. + * relocate.c (resolve_symbol): Likewise. + (relocate_section): Likewise. + +2021-02-01 Érico Nogueira + + * dwfl_error.c (strerror_r): Only use the GNU version when available. + +2021-01-08 Timm Bäder + + * elf-from-memory.c (elf_from_remote_memory): Add for loop over + switch. inline handle_segment call, set vaddr, offset and filesz + directly based on class. + +2021-01-08 Timm Bäder + + * elf-from-memory.c (elf_from_remote_memory): Use if instead of + switch on class. Set new vaddr, memsz, offset and filesz + variables. Inline handle_segment function check and set loadbase, + found_base, segments_end and segments_end_mem directly. + +2020-12-16 Dmitry V. Levin + + * argp-std.c (_): Remove. + * libdwflP.h (_): Likewise. + +2020-12-12 Dmitry V. Levin + + * libdwfl.h: Fix spelling typos in comments. + * dwfl_module_getdwarf.c (open_elf, find_symtab): Likewise. + * dwfl_report_elf.c (__libdwfl_elf_address_range): Likewise. + * linux-pid-attach.c (read_cached_memory): Likewise. + +2020-12-07 Timm Bäder + + * link_map.c (report_r_debug): Pull read_addrs() function into + file scope. + +2020-12-07 Timm Bäder + + * link_map.c (report_r_debug): Pull release_buffer() function into + file scope. Add memory_closure struct. + +2020-12-08 Dmitry V. Levin + + * debuginfod-client.c (__libdwfl_debuginfod_init): Replace + "libdebuginfod-" VERSION ".so" with DEBUGINFOD_SONAME in dlopen call. + Do not fall back to dlopen of "libdebuginfod.so". + +2020-12-01 Timm Bäder + + * link_map.c (dwfl_link_map_report): Removed consider_phdr function + and inline code. + +2020-11-28 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Use GElf_Addr to calculate note_vaddr instead of size_t. + +2020-11-26 Timm Bäder + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Remove consider_notes function. Inline code for type == PT_NOTE. + +2020-11-26 Timm Bäder + + * dwfl_segment_report_module.c (read_portion): New static function. + (dwfl_segment_report_module): Remove read_portion function. + Call static function with read_state, start and segment. + +2020-11-26 Timm Bäder + + * dwfl_segment_report_module.c (struct read_state): New. + (finish_portion): New static function. + (dwfl_segment_report_module): Introduce read_state. Remove + finish_portion function. Call static function with read_state. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Remove + consider_phdr, do checks inline. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Remove + consider_dyn, do checks inline. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Do one + loop check for d32/d64 arrays. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Remove + read_phdr, do check and call memory_callback directly. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Do one + loop check for p32/p64 arrays. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Remove + final_read, call memory_callback directly. + +2020-11-23 Timm Bäder + + * segment_report_module.c (struct elf_build_id): New. + (dwfl_segment_report_module): Pass build_id as struct. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Remove + release_buffer, call memory_callback directly. + +2020-11-23 Timm Bäder + + * segment_report_module.c (dwfl_segment_report_module): Remove + segment_read, call memory_callback directly. + +2020-11-19 Andreas Krebbel + + * linux-pid-attach.c (pid_memory_read): Shift the upper 4 bytes + down on big endian 64 bit targets. + +2020-11-12 Timm Bäder + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Remove + finish function, replace with goto out. + +2020-11-12 Timm Bäder + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Declare + p32 and p64 as pointers instead of arrays. + +2020-09-18 Mark Wielaard + + * zstd.c: New file. + * libdwflP.h: Add DWFL_E_ZSTD and __libdw_unzstd. + * Makefile.am (libdwfl_a_SOURCES): add zstd.c if ZSTD. + * gzip.c: Add defines and includes for ZSTD. + (zlib_fail): Don't define for ZSTD. + (unzip): Change pread_retry failure from zlib_fail to fail. + Add ZSTD support. + * open.c (decompress): Also try __libdw_unzstd. + * linux-kernel-modules.c (check_suffix): Also TRY ".ko.zst". + +2020-08-20 Dmitry V. Levin + + * Makefile.am (libdwfl_a_SOURCES): Conditionalize + debuginfod-client.c on LIBDEBUGINFOD. + * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Conditionalize + __libdwfl_debuginfod_find_executable invocation on + ENABLE_LIBDEBUGINFOD. + * dwfl_end.c (dwfl_end): Conditionalize __libdwfl_debuginfod_end + invocation on ENABLE_LIBDEBUGINFOD. + * find-debuginfo.c (dwfl_standard_find_debuginfo): Conditionalize + __libdwfl_debuginfod_find_debuginfo invocation on + ENABLE_LIBDEBUGINFOD. + * libdwflP.h: Guard debuginfod.h include with ENABLE_LIBDEBUGINFOD. + (struct Dwfl): Guard debuginfod field with ENABLE_LIBDEBUGINFOD. + (__libdwfl_debuginfod_find_executable, + __libdwfl_debuginfod_find_debuginfo, __libdwfl_debuginfod_end): + Guard declarations with ENABLE_LIBDEBUGINFOD. + +2020-07-05 Mark Wielaard + + * argp-std.c (parse_opt): Don't assert, but call fail when + dwfl_report_end fails. + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Don't + assert, but goto bad_id when snprintf fails. + * frame_unwind.c (__libdwfl_frame_unwind): Don't assert, but + return when dwfl_frame_pc fails. + * linux-core-attach.c (core_set_initial_registers): Don't assert, + but return false when gelf_getnote fails or the core note is not + as expected. + * linux-pid-attach.c (dwfl_linux_proc_attach): Don't assert, but + goto fail when snprintf fails. + +2020-06-16 Mark Wielaard + + * frame_unwind.c (handle_cfi): Flag an error if + return_address_register is invalid. + +2020-06-16 Mark Wielaard + + * linux-kernel-modules.c (try_kernel_name): Don't try other + compressed kernels if we already found an compressed image. + +2020-05-09 Mark Wielaard + + * find-debuginfo.c (dwfl_standard_find_debuginfo): Return failure + when mod is NULL. + +2020-05-08 Mark Wielaard + + * libdwfl/core-file.c (dwfl_core_file_report): Keep track of + new bool cleanup_user_core and cleanup dwfl->user_core in error + case. + +2020-04-30 Mark Wielaard + + * find-debuginfo.c (dwfl_standard_find_debuginfo): When mod->dw + is already set then try fetching debugaltlink. + +2020-04-25 Mark Wielaard + + * gzip.c (open_stream): Return DWFL_E_NOMEM instead of calling + zlib_fail. + +2020-04-16 Mark Wielaard + + * find-debuginfo.c (dwfl_standard_find_debuginfo): Initialize bits + to NULL. + +2020-01-24 Mark Wielaard + + * linux-kernel-modules.c (find_kernel_elf): Check release isn't NULL. + (report_kernel): Check release and *release aren't NULL. + (report_kernel_archive): Likewise. + +2019-12-11 Omar Sandoval + + * libdwflP.h (Dwfl_Module): Remove coalescing state. + Rename lookup_tail_ndx to next_segndx. + * segment.c (dwfl_report_segment): Remove coalescing logic. + * libdwfl.h (dwfl_report_segment): Document that IDENT is ignored. + +2019-12-05 Mark Wielaard + + * linux-kernel-modules.c (find_kernel_elf): Also try to find + vmlinux image. + +2019-10-28 Aaron Merey + + * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Call debuginfod + client functions via dlopen to look for elf/dwarf files as fallback. + * find-debuginfo.c (dwfl_standard_find_debuginfo): Ditto. + +2019-10-07 Omar Sandoval + + * dwfl_frame.c (dwfl_getthreads): Get rid of unnecessary + thread_free_all_states calls. + (getthread): Ditto. + (state_free): Remove function. + (thread_free_all_states): Remove function. + (free_states): Add function. + (dwfl_thread_getframes): Don't update thread->unwound while unwinding. + * libdwflP.h (struct Dwfl_Thread): Update comment for unwound member. + +2019-08-12 Mark Wielaard + + * gzip.c (open_stream): Return DWFL_E_ERRNO on bad file operation. + * open.c (libdw_open_elf): New argument bad_elf_ok. Check it and + return DWFL_E_NOERROR in case it is set and error was DWFL_E_BADELF. + (__libdw_open_file): Call libdw_open_elf with bad_elf_ok false. + (__libdw_open_elf): Call libdw_open_elf with bad_elf_ok true. + +2019-08-05 Omar Sandoval + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Assign + mod->main.fd. + +2019-04-28 Mark Wielaard + + * frame_unwind.c (expr_eval): Make sure we left shift a unsigned + 64bit value. + +2019-04-28 Mark Wielaard + + * cu.c (addrarange): Only call realloc when naranges is not zero. + +2019-03-27 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Check + ph_buffer_size vs xlatefrom.d_size after read_portion call. + +2019-02-24 Mark Wielaard + + * linux-kernel-modules.c (intuit_kernel_bounds): Init *notes before + fopen. + (dwfl_linux_kernel_report_kernel): Remove fake note init empty asm. + +2019-01-25 Yonghong Song + + * linux-proc-maps.c (proc_maps_report): Use PRIu64, not PRIi64, to + read the inode number. + +2019-01-20 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Check + dyn_filesz vs dyn_data_size after read_portion call. + +2019-01-16 Mark Wielaard + + * linux-core-attach.c (core_next_thread): Pass desc to ebl_core_note. + (core_set_initial_registers): Likewise. + +2018-10-23 Mark Wielaard + + * relocate.c (relocate_section): Only sanity check mmapped Elf files + for overlap. Don't error when section data was malloced, not mmapped. + +2018-10-20 Mark Wielaard + + * libdwflP.h (__libdw_open_elf): New internal function declaration. + * open.c (what_kind): Rename close_fd to may_close_fd. + (__libdw_open_file): Replaced (and renamed) by a call to ... + (libdw_open_elf): this. And add never_close_fd argument. + (__libdw_open_elf): New function that calls libdw_open_elf. + +2018-10-18 Mark Wielaard + + * dwfl_segment_report_module.c (consider_note): Take align as new + argument. Use align to set d_type and calculate padding. + (dwfl_segment_report_module): Pass align to consider_notes. + * core-file.c (dwfl_core_file_report): Check p_align to set ELF + type. + * linux-kernel-modules.c (check_notes): Check name and type of note + to determine padding. + +2018-10-19 Mark Wielaard + + * dwfl_module_getdwarf.c (find_aux_sym): Check sh_entsize is not zero. + +2018-10-14 Mark Wielaard + + * dwfl_segment_report_module.c (read_portion): Check requested + filesz isn't larger than buffer_available. + (dwfl_segment_report_module): Check data_size vs filesz after + read_portion call. + +2018-10-02 Andreas Schwab + + * relocate.c (relocate): Handle ADD/SUB relocations. + +2018-09-13 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Document why we use e_shnum directly. + * elf-from-memory.c (elf_from_remote_memory): Likewise. + +2018-07-17 Ulf Hermann + + * linux-pid-attach.c: Include sys/uio.h only on linux. + +2018-06-04 Mark Wielaard + + * libdwflP.h (__libdwfl_addrsym): Remove function declaration. + * dwfl_module_addrsym.c (__libdwfl_addrsym): Make a static function. + +2018-05-27 Mark Wielaard + + * relocate.c (__libdwfl_relocate): Always call relocate_section with + partial true. + +2018-05-17 Mark Wielaard + + * dwfl_module (__libdwfl_module_free): Free elfdir. + * dwfl_module_getdwarf.c (load_dw): Close file descriptors after + dwarf_begin_elf call. Set Dwarf debugdir if it is NULL, this is the + main module file and we recorded the elfdir. + * libdwflP.h (struct Dwfl_Module): Add elfdir field. + * offline.c (process_elf): Record the elfdir before we close the + main ELF file descriptor. + +2018-04-10 Mark Wielaard + + * frame_unwind.c (unwind): If __libdwfl_frame_reg_get fails for + the return address either set an error or mark the pc undefined. + +2018-03-17 Mark Wielaard + + * libdwflP.h (struct __libdwfl_remote_mem_cache): New. + (struct __libdwfl_pid_arg): Add mem_cache field. + * linux-pid-attach.c (read_cached_memory): New function. + (clear_cached_memory): Likewise. + (pid_memory_read): Call read_cached_memory. + (pid_detach): Free mem_cache. + (pid_thread_detach): Call clear_cached_memory. + (dwfl_linux_proc_attach): Initialize mem_cache to NULL. + +2018-03-05 Mark Wielaard + + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Use + realpath (name, NULL) instead of canonicalize_file_name (name). + * find-debuginfo.c (dwfl_standard_find_debuginfo): Likewise. + +2018-01-29 Mark Wielaard + + * cu.c (cudie_offset): Use __libdw_first_die_off_from_cu instead of + DIE_OFFSET_FROM_CU_OFFSET. + (intern_cu): Simply use a copy of the given die CU as key instead of + trying to construct a dummy one by hand. + +2018-02-15 Mark Wielaard + + * linux-pid-attach.c: Include sys/wait.h after sys/ptrace.h. + +2018-02-09 Joshua Watt + + * dwfl_report_elf.c (__libdwfl_elf_address_range): Use FALLTHROUGH + macro instead of comment. + * frame_unwind.c (expr_eval): Likewise. + +2017-11-20 Mark Wielaard + + * link_map.c (do_check64): Take a char * and calculate type and val + offsets before reading, possibly unaligned, values. + (do_check32): Likewise. + (check64): Remove define. + (check32): Likewise. + (auxv_format_probe): Call do_check32 and do_check64 directly with + a, possibly unaligned, auxv entry pointer. + (dwfl_link_map_report): Redefine AUXV_SCAN to not dereference a + possibly unaligned auxv entry pointer. + +2017-10-16 Mark Wielaard + + * argp-std.c (parse_opt): For -k call argp_failure not failure to + keep dwfl around. + +2017-07-26 Yunlian Jiang + + * argp-std.c (failure): Move to file scope. + (fail): Likewise. + +2017-04-20 Ulf Hermann + Mark Wielaard + + * derelocate.c (compare_secrefs): Compare by end address and then by + section number if addresses are equal. + +2017-04-20 Ulf Hermann + Mark Wielaard + + * linux-kernel-modules.c: Always return NULL from kernel_release() on + non-linux systems and set errno to ENOTSUP. + +2017-04-20 Ulf Hermann + + * libdwflP.h: Don't include config.h. + * argp-std.c: Include config.h. + * cu.c: Likewise. + * derelocate.c: Likewise. + * dwfl_addrdie.c: Likewise. + * dwfl_addrdwarf.c: Likewise. + * dwfl_addrmodule.c: Likewise. + * dwfl_begin.c: Likewise. + * dwfl_build_id_find_debuginfo.c: Likewise. + * dwfl_build_id_find_elf.c: Likewise. + * dwfl_cumodule.c: Likewise. + * dwfl_dwarf_line.c: Likewise. + * dwfl_end.c: Likewise. + * dwfl_frame.c: Likewise. + * dwfl_frame_regs.c: Likewise. + * dwfl_getdwarf.c: Likewise. + * dwfl_getmodules.c: Likewise. + * dwfl_getsrc.c: Likewise. + * dwfl_getsrclines.c: Likewise. + * dwfl_line_comp_dir.c: Likewise. + * dwfl_linecu.c: Likewise. + * dwfl_lineinfo.c: Likewise. + * dwfl_linemodule.c: Likewise. + * dwfl_module.c: Likewise. + * dwfl_module_addrdie.c: Likewise. + * dwfl_module_addrname.c: Likewise. + * dwfl_module_addrsym.c: Likewise. + * dwfl_module_build_id.c: Likewise. + * dwfl_module_dwarf_cfi.c: Likewise. + * dwfl_module_eh_cfi.c: Likewise. + * dwfl_module_getdarf.c: Likewise. + * dwfl_module_getelf.c: Likewise. + * dwfl_module_getsrc.c: Likewise. + * dwfl_module_getsrc_file.c: Likewise. + * dwfl_module_getsym.c: Likewise. + * dwfl_module_info.c: Likewise. + * dwfl_module_nextcu.c: Likewise. + * dwfl_module_register_names.c: Likewise. + * dwfl_module_report_build_id.c: Likewise. + * dwfl_module_return_value_location.c: Likewise. + * dwfl_nextcu.c: Likewise. + * dwfl_onesrcline.c: Likewise. + * dwfl_report_elf.c: Likewise. + * dwfl_validate_address.c: Likewise. + * dwfl_version.c: Likewise. + * find-debuginfo.c: Likewise. + * gzip.c: Likewise. + * image-header.c: Likewise. + * lines.c: Likewise. + * linux-core-attach.c: Likewise. + * linux-pid-attach.c: Likewise. + * offline.c: Likewise. + * open.c: Likewise. + * relocate.c: Likewise. + * segment.c: Likewise. + +2017-04-20 Ulf Hermann + + * libdwfl.h: Use __const_attribute__. + +2017-04-20 Ulf Hermann + + * elf-from-memory.c: Explicitly cast phnum to size_t. + +2017-04-20 Ulf Hermann + + * dwfl_module_getdwarf.c: Check shnum for 0 before subtracting from + it. + +2017-04-20 Ulf Hermann + + * dwfl_frame.c: Drop unused sys/ptrace.h include. + * frame_unwind.c: Likewise. + * linux-pid-attach.c: Include sys/ptrace.h and sys/syscall.h only on + linux. + +2017-04-20 Ulf Hermann + + * linux-kernel-modules.c: Include sys/types.h before fts.h + +2017-03-24 Mark Wielaard + + * linux-core-attach.c (core_next_thread): If n_namesz == 0 then + the note name data is the empty string. + (dwfl_core_file_attach): Likewise. + +2017-02-15 Ulf Hermann + + * linux-kernel-modules.c: Include system.h. + +2017-02-15 Ulf Hermann + + * linux-kernel-modules.c: Use sysconf(_SC_PAGESIZE) to get page size. + * linux-proc-maps.c: Likewise. + +2016-12-29 Luiz Angelo Daros de Luca + + * dwfl_build_id_find_elf.c: Include system.h. + * dwfl_module_getdwarf.c: Likewise. + * libdwfl_crc32_file.c: Don't define LIB_SYSTEM_H. + +2016-11-23 Mark Wielaard + + * linux-kernel-modules.c: Only include fts.h early if BAD_FTS is + defined. + +2016-10-11 Akihiko Odaki + + * core-file.c: Remove sys/param.h. + * dwfl_segment_report_module.c: Likewise. Add system.h include. + (MAX): Remove definition. + * frame_unwind.c: Add system.h include. + (MAX): Remove definition. + * linux-core-attach.c (MIN): Remove definition. + * linux-pid-attach.c (MAX): Likewise. + +2016-08-12 Mark Wielaard + + * link_map.c (dwfl_link_map_report): Fix assert, set in.d_size. + +2016-04-14 Mark Wielaard + + * dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Free match + on invalid DWARF if we allocated it. + +2016-04-14 Mark Wielaard + + * linux-proc-maps.c (proc_maps_report): Free last_file on bad file + mapping. + +2016-03-01 Steven Chamberlain + + * linux-pid-attach.c: Removed unused pid_thread_callbacks, + pid_thread_detach, pid_detach, pid_set_initial_registers, + pid_memory_read, pid_getthread, pid_next_thread in #ifndef + __linux__ code. + +2016-02-22 Ravi Bangoria + Mark Wielaard + + * find-debuginfo.c (find_debuginfo_in_path): Remember whether + debuglink_file is NULL. Try file basename (without .debug) ofr + absolute and relative path if debug_file was NULL. + * linux-kernel-modules.c (try_kernel_name): If try_debug is true call + dwfl_standard_find_debuginfo with NULL debuglink_file, otherwise with + basename of fname. + +2016-02-13 Mark Wielaard + + * linux-proc-maps.c (proc_maps_report): Free last_file when ENOEXEC. + +2016-02-13 Mark Wielaard + + * frame_unwind.c (new_unwound): Check and return unwound. + (handle_cfi): Check new_unwound was able to allocate new memory + before use. Return DWFL_E_NOMEM otherwise. + +2016-02-11 Mark Wielaard + + * relocate.c (relocate_section): Check result of all gelf_get* calls. + (__libdwfl_relocate): Likewise. + (__libdwfl_relocate_section): Likewise. + +2016-02-11 Mark Wielaard + + * relocate.c (relocate_section): Check result of gelf_update_* calls. + +2016-01-08 Mark Wielaard + + * libdwfl_a_SOURCES: Unconditionally add gzip.c. + * linux-kernel-modules.c (vmlinux_suffixes): We always have at least + .gz support. + (try_kernel_name): Likewise. + (check_suffix): Likewise. + * open.c (decompress): Likewise. + +2015-12-18 Mark Wielaard + + * dwfl_module_getdwarf.c (find_symtab): Uncompress symstr, xndx, sym + sections and aux_str, aux_xndx and aux_sym sections if necessary. + * relocate.c (relocate_getsym): Uncompress symtab and symtab_shndx + if necessary. + (resolve_symbol): Uncompress strtab section if necessary. + (relocate_section): Uncompress the section the relocations apply to + if necessary. + +2015-11-18 Chih-Hung Hsieh + + * linux-proc-maps.c (proc_maps_report): Move nested function + 'report' to file scope. + +2015-11-18 Chih-Hung Hsieh + + * core-file.c (elf_begin_rand): Move nested function 'fail' to file + scope. + * core-file.c (dwfl_elf_phdr_memory_callback): Move nested functions + 'update_end' and 'more' to file scope. + +2015-11-17 Chih-Hung Hsieh + + * link_map.c (auxv_format_probe): Move nested functions + check64 and check32 to file scope. + +2015-12-08 Jose E. Marchesi + + * dwfl_frame.c (state_fetch_pc): Add a backend-defined offset to + the value of the return address register as defined by the CFI + abi. + * frame_unwind.c (handle_cfi): Likewise. + +2015-12-01 Mark Wielaard + + * link_map.c (dwfl_link_map_report): Track whether in.d_buf comes + from exec or memory_callback, free as appropriate. + +2015-12-01 Mark Wielaard + + * libdwflP.h (struct Dwfl_User_Core): New. + (struct DWfl): Replace executable_for_core with user_core. + * argp-std.c (parse_opt): Store core and fd in Dwfl user_core. + * core-file.c (dwfl_core_file_report): Check and store + executable_for_core in Dwfl user_core. + * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Check and use + executable_for_core in Dwfl user_core. + * dwfl_end.c (dwfl_end): Release resources held in Dwfl user_core. + * link-map.c (report_r_debug): Check executable_for_core in Dwfl + user_core. + (dwfl_link_map_report): Likewise. + +2015-11-16 Chih-Hung Hsieh + + * dwfl_module_getdwarf.c (find_prelink_address_sync): Move nested + function 'consider_shdr' to file scope. + * dwfl_module_getdwarf.c (find_dynsym): Move nested function + 'translate_offs' to file scope. + +2015-11-16 Chih-Hung Hsieh + + * dwfl_module_addrsym.c (__libdwfl_addrsym): Move nested functions + 'same_section', 'binding_value', 'try_sym_value', and 'search_table' + to file scope. + +2015-11-19 Mark Wielaard + + * dwfl_module.c (__libdwfl_module_free): Remove Dwfl_Module Ebl from + eh_cfi and dwarf_cfi cache if necessary before calling dwarf_end and + dwarf_cfi_end. + +2015-11-13 Chih-Hung Hsieh + + * gzip.c (unzip): Move nested functions to file scope. + +2015-10-21 Chih-Hung Hsieh + Mark Wielaard + + * dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Move nested + functions 'dwarf_line_file', 'dwfl_line', and 'dwfl_line_file' to + file scope. Rename dwarf_line_file to dwfl_dwarf_line_file. Don't + use INTUSE. + +2015-10-21 Chih-Hung Hsieh + + * frame_unwind.c (expr_eval): Move nested function 'push' and 'pop' + to file scope. Pass used local variables in struct eval_stack. + +2015-10-21 Chih-Hung Hsieh + + * dwfl_module.c (dwfl_report_module): Move nested function 'use' to + file scope. + +2015-10-09 Josh Stone + + * core-file.c (elf_begin_rand): Replace loff_t with off_t. + * open.c (decompress): Replace off64_t with off_t. + * gzip.c (unzip): Likewise. + * image-header.c (__libdw_image_header): Likewise. + * libdwflP.h: Likewise in function declarations. + * argp-std.c (parse_opt): Replace open64 with open. + * dwfl_build_id_find_elf.c (__libdwfl_open_mod_by_build_id, + dwfl_build_id_find_elf): Likewise. + * dwfl_module_getdwarf.c (open_elf_file): Likewise. + * dwfl_report_elf.c (dwfl_report_elf): Likewise. + * dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise. + * link_map.c (report_r_debug): Likewise. + * offline.c (dwfl_report_offline): Likewise. + * linux-proc-maps.c (grovel_auxv, get_pid_class, + dwfl_linux_proc_find_elf): Likewise. + (read_proc_memory): Replace off64_t with off_t. + * find-debuginfo.c (find_debuginfo_in_path): Replace stat64 and + fstat64 with stat and fstat. + (try_open): Likewise, and replace open64 with open. + * linux-kernel-modules.c: Manually define open and fopen to open64 and + fopen64 when needed, since the early fts.h include breaks that. + (try_kernel_name): Replace open64 with open. + (check_notes): Likewise. + +2015-10-09 Jose E. Marchesi + + * linux-proc-maps.c (read_proc_memory): Use seek+read instead of + pread, as the later doesn't accept negative offsets. + +2015-10-07 Mark Wielaard + + * dwfl_module_getdwarf.c (MAX): Removed. + (find_prelink_address_sync): Allocate exact amount of bytes for + phdrs and shdrs. + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Likewise for phdrs. + * elf-from-memory.c (MAX): Removed. + (elf_from_remote_memory): Allocate exact amount of bytes for phdrs. + +2015-10-05 Chih-Hung Hsieh + + * dwfl_module_getdwarf.c (find_prelink_address_sync): Do not use + union of variable length arrays. + * dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise. + * elf-from-memory.c (elf_from_remote_memory): Likewise. + * link_map.c (auxv_format_probe): Likewise. + * link_map.c (report_r_debug): Likewise. + * link_map.c (dwfl_link_map_report): Likewise. + +2015-09-18 Chih-Hung Hsieh + + * relocate.c (relocate_section): Move nested function "relocate" + to file scope, pass all used local variables as constants. + Move nested "check_badreltype" to file scope, pass addresses of + updated used local variables. + * linux-kernel-modules.c (intuit_kernel_bounds): Move nested function + "read_address" to file scope, pass all updated local variables in + a state structure. + * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Move nested + function "subst_name" to file scope, pass all used local variables + as constants. + * linux-kernel-modules.c (dwfl_linux_kernel_report_kernel): Replace + simple nested function "report" with a macro. Work around gcc static + analysis error -Werror=maybe-uninitialized. + +2015-09-22 Mark Wielaard + + * core-file.c: Remove old-style function definitions. + * dwfl_error.c: Likewise. + * dwfl_module_dwarf_cfi.c: Likewise. + * dwfl_module_eh_cfi.c: Likewise. + * dwfl_module_register_names.c: Likewise. + * dwfl_module_return_value_location.c: Likewise. + * dwfl_version.c: Likewise. + +2015-09-09 Chih-Hung Hsieh + Mark Wielaard + + * dwfl_frame.c (dwfl_attach_state): Remove redundant NULL tests + on parameters declared with __nonnull_attribute__. + * libdwfl.h (dwfl_module_getelf): Don't mark first argument as + nonnull. + +2015-09-08 Mark Wielaard + + * libdwflP.h (struct __libdwfl_pid_arg): Add elf and elf_fd. + * linux-pid-attach.c (pid_detach): Call elf_end and close. + (dwfl_linux_proc_attach): Open and save /proc/PID/exe. + +2015-09-04 Chih-Hung Hsieh + + * find-debuginfo.c (find_debuginfo_in_path): Try to locate the + debug info file named debuglink_file under + mod->dwfl->callbacks->debuginfo_path, by looking at + the set of sub-trees under mod->dwfl->callbacks->debuginfo_path + which is common to the set of non-absolute parent trees of + file_name. + +2015-06-18 Mark Wielaard + + * find-debuginfo.c (try_open): Free fname on all failure paths. + +2015-06-18 Mark Wielaard + + * dwfl_module_getdwarf.c (find_symtab): Check shdr is not NULL and + sh_entsize is not zero. + +2015-06-06 Mark Wielaard + + * find-debuginfo.c (find_debuginfo_in_path): Always free localpath, + localname and file_dirname. + +2015-06-06 Mark Wielaard + + * derelocate.c (cache_sections): Free sortrefs. + +2015-06-05 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + If the note_file exists, but the build_id doesn't match discard + the file and continue reporting. + +2015-06-01 Mark Wielaard + + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Copy path + pointer before passing to strsep. + +2015-05-30 Mark Wielaard + + * link_map.c (check32): Use read_4ubyte_unaligned_noncvt to read + type and value. + (read_addrs): Use read_(4|8)ubyte_unaligned_noncvt or to read + addresses. + +2015-05-30 Mark Wielaard + + * find-debuginfo.c (dwfl_standard_find_debuginfo): Check file_name is + not NULL before calling canonicalize_file_name. + +2015-05-24 Mark Wielaard + + * derelocate.c (check_module): Check mod is not NULL. + +2015-05-22 Mark Wielaard + + * link_map.c (dwfl_link_map_report): Allocate phdrs and dyn with + malloc instead of stack allocating. Call free when done with data. + +2015-05-22 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Allocate phdrs with malloc, not on stack. free in finish. + Allocate dyn with malloc, not on stack, free after use. + +2015-05-22 Mark Wielaard + + * find-debuginfo.c (find_debuginfo_in_path): malloc or strdup, + instead of alloca or strdupa, local strings of unknown size. + Call free before return. + +2015-05-22 Mark Wielaard + + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Return + error when id_len too small or too large. strdup, not strdupa, + and free path when done. + +2015-05-19 Mark Wielaard + + * elf-from-memory.c (elf_from_remote_memory): Don't allocate all + phdrs on the stack. Allocate with malloc and free when done. + +2015-05-19 Mark Wielaard + + * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): malloc and + free alternate_name. + +2015-05-19 Mark Wielaard + + * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Don't + stack allocate name. Only change chars up to suffix. + +2015-05-18 Mark Wielaard + + * dwfl_module_getdwarf.c (find_prelink_address_sync): Allocate + phdrs and shdrs unions with malloc, not alloca. Free after use. + +2015-05-18 Mark Wielaard + + * derelocate.c (cache_sections): Allocate temporary newrefs and + sortrefs with malloc, not alloca. Always free them on return. + +2015-05-07 Mark Wielaard + + * cu.c (intern_cu): Check for EOF and check cuoff points to a real + Dwarf_Die before interning. Explicitly check EOF is expected. + +2015-05-05 Mark Wielaard + + * dwfl_lineinfo.c (dwfl_lineinfo): Check info->file is valid. + +2015-05-06 Roland McGrath + + * dwfl_error.c (struct msgtable): Break type definition out of + the 'msgtable' initializer. + (msgtable): Make it a union of struct msgtable and a char array. + (msgstr): Use the full-table char array rather than the msg_0 entry. + +2015-04-23 Max Filippov + + * core-file.c (_compat_without_executable_dwfl_core_file_report): + Guard with SYMBOL_VERSIONING. + * dwfl_module_build_id.c (_compat_vaddr_at_end_dwfl_module_build_id): + Likewise. + * dwfl_report_elf.c (_compat_without_add_p_vaddr_dwfl_report_elf): + Likewise. + +2015-04-02 Mark Wielaard + + * segment.c (insert): Check correct number of lookup_elts. + +2015-03-31 Mark Wielaard + + * core-file.c (core_file_read_eagerly): Special case small images. + +2015-01-26 Mark Wielaard + + * dwfl_module_getdwarf.c (find_symtab): Explicitly clear symdata, + syments and first_global on elferr before calling find_dynsym. + +2014-12-27 Mark Wielaard + + * dwfl_module_getsrc.c (dwfl_module_getsrc): Never match a line that + has end_sequence set. + +2015-01-04 Mark Wielaard + + * cu.c (intern_cu): Store result and return directly when finding + EOF marker. + (__libdwfl_nextcu): Check *nextp as returned by intern_cu isn't -1. + +2014-12-19 Mark Wielaard + + * dwfl_module_getdwarf.c (find_symtab): Always try find_dynsym last. + +2014-12-19 Mark Wielaard + + * elf-from-memory.c (handle_segment): Remove palign sanity check. + +2014-12-18 Mark Wielaard + + * relocate.c (resolve_symbol): Make sure symstrdata->d_buf != NULL. + +2014-12-13 Mark Wielaard + + * dwfl_module_getdwarf.c (find_dynsym): elf_getdata_rawchunk takes + a size_t, make sure it doesn't overflow. + +2014-12-13 Mark Wielaard + + * cu.c (cudie_offset): Make sure Dwarf_Off difference doesn't + wrap around before returning as int. + +2014-12-11 Josh Stone + + * dwfl_module_getsrc.c (dwfl_module_getsrc): Return the *last* line + record <= addr, rather than returning immediately on matches. + +2014-12-09 Mark Wielaard + + * dwfl_segment_report_module.c (handle_file_note): Check count doesn't + overflow. + +2014-12-07 Mark Wielaard + + * relocate.c (relocate_section): Sanity check section overlap against + actually used ehsize, shentsize and phentsize. + +2014-12-07 Mark Wielaard + + * offline.c (dwfl_offline_section_address): Assert shndx is not zero. + * relocate.c (__libdwfl_relocate_value): Don't relocate against + section zero. + +2014-11-29 Mark Wielaard + + * relocate.c (relocate_section): Check relocation section and target + section data don't overlap any of the ELF headers. + (relocate): Check for offset + size overflow. + +2014-11-22 Mark Wielaard + + * link_map.c (consider_executable): Use elf_getphdrnum. + (dwfl_link_map_report): Likewise. + +2014-11-18 Mark Wielaard + + * dwfl_module_getdwarf.c (find_symtab): Sanity check the data buffer, + number of symbols and first_global before use. + +2014-11-14 Mark Wielaard + + * dwfl_module_getdwarf.c (load_symtab): Don't use tables which have + a zero sh_entsize. + +2014-11-10 Mark Wielaard + + * dwfl_module_getdwarf.c (find_dynsym): New inner function + translate_offs that takes an adjust argument. Try finding + the symbol table with and without adjusting to main_bias. + +2014-09-26 Jan Kratochvil + + Support NT_FILE for locating files. + * core-file.c (dwfl_core_file_report): New variables note_file and + note_file_size, set them and pass them to dwfl_segment_report_module. + * dwfl_segment_report_module.c: Include common.h and fcntl.h. + (buf_has_data, buf_read_ulong, handle_file_note): New functions. + (invalid_elf): New function from code of dwfl_segment_report_module. + (dwfl_segment_report_module): Add parameters note_file and + note_file_size. New variables elf and fd, clean them up in finish. + Move some code to invalid_elf. Call handle_file_note, if it found + a name verify the file by invalid_elf. Protect elf and fd against + cleanup by finish if we found the file for new Dwfl_Module. + * libdwflP.h (dwfl_segment_report_module): Add parameters note_file and + note_file_size. + +2014-09-23 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Extract ei_class, ei_data and e_type early and use the result. + +2014-09-18 Jan Kratochvil + + * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Use IS_EXECUTABLE. + * dwfl_segment_report_module.c (dwfl_segment_report_module): Set + IS_EXECUTABLE. + * libdwflP.h (struct Dwfl_Module): New field is_executable. + +2014-08-28 Jan Kratochvil + + * dwfl_module_getdwarf.c (find_offsets): Add parameter main_bias, use + it. + (find_dynsym): Pass the new parameter main_bias. + +2014-08-14 Mark Wielaard + + * linux-kernel-modules.c (check-suffix): Also TRY .ko.xz. + +2014-07-24 Jan Kratochvil + + Fix report_r_debug for prelinked libraries. + * link_map.c (report_r_debug): Comment out variable l_addr. + Use instead new variable base recalculated from l_ld. + +2014-06-24 Kurt Roeckx + + * linux-pid-attach.c: Make it build on non linux hosts. + +2014-06-17 Mark Wielaard + + * frame_unwind.c (handle_cfi): Use ebl_func_addr_mask. + * dwfl_module_getsym.c (__libdwfl_getsym): Likewise. + +2014-06-15 Mark Wielaard + + * linux-core-attach.c (core_memory_read): Use libdw/memory-access.h + macros read_4ubyte_unaligned_noncvt and read_8ubyte_unaligned_noncvt + to read possibly unaligned data. + (core_next_thread): Likewise. + (core_set_initial_registers): Likewise. + (dwfl_core_file_attach): Likewise. + +2014-06-11 Mark Wielaard + + * dwfl_frame.c (__libdwfl_process_free): Reset dwfl->attacherr. + (dwfl_attach_state): Set dwfl->attacherr. + (dwfl_pid): Check and return dwfl->attacherr if set. + (dwfl_getthreads): Likewise. + (getthread): Likewise. + * libdwflP.h: Add DWFL_E_NO_CORE_FILE. + (struct Dwfl): Add attacherr field. + * linux-core-attach.c (dwfl_core_file_attach): Set dwfl->attacherr. + Don't assert if ELF file is not ET_CORE, just return error. + * linux-pid-attach.c (dwfl_linux_proc_attach): Set dwfl->attacherr. + +2014-06-10 Mark Wielaard + + * argp-std.c (parse_opt): Ignore errors from dwfl_core_file_attach + or dwfl_linux_proc_attach. + +2014-05-15 Mark Wielaard + + * linux-proc-maps.c (grovel_auxv): Close fd on error. + +2014-05-02 Mark Wielaard + + * dwfl_module_getdwarf: Remove ENABLE_DWZ ifdefs so find_debug_altlink + is always called. + +2014-05-01 Mark Wielaard + + * libdwflP.h (struct Dwfl_Module): Add alt, alt_fd and alt_elf fields. + (__libdwfl_open_mod_by_build_id): Renamed __libdwfl_open_by_build_id. + (__libdwfl_open_by_build_id): New declaration that takes an explicit + build-id. + * dwfl_build_id_find_debuginfo.c (dwfl_build_id_find_debuginfo): If + we already have the Dwarf then look for the alt dwz multi file by + build-id. + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Add the + build-id we are looking for as argument. + (__libdwfl_open_mod_by_build_id): New function, calls + __libdwfl_open_by_build_id. + (dwfl_build_id_find_elf): Call __libdwfl_open_mod_by_build_id. + * dwfl_module.c (__libdwfl_module_free): Release alt, alt_elf and + close alt_fd if necessary. + * dwfl_module_getdwarf.c (__check_build_id): Removed. + (try_debugaltlink): Removed. + (open_debugaltlink): Removed. + (open_elf_file): First half of open_elf that just opens the elf + file but doesn't setup the load address. + (open_elf): Call open_elf_file. + (find_debug_altlink): New function. + (load_dw): Remove loading of dwz multifile. + (find_dw): Call find_debug_altlink. + * find-debuginfo.c (validate): Handle alt debug case using + dwelf_dwarf_gnu_debugaltlink and mod->alt_elf. + (find_debuginfo_in_path): Handle alt debug files possibly in .dwz + subdirs. + * linux-kernel-modules.c (try_kernel_name): Use fakemod.debug.name + to store name to find by dwfl_standard_find_debuginfo instead of + allocating an extra variable on stack. + +2014-04-30 Mark Wielaard + + * dwfl_module_build_id.c (__libdwfl_find_elf_build_id): Moved to + dwelf_elf_gnu_build_id.c. + (__libdwfl_find_build_id): Add assert to make sure mod is never NULL. + * dwfl_segment_report_module.c (dwfl_segment_report_module): Call + dwelf_elf_gnu_build_id directly instead of __libdwfl_find_build_id. + * dwfl_module_getdwarf.c (__check_build_id): Implement using + dwelf_elf_gnu_build_id. + +2014-04-15 Florian Weimer + + * dwfl_module_getdwarf.c (__check_build_id): Moved from libdw. + (try_debugaltlink): Likewise. + (open_debugaltlink): Likewise. + (load_dw): Locate alternate debug information using + dwelf_dwarf_gnu_debugaltlink and call open_debugaltlink. + +2014-04-11 Mark Wielaard + + * Makefile.am (AM_CPPFLAGS): Add libdwelf. + * libdwflP.h: Include libdwelfP.h. + * dwfl_module_getdwarf.c (find_debuglink): Moved to libdwelf. + (find_debuginfo): Use dwelf_elf_gnu_debuglink. + +2014-04-22 Mark Wielaard + + * frame_unwind.c (__libdwfl_frame_reg_get): Use uint64_t when + checking bits. + (__libdwfl_frame_reg_set): Likewise. + +2014-04-22 Kurt Roeckx + + * linux-pid-attach.c: Make linux only. + +2014-03-14 Mark Wielaard + + * Makefile.am: Remove !MUDFLAP and MUDFLAP conditions. + Remove libelf and libdw definitions when MUDFLAP is defined. + * argp-std.c (__libdwfl_argp_mudflap_options): Removed. + +2014-03-03 Mark Wielaard + + * elf-from-memory.c (elf_from_remote_memory): Keep track of + segments_end_mem. Pass memsz to first handle_segment pass. Only + extend contents_size and use shdrs if only file bits are in + segment. + +2014-03-11 Josh Stone + + * dwfl_module_getdwarf.c (open_elf): Only explicitly set + mod->e_type when processing the main ELF file. + +2014-03-04 Mark Wielaard + + * libdwflP.h (struct __libdwfl_pid_arg): Moved here and renamed from + linux-pid-attach.c (struct pid_arg). + (__libdwfl_get_pid_arg): New internal function declaration. + (__libdwfl_ptrace_attach): Likewise. + (__libdwfl_ptrace_detach): Likewise. + * dwfl_frame.c (dwfl_attach_state): Add "(deleted)" files to the + special exception modules that cannot be checked at this point. + * linux-pid-attach.c (struct pid_arg): Moved to libdwflP.h + (ptrace_attach): Renamed to... + (__libdwfl_ptrace_attach): New internal function. + (__libdwfl_ptrace_detach): Likewise. Extracted from ... + (pid_thread_detach): Call __libdwfl_ptrace_detach now. + (__libdwfl_get_pid_arg): New internal function. + * linux-proc-maps.c (dwfl_linux_proc_find_elf): Check if special + module name contains "(deleted)" and dwfl_pid gives an attached + pid. If pid is set and try to (re)use ptrace attach state of + process before reading memory. + +2014-03-03 Mark Wielaard + + * elf-from-memory.c (elf_from_remote_memory): Take pagesize as + argument. Free buffer when detecting bad elf. Check PT_LOAD + alignment requirements on first handle_segment pass. Calculate + loadbase, start and end of segment using pagesize, not p_align. + * linux-proc-maps.c (dwfl_linux_proc_find_elf): Provide pagesize + to elf_from_remote_memory. + +2014-02-26 Mark Wielaard + + * linux-proc-maps.c (proc_maps_report): Don't assert on bad input. + +2014-02-26 Mark Wielaard + + * elf-from-memory.c (elf_from_remote_memory): Check against p64 + p_type in case ELFCLASS64, not against p32 p_type. + +2014-01-17 Petr Machata + + * relocate.c (relocate_section): Use gelf_fsize instead of relying + on shdr->sh_entsize. + +2014-01-05 Mark Wielaard + + * frame_unwind.c (handle_cfi): Only skip resetting return register + if the regno is not the actual CIE return address register. + +2014-01-02 Mark Wielaard + + * linux-pid-attach.c (dwfl_linux_proc_attach): Use strtol, not atoi. + +2013-12-30 Mark Wielaard + + * argp-std.c (parse_opt): Call dwfl_linux_proc_attach and + dwfl_core_file_attach explicitly. + * core-file.c (dwfl_core_file_report): Don't call + __libdwfl_attach_state_for_core implicitly. + * dwfl_begin.c (dwfl_begin): Remove setting of process_attach_error. + * dwfl_frame.c (dwfl_pid): Set errno to DWFL_E_NO_ATTACH_STATE, not + process_attach_error. + (dwfl_getthreads): Likewise. + (getthread): Likewise. + * libdwfl.h (dwfl_core_file_report): Update documentation. + (dwfl_linux_proc_report): Likewise. + (dwfl_core_file_attach): New function declaration. + (dwfl_linux_proc_attach): Likewise. + * libdwflP.h (struct Dwfl): Remove process_attach_error. + (__libdwfl_attach_state_for_pid): Removed declaration. + (__libdwfl_attach_state_for_core): Likewise. + (dwfl_core_file_attach): New internal declaration. + (dwfl_linux_proc_attach): Likewise. + (attach_state_for_core): Renamed to... + (dwfl_core_file_attach): ...this. Change return type. + (__libdwfl_attach_state_for_core): Removed. + * linux-pid-attach.c (struct pid_arg): Add assume_ptrace_stopped. + (pid_set_initial_registers): Check assume_ptrace_stopped before + calling ptrace. + (pid_thread_detach): Likewise. + (__libdwfl_attach_state_for_pid): Renamed to... + (dwfl_linux_proc_attach): ...this. Adjust return type. + * linux-proc-maps.c (dwfl_linux_proc_report): Don't call + __libdwfl_attach_state_for_pid implicitly. + +2013-12-28 Mark Wielaard + + * linux-proc-maps.c (dwfl_linux_proc_find_elf): Don't return special + character device files, only regular files. + +2013-12-24 Mark Wielaard + + * linux-core-attach.c (core_next_thread): Check whether thread_argp + is NULL. Reset core_arg->thread_note_offset and malloc a thread_arg + in that case. Free thread_arg if there are no more threads. + +2013-12-23 Mark Wielaard + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Free + build_id before returning early. + +2013-12-23 Mark Wielaard + + * linux-pid-attach.c (__libdwfl_attach_state_for_pid): Report actual + pid (thread group leader) to dwfl_attach_state. + +2013-12-21 Mark Wielaard + + * frame_unwind.c (handle_cfi): Track whether the return register + has been set and only allow it to be set once. + +2013-12-20 Mark Wielaard + + * dwfl_frame.c (one_arg): New struct. + (get_one_thread_cb): New function. + (dwfl_getthread): Likewise. + (one_thread): New struct. + (get_one_thread_frames_cb): New function. + (dwfl_getthread_frames): Likewise. + * libdwfl.h (Dwfl_Thread_Callbacks): Add get_thread function. + (dwfl_getthread_frames): Likewise. + * libdwflP.h (dwfl_getthread_frames): New internal function declaration. + * linux-core-attach.c (core_thread_callbacks): Initialize get_thread + to NULL. + * linux-pid-attach.c (pid_getthread): New function. + (pid_thread_callbacks): Initialize get_thread to pid_getthread. + +2013-12-20 Mark Wielaard + + * linux-kernel-modules.c (report_kernel_archive): Correct nested + asprintf result check for debug.a. + +2013-12-18 Mark Wielaard + + * derelocate.c (__libdwfl_find_section_ndx): New internal function. + * dwfl_module_addrname.c (dwfl_module_addrname): Use + dwfl_module_addrinfo. + * dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Replace with... + (__libdwfl_addrsym): ...this. Use __libdwfl_getsym, use value + for comparisons, not st_value. Fill in off. Search for both value + and the (adjusted) sym.st_value when different. + (dwfl_module_addrsym): Implement using __libdwfl_addrsym. + (dwfl_module_addrinfo): New function. + * dwfl_module_getsym.c (dwfl_module_getsym_elf): Replace with... + (__libdwfl_getsym): ...this. Use ebl_resolve_sym_value if requested + and possible. Adjust sym->st_value only when requested. Fill in addr + if available. + (dwfl_module_getsym_info): New function. + (dwfl_module_getsym): Use __libdwfl_getsym. + * libdwfl.h (dwfl_module_getsym_elf): Removed. + (dwfl_module_getsym_info): New function declaration. + (dwfl_module_addrinfo): Likewise. + (dwfl_module_addrsym): Add documentation describing differences + with addrinfo variants. + (dwfl_module_addrsym_elf): Removed. + * libdwflP.h (__libdwfl_getsym): New internal function declaration. + (__libdwfl_addrsym): Likewise. + (__libdwfl_find_section_ndx): Likewise. + (dwfl_module_addrinfo): New internal declaration. + (dwfl_module_getsym_info): Likewise. + (dwfl_module_addrsym_elf): Removed. + (dwfl_module_getsym_elf): Likewise. + +2013-12-18 Jan Kratochvil + + * argp-std.c (offline_find_elf): Remove. + (offline_callbacks): Use dwfl_build_id_find_elf instead. + * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Move here the code + removed above. + +2013-12-18 Jan Kratochvil + + unwinder: s390 and s390x + * dwfl_frame_pc.c (dwfl_frame_pc): Call ebl_normalize_pc. + * frame_unwind.c (new_unwound): New function from ... + (handle_cfi): ... here. Call it. + (setfunc, getfunc, readfunc): New functions. + (__libdwfl_frame_unwind): Call ebl_unwind with those functions. + * linux-core-attach.c (core_set_initial_registers): Always iterate + through the Ebl_Register_Location loop. Call + dwfl_thread_state_register_pc there. + +2013-12-17 Jan Kratochvil + + * frame_unwind.c (handle_cfi): Call ebl_dwarf_to_regno for RA. + +2013-12-17 Mark Wielaard + + * linux-pid-attach.c (pid_next_thread): Call rewinddir on first + traversal. + +2013-12-16 Mark Wielaard + + * libdwfl.h (dwfl_module_getsymtab_first_global): New function + definition. + * dwfl_module_getdwarf.c (dwfl_module_getsymtab_first_global): New + function. + * libdwflP.h (dwfl_module_getsymtab_first_global): New internal + function definition. + * dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Use new function. + +2013-12-14 Mark Wielaard + + * dwfl_module.c (__libdwfl_module_free): Free mod->reloc_info if + allocated. Call dwarf_cfi_end on mod->eh_cfi if necessary. + * frame_unwind.c (handle_cfi): Free frame result from + dwarf_cfi_addrframe when done. + +2013-12-15 Jan Kratochvil + + unwinder: ppc and ppc64 + * frame_unwind.c (__libdwfl_frame_reg_get, __libdwfl_frame_reg_set): + Call ebl_dwarf_to_regno. + * linux-core-attach.c (core_set_initial_registers): Implement + pc_register support. + * linux-pid-attach.c (pid_thread_state_registers_cb): Implement + FIRSTREG -1. + +2013-11-30 Jan Kratochvil + + Introduce process_attach_error. + * dwfl_begin.c (dwfl_begin): Initialize process_attach_error. + * dwfl_frame.c (dwfl_pid, dwfl_getthreads): Use PROCESS_ATTACH_ERROR if + PROCESS is NULL. + * libdwflP.h (struct Dwfl): New field process_attach_error. + * linux-core-attach.c (__libdwfl_attach_state_for_core): Rename to ... + (attach_state_for_core): ... here, make it static, change return type, + no longer use __libdwfl_seterrno. + (__libdwfl_attach_state_for_core): New wrapper for it. + +2013-11-27 Mark Wielaard + + * dwfl_module_addrsym.c (dwfl_module_addrsym): Rename to and call... + (dwfl_module_addrsym_elf): this. Add elfp and biasp arguments, + keep track of symelf, addr_symelf, closest_elf and sizeless_elf + instead of tracking dwfl_files. + * dwfl_module_getsym.c (__libdwfl_module_getsym): Renamed to... + (dwfl_module_getsym_elf): ...this. Remove dwfl_file argument, add + new elfp and biasp arguments. Track elf instead of file. + (dwfl_module_getsym): Call dwfl_module_getsym_elf. + dwfl_module_info.c (dwfl_module_info): Pass elf to + dwfl_adjusted_st_value. + * libdwfl.h (dwfl_module_getsym): Document limitations of shndx. + (dwfl_module_getsym_elf): New function declaration. + (dwfl_module_addrsym_elf): Likewise. + * libdwflP.h (dwfl_module_addrsym_elf): INTDECL. + (dwfl_module_getsym_elf): Likewise. + (dwfl_adjusted_st_value): Take and check elf not dwfl_file. + (dwfl_deadjust_st_value): Likewise. + (__libdwfl_module_getsym): Removed. + * relocate.c (resolve_symbol): Pass elf to dwfl_adjusted_st_value. + +2013-11-21 Jan Kratochvil + + Fix non-build-id core files on build-id system. + * link_map.c (report_r_debug): Remove valid clearing if build-id cannot + be read from memory. + +2013-11-21 Jan Kratochvil + + * dwfl_segment_report_module.c (dwfl_segment_report_module): New + variable close_elf. Call __libdwfl_find_elf_build_id and compare the + content, if possible. + +2013-11-21 Jan Kratochvil + + link_map: Use proper bias, not l_addr. + * core-file.c (dynamic_vaddr_get): Rename to ... + (__libdwfl_dynamic_vaddr_get): ... here, make it global, + internal_function. + (dwfl_core_file_report): Update name in the caller. + * libdwflP.h (__libdwfl_dynamic_vaddr_get): New declaration. + * link_map.c (report_r_debug): New variable elf_dynamic_vaddr. Call + __libdwfl_dynamic_vaddr_get for it. Remove L_ADDR FIXME comment. + Use ELF_DYNAMIC_VADDR instead of L_ADDR. + +2013-11-19 Jan Kratochvil + + Compatibility with older kernels such as RHEL-6. + * linux-pid-attach.c (struct pid_arg): New field tid_was_stopped. + (ptrace_attach): New parameter tid_was_stoppedp. Set it. + (pid_set_initial_registers): Pass tid_was_stopped. + (pid_thread_detach): Use tid_was_stopped. + +2013-11-18 Josh Stone + + * dwfl_module_getdwarf.c (find_aux_address_sync): New function. + (find_aux_sym): Use it. + +2013-11-14 Jan Kratochvil + + Code cleanup: Remove const in prototype + * dwfl_frame_regs.c (dwfl_thread_state_registers): Remove const from + firstreg. + * libdwfl.h (dwfl_thread_state_registers): Likewise. + * linux-pid-attach.c (pid_thread_state_registers_cb): Likewise. + +2013-11-14 Jan Kratochvil + + Fix dwfl_attach_state machine->elf. + * dwfl_frame.c (dwfl_attach_state): Change parameter machine to elf. + Call ebl_openbackend instead of ebl_openbackend_machine. + * libdwfl.h (dwfl_attach_state): Change parameter machine to elf. + Update the function description. + * linux-core-attach.c (__libdwfl_attach_state_for_core): Pass CORE to + dwfl_attach_state. + * linux-pid-attach.c (__libdwfl_attach_state_for_pid): Pass NULL to + dwfl_attach_state. + +2013-11-06 Jan Kratochvil + + Provide __libdwfl_module_getsym to get dwfl_file *. + * dwfl_module_addrsym.c (dwfl_module_addrsym) (i_to_symfile): Remove. + (dwfl_module_addrsym) (search_table): New variable file. Use + __libdwfl_module_getsym. Use file. + * dwfl_module_getsym.c (dwfl_module_getsym): Rename to ... + (__libdwfl_module_getsym): ... here. Add parameter filep. Set it. + (dwfl_module_getsym): New wrapper. + * libdwflP.h (__libdwfl_module_getsym): New declaration. + +2013-11-13 Jan Kratochvil + + Fix dwfl_module_addrsym for minidebuginfo. + * dwfl_module_addrsym.c (dwfl_module_addrsym): New variable + addr_symfile. + (dwfl_module_addrsym) (same_section): Use it. + (dwfl_module_addrsym) (i_to_symfile): New function. + (dwfl_module_addrsym) (search_table): Use it. + +2013-11-07 Jan Kratochvil + Mark Wielaard + + * Makefile.am (libdwfl_a_SOURCES): Add dwfl_frame.c, frame_unwind.c, + dwfl_frame_pc.c, linux-pid-attach.c, linux-core-attach.c and + dwfl_frame_regs.c. + * core-file.c (dwfl_core_file_report): Call + __libdwfl_attach_state_for_core. + * dwfl_end.c (dwfl_end): Call __libdwfl_process_free. + * dwfl_frame.c: New file. + * frame_unwind.c: New file. + * dwfl_frame_pc.c: New file. + * linux-pid-attach.c: New file. + * linux-core-attach.c: New file. + * dwfl_frame_regs.c: New file. + * libdwfl.h (Dwfl_Thread, Dwfl_Frame): New typedefs. + (dwfl_core_file_report, dwfl_linux_proc_report): Extend comments. + (Dwfl_Thread_Callbacks): New definition. + (struct ebl, dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl) + (dwfl_thread_tid, dwfl_frame_thread, dwfl_thread_state_registers) + (dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes) + (dwfl_frame_pc): New declarations. + * libdwflP.h (Dwfl_Process): New typedef. + (LIBEBL_BAD, CORE_MISSING, INVALID_REGISTER, PROCESS_MEMORY_READ) + (PROCESS_NO_ARCH, PARSE_PROC, INVALID_DWARF, UNSUPPORTED_DWARF) + (NEXT_THREAD_FAIL, ATTACH_STATE_CONFLICT, NO_ATTACH_STATE, NO_UNWIND) + (INVALID_ARGUMENT): New DWFL_ERROR entries. + (struct Dwfl): New entry process. + (struct Dwfl_Process, struct Dwfl_Thread, struct Dwfl_Frame) + (__libdwfl_frame_reg_get, __libdwfl_frame_reg_set) + (__libdwfl_process_free, __libdwfl_frame_unwind) + (__libdwfl_attach_state_for_pid, __libdwfl_attach_state_for_core) + (__libdwfl_segment_start, __libdwfl_segment_end): New declarations. + (dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid) + (dwfl_frame_thread, dwfl_thread_state_registers) + (dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes) + (dwfl_frame_pc): New INTDECL entries. + * linux-proc-maps.c (dwfl_linux_proc_report): Call + __libdwfl_attach_state_for_pid. + * segment.c (segment_start): Rename to ... + (__libdwfl_segment_start): ... here and make it internal_function. + (segment_end): Rename to ... + (__libdwfl_segment_end): ... here and make it internal_function. + (reify_segments, dwfl_report_segment): Rename them at the callers. + +2013-11-07 Jan Kratochvil + + * core-file.c (dwfl_core_file_report): Remove the use of MAX. + +2013-11-07 Jan Kratochvil + + * core-file.c (dwfl_core_file_report): Replaced variable sniffed by + retval. Fix one forgotten LISTED increase. + +2013-11-07 Jan Kratochvil + + Fix core files for re-prelink-ed files. + * core-file.c (dynamic_vaddr_get): New function. + (dwfl_core_file_report): New variable file_dynamic_vaddr. Call + dynamic_vaddr_get instead of using L_ADDR. + * libdwflP.h (struct r_debug_info_module): Remove field l_addr. + * link_map.c (report_r_debug): Do not initialize l_addr. + +2013-11-07 Jan Kratochvil + + Code cleanup. + * core-file.c (dwfl_core_file_report): Reindent block of code by + continue keyword. + +2013-10-30 Jan Kratochvil + + * argp-std.c (parse_opt): Use executable parameter of + dwfl_core_file_report. + * core-file.c (dwfl_core_file_report): Add parameter executable. Set + it to DWFL. Add NEW_VERSION for it. + (_compat_without_executable_dwfl_core_file_report): New. Twice. + * libdwfl.h (dwfl_core_file_report): Add parameter executable, update + the function comment. + +2013-10-15 Mark Wielaard + + * linux-proc-maps.c (proc_maps_report): Ignore non-absolute file + mappings. + (dwfl_linux_proc_find_elf): Don't abort, just return failure. + +2013-09-12 Mark Wielaard + + * cu.c (intern_cu): If dwarf_offdie fails free cu. + +2013-09-12 Mark Wielaard + + * linux-proc-maps.c (proc_maps_report): Don't fclose FILE in + bad_report. + +2013-09-12 Mark Wielaard + + * dwfl_module_getdwarf.c (find_symtab): Call elf_getdata with + aux_xndxscn, not xndxscn, for aux_symxndxdata. + +2013-08-25 Mark Wielaard + + * linux-kernel-modules.c (report_kernel): Pass add_p_vaddr as true + to dwfl_report_elf. + +2013-07-25 Jan Kratochvil + + * dwfl_segment_report_module.c (dwfl_segment_report_module): Check for + conflicts all the modules, not just the first one. Compare L_LD if it + is equal, not if it is in a module address range. + +2013-07-23 Jan Kratochvil + + * libdwflP.h (__libdwfl_elf_address_range): Add internal_function. + +2013-07-23 Jan Kratochvil + + * core-file.c (clear_r_debug_info): Close also ELF and FD. + (dwfl_core_file_report): Call __libdwfl_report_elf for + R_DEBUG_INFO.MODULE. + * dwfl_report_elf.c (__libdwfl_elf_address_range): New function from + code of ... + (__libdwfl_report_elf): ... this function. Call it. + * dwfl_segment_report_module.c: Include unistd.h. + (dwfl_segment_report_module): Use basename for MODULE->NAME. + Clear MODULE if it has no build-id and we have segment with build-id. + Ignore this segment only if MODULE still contains valid ELF. + * libdwflP.h (__libdwfl_elf_address_range): New declaration. + (struct r_debug_info_module): New fields fd, elf, l_addr, start, end + and disk_file_has_build_id. + (dwfl_link_map_report): Extend the comment. + * link_map.c (report_r_debug): Extend the comment. Always fill in new + r_debug_info_module. Initialize also the new r_debug_info_module + fields. Remove one FIXME comment. Call __libdwfl_elf_address_range + instead of __libdwfl_report_elf when R_DEBUG_INFO is not NULL. + +2013-07-19 Jan Kratochvil + + * libdwflP.h (__libdwfl_find_elf_build_id): Add internal_function. + +2013-07-02 Mark Wielaard + + * relocate.c (__libdwfl_relocate_value): Remove mod->e_type assert. + +2013-06-05 Mark Wielaard + + * link_map.c (report_r_debug): Always call release_buffer after + memory_callback succeeded reading build_id. + +2013-05-30 Jan Kratochvil + + * argp-std.c (parse_opt) core> e>: Set + executable_for_core before calling dwfl_core_file_report. + * core-file.c (clear_r_debug_info): New function. + (dwfl_core_file_report): Move raw segments reporting lower. New + variable r_debug_info, pass it to dwfl_segment_report_module. Call + clear_r_debug_info in the end. Return sum of LISTED and SNIFFED. + * dwfl_module_build_id.c (check_notes): Move into + __libdwfl_find_elf_build_id. + (__libdwfl_find_build_id): Rename to ... + (__libdwfl_find_elf_build_id): ... here. Add parameters build_id_bits, + build_id_elfaddr and build_id_len. Verify MOD vs. ELF. + (__libdwfl_find_elf_build_id) (check_notes): Remove parameters mod and + set, rename data_vaddr to data_elfaddr. Do not call found_build_id. + (__libdwfl_find_elf_build_id): Update the check_notes caller, do not + adjust its data_elfaddr parameter. + (__libdwfl_find_build_id): New wrapper of __libdwfl_find_elf_build_id. + * dwfl_segment_report_module.c (dwfl_segment_report_module): New + parameter r_debug_info. New variable name_is_final. Adjust addresses + according to R_DEBUG_INFO->MODULE. Check conflicts against DWFL. + Do not overwrite NAME by SONAME if NAME_IS_FINAL. + * libdwflP.h (__libdwfl_find_elf_build_id): New declaration. + (struct r_debug_info_module, struct r_debug_info): New definitions. + (dwfl_segment_report_module, dwfl_link_map_report): Add parameter + r_debug_info. + * link_map.c: Include fcntl.h. + (report_r_debug): Add parameter r_debug_info, describe it in the + function comment. Delete dwfl_addrmodule call and its dependent code. + Verify build-id before calling dwfl_report_elf, also supply + executable_for_core to it. Store r_debug_info->module info when + appropriate. + (dwfl_link_map_report): Add parameter r_debug_info. New variable + in_ok. Try to read IN from EXECUTABLE_FOR_CORE. Update report_r_debug + caller parameters. + +2013-04-30 Jan Kratochvil + + * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. + Set it to true for ET_EXEC and ET_CORE. Provide alternative + setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. + (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add + NEW_VERSION. + (_compat_without_add_p_vaddr_dwfl_report_elf) : New, with + COMPAT_VERSION. + * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. + * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. + * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. + * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for + dwfl_report_elf. + * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf. + +2013-04-27 Mark Wielaard + + * link_map.c: #include system.h. + +2013-04-26 Jan Kratochvil + + * link_map.c (BE32, BE64, LE32, LE64): Delete the definitions, move + them to lib/system.h. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2013-03-20 Jan Kratochvil + + * dwfl_report_elf.c (__libdwfl_report_elf): Remove BASE aligning. + +2013-03-12 Mark Wielaard + + * dwfl_getsrclines.c (dwfl_getsrclines): Return 0 on success. + +2013-02-22 Mark Wielaard + + * open.c (__libdw_gunzip,__libdw_bunzip2,__libdw_unlzma): Define + as DWFL_E_BADELF when not used. + +2013-02-10 Mark Wielaard + + * argp-std.c (parse_opt): Use opt->core and opt->e explicitly in + failure messages When handling ARGP_KEY_SUCCESS because arg will + not have been set. + +2013-01-30 Jan Kratochvil + + * linux-proc-maps.c: Include system.h. + (PROCEXEFMT, get_pid_class): New. + (grovel_auxv): Detect 32-bit vs. 64-bit auxv, possibly call + get_pid_class. + +2013-01-23 Mark Wielaard + + * dwfl_module_getdwarf.c (find_aux_sym): Don't subtract one + from aux_syments by default. + (find_symtab): Also succeed when only aux_symdata is found. + When no symtab is found always try to load auxiliary table. + (dwfl_module_getsymtab): Substract one from result when both + tables have symbols. + * dwfl_module_getsym.c (dwfl_module_getsym): Only skip auxiliary + zero entry when both tables have symbols. + * dwfl_module_addrsym.c (dwfl_module_addrsym): Only subtract + one from first_global when both tables have symbols. + +2013-01-16 Mark Wielaard + + * libdwflP.h (struct Dwfl_Module): Add aux_sym, aux_symdata, + aux_syments, aux_symstrdata, aux_symxndxdata and aux_first_global. + (dwfl_adjusted_aux_sym_addr): New function. + (dwfl_deadjust_aux_sym_addr): Likewise. + (dwfl_adjusted_st_value): Take and check symfile argument. + (dwfl_deadjust_st_value): Likewise. + * dwfl_module_getdwarf.c (find_prelink_address_sync): Take and + use dwfl_file as argument to set address_sync. + (find_debuginfo): Call find_prelink_address_sync with debug file. + (find_aux_sym): New function. + (find_symtab): Use find_aux_sym if all we have is the dynsym table + and fill in aux DwflModule fields. + (dwfl_module_getsymtab): Return syments plus aux_syments. + (load_symtab): Always set first_global. + * dwfl_module_addrsym.c (dwfl_module_addrsym): Check symfile + when using same_section. Calculate first_global based on both + mod->first_global and mod->aux_first_global. + * dwfl_module.c (__libdwfl_module_free): Free aux_sym. + * dwfl_module_getsym.c (dwfl_module_getsym): Use auxsym table + to retrieve symbol and name if necessary, making sure all locals + from any table come before any globals. + * dwfl_module_info.c (dwfl_module_info): Call dwfl_adjusted_st_value + with symfile. + * relocate.c (resolve_symbol): Likewise. + +2013-01-07 Roland McGrath + + * link_map.c (auxv_format_probe): Handle unaligned 64-bit data, but + still assume the data is at least 32-bit aligned anyway. + (dwfl_link_map_report): Handle unaligned auxv data. + +2012-12-11 Mark Wielaard + + * linux-kernel-modules.c (report_kernel): Only free fname if + find_kernel_elf succeeds and allocates it. + (report_kernel_archive): Fix brackets around unlikely expression. + +2012-11-29 Jan Kratochvil + + * argp-std.c: Update Copyright year. + (offline_find_elf): New function. + (offline_callbacks): Use it for find_elf. + (struct parse_opt): New. + (parse_opt): New key ARGP_KEY_INIT. In other make hook struct + parse_opt pointer from former Dwfl pointer. Delay 'e and OPT_COREFILE + processing till ARGP_KEY_SUCCESS. Initialize state->input already from + ARGP_KEY_SUCCESS. Modify the cleanup in ARGP_KEY_ERROR. Make the + final state->input initialization optional. + * dwfl_end.c: Update Copyright year. + (dwfl_end): Free executable_for_core. + * libdwflP.h: Update Copyright year. + (struct Dwfl): New field executable_for_core. + +2012-11-20 Jan Kratochvil + + * dwfl_report_elf.c (__libdwfl_report_elf): Simplify START and BIAS + calculation. + +2012-10-17 Jan Kratochvil + + * dwfl_module_getdwarf.c (mod_verify_build_id): New function with code + from ... + (__libdwfl_getelf): ... here. Call it. + +2012-10-17 Jan Kratochvil + + * libdwfl.h (dwfl_module_getelf): Add __nonnull_attribute__. + +2012-10-10 Jan Kratochvil + + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Initialize mod->MAIN_BIAS. + +2012-10-10 Jan Kratochvil + + * dwfl_module_addrsym.c (dwfl_module_addrsym): New function + binding_value. Use it for both zero and non-zero size symbols + comparisons. + +2012-10-01 Mark Wielaard + + * cu.c (cudie_offset): Don't use type_sig8, it might not be + initialized and these are always real CUs, never TUs. + +2012-10-01 Mark Wielaard + + * derelocate.c (find_section): Check next section exists before + accessing it. + +2012-08-01 Petr Machata + + * offline.c (process_archive_member): Ignore entry "/SYM64/". + +2012-03-28 Roland McGrath + + * dwfl_segment_report_module.c + (dwfl_segment_report_module: read_portion): Don't use existing buffer + when FILESZ is zero (string mode) and available portion doesn't hold + a terminated string. + +2011-12-02 Roland McGrath + + * elf-from-memory.c (elf_from_remote_memory): Fix ELFCLASS64 case + to use elf64_xlatetom and PHDRS.p64. + Reported by Serge Pavlov . + +2011-11-31 Mark Wielaard + + * dwfl_module_addrsym.c (dwfl_module_addrsym): First search all + global symbols. Then only when that doesn't provide a match search + all local symbols too. + * dwfl_module_getdwarf.c (load_symtab): Take first_global int arg + and fill it in. + (find_symtab): Initialize mod->first_global and pass it to load_symtab. + * libdwfl/libdwflP.h (Dwfl_Module): Add first_global field. + +2011-11-31 Mark Wielaard + + * dwfl_module_addrsym.c (dwfl_module_addrsym): Only update + sizeless_sym if needed and closer to desired addr. + +2011-10-20 Mark Wielaard + + * derelocate.c (cache_sections): Intern mod->reloc_info check. + (dwfl_module_relocations): Don't check mod->reloc_info. + (dwfl_module_relocation_info): Likewise. + (find_section): Likewise. + +2011-07-09 Roland McGrath + + * image-header.c (LE32): Macro removed (now in lib/system.h). + +2011-04-11 Mark Wielaard + + * linux-kernel-modules.c (vmlinux_suffixes): Guard definition + by check for zlib, bzlib or lzma defines to check it isn't empty. + (try_kernel_name): Use same guard for use of vmlinux_suffixes. + +2011-03-08 Roland McGrath + + * dwfl_module_getdwarf.c (open_elf): Clear errno before CBFAIL. + Reported by Kurt Roeckx . + +2011-02-11 Roland McGrath + + * linux-kernel-modules.c (try_kernel_name): Try .gz, .bz2, .xz + suffixes if corresponding decompression support is enabled. + +2011-02-01 Roland McGrath + + * dwfl_module_getdwarf.c (find_prelink_address_sync): Use the + section-end address as the synchronization point, rather than sh_addr. + + * dwfl_module_getdwarf.c (find_prelink_address_sync): Discover + PT_INTERP p_vaddr separately from main phdrs and undo phdrs. + + * dwfl_module_getdwarf.c (find_prelink_address_sync): Fix pasto in + last change, so we recognize PT_INTERP in ELFCLASS64 correctly. + +2011-01-11 Roland McGrath + + * dwfl_module_getdwarf.c (open_elf): Remove section-based + address_sync fixup from here. + (find_prelink_address_sync): New function. + (find_debuginfo): Call it. + * libdwflP.h (DWFL_ERRORS): Add BAD_PRELINK error. + +2011-01-04 Roland McGrath + + * dwfl_module_getdwarf.c (open_elf): Enhance address_sync calculation + logic to consider section addresses, the better to survive all the + possible prelink machinations. + * libdwflP.h (struct dwfl_file): Comment change. + +2010-11-30 Roland McGrath + + * derelocate.c (dwfl_module_relocations): Remove over-eager assert. + +2010-11-12 Roland McGrath + + * libdwflP.h (struct Dwfl_Module): New member main_bias. + (dwfl_adjusted_address, dwfl_deadjust_address): Use it. + * dwfl_module_getdwarf.c (__libdwfl_getelf): Initialize it. + + * libdwflP.h (dwfl_deadjust_address): New function. + (dwfl_deadjust_dwarf_addr, dwfl_deadjust_st_value): New functions. + * cu.c (addrarange): Use dwfl_deadjust_dwarf_addr. + * dwfl_module_addrsym.c: Use dwfl_deadjust_st_value. + +2010-11-11 Roland McGrath + + * libdwflP.h (struct dwfl_file): Remove bias member. + Add vaddr and address_sync members instead. + (dwfl_adjusted_address): Calculate using vaddr. + (dwfl_adjusted_dwarf_addr): Calculate using address_sync and call that. + (dwfl_adjusted_st_value): Use one of those calls. + * dwfl_module_getdwarf.c (open_elf): Initialize vaddr and address_sync. + * dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise. + * derelocate.c (dwfl_module_relocations): Update ET_EXEC assertions. + * link_map.c (consider_executable): Adjust only MOD->low_addr for + detected PIE bias change. + + * libdwflP.h (dwfl_adjusted_dwarf_addr): New function. + * dwfl_module_info.c: Use it. + * cu.c (addrarange): Likewise. + * dwfl_dwarf_line.c: Likewise. + * dwfl_module_dwarf_cfi.c: Likewise. + * dwfl_lineinfo.c: Likewise. + * dwfl_nextcu.c: Likewise. + * dwfl_module_getdwarf.c (dwfl_module_getdwarf): Likewise. + + * libdwflP.h (dwfl_adjusted_st_value): New function. + * relocate.c (resolve_symbol): Use it. + * dwfl_module_getsym.c: Likewise. + * dwfl_module_addrsym.c: Likewise. + * dwfl_module_info.c: Likewise. + + * libdwflP.h (dwfl_adjusted_address): New function. + * dwfl_module_build_id.c (__libdwfl_find_build_id): Use it. + * relocate.c (__libdwfl_relocate_value): Likewise. + * derelocate.c (cache_sections): Likewise. + (dwfl_module_address_section): Likewise. + * dwfl_module_getelf.c: Likewise. + * dwfl_module_eh_cfi.c: Likewise. + * link_map.c (consider_executable): Likewise. + +2010-08-24 Roland McGrath + + * dwfl_dwarf_line.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + +2010-08-18 Roland McGrath + + * link_map.c (report_r_debug): Use found name if we have no name, + even if we already have an Elf handle. + +2010-06-30 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't be + confused by -1 return from dwfl_build_id_find_elf after it opened + the Elf handle. + * find-debuginfo.c (dwfl_standard_find_debuginfo): Likewise for + dwfl_build_id_find_debuginfo. + +2010-06-16 Roland McGrath + + * cu.c (cudie_offset): Use DIE_OFFSET_FROM_CU_OFFSET macro. + +2010-06-14 Roland McGrath + + * find-debuginfo.c (try_open): Take new arg MAIN_STAT. Compare + candidate file to that st_dev/st_ino and pretend it didn't exist + if they match. + (find_debuginfo_in_path): Update caller, pass main file's info. + +2010-05-20 Roland McGrath + + * linux-proc-maps.c (find_sysinfo_ehdr): Renamed to ... + (grovel_auxv): ... this. Take DWFL argument. + (dwfl_linux_proc_report): Update caller. + + * dwfl_module_getdwarf.c (open_elf): Calculate alignment for bias + based on dwfl->segment_align or manifest alignment of MOD->low_addr. + +2010-05-19 Roland McGrath + + * linux-kernel-modules.c (intuit_kernel_bounds): Rewritten. + +2010-05-06 Roland McGrath + + * segment.c (insert): Clear inserted elements of DWFL->lookup_module. + + * libdwflP.h (DWFL_ERRORS): Add WRONG_ID_ELF. + * dwfl_build_id_find_elf.c: Set MOD->main.valid when there is a build + ID but we didn't find a file. + * dwfl_module_getdwarf.c (__libdwfl_getelf): When that's set, check + and refuse any fallback file-by-name if it lacks the matching ID. + + * dwfl_error.c (dwfl_errno): Add INTDEF. + * libdwflP.h: Add INTDECL. + + * dwfl_module_getdwarf.c (open_elf): Do elf_end and clear FILE->elf in + failure cases. + +2010-05-04 Roland McGrath + + * dwfl_segment_report_module.c: Use "[pie]" rather than "[dso]" for an + ET_DYN that has a DT_DEBUG. + + * dwfl_segment_report_module.c: Fix jump-start of NDX-finding loop. + + * segment.c (insert): Fix moving of values following insertion. + (reify_segments): Fix up MOD->segment backpointer indices after + later insertions in the main loop invalidate them. + + * link_map.c (dwfl_link_map_report): Detect bias of embedded phdrs and + apply it to PT_DYNAMIC p_vaddr so we handle a PIE correctly. + + * core-file.c (dwfl_core_file_report): Return any nonzero count of + modules reported, even if link_map grovelling failed and only sniffing + found anything. + +2010-04-26 Roland McGrath + + * relocate.c (relocate_section): Treat R_*_NONE reloc as no reloc. + Works around probably-wrong ld -r behavior for case of a DWARF address + constant that refers to a discarded SHF_ALLOC section. + +2010-04-14 Roland McGrath + + * link_map.c (report_r_debug): Limit iterations on the l_next chain to + an upper bound on sane possible number of elements. + +2010-03-11 Roland McGrath + + * link_map.c (auxv_format_probe): Fix scanning loop, so we really scan + the second half for 32-bit matches. + +2010-03-10 Roland McGrath + + * core-file.c (dwfl_core_file_report): Punt EHDR argument. + * argp-std.c (parse_opt): Update caller. + * libdwfl.h: Declare dwfl_core_file_report. + * libdwflP.h: Don't. + +2010-02-17 Roland McGrath + + * dwfl_segment_report_module.c (addr_segndx): Take new flag argument. + If set, find the first index not below ADDR. + (dwfl_segment_report_module): Update callers. + Pass true when calculating return value. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + + * find-debuginfo.c (find_debuginfo_in_path): Fix uninitialized + variable in failure path. + +2010-02-02 Mark Wielaard + + * dwfl_module_dwarf_cfi.c (dwfl_module_dwarf_cfi): Always set bias. + * dwfl_module_eh_cfi.c (dwfl_module_eh_cfi): Likewise + +2010-01-07 Roland McGrath + + * core-file.c (dwfl_core_file_report): Use elf_getphdrnum. + * dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise. + * dwfl_module_getdwarf.c (open_elf, find_dynsym): Likewise. + * dwfl_report_elf.c (__libdwfl_report_elf): Likewise. + +2010-01-06 Roland McGrath + + * relocate.c (relocate_getsym): For SHN_COMMON, zero st_value. + (relocate_section): Let unresolved SHN_COMMON symbol stay 0. + +2009-11-16 Roland McGrath + + * relocate.c (relocate_section): Skip SHT_NOBITS or empty target scn. + +2009-11-12 Petr Machata + + * core-file.c (dwfl_elf_phdr_memory_callback): Only load ahead if + the chunk is both offset-contiguous and vaddr-contiguous. + +2009-11-05 Roland McGrath + + * link_map.c (report_r_debug): Skip entries with l_ld==0. + Use dwfl_addrmodule for l_ld lookup, don't bail on lookup failure. + +2009-09-04 Roland McGrath + + * image-header.c (__libdw_image_header): Fix tranposed comparison. + +2009-08-27 Roland McGrath + + * image-header.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwflP.h: Declare __libdw_image_header. + * open.c (decompress): Don't consume ELF on failure. + (what_kind): New function, broken out of ... + (__libdw_open_file): ... here. Call it. + If it fails, try __libdw_image_header and then try what_kind again. + + * gzip.c (unzip): Reuse *WHOLE as first INPUT_BUFFER, + leave it behind for next decompressor. + * open.c (decompress): Free BUFFER on failure. + +2009-08-26 Roland McGrath + + * gzip.c (find_zImage_payload): New function, broken out of ... + (mapped_zImage): ... here. Call it. + (find_zImage_payload) [LZMA]: Match LZMA-compressed kernels with + stupid method of just trying the decoder. + + * open.c [USE_LZMA]: Try __libdw_unlzma. + * libdwflP.h: Declare it. + (DWFL_ERRORS): Add DWFL_E_LZMA. + * gzip.c [LZMA]: Implement liblzma version for XZ file format. + * lzma.c: New file. + * Makefile.am [LZMA] (libdwfl_a_SOURCES): Add it. + + * gzip.c (mapped_zImage): Limit scan to 32kb. + Make this unconditional, support bzip2 kernel images too. + (unzip): Use direct inflate method for non-mmap case too. + Only zlib uses the stream method. + +2009-08-09 Roland McGrath + + * dwfl_module_build_id.c: Use new macros for versioned definitions. + +2009-07-08 Roland McGrath + + * dwfl_module_dwarf_cfi.c: New file. + * dwfl_module_eh_cfi.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add them. + * libdwflP.h (struct Dwfl_Module): New members `dwarf_cfi', `eh_cfi. + Add INTDECL for dwfl_module_eh_cfi, dwfl_module_dwarf_cfi. + +2009-07-08 Roland McGrath + + * libdwflP.h (struct Dwfl_Module): Reorder members to pack better. + +2009-06-18 Mark Wielaard + + * dwfl_report_elf.c (__libdwfl_report_elf): Return NULL on overlap. + +2009-06-13 Ulrich Drepper + + * derelocate.c: Don't use deprecated libelf functions. + * dwfl_module_getdwarf.c: Likewise. + * relocate.c: Likewise. + +2009-04-23 Ulrich Drepper + + * dwfl_module_build_id.c: Define versioned symbols only if SHARED is + defined. Otherwise just define the latest version. + +2009-04-22 Roland McGrath + + * relocate.c (resolve_symbol): Apply correct bias to st_value found in + a non-ET_REL module. + + * dwfl_module_build_id.c (__libdwfl_find_build_id): Fix last change to + adjust properly for non-ET_REL. + +2009-04-21 Roland McGrath + + * dwfl_module_getsym.c: Apply non-ET_REL bias only if SHF_ALLOC. + + * relocate.c (__libdwfl_relocate_value): Assert that MOD is ET_REL. + * derelocate.c (cache_sections): Call __libdwfl_relocate_value only + for ET_REL. + * dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise. + +2009-04-20 Roland McGrath + + * dwfl_module_getdwarf.c (__libdwfl_getelf): Add internal_function. + +2009-04-19 Roland McGrath + + * dwfl_module_getdwarf.c (find_file): Renamed to ... + (__libdwfl_getelf): ... this. Make it global. + (find_symtab, find_dw): Update callers. + (dwfl_module_getelf): Functions moved ... + * dwfl_module_getelf.c: ... here, new file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwflP.h: Declare __libdwfl_getelf. + +2009-04-14 Roland McGrath + + * dwfl_segment_report_module.c: Handle DT_STRTAB value being either + absolute (already adjusted in place) or needing load bias adjustment. + + * core-file.c (dwfl_elf_phdr_memory_callback): Fix return value for + gelf_getphdr failure. Fix file size limit checks. + + * dwfl_segment_report_module.c: Fix underflow in DYNSTRSZ check. + +2009-04-08 Roland McGrath + + * dwfl_module_getsym.c: Don't adjust for bias again after + __libdwfl_relocate_value. + + * relocate.c (__libdwfl_relocate_value): Don't adjust a value from + a non-SHF_ALLOC section. + (relocate_getsym): Test st_shndx for SHN_* values, not *SHNDX. + * dwfl_module_getsym.c (dwfl_module_getsym): Likewise. + +2009-03-09 Roland McGrath + + * dwfl_module_build_id.c (__libdwfl_find_build_id): Move SHSTRNDX + variable to outer scope, so we cache it for the loop. + + * relocate.c (__libdwfl_relocate_value): Add MOD->main.bias to sh_addr. + +2009-02-12 Roland McGrath + + * dwfl_module_build_id.c (__libdwfl_find_build_id): Use + __libdwfl_relocate_value to find correct sh_addr value. + +2009-02-10 Roland McGrath + + * dwfl_report_elf.c (__libdwfl_report_elf): Take new arg SANITY. + If false, don't fail for NO_PHDR. + (dwfl_report_elf): Update caller. + * libdwflP.h: Update decl. + * offline.c (process_elf): Call it with false, so we don't refuse + dubiously-formed objects here. + + * link_map.c (consider_executable): Don't assert dwfl_addrsegment + finds our module. We shouldn't crash when we confuse some guesses. + +2009-02-10 Ulrich Drepper + + * open.c (decompress): Avoid crash with empty input file. + +2009-01-27 Roland McGrath + + * dwfl_report_elf.c (__libdwfl_report_elf): Ignore trailing PT_LOAD + with zero vaddr and memsz. + +2009-01-22 Roland McGrath + + * open.c (decompress): Move BUFFER, SIZE decls outside #if. + + * dwfl_segment_report_module.c (addr_segndx): Remove bogus adjustments + after address-matching loop. + + * segment.c (lookup): Fix fencepost in checking for HINT match. + +2009-01-14 Roland McGrath + + * gzip.c [!BZLIB] (mapped_zImage): New function. + (unzip) [!BZLIB]: Grok Linux kernel zImage format. + +2009-01-10 Ulrich Drepper + + * dwfl_error.c: Always use __thread. Remove all !USE_TLS code. + +2009-01-08 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): + Skip subdirectory named "source". + (dwfl_linux_kernel_find_elf): Likewise. + +2009-01-06 Roland McGrath + + * linux-kernel-modules.c (check_suffix): New function. + Match ".ko", ".ko.gz", and ".ko.bz2" suffixes. + (dwfl_linux_kernel_report_offline): Use it. + (dwfl_linux_kernel_find_elf): Likewise. + +2009-01-05 Roland McGrath + + * argp-std.c (parse_opt): Use __libdw_open_file for core file. + * dwfl_build_id_find_debuginfo.c: Use it to open the file. + * dwfl_build_id_find_elf.c: Likewise. + * dwfl_module_getdwarf.c (open_elf): Likewise. + * dwfl_report_elf.c: Likewise. + * find-debuginfo.c (validate): Likewise. + * offline.c (__libdwfl_report_offline): Likewise. + + * libdwflP.h: Declare __libdw_open_file. + * open.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + + * gzip.c: New file. + * Makefile.am [ZLIB] (libdwfl_a_SOURCES): Add it. + * bzip2.c: New file. + * Makefile.am [BZLIB] (libdwfl_a_SOURCES): Add it. + * libdwflP.h: Declare __libdw_gunzip, __libdw_bunzip2. + +2008-12-16 Roland McGrath + + * dwfl_module_build_id.c (dwfl_module_build_id): Define with alias and + symver magic to bind to ELFUTILS_0.138. + (_BUG_COMPAT_dwfl_module_build_id): New function, bug compatible + wrapper for ELFUTILS_0.130 version set. + +2008-12-18 Roland McGrath + + * derelocate.c (dwfl_module_relocate_address): Fix last fix: ET_DYN + addresses are taken as relative to MOD->low_addr. + +2008-12-15 Roland McGrath + + * derelocate.c (dwfl_module_relocate_address): Apply main.bias, not + debug.bias. + +2008-12-11 Roland McGrath + + * offline.c (process_archive): Don't call elf_end and close if + returning NULL. Check first elf_begin call and set error code + specially for empty archive. + Fixes RHBZ#465878. + +2008-12-02 Roland McGrath + + * dwfl_getmodules.c (dwfl_getmodules): Typo fix in last change. + +2008-11-26 Roland McGrath + + * dwfl_getmodules.c (dwfl_getmodules): Encode iteration style in + return value, and interpret encoded OFFSET argument. + +2008-10-07 Roland McGrath + + * dwfl_module_build_id.c (check_notes): Fix typo in vaddr calculation. + +2008-09-29 Roland McGrath + + * segment.c (insert): Must realloc DWFL->lookup_module here too. + (dwfl_report_segment): Clear DWFL->lookup_module before insert calls. + +2008-08-28 Roland McGrath + + * segment.c (reify_segments): Fix last change. + +2008-08-27 Roland McGrath + + * linux-proc-maps.c (read_proc_memory): Return 0 for EINVAL or EPERM + failure from pread64. + +2008-08-26 Roland McGrath + + * segment.c (reify_segments): Insert a trailing segment for a module + end that is above the highest current segment. + +2008-08-25 Roland McGrath + + * dwfl_module_getdwarf.c (open_elf): Extract elf_errno () for + coded return value, not plain DWFL_E_LIBELF. Return DWFL_E_BADELF + if FILE->elf is not ELF_K_ELF. + + * dwfl_segment_report_module.c: Add a cast. + +2008-08-21 Denys Vlasenko + + * dwfl_module_addrsym.c (dwfl_module_addrsym): Improve logic + which decides which symbol is "closest" to a given address. + +2008-08-15 Roland McGrath + + * argp-std.c (offline_callbacks): Use dwfl_build_id_find_elf. + (options, parse_opt): Handle --core. + + * core-file.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwflP.h (dwfl_core_file_report): Declare it. + + * link_map.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwflP.h (dwfl_link_map_report): Declare it. + + * libdwflP.h (MIN, MAX): New macros. + (Dwfl_Memory_Callback): New typedef. + (Dwfl_Module_Callback): New typedef. + (dwfl_segment_report_module): Declare it. + * dwfl_segment_report_module.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + + * derelocate.c (dwfl_module_address_section): Add INTDEF. + * libdwflP.h: Add INTDECL. + + * segment.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_addrsegment, dwfl_report_segment. + * libdwflP.h (struct Dwfl): New members lookup_elts, lookup_alloc, + lookup_addr, lookup_module, lookup_segndx, replace removed members + modules, nmodules. + (struct Dwfl_Module): New member segment. + * dwfl_end.c (dwfl_end): Free the new ones. Iterate via modulelist + to each free module. + * dwfl_module.c (dwfl_report_begin_add): Do nothing. + (dwfl_report_begin): Don't call it. Truncate the segment table instead. + (dwfl_report_module): Don't touch DWFL->nmodules. + (dwfl_report_end): Don't touch DWFL->modules and DWFL->nmodules. + (compare_modules): Function removed. + * dwfl_getmodules.c: Rewritten. + Add INTDEF. + * libdwflP.h: Add INTDECLs. + * dwfl_getdwarf.c: Rewritten to call dwfl_getmodules. + * dwfl_addrmodule.c: Rewritten to just call dwfl_addrsegment. + +2008-08-03 Roland McGrath + + * linux-kernel-modules.c: Include before . + +2008-07-17 Roland McGrath + + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Set errno to + zero if the failure was only ENOENT. + +2008-06-03 Roland McGrath + + * dwfl_module_addrsym.c (dwfl_module_addrsym): Exclude undefined + symbols. + +2008-05-22 Petr Machata + + * dwfl_module_getdwarf.c (open_elf): Bias of ET_EXEC files is always 0. + +2008-05-06 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Use + FTS_LOGICAL here too. + (dwfl_linux_kernel_find_elf): Likewise. + +2008-04-29 Roland McGrath + + * find-debuginfo.c (dwfl_standard_find_debuginfo): Try path search + based on canonicalize_file_name if it differs from the supplied name. + + * linux-kernel-modules.c (check_module_notes): Use FTS_LOGICAL so + we accept symlinks. + +2008-04-27 Roland McGrath + + * linux-kernel-modules.c (report_kernel): Fix crash when + dwfl_report_elf fails. + +2008-04-05 Roland McGrath + + * linux-proc-maps.c (proc_maps_report): Don't leak LAST_FILE. + + * dwfl_module_getdwarf.c (find_file): Always free build_id_bits. + Clear it after freeing. + * dwfl_module_report_build_id.c (dwfl_module_report_build_id): Likewise. + +2008-03-26 Roland McGrath + + * dwfl_module_getdwarf.c (load_symtab): Don't return success for + SHT_DYNSYM, just set *SYMSCN like the comment says. + + * dwfl_end.c (dwfl_end): Iterate on modulelist chain, not modules array. + + * argp-std.c (parse_opt): On failure, call dwfl_end before argp_failure. + +2008-03-19 Roland McGrath + + * dwfl_module_getsrc.c: Adjust address for module bias before search. + +2008-03-01 Roland McGrath + + * libdwflP.h (__libdwfl_seterrno): Remove parameter name from + prototype to avoid older compiler's complaint about reuse of the name. + (__libdwfl_canon_error): Likewise. + +2008-02-19 Roland McGrath + + * relocate.c (relocate_section): Check for an unhandled relocation + type before resolving a reloc's symbol. Lift DWFL_E_BADRELTYPE -> + DWFL_E_UNKNOWN_MACHINE check out of loops. + + * dwfl_module_getdwarf.c (load_dw): Skip relocation if + DEBUGFILE->relocated is already set. + +2008-01-26 Roland McGrath + + * dwfl_module_getdwarf.c (open_elf): Open FILE->name if it's non-null. + + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Don't clear + incoming *FILE_NAME at the start. + +2008-01-08 Roland McGrath + + * Makefile.am (euinclude): Variable removed. + (pkginclude_HEADERS): Set this instead of euinclude_HEADERS. + +2007-10-23 Roland McGrath + + * linux-kernel-modules.c (report_kernel_archive): Reorder the kernel + module to appear first. + +2007-10-20 Roland McGrath + + * offline.c (process_archive_member): Take FD argument, pass it down + to process_file. Return Elf_Cmd, not bool. + Call elf_next here, always before elf_end. + (process_archive): Update caller. Don't close FD here unless there + are no member refs. + + * dwfl_module.c (free_file): Close fd only when elf_end returns zero. + + * libdwflP.h (struct dwfl_file): New bool member `relocated'. + * dwfl_module_getdwarf.c (dwfl_module_getelf): For ET_REL, apply + partial relocation to one or both files. + (dwfl_module_getdwarf): For ET_REL, make sure extra sections' + relocations have been applied to the debug file if dwfl_module_getelf + has been used before. + + * relocate.c (resolve_symbol): New function. + (relocate_section): Call it. + + * relocate.c (relocate_getsym): Handle null MOD->symfile. + (relocate_section): Take new bool arg, PARTIAL. If true, + no error for BADRELTYPE/RELUNDEF, instead just skip them + and leave only those skipped relocs behind the reloc section. + (__libdwfl_relocate_section): Take new arg, pass it down. + (__libdwfl_relocate): Take new bool arg, DEBUG. If false, + do partial relocation on all sections. + * dwfl_module_getdwarf.c (load_dw): Update caller. + * libdwflP.h: Update decls. + * derelocate.c (dwfl_module_address_section): Pass new argument + to __libdwfl_relocate_section, true. + + * derelocate.c (cache_sections): Don't cache reloc sections when + section_address callback is null. + +2007-10-19 Roland McGrath + + * relocate.c (relocate_section): Fix fencepost error in r_offset check. + + * derelocate.c (struct dwfl_relocation): Add member `relocs'. + (struct secref): Likewise. + (cache_sections): Cache the relocation section referring to each + section we cache, if any. + (dwfl_module_address_section): Use __libdwfl_relocate_section as + necessary. + + * relocate.c (struct reloc_symtab_cache): New type. + (relocate_getsym): Use it instead of four arguments. + (__libdwfl_relocate): Update caller. + (relocate_section): New function, broken out of ... + (__libdwfl_relocate): ... here. + (__libdwfl_relocate_section): New function. + * libdwflP.h: Declare it. + +2007-10-17 Roland McGrath + + * dwfl_module_getsym.c (dwfl_module_getsym): Apply MOD->symfile->bias + to relocated st_value. + + * dwfl_report_elf.c (__libdwfl_report_elf): Align initial BASE for + ET_REL to 0x100. + +2007-10-16 Roland McGrath + + * dwfl_report_elf.c (__libdwfl_report_elf): Readjust BASE when a later + section has larger alignment requirements not met by the original BASE, + rather than padding more between sections. + + * dwfl_report_elf.c (__libdwfl_report_elf): Fix bias calculation. + + * dwfl_module_build_id.c (__libdwfl_find_build_id): Apply module bias + to sh_addr value. + + * dwfl_report_elf.c (__libdwfl_report_elf): Don't be confused by BASE + at zero in ET_REL case. Adjust BASE to necessary alignment. + + * dwfl_module_build_id.c (check_notes): Take -1, not 0, as stub value + for DATA_VADDR. + (__libdwfl_find_build_id): Update caller. + + * relocate.c (__libdwfl_relocate_value): Don't use sh_offset. + * dwfl_report_elf.c (__libdwfl_report_elf): Likewise. + * offline.c (dwfl_offline_section_address): Bail early if there is + separate debug file. + + * relocate.c (__libdwfl_relocate): Don't return DWFL_E_NO_DWARF. + +2007-10-09 Roland McGrath + + * dwfl_report_elf.c (__libdwfl_report_elf): Clear SHDR->sh_offset when + caching SHDR->sh_addr = 0. + * offline.c (dwfl_offline_section_address): Never called for sh_addr + really at 0, don't check for it. Use MOD->debug directly, not symfile. + + * dwfl_module_getdwarf.c (load_symtab): Return success properly when + we've found SHT_SYMTAB. + + * relocate.c (relocate_getsym): New function. + (__libdwfl_relocate): Use it. + (__libdwfl_relocate_value): Take new Elf * argument. Make SYMSHSTRNDX + be a pointer instead of value; cache getshstrndx result there. + * libdwflP.h: Update decl. + * derelocate.c (cache_sections): Update caller. + Always work on the main file, not the symfile. + (dwfl_module_address_section): Likewise. + * dwfl_module_getsym.c (dwfl_module_getsym): Update caller. + +2007-10-07 Roland McGrath + + * offline.c (process_archive): Initialize MOD. + + * linux-kernel-modules.c (get_release): New function, broken out of ... + (report_kernel): ... here. Call it. + (try_kernel_name): Take new arg TRY_DEBUG, only try ".debug" if set. + (find_kernel_elf): Update caller. + (report_kernel_archive): New function. + (dwfl_linux_kernel_report_offline): Call it. + + * offline.c (process_file): Take new arg PREDICATE, pass it down. + (process_archive): Likewise. + (process_archive_member): Likewise. When nonnull, let the predicate + decide whether to use this member. + (__libdwfl_report_offline): New function, broken out of ... + (dwfl_report_offline): ... here. Call it. + * libdwflP.h: Declare it. + + * offline.c (process_archive, process_archive_member): New functions. + (process_elf, process_file): New functions, broken out of ... + (dwfl_report_offline): ... here. Call process_file, which recurses on + ELF_K_AR files. + + * dwfl_report_elf.c (__libdwfl_report_elf): New, broken out of ... + (dwfl_report_elf): ... here. Call it. + * libdwflP.h: Declare it. + +2007-10-06 Roland McGrath + + * derelocate.c (dwfl_module_relocations): Don't call + dwfl_module_getdwarf. + + * derelocate.c (find_section): Use __libdwfl_seterrno, not + __libdw_seterrno. + + * relocate.c (__libdwfl_relocate_value): Abuse sh_offset, not + SHF_ALLOC, to cache sh_addr resolved to 0. + + * dwfl_report_elf.c (dwfl_report_elf): When an ET_REL file has sh_addr + values nonzero already, just use its existing layout. + + * relocate.c (__libdwfl_relocate): Clear size of reloc section in its + in-core shdr after applying it. + +2007-10-04 Ulrich Drepper + + * linux-kernel-modules.c (dwfl_linux_kernel_report_kernel): Fake + initialization of notes variable. + +2007-10-04 Roland McGrath + + * linux-kernel-modules.c (intuit_kernel_bounds): Take new arg NOTES, + fill in with vaddr of "__start_notes" symbol if found. + (check_notes): New function. + (check_kernel_notes): New function. + (dwfl_linux_kernel_report_kernel): Call it. + (check_module_notes): New function. + (dwfl_linux_kernel_report_modules): Call it. + + * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): + Try dwfl_build_id_find_elf first. + + * linux-kernel-modules.c (report_kernel): Don't leak FD if !REPORT. + Set kernel module e_type to ET_DYN. + +2007-10-03 Roland McGrath + + * find-debuginfo.c (validate): New function, broken out of ... + (find_debuginfo_in_path): ... here. New function, broken out of ... + (dwfl_standard_find_debuginfo): ... here. Call it, after trying + dwfl_build_id_find_debuginfo first. + + * dwfl_build_id_find_elf.c: New file. + * dwfl_build_id_find_debuginfo.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add them. + * libdwfl.h: Declare them. + * libdwflP.h: Add INTDECLs. + + * dwfl_module_build_id.c: New file. + * dwfl_module_report_build_id.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add them. + * libdwfl.h: Declare them. + * libdwflP.h (struct Dwfl_Module): New members build_id_bits, + build_id_len, build_id_vaddr. Declare __libdwfl_find_build_id. + * dwfl_module.c (__libdwfl_module_free): Free MOD->build_id_bits. + + * dwfl_module_getdwarf.c (find_offsets): New function. + (find_dynsym): New function, calls that. + (find_symtab): Call it. + +2007-09-11 Roland McGrath + + * dwfl_module_addrsym.c: Prefer a later global symbol at the same + address if its st_size is smaller. + +2007-08-13 Roland McGrath + + * dwfl_module_addrsym.c: Add dead initializer for stupid compiler. + +2007-08-12 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Don't use + FTS_LOGICAL. + + * elf-from-memory.c (elf_from_remote_memory): Don't reset LOADBASE on + a second phdr if it happens to match EHDR_VMA exactly. + +2007-08-08 Roland McGrath + + * dwfl_module_addrsym.c: Don't use STT_SECTION, STT_FILE symbols and + those with no names. Rewrite best symbol algorithm not to assume a + sorted table and to be smarter handling sizeless symbols. + +2007-07-16 Roland McGrath + + * dwfl_module.c (dwfl_report_module): Increment DWFL->nmodules when + reviving an existing module. + +2007-06-08 Roland McGrath + + * libdwflP.h: Fix #ifndef for config.h to use PACKAGE_NAME. + +2007-05-17 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Look at + whole /lib/modules/VERSION tree, not just /lib/modules/VERSION/kernel. + (dwfl_linux_kernel_find_elf): Likewise. + + * linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use + getline and sscanf instead of fscanf. + +2007-05-08 Roland McGrath + + * offline.c (dwfl_offline_section_address): Don't assume section + numbers match between stripped and debuginfo files. Instead, assume + only that the ordering among SHF_ALLOC sections matches. + + * linux-kernel-modules.c (report_kernel): Change RELEASE argument to + pointer to string. + (dwfl_linux_kernel_report_offline): Update caller. + (dwfl_linux_kernel_report_kernel): Likewise. + +2007-04-23 Roland McGrath + + * argp-std.c (options): Fix group title string. + + * argp-std.c (parse_opt): Handle ARGP_KEY_ERROR, free the Dwfl. + Update via STATE->input every time we set STATE->hook, not only at + ARGP_KEY_SUCCESS. + + * dwfl_module.c (free_file): Free FILE->name. + +2007-04-16 Roland McGrath + + * derelocate.c (cache_sections): Apply bias to sh_addr. + (compare_secrefs): Fix address comparison to avoid signed overflow. + (find_section): New function, broken out of ... + (dwfl_module_relocate_address): ... here, call it. + (check_module): New function, broken out of ... + (dwfl_module_relocate_address): ... here, call it. + (dwfl_module_address_section): New function. + * libdwfl.h: Declare it. + +2007-03-26 Roland McGrath + + * dwfl_module.c (__libdwfl_module_free): Free MOD itself. + +2007-03-18 Roland McGrath + + * dwfl_module_getdwarf.c (find_debuglink): New function, broken out of + (find_debuginfo): ... here. Call it. + Don't return error for libelf errors finding .gnu_debuglink section. + +2007-03-12 Roland McGrath + + * dwfl_module.c (dwfl_report_begin_add): New function broken out of ... + (dwfl_report_begin): ... here. Call it. + * libdwfl.h: Declare it. + * libdwflP.h: Add INTDECL. + + * elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo. + + * offline.c: Comment typo fix. + +2007-03-04 Roland McGrath + + * linux-kernel-modules.c (KERNEL_MODNAME): New macro for "kernel". + (find_kernel_elf): New function, broken out of ... + (report_kernel): ... here. Call it. + (dwfl_linux_kernel_find_elf): Use it for module named KERNEL_MODNAME. + (intuit_kernel_bounds): New function, grovel /proc/kallsyms to guess + virtual address bounds of kernel from symbols rounded to page size. + (dwfl_linux_kernel_report_kernel): Use that if it works, before + resorting to report_kernel. + + * dwfl_module_getdwarf.c (open_elf): Set MOD->e_type to ET_DYN for an + ET_EXEC file with nonzero bias. + + * dwfl_module_addrname.c (dwfl_module_addrname): Just call + dwfl_module_addrsym. Guts moved to ... + * dwfl_module_addrsym.c: ... here; new file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_module_addrsym. + * libdwflP.h: Add INTDECL. + +2007-03-03 Roland McGrath + + * dwfl_module.c (free_file): New function, broken out of ... + (__libdwfl_module_free): ... here. In it, close fd after elf_end. + + * dwfl_module_getdwarf.c (open_elf): Close fd and reset to -1 + on libelf failure. + +2007-03-02 Roland McGrath + + * linux-kernel-modules.c: Fix bogus error test for asprintf call. + +2007-02-02 Roland McGrath + + * dwfl_addrmodule.c (dwfl_addrmodule): Match a module's high boundary + address exactly if it's no other module's low boundary. + + * dwfl_module_addrname.c (dwfl_module_addrname): If no symbol's value + and size cover the address, select the closest symbol with st_size==0 + that lies in the same section. + +2007-01-29 Roland McGrath + + * dwfl_version.c (dwfl_version): Return PACKAGE_VERSION, + not PACKAGE_STRING. + +2007-01-20 Roland McGrath + + * relocate.c (__libdwfl_relocate_value): Treat section_address of -1 + as omitted, not 0. + * libdwfl.h (Dwfl_Callbacks): Update comment. + * derelocate.c (cache_sections): Don't ignore sh_addr == 0 sections. + * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address): + For ignored missing section, use -1 instead of 0. + * offline.c (dwfl_offline_section_address): Expect a call for 0. + +2007-01-19 Roland McGrath + + * argp-std.c (parse_opt): For -e, reset DWFL->offline_next_address to + zero so a lone -e foo.so is shown without address bias. + +2007-01-10 Roland McGrath + + * linux-kernel-modules.c (report_kernel): Check asprintf return value + directly instead of via side effect, to silence warn_unused_result. + (dwfl_linux_kernel_report_offline): Likewise. + (dwfl_linux_kernel_find_elf): Likewise. + (dwfl_linux_kernel_module_section_address): Likewise. + * find-debuginfo.c (try_open): Likewise. + * linux-proc-maps.c (find_sysinfo_ehdr): Likewise. + (dwfl_linux_proc_report): Likewise. + + * libdwfl.h (dwfl_begin): Require nonnull argument. + +2006-12-27 Roland McGrath + + * dwfl_module.c (compare_modules): Fix address comparison to avoid + signed overflow. Patch by Frank Ch. Eigler . + +2006-10-30 Roland McGrath + + * dwfl_module.c (dwfl_report_module): Comment typo fix. + +2006-09-05 Roland McGrath + + * derelocate.c (cache_sections): Use alloca instead of variable-sized + auto array, in function already using alloca. + +2006-08-14 Roland McGrath + + * linux-kernel-modules.c (try_kernel_name): If the call to + dwfl_standard_find_debuginfo produces no results, try it again + with NULL as DEBUGLINK_FILE to try *FNAME with .debug suffix. + + * find-debuginfo.c (DEFAULT_DEBUGINFO_PATH): Macro moved ... + * libdwflP.h: ... to here. + * linux-kernel-modules.c (try_kernel_name): Skip manual open if it + repeats the first thing dwfl_standard_find_debuginfo will try. + + * linux-kernel-modules.c (MODULE_SECT_NAME_LEN): New macro. + (dwfl_linux_kernel_module_section_address): If a /sys file is missing + and the section name is >= MODULE_SECT_NAME_LEN, try truncating the + section name. + +2006-07-12 Ulrich Drepper + + * cu.c: Adjust for internal_function_def removal. + * dwfl_error.c: Likewise. + * dwfl_module.c: Likewise. + * dwfl_module_getdwarf.c: Likewise. + * lines.c: Likewise. + * relocate.c: Likewise. + +2006-07-11 Ulrich Drepper + + * dwfl_module.c (compare_modules): Don't return GElf_Sxword value, + it can overflow the return value type. + Patch by Tim Moore . + +2006-06-28 Roland McGrath + + * libdwfl.h: Cosmetic changes. + + * dwfl_line_comp_dir.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_line_comp_dir. + + * dwfl_lineinfo.c (dwfl_lineinfo): Remove stray extern in defn. + + * dwfl_linecu.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_linecu. + + * libdwflP.h (dwfl_linecu_inline): Function renamed from dwfl_linecu. + (dwfl_linecu): Define as macro. + + * relocate.c (__libdwfl_relocate): Use dwfl_module_getsym. + + * dwfl_module_getdwarf.c (dwfl_module_getsymtab): New function. + (dwfl_module_addrname): Function moved ... + * dwfl_module_addrname.c: ... here, new file. + * dwfl_module_getsym.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add them. + * libdwfl.h: Declare dwfl_module_getsymtab, dwfl_module_getsym. + * libdwflP.h: Add INTDECLs. + +2006-06-27 Roland McGrath + + * dwfl_module.c (dwfl_report_end): Whitespace fix. + +2006-06-13 Roland McGrath + + * elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo. + Use __libdwfl_seterrno for elf_memory failure. + +2006-05-22 Roland McGrath + + * dwfl_module_return_value_location.c + (dwfl_module_return_value_location): Use __libdwfl_module_getebl. + +2006-05-27 Ulrich Drepper + + * libdwfl.h: Add extern "C". + +2006-05-22 Ulrich Drepper + + * cu.c (addrarange): Handle files without aranges information. + +2006-05-16 Ulrich Drepper + + * dwfl_addrmodule.c (dwfl_addrmodule): Also return NULL of + ->modules is NULL. + +2006-02-26 Roland McGrath + + * dwfl_version.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_version. + + * offline.c (dwfl_report_offline): Account for dwfl_report_elf having + aligned up from DWFL->offline_next_address when checking for overlap. + +2005-12-22 Roland McGrath + + * argp-std.c (parse_opt): Call dwfl_end in failure cases. + + * linux-proc-maps.c (proc_maps_report): New function, broken out of ... + (dwfl_linux_proc_report): ... here. Call it. + (dwfl_linux_proc_maps_report): New function. + * libdwfl.h: Declare it. + * libdwflP.h: Add INTDECL. + * argp-std.c (options, parse_opt): Grok -M/--linux-process-map. + + * dwfl_nextcu.c (dwfl_nextcu): Don't fail when dwfl_module_getdwarf + failed with DWFL_E_NO_DWARF. + +2005-11-26 Roland McGrath + + * dwfl_end.c (dwfl_end): Free the DWFL itself. + +2005-11-25 Roland McGrath + + * dwfl_module_getdwarf.c (__libdwfl_module_getebl): New function. + (load_dw): Use it. + * dwfl_module_register_names.c (dwfl_module_register_names): Likewise. + * libdwflP.h: Declare it. + + * dwfl_module_register_names.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_module_register_names. + +2005-11-21 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address): + Don't leak malloc'd file name. + If a /sys/.../sections file is missing and starts with ".init", + try the variant with "_init" too; catches PPC64 kernel braindamage. + +2005-11-15 Roland McGrath + + * libdwfl.h: Comment fixes. + + * dwfl_module_return_value_location.c: Add unlikely for error case. + +2005-11-13 Roland McGrath + + * dwfl_return_value_location.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_module_return_value_location. + * libdwflP.h (DWFL_ERRORS): Add DWFL_E_WEIRD_TYPE. + +2005-10-20 Roland McGrath + + * libdwflP.h (DWFL_ERRORS): New error UNKNOWN_MACHINE. + * relocate.c (__libdwfl_relocate): Return DWFL_E_UNKNOWN_MACHINE + instead of DWFL_E_BADRELTYPE if ebl_get_elfmachine yields EM_NONE. + +2005-10-01 Roland McGrath + + * linux-kernel-modules.c (report_kernel): Return ENOENT if we fail + with errno 0. + +2005-09-19 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use + PRIx64 instead of PRIi64, lest addresses with high bits set overflow + the signed integer reading; they will just have to be in hexadecimal. + (dwfl_linux_kernel_module_section_address): Likewise. + +2005-08-28 Ulrich Drepper + + * Makefile.am (%.os): Use COMPILE.os. + (COMPILE.os): Filter out gconv options. + +2005-08-25 Roland McGrath + + * cu.c (__libdwfl_nextcu): Return success when dwarf_nextcu hits end. + * dwfl_nextcu.c (dwfl_nextcu): Skip modules with no dwarf info. + +2005-08-24 Roland McGrath + + * dwfl_lineinfo.c (dwfl_lineinfo): Add bias, don't subtract it. + + * argp-std.c [_MUDFLAP] (__libdwfl_argp_mudflap_options): New function, + magic initializer to set -heur-stack-bound option. + +2005-08-22 Roland McGrath + + * dwfl_validate_address.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_validate_address. + + * derelocate.c (dwfl_module_relocate_address): Add INTDEF. + * libdwflP.h: Add INTDECL. + + * dwfl_module_getdwarf.c (find_symtab): Use elf_getdata instead of + elf_rawdata for symbol-related sections. + + * offline.c (dwfl_report_offline): Move offline_next_address outside + module's range, in case it's an ET_EXEC using fixed segment locations. + * libdwfl.h: Update comment. + + * dwfl_report_elf.c (dwfl_report_elf): Align BASE to first segment's + required alignment. + +2005-08-20 Roland McGrath + + * linux-kernel-modules.c (report_kernel): Take new argument PREDICATE, + function to choose whether to report. + (dwfl_linux_kernel_report_offline): Likewise. + * libdwfl.h: Update decl. + * argp-std.c (parse_opt): Update caller. + + * dwfl_getsrclines.c: New file. + * dwfl_onesrcline.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add them. + * libdwfl.h: Declare dwfl_getsrclines, dwfl_onesrcline. + + * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't leak + MODULESDIR[0]. Call fts_close on failure. + + * dwfl_module_getdwarf.c (load_dw): Take dwfl_file * instead of Elf *. + Close ET_REL file descriptors after relocation. + (find_dw): Update caller. + * offline.c (dwfl_report_offline): Get the file into memory and close + the file descriptor. + + * dwfl_module_getdwarf.c (find_debuginfo): Do nothing when + MOD->debug.elf is already set. + + * find-debuginfo.c (try_open): Use TEMP_FAILURE_RETRY. + (dwfl_standard_find_debuginfo): Fail on errors not ENOENT or ENOTDIR. + + * argp-std.c (options, parse_opt): Grok -K/--offline-kernel, use + dwfl_linux_kernel_report_offline with offline_callbacks. + + * linux-kernel-modules.c (report_kernel): New function, broken out of + ... + (dwfl_linux_kernel_report_kernel): ... here. Use it. + (dwfl_linux_kernel_report_offline): New function. + * libdwfl.h: Declare it. + * libdwflP.h: Add INTDECL. + +2005-08-19 Roland McGrath + + Use standard debuginfo search path to look for vmlinux. + * find-debuginfo.c (dwfl_standard_find_debuginfo): Don't check CRC if + passed zero. + * linux-kernel-modules.c (try_kernel_name): New function, broken out + of ... + (dwfl_linux_kernel_report_kernel): ... here. Use it. + + * argp-std.c (offline_callbacks): New variable. + (parse_opt): Use it for -e. Allow multiple -e options. + + * offline.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + * libdwfl.h: Declare dwfl_offline_section_address, dwfl_report_offline. + * libdwflP.h: Add INTDECLs. + (OFFLINE_REDZONE): New macro. + (struct Dwfl): New member `offline_next_address'. + * dwfl_begin.c (dwfl_begin): Initialize it. + * dwfl_module.c (dwfl_report_begin): Likewise. + + * dwfl_report_elf.c (dwfl_report_elf): Accept all types. When ET_REL, + do a nominal absolute section layout starting at BASE. + * libdwfl.h: Update comment. + +2005-08-18 Roland McGrath + + * dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Do + dwfl_module_getdwarf if necessary. + + * dwfl_report_elf.c (dwfl_report_elf): Permit ET_REL with BASE==0. + * libdwfl.h: Update comment. + + * derelocate.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + + * libdwflP.h (struct Dwfl_Module): isrel -> e_type. + * dwfl_report_elf.c (dwfl_report_elf): Initialize it. + * dwfl_module_getdwarf.c (open_elf): Update initialization. + (load_dw, dwfl_module_addrname): Update uses. + * relocate.c (__libdwfl_relocate): Likewise. + +2005-08-04 Roland McGrath + + * libdwfl.h (Dwfl_Callbacks.section_address): Take additional + arguments SHNDX, SHDR. + (dwfl_linux_kernel_module_section_address): Update prototype. + * relocate.c (__libdwfl_relocate_value): Update caller. + * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address): + Take the new arguments. + +2005-08-10 Roland McGrath + + * relocate.c (__libdwfl_relocate): Take argument DEBUGFILE, + use it instead of MOD->debug.file. + * libdwflP.h: Update decl. + * dwfl_module_getdwarf.c (load_dw): Update caller. + Fixes bug #165598. + +2005-08-09 Roland McGrath + + * libdwflP.h: Include ../libdw/libdwP.h for its INTDECLs. + * cu.c: Use INTUSE on dwarf_* calls. + * dwfl_error.c: Likewise. + * dwfl_module.c: Likewise. + * dwfl_module_getdwarf.c: Likewise. + * dwfl_module_getsrc_file.c: Likewise. + * lines.c: Likewise. + +2005-08-07 Roland McGrath + + * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): When module + names contain '_' or '-', look for files named either "foo-bar.ko" + or "foo_bar.ko". + +2005-07-29 Roland McGrath + + * loc2c.c: File removed. + * loc2c.h: File removed. + * loc2c-runtime.h: File removed. + * test2.c: File removed. + * Makefile.am (EXTRA_DIST): Variable removed. + (noinst_HEADERS): Remove loc2c.h from here. + +2005-07-28 Ulrich Drepper + + * libdwfl.h: Add a few missing extern for function prototypes. + + * libdwfl_crc32.c: New file. + * libdwfl_crc32_file.c: New file. + * libdwflP.h: Declare the new functions. + * Makefile.am (libdwfl_a_SOURCES): Add libdwfl_crc32.c and + libdwfl_crc32_file.c. + * libdwfl/find-debuginfo.c (check_crc): Use __libdwfl_crc32_file + instead of crc32_file. + +2005-07-28 Roland McGrath + + * ptest.c: Moved to ../tests/dwflmodtest.c. + + * Makefile.am (noinst_PROGRAMS): Variable removed. + (libdwfl_so_SOURCES, libdwfl_LIBS, libdwfl_so_LDADD): Likewise. + (EXTRA_DIST, ptest_LDADD, test2_LDADD): Likewise. + (libdwfl): Don't use libdwfl.so any more. + (libdwfl.so, install, uninstall): Targets removed. + (test2_SOURCES): Define EXTRA_DIST instead of this. + * libdwfl.map: File removed. + + * libdwfl.h: Use "" for libdw.h #include. + +2005-07-27 Roland McGrath + + * libdwfl.map: Add dwfl_getmodules. + +2005-07-23 Ulrich Drepper + + * Makefile.am: Fix rules to allow building with mudflap. + +2005-07-21 Roland McGrath + + * Makefile.am (noinst_HEADERS): Add loc2c.c. + + * test2.c (main): Check sscanf result to quiet warning. + +2005-07-20 Roland McGrath + + * libdwfl-branch merged, creating this direcotry. diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am new file mode 100644 index 00000000..a0013e41 --- /dev/null +++ b/libdwfl/Makefile.am @@ -0,0 +1,99 @@ +## Makefile.am for libdwfl library subdirectory in elfutils. +## +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2005-2010, 2013 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf -I$(srcdir)/../debuginfod +VERSION = 1 + +noinst_LIBRARIES = libdwfl.a +noinst_LIBRARIES += libdwfl_pic.a + +pkginclude_HEADERS = libdwfl.h + + +libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \ + dwfl_module.c dwfl_report_elf.c relocate.c \ + dwfl_module_build_id.c dwfl_module_report_build_id.c \ + derelocate.c offline.c segment.c \ + dwfl_module_info.c dwfl_getmodules.c dwfl_getdwarf.c \ + dwfl_module_getdwarf.c dwfl_module_getelf.c \ + dwfl_validate_address.c \ + argp-std.c find-debuginfo.c \ + dwfl_build_id_find_elf.c \ + dwfl_build_id_find_debuginfo.c \ + linux-kernel-modules.c linux-proc-maps.c \ + dwfl_addrmodule.c dwfl_addrdwarf.c \ + cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \ + dwfl_module_addrdie.c dwfl_addrdie.c \ + lines.c dwfl_lineinfo.c dwfl_line_comp_dir.c \ + dwfl_linemodule.c dwfl_linecu.c dwfl_dwarf_line.c \ + dwfl_getsrclines.c dwfl_onesrcline.c \ + dwfl_module_getsrc.c dwfl_getsrc.c \ + dwfl_module_getsrc_file.c \ + libdwfl_crc32.c libdwfl_crc32_file.c \ + elf-from-memory.c \ + dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \ + dwfl_module_getsym.c \ + dwfl_module_addrname.c dwfl_module_addrsym.c \ + dwfl_module_return_value_location.c \ + dwfl_module_register_names.c \ + dwfl_segment_report_module.c \ + link_map.c core-file.c open.c image-header.c \ + dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \ + linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c \ + gzip.c + +if BZLIB +libdwfl_a_SOURCES += bzip2.c +endif +if LZMA +libdwfl_a_SOURCES += lzma.c +endif +if ZSTD +libdwfl_a_SOURCES += zstd.c +endif +if LIBDEBUGINFOD +libdwfl_a_SOURCES += debuginfod-client.c +endif + +libdwfl = $(libdw) +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +libebl = ../libebl/libebl.a +libeu = ../lib/libeu.a + +libdwfl_pic_a_SOURCES = +am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os) + +noinst_HEADERS = libdwflP.h + +CLEANFILES += $(am_libdwfl_pic_a_OBJECTS) diff --git a/libdwfl/Makefile.in b/libdwfl/Makefile.in new file mode 100644 index 00000000..5620ed1c --- /dev/null +++ b/libdwfl/Makefile.in @@ -0,0 +1,1099 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@BZLIB_TRUE@am__append_2 = bzip2.c +@LZMA_TRUE@am__append_3 = lzma.c +@ZSTD_TRUE@am__append_4 = zstd.c +@LIBDEBUGINFOD_TRUE@am__append_5 = debuginfod-client.c +subdir = libdwfl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(pkginclude_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libdwfl_a_AR = $(AR) $(ARFLAGS) +libdwfl_a_LIBADD = +am__libdwfl_a_SOURCES_DIST = dwfl_begin.c dwfl_end.c dwfl_error.c \ + dwfl_version.c dwfl_module.c dwfl_report_elf.c relocate.c \ + dwfl_module_build_id.c dwfl_module_report_build_id.c \ + derelocate.c offline.c segment.c dwfl_module_info.c \ + dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \ + dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \ + find-debuginfo.c dwfl_build_id_find_elf.c \ + dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \ + linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \ + dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \ + dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \ + dwfl_line_comp_dir.c dwfl_linemodule.c dwfl_linecu.c \ + dwfl_dwarf_line.c dwfl_getsrclines.c dwfl_onesrcline.c \ + dwfl_module_getsrc.c dwfl_getsrc.c dwfl_module_getsrc_file.c \ + libdwfl_crc32.c libdwfl_crc32_file.c elf-from-memory.c \ + dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \ + dwfl_module_getsym.c dwfl_module_addrname.c \ + dwfl_module_addrsym.c dwfl_module_return_value_location.c \ + dwfl_module_register_names.c dwfl_segment_report_module.c \ + link_map.c core-file.c open.c image-header.c dwfl_frame.c \ + frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \ + linux-core-attach.c dwfl_frame_regs.c gzip.c bzip2.c lzma.c \ + zstd.c debuginfod-client.c +@BZLIB_TRUE@am__objects_1 = bzip2.$(OBJEXT) +@LZMA_TRUE@am__objects_2 = lzma.$(OBJEXT) +@ZSTD_TRUE@am__objects_3 = zstd.$(OBJEXT) +@LIBDEBUGINFOD_TRUE@am__objects_4 = debuginfod-client.$(OBJEXT) +am_libdwfl_a_OBJECTS = dwfl_begin.$(OBJEXT) dwfl_end.$(OBJEXT) \ + dwfl_error.$(OBJEXT) dwfl_version.$(OBJEXT) \ + dwfl_module.$(OBJEXT) dwfl_report_elf.$(OBJEXT) \ + relocate.$(OBJEXT) dwfl_module_build_id.$(OBJEXT) \ + dwfl_module_report_build_id.$(OBJEXT) derelocate.$(OBJEXT) \ + offline.$(OBJEXT) segment.$(OBJEXT) dwfl_module_info.$(OBJEXT) \ + dwfl_getmodules.$(OBJEXT) dwfl_getdwarf.$(OBJEXT) \ + dwfl_module_getdwarf.$(OBJEXT) dwfl_module_getelf.$(OBJEXT) \ + dwfl_validate_address.$(OBJEXT) argp-std.$(OBJEXT) \ + find-debuginfo.$(OBJEXT) dwfl_build_id_find_elf.$(OBJEXT) \ + dwfl_build_id_find_debuginfo.$(OBJEXT) \ + linux-kernel-modules.$(OBJEXT) linux-proc-maps.$(OBJEXT) \ + dwfl_addrmodule.$(OBJEXT) dwfl_addrdwarf.$(OBJEXT) \ + cu.$(OBJEXT) dwfl_module_nextcu.$(OBJEXT) \ + dwfl_nextcu.$(OBJEXT) dwfl_cumodule.$(OBJEXT) \ + dwfl_module_addrdie.$(OBJEXT) dwfl_addrdie.$(OBJEXT) \ + lines.$(OBJEXT) dwfl_lineinfo.$(OBJEXT) \ + dwfl_line_comp_dir.$(OBJEXT) dwfl_linemodule.$(OBJEXT) \ + dwfl_linecu.$(OBJEXT) dwfl_dwarf_line.$(OBJEXT) \ + dwfl_getsrclines.$(OBJEXT) dwfl_onesrcline.$(OBJEXT) \ + dwfl_module_getsrc.$(OBJEXT) dwfl_getsrc.$(OBJEXT) \ + dwfl_module_getsrc_file.$(OBJEXT) libdwfl_crc32.$(OBJEXT) \ + libdwfl_crc32_file.$(OBJEXT) elf-from-memory.$(OBJEXT) \ + dwfl_module_dwarf_cfi.$(OBJEXT) dwfl_module_eh_cfi.$(OBJEXT) \ + dwfl_module_getsym.$(OBJEXT) dwfl_module_addrname.$(OBJEXT) \ + dwfl_module_addrsym.$(OBJEXT) \ + dwfl_module_return_value_location.$(OBJEXT) \ + dwfl_module_register_names.$(OBJEXT) \ + dwfl_segment_report_module.$(OBJEXT) link_map.$(OBJEXT) \ + core-file.$(OBJEXT) open.$(OBJEXT) image-header.$(OBJEXT) \ + dwfl_frame.$(OBJEXT) frame_unwind.$(OBJEXT) \ + dwfl_frame_pc.$(OBJEXT) linux-pid-attach.$(OBJEXT) \ + linux-core-attach.$(OBJEXT) dwfl_frame_regs.$(OBJEXT) \ + gzip.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) +libdwfl_a_OBJECTS = $(am_libdwfl_a_OBJECTS) +libdwfl_pic_a_AR = $(AR) $(ARFLAGS) +libdwfl_pic_a_LIBADD = +libdwfl_pic_a_OBJECTS = $(am_libdwfl_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/argp-std.Po ./$(DEPDIR)/bzip2.Po \ + ./$(DEPDIR)/core-file.Po ./$(DEPDIR)/cu.Po \ + ./$(DEPDIR)/debuginfod-client.Po ./$(DEPDIR)/derelocate.Po \ + ./$(DEPDIR)/dwfl_addrdie.Po ./$(DEPDIR)/dwfl_addrdwarf.Po \ + ./$(DEPDIR)/dwfl_addrmodule.Po ./$(DEPDIR)/dwfl_begin.Po \ + ./$(DEPDIR)/dwfl_build_id_find_debuginfo.Po \ + ./$(DEPDIR)/dwfl_build_id_find_elf.Po \ + ./$(DEPDIR)/dwfl_cumodule.Po ./$(DEPDIR)/dwfl_dwarf_line.Po \ + ./$(DEPDIR)/dwfl_end.Po ./$(DEPDIR)/dwfl_error.Po \ + ./$(DEPDIR)/dwfl_frame.Po ./$(DEPDIR)/dwfl_frame_pc.Po \ + ./$(DEPDIR)/dwfl_frame_regs.Po ./$(DEPDIR)/dwfl_getdwarf.Po \ + ./$(DEPDIR)/dwfl_getmodules.Po ./$(DEPDIR)/dwfl_getsrc.Po \ + ./$(DEPDIR)/dwfl_getsrclines.Po \ + ./$(DEPDIR)/dwfl_line_comp_dir.Po ./$(DEPDIR)/dwfl_linecu.Po \ + ./$(DEPDIR)/dwfl_lineinfo.Po ./$(DEPDIR)/dwfl_linemodule.Po \ + ./$(DEPDIR)/dwfl_module.Po ./$(DEPDIR)/dwfl_module_addrdie.Po \ + ./$(DEPDIR)/dwfl_module_addrname.Po \ + ./$(DEPDIR)/dwfl_module_addrsym.Po \ + ./$(DEPDIR)/dwfl_module_build_id.Po \ + ./$(DEPDIR)/dwfl_module_dwarf_cfi.Po \ + ./$(DEPDIR)/dwfl_module_eh_cfi.Po \ + ./$(DEPDIR)/dwfl_module_getdwarf.Po \ + ./$(DEPDIR)/dwfl_module_getelf.Po \ + ./$(DEPDIR)/dwfl_module_getsrc.Po \ + ./$(DEPDIR)/dwfl_module_getsrc_file.Po \ + ./$(DEPDIR)/dwfl_module_getsym.Po \ + ./$(DEPDIR)/dwfl_module_info.Po \ + ./$(DEPDIR)/dwfl_module_nextcu.Po \ + ./$(DEPDIR)/dwfl_module_register_names.Po \ + ./$(DEPDIR)/dwfl_module_report_build_id.Po \ + ./$(DEPDIR)/dwfl_module_return_value_location.Po \ + ./$(DEPDIR)/dwfl_nextcu.Po ./$(DEPDIR)/dwfl_onesrcline.Po \ + ./$(DEPDIR)/dwfl_report_elf.Po \ + ./$(DEPDIR)/dwfl_segment_report_module.Po \ + ./$(DEPDIR)/dwfl_validate_address.Po \ + ./$(DEPDIR)/dwfl_version.Po ./$(DEPDIR)/elf-from-memory.Po \ + ./$(DEPDIR)/find-debuginfo.Po ./$(DEPDIR)/frame_unwind.Po \ + ./$(DEPDIR)/gzip.Po ./$(DEPDIR)/image-header.Po \ + ./$(DEPDIR)/libdwfl_crc32.Po ./$(DEPDIR)/libdwfl_crc32_file.Po \ + ./$(DEPDIR)/lines.Po ./$(DEPDIR)/link_map.Po \ + ./$(DEPDIR)/linux-core-attach.Po \ + ./$(DEPDIR)/linux-kernel-modules.Po \ + ./$(DEPDIR)/linux-pid-attach.Po ./$(DEPDIR)/linux-proc-maps.Po \ + ./$(DEPDIR)/lzma.Po ./$(DEPDIR)/offline.Po ./$(DEPDIR)/open.Po \ + ./$(DEPDIR)/relocate.Po ./$(DEPDIR)/segment.Po \ + ./$(DEPDIR)/zstd.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdwfl_a_SOURCES) $(libdwfl_pic_a_SOURCES) +DIST_SOURCES = $(am__libdwfl_a_SOURCES_DIST) $(libdwfl_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgincludedir)" +HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. -I$(srcdir) \ + -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \ + -I$(srcdir)/../debuginfod + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda $(am_libdwfl_pic_a_OBJECTS) +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +noinst_LIBRARIES = libdwfl.a libdwfl_pic.a +pkginclude_HEADERS = libdwfl.h +libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c \ + dwfl_version.c dwfl_module.c dwfl_report_elf.c relocate.c \ + dwfl_module_build_id.c dwfl_module_report_build_id.c \ + derelocate.c offline.c segment.c dwfl_module_info.c \ + dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \ + dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \ + find-debuginfo.c dwfl_build_id_find_elf.c \ + dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \ + linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \ + dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \ + dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \ + dwfl_line_comp_dir.c dwfl_linemodule.c dwfl_linecu.c \ + dwfl_dwarf_line.c dwfl_getsrclines.c dwfl_onesrcline.c \ + dwfl_module_getsrc.c dwfl_getsrc.c dwfl_module_getsrc_file.c \ + libdwfl_crc32.c libdwfl_crc32_file.c elf-from-memory.c \ + dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \ + dwfl_module_getsym.c dwfl_module_addrname.c \ + dwfl_module_addrsym.c dwfl_module_return_value_location.c \ + dwfl_module_register_names.c dwfl_segment_report_module.c \ + link_map.c core-file.c open.c image-header.c dwfl_frame.c \ + frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \ + linux-core-attach.c dwfl_frame_regs.c gzip.c $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) +libdwfl = $(libdw) +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +libebl = ../libebl/libebl.a +libeu = ../lib/libeu.a +libdwfl_pic_a_SOURCES = +am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os) +noinst_HEADERS = libdwflP.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdwfl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libdwfl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libdwfl.a: $(libdwfl_a_OBJECTS) $(libdwfl_a_DEPENDENCIES) $(EXTRA_libdwfl_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdwfl.a + $(AM_V_AR)$(libdwfl_a_AR) libdwfl.a $(libdwfl_a_OBJECTS) $(libdwfl_a_LIBADD) + $(AM_V_at)$(RANLIB) libdwfl.a + +libdwfl_pic.a: $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_DEPENDENCIES) $(EXTRA_libdwfl_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdwfl_pic.a + $(AM_V_AR)$(libdwfl_pic_a_AR) libdwfl_pic.a $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libdwfl_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-std.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bzip2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core-file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debuginfod-client.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/derelocate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrdie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrdwarf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrmodule.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_begin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_build_id_find_debuginfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_build_id_find_elf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_cumodule.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_dwarf_line.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_end.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_error.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_frame.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_frame_pc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_frame_regs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getdwarf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getmodules.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getsrc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getsrclines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_line_comp_dir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_linecu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_lineinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_linemodule.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrdie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrsym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_build_id.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_dwarf_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_eh_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getdwarf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getelf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsrc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsrc_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_nextcu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_register_names.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_report_build_id.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_return_value_location.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_nextcu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_onesrcline.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_report_elf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_segment_report_module.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_validate_address.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_version.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-from-memory.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find-debuginfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame_unwind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image-header.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwfl_crc32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwfl_crc32_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_map.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-core-attach.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-kernel-modules.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-pid-attach.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-proc-maps.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzma.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/offline.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relocate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/segment.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zstd.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/argp-std.Po + -rm -f ./$(DEPDIR)/bzip2.Po + -rm -f ./$(DEPDIR)/core-file.Po + -rm -f ./$(DEPDIR)/cu.Po + -rm -f ./$(DEPDIR)/debuginfod-client.Po + -rm -f ./$(DEPDIR)/derelocate.Po + -rm -f ./$(DEPDIR)/dwfl_addrdie.Po + -rm -f ./$(DEPDIR)/dwfl_addrdwarf.Po + -rm -f ./$(DEPDIR)/dwfl_addrmodule.Po + -rm -f ./$(DEPDIR)/dwfl_begin.Po + -rm -f ./$(DEPDIR)/dwfl_build_id_find_debuginfo.Po + -rm -f ./$(DEPDIR)/dwfl_build_id_find_elf.Po + -rm -f ./$(DEPDIR)/dwfl_cumodule.Po + -rm -f ./$(DEPDIR)/dwfl_dwarf_line.Po + -rm -f ./$(DEPDIR)/dwfl_end.Po + -rm -f ./$(DEPDIR)/dwfl_error.Po + -rm -f ./$(DEPDIR)/dwfl_frame.Po + -rm -f ./$(DEPDIR)/dwfl_frame_pc.Po + -rm -f ./$(DEPDIR)/dwfl_frame_regs.Po + -rm -f ./$(DEPDIR)/dwfl_getdwarf.Po + -rm -f ./$(DEPDIR)/dwfl_getmodules.Po + -rm -f ./$(DEPDIR)/dwfl_getsrc.Po + -rm -f ./$(DEPDIR)/dwfl_getsrclines.Po + -rm -f ./$(DEPDIR)/dwfl_line_comp_dir.Po + -rm -f ./$(DEPDIR)/dwfl_linecu.Po + -rm -f ./$(DEPDIR)/dwfl_lineinfo.Po + -rm -f ./$(DEPDIR)/dwfl_linemodule.Po + -rm -f ./$(DEPDIR)/dwfl_module.Po + -rm -f ./$(DEPDIR)/dwfl_module_addrdie.Po + -rm -f ./$(DEPDIR)/dwfl_module_addrname.Po + -rm -f ./$(DEPDIR)/dwfl_module_addrsym.Po + -rm -f ./$(DEPDIR)/dwfl_module_build_id.Po + -rm -f ./$(DEPDIR)/dwfl_module_dwarf_cfi.Po + -rm -f ./$(DEPDIR)/dwfl_module_eh_cfi.Po + -rm -f ./$(DEPDIR)/dwfl_module_getdwarf.Po + -rm -f ./$(DEPDIR)/dwfl_module_getelf.Po + -rm -f ./$(DEPDIR)/dwfl_module_getsrc.Po + -rm -f ./$(DEPDIR)/dwfl_module_getsrc_file.Po + -rm -f ./$(DEPDIR)/dwfl_module_getsym.Po + -rm -f ./$(DEPDIR)/dwfl_module_info.Po + -rm -f ./$(DEPDIR)/dwfl_module_nextcu.Po + -rm -f ./$(DEPDIR)/dwfl_module_register_names.Po + -rm -f ./$(DEPDIR)/dwfl_module_report_build_id.Po + -rm -f ./$(DEPDIR)/dwfl_module_return_value_location.Po + -rm -f ./$(DEPDIR)/dwfl_nextcu.Po + -rm -f ./$(DEPDIR)/dwfl_onesrcline.Po + -rm -f ./$(DEPDIR)/dwfl_report_elf.Po + -rm -f ./$(DEPDIR)/dwfl_segment_report_module.Po + -rm -f ./$(DEPDIR)/dwfl_validate_address.Po + -rm -f ./$(DEPDIR)/dwfl_version.Po + -rm -f ./$(DEPDIR)/elf-from-memory.Po + -rm -f ./$(DEPDIR)/find-debuginfo.Po + -rm -f ./$(DEPDIR)/frame_unwind.Po + -rm -f ./$(DEPDIR)/gzip.Po + -rm -f ./$(DEPDIR)/image-header.Po + -rm -f ./$(DEPDIR)/libdwfl_crc32.Po + -rm -f ./$(DEPDIR)/libdwfl_crc32_file.Po + -rm -f ./$(DEPDIR)/lines.Po + -rm -f ./$(DEPDIR)/link_map.Po + -rm -f ./$(DEPDIR)/linux-core-attach.Po + -rm -f ./$(DEPDIR)/linux-kernel-modules.Po + -rm -f ./$(DEPDIR)/linux-pid-attach.Po + -rm -f ./$(DEPDIR)/linux-proc-maps.Po + -rm -f ./$(DEPDIR)/lzma.Po + -rm -f ./$(DEPDIR)/offline.Po + -rm -f ./$(DEPDIR)/open.Po + -rm -f ./$(DEPDIR)/relocate.Po + -rm -f ./$(DEPDIR)/segment.Po + -rm -f ./$(DEPDIR)/zstd.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/argp-std.Po + -rm -f ./$(DEPDIR)/bzip2.Po + -rm -f ./$(DEPDIR)/core-file.Po + -rm -f ./$(DEPDIR)/cu.Po + -rm -f ./$(DEPDIR)/debuginfod-client.Po + -rm -f ./$(DEPDIR)/derelocate.Po + -rm -f ./$(DEPDIR)/dwfl_addrdie.Po + -rm -f ./$(DEPDIR)/dwfl_addrdwarf.Po + -rm -f ./$(DEPDIR)/dwfl_addrmodule.Po + -rm -f ./$(DEPDIR)/dwfl_begin.Po + -rm -f ./$(DEPDIR)/dwfl_build_id_find_debuginfo.Po + -rm -f ./$(DEPDIR)/dwfl_build_id_find_elf.Po + -rm -f ./$(DEPDIR)/dwfl_cumodule.Po + -rm -f ./$(DEPDIR)/dwfl_dwarf_line.Po + -rm -f ./$(DEPDIR)/dwfl_end.Po + -rm -f ./$(DEPDIR)/dwfl_error.Po + -rm -f ./$(DEPDIR)/dwfl_frame.Po + -rm -f ./$(DEPDIR)/dwfl_frame_pc.Po + -rm -f ./$(DEPDIR)/dwfl_frame_regs.Po + -rm -f ./$(DEPDIR)/dwfl_getdwarf.Po + -rm -f ./$(DEPDIR)/dwfl_getmodules.Po + -rm -f ./$(DEPDIR)/dwfl_getsrc.Po + -rm -f ./$(DEPDIR)/dwfl_getsrclines.Po + -rm -f ./$(DEPDIR)/dwfl_line_comp_dir.Po + -rm -f ./$(DEPDIR)/dwfl_linecu.Po + -rm -f ./$(DEPDIR)/dwfl_lineinfo.Po + -rm -f ./$(DEPDIR)/dwfl_linemodule.Po + -rm -f ./$(DEPDIR)/dwfl_module.Po + -rm -f ./$(DEPDIR)/dwfl_module_addrdie.Po + -rm -f ./$(DEPDIR)/dwfl_module_addrname.Po + -rm -f ./$(DEPDIR)/dwfl_module_addrsym.Po + -rm -f ./$(DEPDIR)/dwfl_module_build_id.Po + -rm -f ./$(DEPDIR)/dwfl_module_dwarf_cfi.Po + -rm -f ./$(DEPDIR)/dwfl_module_eh_cfi.Po + -rm -f ./$(DEPDIR)/dwfl_module_getdwarf.Po + -rm -f ./$(DEPDIR)/dwfl_module_getelf.Po + -rm -f ./$(DEPDIR)/dwfl_module_getsrc.Po + -rm -f ./$(DEPDIR)/dwfl_module_getsrc_file.Po + -rm -f ./$(DEPDIR)/dwfl_module_getsym.Po + -rm -f ./$(DEPDIR)/dwfl_module_info.Po + -rm -f ./$(DEPDIR)/dwfl_module_nextcu.Po + -rm -f ./$(DEPDIR)/dwfl_module_register_names.Po + -rm -f ./$(DEPDIR)/dwfl_module_report_build_id.Po + -rm -f ./$(DEPDIR)/dwfl_module_return_value_location.Po + -rm -f ./$(DEPDIR)/dwfl_nextcu.Po + -rm -f ./$(DEPDIR)/dwfl_onesrcline.Po + -rm -f ./$(DEPDIR)/dwfl_report_elf.Po + -rm -f ./$(DEPDIR)/dwfl_segment_report_module.Po + -rm -f ./$(DEPDIR)/dwfl_validate_address.Po + -rm -f ./$(DEPDIR)/dwfl_version.Po + -rm -f ./$(DEPDIR)/elf-from-memory.Po + -rm -f ./$(DEPDIR)/find-debuginfo.Po + -rm -f ./$(DEPDIR)/frame_unwind.Po + -rm -f ./$(DEPDIR)/gzip.Po + -rm -f ./$(DEPDIR)/image-header.Po + -rm -f ./$(DEPDIR)/libdwfl_crc32.Po + -rm -f ./$(DEPDIR)/libdwfl_crc32_file.Po + -rm -f ./$(DEPDIR)/lines.Po + -rm -f ./$(DEPDIR)/link_map.Po + -rm -f ./$(DEPDIR)/linux-core-attach.Po + -rm -f ./$(DEPDIR)/linux-kernel-modules.Po + -rm -f ./$(DEPDIR)/linux-pid-attach.Po + -rm -f ./$(DEPDIR)/linux-proc-maps.Po + -rm -f ./$(DEPDIR)/lzma.Po + -rm -f ./$(DEPDIR)/offline.Po + -rm -f ./$(DEPDIR)/open.Po + -rm -f ./$(DEPDIR)/relocate.Po + -rm -f ./$(DEPDIR)/segment.Po + -rm -f ./$(DEPDIR)/zstd.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgincludeHEADERS \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c new file mode 100644 index 00000000..01ec18e2 --- /dev/null +++ b/libdwfl/argp-std.c @@ -0,0 +1,381 @@ +/* Standard argp argument parsers for tools using libdwfl. + Copyright (C) 2005-2010, 2012, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include +#include +#include +#include +#include + + +#define OPT_DEBUGINFO 0x100 +#define OPT_COREFILE 0x101 + +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Input selection options:"), 0 }, + { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 }, + { "core", OPT_COREFILE, "COREFILE", 0, + N_("Find addresses from signatures found in COREFILE"), 0 }, + { "pid", 'p', "PID", 0, + N_("Find addresses in files mapped into process PID"), 0 }, + { "linux-process-map", 'M', "FILE", 0, + N_("Find addresses in files mapped as read from FILE" + " in Linux /proc/PID/maps format"), 0 }, + { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 }, + { "offline-kernel", 'K', "RELEASE", OPTION_ARG_OPTIONAL, + N_("Kernel with all modules"), 0 }, + { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0, + N_("Search path for separate debuginfo files"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +static char *debuginfo_path; + +static const Dwfl_Callbacks offline_callbacks = + { + .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), + .debuginfo_path = &debuginfo_path, + + .section_address = INTUSE(dwfl_offline_section_address), + + /* We use this table for core files too. */ + .find_elf = INTUSE(dwfl_build_id_find_elf), + }; + +static const Dwfl_Callbacks proc_callbacks = + { + .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), + .debuginfo_path = &debuginfo_path, + + .find_elf = INTUSE(dwfl_linux_proc_find_elf), + }; + +static const Dwfl_Callbacks kernel_callbacks = + { + .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), + .debuginfo_path = &debuginfo_path, + + .find_elf = INTUSE(dwfl_linux_kernel_find_elf), + .section_address = INTUSE(dwfl_linux_kernel_module_section_address), + }; + +/* Structure held at state->HOOK. */ +struct parse_opt +{ + Dwfl *dwfl; + /* The -e|--executable parameter. */ + const char *e; + /* The --core parameter. */ + const char *core; +}; + +static inline void +failure (Dwfl *dwfl, int errnum, const char *msg, struct argp_state *state) +{ + if (dwfl != NULL) + dwfl_end (dwfl); + if (errnum == -1) + argp_failure (state, EXIT_FAILURE, 0, "%s: %s", + msg, INTUSE(dwfl_errmsg) (-1)); + else + argp_failure (state, EXIT_FAILURE, errnum, "%s", msg); +} + +static inline error_t +fail (Dwfl *dwfl, int errnum, const char *msg, struct argp_state *state) +{ + failure (dwfl, errnum, msg, state); + return errnum == -1 ? EIO : errnum; +} + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case ARGP_KEY_INIT: + { + assert (state->hook == NULL); + struct parse_opt *opt = calloc (1, sizeof (*opt)); + if (opt == NULL) + failure (NULL, DWFL_E_ERRNO, "calloc", state); + state->hook = opt; + } + break; + + case OPT_DEBUGINFO: + debuginfo_path = arg; + break; + + case 'e': + { + struct parse_opt *opt = state->hook; + Dwfl *dwfl = opt->dwfl; + if (dwfl == NULL) + { + dwfl = INTUSE(dwfl_begin) (&offline_callbacks); + if (dwfl == NULL) + return fail (dwfl, -1, arg, state); + opt->dwfl = dwfl; + + /* Start at zero so if there is just one -e foo.so, + the DSO is shown without address bias. */ + dwfl->offline_next_address = 0; + } + if (dwfl->callbacks != &offline_callbacks) + { + toomany: + argp_error (state, "%s", + _("only one of -e, -p, -k, -K, or --core allowed")); + return EINVAL; + } + opt->e = arg; + } + break; + + case 'p': + { + struct parse_opt *opt = state->hook; + if (opt->dwfl == NULL) + { + Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks); + int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg)); + if (result != 0) + return fail (dwfl, result, arg, state); + + /* Non-fatal to not be able to attach to process, ignore error. */ + INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false); + + opt->dwfl = dwfl; + } + else + goto toomany; + } + break; + + case 'M': + { + struct parse_opt *opt = state->hook; + if (opt->dwfl == NULL) + { + FILE *f = fopen (arg, "r"); + if (f == NULL) + { + int code = errno; + argp_failure (state, EXIT_FAILURE, code, + "cannot open '%s'", arg); + return code; + } + Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks); + int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f); + fclose (f); + if (result != 0) + return fail (dwfl, result, arg, state); + opt->dwfl = dwfl; + } + else + goto toomany; + } + break; + + case OPT_COREFILE: + { + struct parse_opt *opt = state->hook; + Dwfl *dwfl = opt->dwfl; + if (dwfl == NULL) + opt->dwfl = dwfl = INTUSE(dwfl_begin) (&offline_callbacks); + /* Permit -e and --core together. */ + else if (dwfl->callbacks != &offline_callbacks) + goto toomany; + opt->core = arg; + } + break; + + case 'k': + { + struct parse_opt *opt = state->hook; + if (opt->dwfl == NULL) + { + Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks); + int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl); + if (result != 0) + return fail (dwfl, result, _("cannot load kernel symbols"), state); + result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl); + if (result != 0) + /* Non-fatal to have no modules since we do have the kernel. */ + argp_failure (state, 0, result, _("cannot find kernel modules")); + opt->dwfl = dwfl; + } + else + goto toomany; + } + break; + + case 'K': + { + struct parse_opt *opt = state->hook; + if (opt->dwfl == NULL) + { + Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks); + int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg, + NULL); + if (result != 0) + return fail (dwfl, result, _("cannot find kernel or modules"), state); + opt->dwfl = dwfl; + } + else + goto toomany; + } + break; + + case ARGP_KEY_SUCCESS: + { + struct parse_opt *opt = state->hook; + Dwfl *dwfl = opt->dwfl; + + if (dwfl == NULL) + { + /* Default if no -e, -p, or -k, is "-e a.out". */ + arg = "a.out"; + dwfl = INTUSE(dwfl_begin) (&offline_callbacks); + if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL) + return fail (dwfl, -1, arg, state); + opt->dwfl = dwfl; + } + + if (opt->core) + { + int fd = open (opt->core, O_RDONLY); + if (fd < 0) + { + int code = errno; + argp_failure (state, EXIT_FAILURE, code, + "cannot open '%s'", opt->core); + return code; + } + + Elf *core; + Dwfl_Error error = __libdw_open_file (&fd, &core, true, false); + if (error != DWFL_E_NOERROR) + { + argp_failure (state, EXIT_FAILURE, 0, + _("cannot read ELF core file: %s"), + INTUSE(dwfl_errmsg) (error)); + return error == DWFL_E_ERRNO ? errno : EIO; + } + + int result = INTUSE(dwfl_core_file_report) (dwfl, core, opt->e); + if (result < 0) + { + elf_end (core); + close (fd); + return fail (dwfl, result, opt->core, state); + } + + /* Non-fatal to not be able to attach to core, ignore error. */ + INTUSE(dwfl_core_file_attach) (dwfl, core); + + /* Store core Elf and fd in Dwfl to expose with dwfl_end. */ + if (dwfl->user_core == NULL) + { + dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core)); + if (dwfl->user_core == NULL) + { + argp_failure (state, EXIT_FAILURE, 0, + _("Not enough memory")); + return ENOMEM; + } + } + dwfl->user_core->core = core; + dwfl->user_core->fd = fd; + + if (result == 0) + { + argp_failure (state, EXIT_FAILURE, 0, + _("No modules recognized in core file")); + return ENOENT; + } + } + else if (opt->e) + { + if (INTUSE(dwfl_report_offline) (dwfl, "", opt->e, -1) == NULL) + return fail (dwfl, -1, opt->e, state); + } + + /* One of the three flavors has done dwfl_begin and some reporting + if we got here. Tie up the Dwfl and return it to the caller of + argp_parse. */ + + int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL); + if (result != 0) + return fail (dwfl, -1, arg, state); + + /* Update the input all along, so a parent parser can see it. + As we free OPT the update below will be no longer active. */ + *(Dwfl **) state->input = dwfl; + free (opt); + state->hook = NULL; + } + break; + + case ARGP_KEY_ERROR: + { + struct parse_opt *opt = state->hook; + dwfl_end (opt->dwfl); + free (opt); + state->hook = NULL; + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + /* Update the input all along, so a parent parser can see it. */ + struct parse_opt *opt = state->hook; + if (opt) + *(Dwfl **) state->input = opt->dwfl; + + return 0; +} + +static const struct argp libdwfl_argp = + { .options = options, .parser = parse_opt }; + +const struct argp * +dwfl_standard_argp (void) +{ + return &libdwfl_argp; +} diff --git a/libdwfl/bzip2.c b/libdwfl/bzip2.c new file mode 100644 index 00000000..8ad4ee5a --- /dev/null +++ b/libdwfl/bzip2.c @@ -0,0 +1,4 @@ +/* bzlib is almost just like zlib. */ + +#define BZLIB +#include "gzip.c" diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c new file mode 100644 index 00000000..a0ccc9b3 --- /dev/null +++ b/libdwfl/core-file.c @@ -0,0 +1,641 @@ +/* Core file handling. + Copyright (C) 2008-2010, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include "../libelf/libelfP.h" /* For NOTE_ALIGN. */ +#undef _ +#include "libdwflP.h" +#include + +#include +#include +#include +#include "system.h" + + +/* On failure return, we update *NEXT to point back at OFFSET. */ +static inline Elf * +do_fail (int error, off_t *next, off_t offset) +{ + if (next != NULL) + *next = offset; + //__libelf_seterrno (error); + __libdwfl_seterrno (DWFL_E (LIBELF, error)); + return NULL; +} + +#define fail(error) do_fail (error, next, offset) + +/* This is a prototype of what a new libelf interface might be. + This implementation is pessimal for non-mmap cases and should + be replaced by more diddling inside libelf internals. */ +static Elf * +elf_begin_rand (Elf *parent, off_t offset, off_t size, off_t *next) +{ + if (parent == NULL) + return NULL; + + off_t min = (parent->kind == ELF_K_ELF ? + (parent->class == ELFCLASS32 + ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)) + : parent->kind == ELF_K_AR ? SARMAG + : 0); + + if (unlikely (offset < min) + || unlikely (offset >= (off_t) parent->maximum_size)) + return fail (ELF_E_RANGE); + + /* For an archive, fetch just the size field + from the archive header to override SIZE. */ + if (parent->kind == ELF_K_AR) + { + struct ar_hdr h = { .ar_size = "" }; + + if (unlikely (parent->maximum_size - offset < sizeof h)) + return fail (ELF_E_RANGE); + + if (parent->map_address != NULL) + memcpy (h.ar_size, parent->map_address + parent->start_offset + offset, + sizeof h.ar_size); + else if (unlikely (pread_retry (parent->fildes, + h.ar_size, sizeof (h.ar_size), + parent->start_offset + offset + + offsetof (struct ar_hdr, ar_size)) + != sizeof (h.ar_size))) + return fail (ELF_E_READ_ERROR); + + offset += sizeof h; + + char *endp; + size = strtoll (h.ar_size, &endp, 10); + if (unlikely (endp == h.ar_size) + || unlikely ((off_t) parent->maximum_size - offset < size)) + return fail (ELF_E_INVALID_ARCHIVE); + } + + if (unlikely ((off_t) parent->maximum_size - offset < size)) + return fail (ELF_E_RANGE); + + /* Even if we fail at this point, update *NEXT to point past the file. */ + if (next != NULL) + *next = offset + size; + + if (unlikely (offset == 0) + && unlikely (size == (off_t) parent->maximum_size)) + return elf_clone (parent, parent->cmd); + + /* Note the image is guaranteed live only as long as PARENT + lives. Using elf_memory is quite suboptimal if the whole + file is not mmap'd. We really should have something like + a generalization of the archive support. */ + Elf_Data *data = elf_getdata_rawchunk (parent, offset, size, ELF_T_BYTE); + if (data == NULL) + return NULL; + assert ((off_t) data->d_size == size); + return elf_memory (data->d_buf, size); +} + + +int +dwfl_report_core_segments (Dwfl *dwfl, Elf *elf, size_t phnum, GElf_Phdr *notes) +{ + if (unlikely (dwfl == NULL)) + return -1; + + int result = 0; + + if (notes != NULL) + notes->p_type = PT_NULL; + + for (size_t ndx = 0; result >= 0 && ndx < phnum; ++ndx) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, ndx, &phdr_mem); + if (unlikely (phdr == NULL)) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return -1; + } + switch (phdr->p_type) + { + case PT_LOAD: + result = dwfl_report_segment (dwfl, ndx, phdr, 0, NULL); + break; + + case PT_NOTE: + if (notes != NULL) + { + *notes = *phdr; + notes = NULL; + } + break; + } + } + + return result; +} + +/* Never read more than this much without mmap. */ +#define MAX_EAGER_COST 8192 + +/* Dwfl_Module_Callback passed to and called by dwfl_segment_report_module + to read in a segment as ELF image directly if possible or indicate an + attempt must be made to read in the while segment right now. */ +static bool +core_file_read_eagerly (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr start __attribute__ ((unused)), + void **buffer, size_t *buffer_available, + GElf_Off cost, GElf_Off worthwhile, + GElf_Off whole, + GElf_Off contiguous __attribute__ ((unused)), + void *arg, Elf **elfp) +{ + Elf *core = arg; + + /* The available buffer is often the whole segment when the core file + was mmap'd if used together with the dwfl_elf_phdr_memory_callback. + Which means that if it is complete we can just construct the whole + ELF image right now without having to read in anything more. */ + if (whole <= *buffer_available) + { + /* All there ever was, we already have on hand. */ + + if (core->map_address == NULL) + { + /* We already malloc'd the buffer. */ + *elfp = elf_memory (*buffer, whole); + if (unlikely (*elfp == NULL)) + return false; + + (*elfp)->flags |= ELF_F_MALLOCED; + *buffer = NULL; + *buffer_available = 0; + return true; + } + + /* We can use the image inside the core file directly. */ + *elfp = elf_begin_rand (core, *buffer - core->map_address, whole, NULL); + *buffer = NULL; + *buffer_available = 0; + return *elfp != NULL; + } + + /* We don't have the whole file. Which either means the core file + wasn't mmap'd, but needs to still be read in, or that the segment + is truncated. Figure out if this is better than nothing. */ + + if (worthwhile == 0) + /* Caller doesn't think so. */ + return false; + + /* + XXX would like to fall back to partial file via memory + when build id find_elf fails + also, link_map name may give file name from disk better than partial here + requires find_elf hook re-doing the magic to fall back if no file found + */ + + if (whole > MAX_EAGER_COST && mod->build_id_len > 0) + /* We can't cheaply read the whole file here, so we'd + be using a partial file. But there is a build ID that could + help us find the whole file, which might be more useful than + what we have. We'll just rely on that. */ + return false; + + /* The file is either small (most likely the vdso) or big and incomplete, + but we don't have a build-id. */ + + if (core->map_address != NULL) + /* It's cheap to get, so get it. */ + return true; + + /* Only use it if there isn't too much to be read. */ + return cost <= MAX_EAGER_COST; +} + +static inline void +update_end (GElf_Phdr *pphdr, const GElf_Off align, + GElf_Off *pend, GElf_Addr *pend_vaddr) +{ + *pend = (pphdr->p_offset + pphdr->p_filesz + align - 1) & -align; + *pend_vaddr = (pphdr->p_vaddr + pphdr->p_memsz + align - 1) & -align; +} + +/* Use following contiguous segments to get towards SIZE. */ +static inline bool +do_more (size_t size, GElf_Phdr *pphdr, const GElf_Off align, + Elf *elf, GElf_Off start, int *pndx, + GElf_Off *pend, GElf_Addr *pend_vaddr) +{ + while (*pend <= start || *pend - start < size) + { + if (pphdr->p_filesz < pphdr->p_memsz) + /* This segment is truncated, so no following one helps us. */ + return false; + + if (unlikely (gelf_getphdr (elf, (*pndx)++, pphdr) == NULL)) + return false; + + if (pphdr->p_type == PT_LOAD) + { + if (pphdr->p_offset > *pend + || pphdr->p_vaddr > *pend_vaddr) + /* It's discontiguous! */ + return false; + + update_end (pphdr, align, pend, pend_vaddr); + } + } + return true; +} + +#define more(size) do_more (size, &phdr, align, elf, start, &ndx, &end, &end_vaddr) + +bool +dwfl_elf_phdr_memory_callback (Dwfl *dwfl, int ndx, + void **buffer, size_t *buffer_available, + GElf_Addr vaddr, + size_t minread, + void *arg) +{ + Elf *elf = arg; + + if (ndx == -1) + { + /* Called for cleanup. */ + if (elf->map_address == NULL) + free (*buffer); + *buffer = NULL; + *buffer_available = 0; + return false; + } + + const GElf_Off align = dwfl->segment_align ?: 1; + GElf_Phdr phdr; + + do + if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL)) + return false; + while (phdr.p_type != PT_LOAD + || ((phdr.p_vaddr + phdr.p_memsz + align - 1) & -align) <= vaddr); + + GElf_Off start = vaddr - phdr.p_vaddr + phdr.p_offset; + GElf_Off end; + GElf_Addr end_vaddr; + + update_end (&phdr, align, &end, &end_vaddr); + + /* We need at least this much. */ + if (! more (minread)) + return false; + + /* See how much more we can get of what the caller wants. */ + (void) more (*buffer_available); + + /* If it's already on hand anyway, use as much as there is. */ + if (elf->map_address != NULL) + (void) more (elf->maximum_size - start); + + /* Make sure we don't look past the end of the actual file, + even if the headers tell us to. */ + if (unlikely (end > elf->maximum_size)) + end = elf->maximum_size; + + /* If the file is too small, there is nothing at all to get. */ + if (unlikely (start >= end)) + return false; + + if (elf->map_address != NULL) + { + void *contents = elf->map_address + elf->start_offset + start; + size_t size = end - start; + + if (minread == 0) /* String mode. */ + { + const void *eos = memchr (contents, '\0', size); + if (unlikely (eos == NULL) || unlikely (eos == contents)) + return false; + size = eos + 1 - contents; + } + + if (*buffer == NULL) + { + *buffer = contents; + *buffer_available = size; + } + else + { + *buffer_available = MIN (size, *buffer_available); + memcpy (*buffer, contents, *buffer_available); + } + } + else + { + void *into = *buffer; + if (*buffer == NULL) + { + *buffer_available = MIN (minread ?: 512, + MAX (4096, MIN (end - start, + *buffer_available))); + into = malloc (*buffer_available); + if (unlikely (into == NULL)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return false; + } + } + + ssize_t nread = pread_retry (elf->fildes, into, *buffer_available, start); + if (nread < (ssize_t) minread) + { + if (into != *buffer) + free (into); + if (nread < 0) + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; + } + + if (minread == 0) /* String mode. */ + { + const void *eos = memchr (into, '\0', nread); + if (unlikely (eos == NULL) || unlikely (eos == into)) + { + if (*buffer == NULL) + free (into); + return false; + } + nread = eos + 1 - into; + } + + if (*buffer == NULL) + *buffer = into; + *buffer_available = nread; + } + + return true; +} + +/* Free the contents of R_DEBUG_INFO without the R_DEBUG_INFO memory itself. */ + +static void +clear_r_debug_info (struct r_debug_info *r_debug_info) +{ + while (r_debug_info->module != NULL) + { + struct r_debug_info_module *module = r_debug_info->module; + r_debug_info->module = module->next; + elf_end (module->elf); + if (module->fd != -1) + close (module->fd); + free (module); + } +} + +bool +internal_function +__libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp) +{ + size_t phnum; + if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) + return false; + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (unlikely (phdr == NULL)) + return false; + if (phdr->p_type == PT_DYNAMIC) + { + *vaddrp = phdr->p_vaddr; + return true; + } + } + return false; +} + +int +dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable) +{ + size_t phnum; + if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return -1; + } + + bool cleanup_user_core = false; + if (dwfl->user_core != NULL) + free (dwfl->user_core->executable_for_core); + if (executable == NULL) + { + if (dwfl->user_core != NULL) + dwfl->user_core->executable_for_core = NULL; + } + else + { + if (dwfl->user_core == NULL) + { + cleanup_user_core = true; + dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core)); + if (dwfl->user_core == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + dwfl->user_core->fd = -1; + } + dwfl->user_core->executable_for_core = strdup (executable); + if (dwfl->user_core->executable_for_core == NULL) + { + if (cleanup_user_core) + { + free (dwfl->user_core); + dwfl->user_core = NULL; + } + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + } + + /* First report each PT_LOAD segment. */ + GElf_Phdr notes_phdr; + int ndx = dwfl_report_core_segments (dwfl, elf, phnum, ¬es_phdr); + if (unlikely (ndx <= 0)) + { + if (cleanup_user_core) + { + free (dwfl->user_core->executable_for_core); + free (dwfl->user_core); + dwfl->user_core = NULL; + } + return ndx; + } + + /* Next, we should follow the chain from DT_DEBUG. */ + + const void *auxv = NULL; + const void *note_file = NULL; + size_t auxv_size = 0; + size_t note_file_size = 0; + if (likely (notes_phdr.p_type == PT_NOTE)) + { + /* PT_NOTE -> NT_AUXV -> AT_PHDR -> PT_DYNAMIC -> DT_DEBUG */ + + Elf_Data *notes = elf_getdata_rawchunk (elf, + notes_phdr.p_offset, + notes_phdr.p_filesz, + (notes_phdr.p_align == 8 + ? ELF_T_NHDR8 + : ELF_T_NHDR)); + if (likely (notes != NULL)) + { + size_t pos = 0; + GElf_Nhdr nhdr; + size_t name_pos; + size_t desc_pos; + while ((pos = gelf_getnote (notes, pos, &nhdr, + &name_pos, &desc_pos)) > 0) + if (nhdr.n_namesz == sizeof "CORE" + && !memcmp (notes->d_buf + name_pos, "CORE", sizeof "CORE")) + { + if (nhdr.n_type == NT_AUXV) + { + auxv = notes->d_buf + desc_pos; + auxv_size = nhdr.n_descsz; + } + if (nhdr.n_type == NT_FILE) + { + note_file = notes->d_buf + desc_pos; + note_file_size = nhdr.n_descsz; + } + } + } + } + + /* Now we have NT_AUXV contents. From here on this processing could be + used for a live process with auxv read from /proc. */ + + struct r_debug_info r_debug_info; + memset (&r_debug_info, 0, sizeof r_debug_info); + int retval = dwfl_link_map_report (dwfl, auxv, auxv_size, + dwfl_elf_phdr_memory_callback, elf, + &r_debug_info); + int listed = retval > 0 ? retval : 0; + + /* Now sniff segment contents for modules hinted by information gathered + from DT_DEBUG. */ + + ndx = 0; + do + { + int seg = dwfl_segment_report_module (dwfl, ndx, NULL, + &dwfl_elf_phdr_memory_callback, elf, + core_file_read_eagerly, elf, + note_file, note_file_size, + &r_debug_info); + if (unlikely (seg < 0)) + { + clear_r_debug_info (&r_debug_info); + return seg; + } + if (seg > ndx) + { + ndx = seg; + ++listed; + } + else + ++ndx; + } + while (ndx < (int) phnum); + + /* Now report the modules from dwfl_link_map_report which were not filtered + out by dwfl_segment_report_module. */ + + Dwfl_Module **lastmodp = &dwfl->modulelist; + while (*lastmodp != NULL) + lastmodp = &(*lastmodp)->next; + for (struct r_debug_info_module *module = r_debug_info.module; + module != NULL; module = module->next) + { + if (module->elf == NULL) + continue; + GElf_Addr file_dynamic_vaddr; + if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr)) + continue; + Dwfl_Module *mod; + mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name, + module->fd, module->elf, + module->l_ld - file_dynamic_vaddr, + true, true); + if (mod == NULL) + continue; + ++listed; + module->elf = NULL; + module->fd = -1; + /* Move this module to the end of the list, so that we end + up with a list in the same order as the link_map chain. */ + if (mod->next != NULL) + { + if (*lastmodp != mod) + { + lastmodp = &dwfl->modulelist; + while (*lastmodp != mod) + lastmodp = &(*lastmodp)->next; + } + *lastmodp = mod->next; + mod->next = NULL; + while (*lastmodp != NULL) + lastmodp = &(*lastmodp)->next; + *lastmodp = mod; + } + lastmodp = &mod->next; + } + + clear_r_debug_info (&r_debug_info); + + /* We return the number of modules we found if we found any. + If we found none, we return -1 instead of 0 if there was an + error rather than just nothing found. */ + return listed > 0 ? listed : retval; +} +INTDEF (dwfl_core_file_report) +NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158) + +#ifdef SYMBOL_VERSIONING +int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf); +COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146, + without_executable) + +int +_compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf) +{ + return dwfl_core_file_report (dwfl, elf, NULL); +} +#endif diff --git a/libdwfl/cu.c b/libdwfl/cu.c new file mode 100644 index 00000000..4de66248 --- /dev/null +++ b/libdwfl/cu.c @@ -0,0 +1,317 @@ +/* Keeping track of DWARF compilation units in libdwfl. + Copyright (C) 2005-2010, 2015, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/libdwP.h" +#include "../libdw/memory-access.h" +#include + + +static inline Dwarf_Arange * +dwar (Dwfl_Module *mod, unsigned int idx) +{ + return &mod->dw->aranges->info[mod->aranges[idx].arange]; +} + + +static Dwfl_Error +addrarange (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_arange **arange) +{ + if (mod->aranges == NULL) + { + struct dwfl_arange *aranges = NULL; + Dwarf_Aranges *dwaranges = NULL; + size_t naranges; + if (INTUSE(dwarf_getaranges) (mod->dw, &dwaranges, &naranges) != 0) + return DWFL_E_LIBDW; + + /* If the module has no aranges (when no code is included) we + allocate nothing. */ + if (naranges != 0) + { + aranges = malloc (naranges * sizeof *aranges); + if (unlikely (aranges == NULL)) + return DWFL_E_NOMEM; + + /* libdw has sorted its list by address, which is how we want it. + But the sorted list is full of not-quite-contiguous runs pointing + to the same CU. We don't care about the little gaps inside the + module, we'll consider them part of the surrounding CU anyway. + Collect our own array with just one record for each run of ranges + pointing to one CU. */ + + naranges = 0; + Dwarf_Off lastcu = 0; + for (size_t i = 0; i < dwaranges->naranges; ++i) + if (i == 0 || dwaranges->info[i].offset != lastcu) + { + aranges[naranges].arange = i; + aranges[naranges].cu = NULL; + ++naranges; + lastcu = dwaranges->info[i].offset; + } + } + + /* Store the final array, which is probably much smaller than before. */ + mod->naranges = naranges; + if (naranges > 0) + mod->aranges = (realloc (aranges, naranges * sizeof aranges[0]) + ?: aranges); + else if (aranges != NULL) + free (aranges); + mod->lazycu += naranges; + } + + /* The address must be inside the module to begin with. */ + addr = dwfl_deadjust_dwarf_addr (mod, addr); + + /* The ranges are sorted by address, so we can use binary search. */ + size_t l = 0, u = mod->naranges; + while (l < u) + { + size_t idx = (l + u) / 2; + Dwarf_Addr start = dwar (mod, idx)->addr; + if (addr < start) + { + u = idx; + continue; + } + else if (addr > start) + { + if (idx + 1 < mod->naranges) + { + if (addr >= dwar (mod, idx + 1)->addr) + { + l = idx + 1; + continue; + } + } + else + { + /* It might be in the last range. */ + const Dwarf_Arange *last + = &mod->dw->aranges->info[mod->dw->aranges->naranges - 1]; + if (addr > last->addr + last->length) + break; + } + } + + *arange = &mod->aranges[idx]; + return DWFL_E_NOERROR; + } + + return DWFL_E_ADDR_OUTOFRANGE; +} + + +static void +nofree (void *arg) +{ + struct dwfl_cu *cu = arg; + if (cu == (void *) -1l) + return; + + assert (cu->mod->lazycu == 0); +} + +/* One reason fewer to keep the lazy lookup table for CUs. */ +static inline void +less_lazy (Dwfl_Module *mod) +{ + if (--mod->lazycu > 0) + return; + + /* We know about all the CUs now, we don't need this table. */ + tdestroy (mod->lazy_cu_root, nofree); + mod->lazy_cu_root = NULL; +} + +static inline Dwarf_Off +cudie_offset (const struct dwfl_cu *cu) +{ + return __libdw_first_die_off_from_cu (cu->die.cu); +} + +static int +compare_cukey (const void *a, const void *b) +{ + Dwarf_Off a_off = cudie_offset (a); + Dwarf_Off b_off = cudie_offset (b); + return (a_off < b_off) ? -1 : ((a_off > b_off) ? 1 : 0); +} + +/* Intern the CU if necessary. */ +static Dwfl_Error +intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result) +{ + if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size)) + { + if (likely (mod->lazycu == 1)) + { + /* This is the EOF marker. Now we have interned all the CUs. + One increment in MOD->lazycu counts not having hit EOF yet. */ + *result = (void *) -1; + less_lazy (mod); + return DWFL_E_NOERROR; + } + else + { + /* Unexpected EOF, most likely a bogus aranges. */ + return (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF)); + } + } + + /* Make sure the cuoff points to a real DIE. */ + Dwarf_Die cudie; + Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cudie); + if (die == NULL) + return DWFL_E_LIBDW; + + struct dwfl_cu key; + key.die.cu = die->cu; + struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey); + if (unlikely (found == NULL)) + return DWFL_E_NOMEM; + + if (*found == &key || *found == NULL) + { + /* This is a new entry, meaning we haven't looked at this CU. */ + + *found = NULL; + + struct dwfl_cu *cu = malloc (sizeof *cu); + if (unlikely (cu == NULL)) + return DWFL_E_NOMEM; + + cu->mod = mod; + cu->next = NULL; + cu->lines = NULL; + cu->die = cudie; + + struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1) + * sizeof (mod->cu[0]))); + if (newvec == NULL) + { + free (cu); + return DWFL_E_NOMEM; + } + mod->cu = newvec; + + mod->cu[mod->ncu++] = cu; + if (cu->die.cu->start == 0) + mod->first_cu = cu; + + *found = cu; + } + + *result = *found; + return DWFL_E_NOERROR; +} + + +/* Traverse all the CUs in the module. */ + +Dwfl_Error +internal_function +__libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu, + struct dwfl_cu **cu) +{ + Dwarf_Off cuoff; + struct dwfl_cu **nextp; + + if (lastcu == NULL) + { + /* Start the traversal. */ + cuoff = 0; + nextp = &mod->first_cu; + } + else + { + /* Continue following LASTCU. */ + cuoff = lastcu->die.cu->end; + nextp = &lastcu->next; + } + + if (*nextp == NULL) + { + size_t cuhdrsz; + Dwarf_Off nextoff; + int end = INTUSE(dwarf_nextcu) (mod->dw, cuoff, &nextoff, &cuhdrsz, + NULL, NULL, NULL); + if (end < 0) + return DWFL_E_LIBDW; + if (end > 0) + { + *cu = NULL; + return DWFL_E_NOERROR; + } + + Dwfl_Error result = intern_cu (mod, cuoff + cuhdrsz, nextp); + if (result != DWFL_E_NOERROR) + return result; + + if (*nextp != (void *) -1 + && (*nextp)->next == NULL && nextoff == (Dwarf_Off) -1l) + (*nextp)->next = (void *) -1l; + } + + *cu = *nextp == (void *) -1l ? NULL : *nextp; + return DWFL_E_NOERROR; +} + + +/* Intern the CU arange points to, if necessary. */ + +static Dwfl_Error +arangecu (Dwfl_Module *mod, struct dwfl_arange *arange, struct dwfl_cu **cu) +{ + if (arange->cu == NULL) + { + const Dwarf_Arange *dwarange = &mod->dw->aranges->info[arange->arange]; + Dwfl_Error result = intern_cu (mod, dwarange->offset, &arange->cu); + if (result != DWFL_E_NOERROR) + return result; + assert (arange->cu != NULL && arange->cu != (void *) -1l); + less_lazy (mod); /* Each arange with null ->cu counts once. */ + } + + *cu = arange->cu; + return DWFL_E_NOERROR; +} + +Dwfl_Error +internal_function +__libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_cu **cu) +{ + struct dwfl_arange *arange; + return addrarange (mod, addr, &arange) ?: arangecu (mod, arange, cu); +} diff --git a/libdwfl/debuginfod-client.c b/libdwfl/debuginfod-client.c new file mode 100644 index 00000000..99b66b6e --- /dev/null +++ b/libdwfl/debuginfod-client.c @@ -0,0 +1,128 @@ +/* Try to get an ELF or debug file through the debuginfod. + Copyright (C) 2019 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include + +static __typeof__ (debuginfod_begin) *fp_debuginfod_begin; +static __typeof__ (debuginfod_find_executable) *fp_debuginfod_find_executable; +static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo; +static __typeof__ (debuginfod_end) *fp_debuginfod_end; + +/* NB: this is slightly thread-unsafe */ + +static debuginfod_client * +get_client (Dwfl *dwfl) +{ + if (dwfl->debuginfod != NULL) + return dwfl->debuginfod; + + if (fp_debuginfod_begin != NULL) + { + dwfl->debuginfod = (*fp_debuginfod_begin) (); + return dwfl->debuginfod; + } + + return NULL; +} + +int +__libdwfl_debuginfod_find_executable (Dwfl *dwfl, + const unsigned char *build_id_bits, + size_t build_id_len) +{ + int fd = -1; + if (build_id_len > 0) + { + debuginfod_client *c = get_client (dwfl); + if (c != NULL) + fd = (*fp_debuginfod_find_executable) (c, build_id_bits, + build_id_len, NULL); + } + + return fd; +} + +int +__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl, + const unsigned char *build_id_bits, + size_t build_id_len) +{ + int fd = -1; + if (build_id_len > 0) + { + debuginfod_client *c = get_client (dwfl); + if (c != NULL) + fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits, + build_id_len, NULL); + } + + return fd; +} + +void +__libdwfl_debuginfod_end (debuginfod_client *c) +{ + if (c != NULL) + (*fp_debuginfod_end) (c); +} + +/* Try to get the libdebuginfod library functions to make sure + everything is initialized early. */ +void __attribute__ ((constructor)) +__libdwfl_debuginfod_init (void) +{ + void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY); + + if (debuginfod_so != NULL) + { + fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin"); + fp_debuginfod_find_executable = dlsym (debuginfod_so, + "debuginfod_find_executable"); + fp_debuginfod_find_debuginfo = dlsym (debuginfod_so, + "debuginfod_find_debuginfo"); + fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end"); + + /* We either get them all, or we get none. */ + if (fp_debuginfod_begin == NULL + || fp_debuginfod_find_executable == NULL + || fp_debuginfod_find_debuginfo == NULL + || fp_debuginfod_end == NULL) + { + fp_debuginfod_begin = NULL; + fp_debuginfod_find_executable = NULL; + fp_debuginfod_find_debuginfo = NULL; + fp_debuginfod_end = NULL; + dlclose (debuginfod_so); + } + } +} diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c new file mode 100644 index 00000000..2f80b20f --- /dev/null +++ b/libdwfl/derelocate.c @@ -0,0 +1,434 @@ +/* Recover relocatibility for addresses computed from debug information. + Copyright (C) 2005-2010, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +struct dwfl_relocation +{ + size_t count; + struct + { + Elf_Scn *scn; + Elf_Scn *relocs; + const char *name; + GElf_Addr start, end; + } refs[0]; +}; + + +struct secref +{ + struct secref *next; + Elf_Scn *scn; + Elf_Scn *relocs; + const char *name; + GElf_Addr start, end; +}; + +static int +compare_secrefs (const void *a, const void *b) +{ + struct secref *const *p1 = a; + struct secref *const *p2 = b; + + /* No signed difference calculation is correct here, since the + terms are unsigned and could be more than INT64_MAX apart. */ + if ((*p1)->start < (*p2)->start) + return -1; + if ((*p1)->start > (*p2)->start) + return 1; + + if ((*p1)->end < (*p2)->end) + return -1; + if ((*p1)->end > (*p2)->end) + return 1; + + /* Same start/end, then just compare which section came first. */ + return elf_ndxscn ((*p1)->scn) - elf_ndxscn ((*p2)->scn); +} + +static int +cache_sections (Dwfl_Module *mod) +{ + if (likely (mod->reloc_info != NULL)) + return mod->reloc_info->count; + + struct secref *refs = NULL; + size_t nrefs = 0; + + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)) + { + elf_error: + __libdwfl_seterrno (DWFL_E_LIBELF); + nrefs = -1; + goto free_refs; + } + + bool check_reloc_sections = false; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + goto elf_error; + + if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0 + && mod->e_type == ET_REL) + { + /* This section might not yet have been looked at. */ + if (__libdwfl_relocate_value (mod, mod->main.elf, &shstrndx, + elf_ndxscn (scn), + &shdr->sh_addr) != DWFL_E_NOERROR) + continue; + shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + goto elf_error; + } + + if (shdr->sh_flags & SHF_ALLOC) + { + const char *name = elf_strptr (mod->main.elf, shstrndx, + shdr->sh_name); + if (unlikely (name == NULL)) + goto elf_error; + + struct secref *newref = malloc (sizeof *newref); + if (unlikely (newref == NULL)) + { + nomem: + __libdwfl_seterrno (DWFL_E_NOMEM); + nrefs = -1; + goto free_refs; + } + + newref->scn = scn; + newref->relocs = NULL; + newref->name = name; + newref->start = dwfl_adjusted_address (mod, shdr->sh_addr); + newref->end = newref->start + shdr->sh_size; + newref->next = refs; + refs = newref; + ++nrefs; + } + + if (mod->e_type == ET_REL + && shdr->sh_size != 0 + && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) + && mod->dwfl->callbacks->section_address != NULL) + { + if (shdr->sh_info < elf_ndxscn (scn)) + { + /* We've already looked at the section these relocs apply to. */ + Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info); + if (likely (tscn != NULL)) + for (struct secref *sec = refs; sec != NULL; sec = sec->next) + if (sec->scn == tscn) + { + sec->relocs = scn; + break; + } + } + else + /* We'll have to do a second pass. */ + check_reloc_sections = true; + } + } + + mod->reloc_info = malloc (offsetof (struct dwfl_relocation, refs[nrefs])); + if (unlikely (mod->reloc_info == NULL)) + goto nomem; + + struct secref **sortrefs = malloc (nrefs * sizeof sortrefs[0]); + if (unlikely (sortrefs == NULL)) + goto nomem; + + for (size_t i = nrefs; i-- > 0; refs = refs->next) + sortrefs[i] = refs; + assert (refs == NULL); + + qsort (sortrefs, nrefs, sizeof sortrefs[0], &compare_secrefs); + + mod->reloc_info->count = nrefs; + for (size_t i = 0; i < nrefs; ++i) + { + mod->reloc_info->refs[i].name = sortrefs[i]->name; + mod->reloc_info->refs[i].scn = sortrefs[i]->scn; + mod->reloc_info->refs[i].relocs = sortrefs[i]->relocs; + mod->reloc_info->refs[i].start = sortrefs[i]->start; + mod->reloc_info->refs[i].end = sortrefs[i]->end; + free (sortrefs[i]); + } + + free (sortrefs); + + if (unlikely (check_reloc_sections)) + { + /* There was a reloc section that preceded its target section. + So we have to scan again now that we have cached all the + possible target sections we care about. */ + + scn = NULL; + while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + goto elf_error; + + if (shdr->sh_size != 0 + && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)) + { + Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info); + if (likely (tscn != NULL)) + for (size_t i = 0; i < nrefs; ++i) + if (mod->reloc_info->refs[i].scn == tscn) + { + mod->reloc_info->refs[i].relocs = scn; + break; + } + } + } + } + +free_refs: + while (refs != NULL) + { + struct secref *ref = refs; + refs = ref->next; + free (ref); + } + + return nrefs; +} + + +int +dwfl_module_relocations (Dwfl_Module *mod) +{ + if (mod == NULL) + return -1; + + switch (mod->e_type) + { + case ET_REL: + return cache_sections (mod); + + case ET_DYN: + return 1; + + case ET_EXEC: + assert (mod->main.vaddr == mod->low_addr); + break; + } + + return 0; +} + +const char * +dwfl_module_relocation_info (Dwfl_Module *mod, unsigned int idx, + Elf32_Word *shndxp) +{ + if (mod == NULL) + return NULL; + + switch (mod->e_type) + { + case ET_REL: + break; + + case ET_DYN: + if (idx != 0) + return NULL; + if (shndxp) + *shndxp = SHN_ABS; + return ""; + + default: + return NULL; + } + + if (cache_sections (mod) < 0) + return NULL; + + struct dwfl_relocation *sections = mod->reloc_info; + + if (idx >= sections->count) + return NULL; + + if (shndxp) + *shndxp = elf_ndxscn (sections->refs[idx].scn); + + return sections->refs[idx].name; +} + +/* Check that MOD is valid and make sure its relocation has been done. */ +static bool +check_module (Dwfl_Module *mod) +{ + if (mod == NULL) + return true; + + if (INTUSE(dwfl_module_getsymtab) (mod) < 0) + { + Dwfl_Error error = dwfl_errno (); + if (error != DWFL_E_NO_SYMTAB) + { + __libdwfl_seterrno (error); + return true; + } + } + + if (mod->dw == NULL) + { + Dwarf_Addr bias; + if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL) + { + Dwfl_Error error = dwfl_errno (); + if (error != DWFL_E_NO_DWARF) + { + __libdwfl_seterrno (error); + return true; + } + } + } + + return false; +} + +/* Find the index in MOD->reloc_info.refs containing *ADDR. */ +static int +find_section (Dwfl_Module *mod, Dwarf_Addr *addr) +{ + if (cache_sections (mod) < 0) + return -1; + + struct dwfl_relocation *sections = mod->reloc_info; + + /* The sections are sorted by address, so we can use binary search. */ + size_t l = 0, u = sections->count; + while (l < u) + { + size_t idx = (l + u) / 2; + if (*addr < sections->refs[idx].start) + u = idx; + else if (*addr > sections->refs[idx].end) + l = idx + 1; + else + { + /* Consider the limit of a section to be inside it, unless it's + inside the next one. A section limit address can appear in + line records. */ + if (*addr == sections->refs[idx].end + && idx + 1 < sections->count + && *addr == sections->refs[idx + 1].start) + ++idx; + + *addr -= sections->refs[idx].start; + return idx; + } + } + + __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_NO_MATCH)); + return -1; +} + +size_t +internal_function +__libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr) +{ + int idx = find_section (mod, addr); + if (unlikely (idx == -1)) + return SHN_UNDEF; + + return elf_ndxscn (mod->reloc_info->refs[idx].scn); +} + +int +dwfl_module_relocate_address (Dwfl_Module *mod, Dwarf_Addr *addr) +{ + if (unlikely (check_module (mod))) + return -1; + + switch (mod->e_type) + { + case ET_REL: + return find_section (mod, addr); + + case ET_DYN: + /* All relative to first and only relocation base: module start. */ + *addr -= mod->low_addr; + break; + + default: + /* Already absolute, dwfl_module_relocations returned zero. We + shouldn't really have been called, but it's a harmless no-op. */ + break; + } + + return 0; +} +INTDEF (dwfl_module_relocate_address) + +Elf_Scn * +dwfl_module_address_section (Dwfl_Module *mod, Dwarf_Addr *address, + Dwarf_Addr *bias) +{ + if (check_module (mod)) + return NULL; + + int idx = find_section (mod, address); + if (idx < 0) + return NULL; + + if (mod->reloc_info->refs[idx].relocs != NULL) + { + assert (mod->e_type == ET_REL); + + Elf_Scn *tscn = mod->reloc_info->refs[idx].scn; + Elf_Scn *relocscn = mod->reloc_info->refs[idx].relocs; + Dwfl_Error result = __libdwfl_relocate_section (mod, mod->main.elf, + relocscn, tscn, true); + if (likely (result == DWFL_E_NOERROR)) + mod->reloc_info->refs[idx].relocs = NULL; + else + { + __libdwfl_seterrno (result); + return NULL; + } + } + + *bias = dwfl_adjusted_address (mod, 0); + return mod->reloc_info->refs[idx].scn; +} +INTDEF (dwfl_module_address_section) diff --git a/libdwfl/dwfl_addrdie.c b/libdwfl/dwfl_addrdie.c new file mode 100644 index 00000000..c5b1d68e --- /dev/null +++ b/libdwfl/dwfl_addrdie.c @@ -0,0 +1,40 @@ +/* Fetch CU DIE from address. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwarf_Die * +dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) +{ + return INTUSE(dwfl_module_addrdie) (INTUSE(dwfl_addrmodule) (dwfl, addr), + addr, bias); +} diff --git a/libdwfl/dwfl_addrdwarf.c b/libdwfl/dwfl_addrdwarf.c new file mode 100644 index 00000000..4f9efabf --- /dev/null +++ b/libdwfl/dwfl_addrdwarf.c @@ -0,0 +1,41 @@ +/* Fetch libdw handle from address. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwarf * +dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Addr *bias) +{ + return INTUSE(dwfl_module_getdwarf) (INTUSE(dwfl_addrmodule) (dwfl, address), + bias); +} +INTDEF (dwfl_addrdwarf) diff --git a/libdwfl/dwfl_addrmodule.c b/libdwfl/dwfl_addrmodule.c new file mode 100644 index 00000000..abf1ff48 --- /dev/null +++ b/libdwfl/dwfl_addrmodule.c @@ -0,0 +1,42 @@ +/* Find module containing address. + Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwfl_Module * +dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address) +{ + Dwfl_Module *mod; + (void) INTUSE(dwfl_addrsegment) (dwfl, address, &mod); + return mod; +} +INTDEF (dwfl_addrmodule) diff --git a/libdwfl/dwfl_begin.c b/libdwfl/dwfl_begin.c new file mode 100644 index 00000000..b03f5cf4 --- /dev/null +++ b/libdwfl/dwfl_begin.c @@ -0,0 +1,55 @@ +/* Set up a session using libdwfl. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwfl * +dwfl_begin (const Dwfl_Callbacks *callbacks) +{ + if (elf_version (EV_CURRENT) == EV_NONE) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return NULL; + } + + Dwfl *dwfl = calloc (1, sizeof *dwfl); + if (dwfl == NULL) + __libdwfl_seterrno (DWFL_E_NOMEM); + else + { + dwfl->callbacks = callbacks; + dwfl->offline_next_address = OFFLINE_REDZONE; + } + + return dwfl; +} +INTDEF (dwfl_begin) diff --git a/libdwfl/dwfl_build_id_find_debuginfo.c b/libdwfl/dwfl_build_id_find_debuginfo.c new file mode 100644 index 00000000..273e5e5f --- /dev/null +++ b/libdwfl/dwfl_build_id_find_debuginfo.c @@ -0,0 +1,132 @@ +/* Find the debuginfo file for a module from its build ID. + Copyright (C) 2007, 2009, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include + + +int +dwfl_build_id_find_debuginfo (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *modname __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + const char *file __attribute__ ((unused)), + const char *debuglink __attribute__ ((unused)), + GElf_Word crc __attribute__ ((unused)), + char **debuginfo_file_name) +{ + int fd = -1; + + /* Are we looking for a separate debug file for the main file or for + an alternate (dwz multi) debug file? Alternatively we could check + whether the dwbias == -1. */ + if (mod->dw != NULL) + { + const void *build_id; + const char *altname; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, + &altname, + &build_id); + if (build_id_len > 0) + fd = __libdwfl_open_by_build_id (mod, true, debuginfo_file_name, + build_id_len, build_id); + + if (fd >= 0) + { + /* We need to open an Elf handle on the file so we can check its + build ID note for validation. Backdoor the handle into the + module data structure since we had to open it early anyway. */ + Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf, + true, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else + { + const void *alt_build_id; + ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf, + &alt_build_id); + if (alt_len > 0 && alt_len == build_id_len + && memcmp (build_id, alt_build_id, alt_len) == 0) + return fd; + else + { + /* A mismatch! */ + elf_end (mod->alt_elf); + mod->alt_elf = NULL; + close (fd); + fd = -1; + } + free (*debuginfo_file_name); + *debuginfo_file_name = NULL; + errno = 0; + } + } + return fd; + } + + /* We don't even have the Dwarf yet and it isn't in the main file. + Try to find separate debug file now using the module build id. */ + const unsigned char *bits; + GElf_Addr vaddr; + + if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0) + fd = __libdwfl_open_mod_by_build_id (mod, true, debuginfo_file_name); + if (fd >= 0) + { + /* We need to open an Elf handle on the file so we can check its + build ID note for validation. Backdoor the handle into the + module data structure since we had to open it early anyway. */ + Dwfl_Error error = __libdw_open_file (&fd, &mod->debug.elf, true, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else if (likely (__libdwfl_find_build_id (mod, false, + mod->debug.elf) == 2)) + { + /* Also backdoor the gratuitous flag. */ + mod->debug.valid = true; + return fd; + } + else + { + /* A mismatch! */ + elf_end (mod->debug.elf); + mod->debug.elf = NULL; + close (fd); + fd = -1; + } + free (*debuginfo_file_name); + *debuginfo_file_name = NULL; + errno = 0; + } + return fd; +} +INTDEF (dwfl_build_id_find_debuginfo) diff --git a/libdwfl/dwfl_build_id_find_elf.c b/libdwfl/dwfl_build_id_find_elf.c new file mode 100644 index 00000000..7b604d47 --- /dev/null +++ b/libdwfl/dwfl_build_id_find_elf.c @@ -0,0 +1,213 @@ +/* Find an ELF file for a module from its build ID. + Copyright (C) 2007-2010, 2014, 2015, 2019 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include +#include +#include "system.h" + + +int +internal_function +__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name, + const size_t id_len, const uint8_t *id) +{ + /* We don't handle very short or really large build-ids. We need at + at least 3 and allow for up to 64 (normally ids are 20 long). */ +#define MIN_BUILD_ID_BYTES 3 +#define MAX_BUILD_ID_BYTES 64 + if (id_len < MIN_BUILD_ID_BYTES || id_len > MAX_BUILD_ID_BYTES) + { + bad_id: + __libdwfl_seterrno (DWFL_E_WRONG_ID_ELF); + return -1; + } + + /* Search debuginfo_path directories' .build-id/ subdirectories. */ + + char id_name[sizeof "/.build-id/" + 1 + MAX_BUILD_ID_BYTES * 2 + + sizeof ".debug" - 1]; + strcpy (id_name, "/.build-id/"); + int n = snprintf (&id_name[sizeof "/.build-id/" - 1], + 4, "%02" PRIx8 "/", (uint8_t) id[0]); + if (n != 3) + goto bad_id;; + for (size_t i = 1; i < id_len; ++i) + { + n = snprintf (&id_name[sizeof "/.build-id/" - 1 + 3 + (i - 1) * 2], + 3, "%02" PRIx8, (uint8_t) id[i]); + if (n != 2) + goto bad_id; + } + if (debug) + strcpy (&id_name[sizeof "/.build-id/" - 1 + 3 + (id_len - 1) * 2], + ".debug"); + + const Dwfl_Callbacks *const cb = mod->dwfl->callbacks; + char *path = strdup ((cb->debuginfo_path ? *cb->debuginfo_path : NULL) + ?: DEFAULT_DEBUGINFO_PATH); + if (path == NULL) + return -1; + + int fd = -1; + char *dir; + char *paths = path; + while (fd < 0 && (dir = strsep (&paths, ":")) != NULL) + { + if (dir[0] == '+' || dir[0] == '-') + ++dir; + + /* Only absolute directory names are useful to us. */ + if (dir[0] != '/') + continue; + + size_t dirlen = strlen (dir); + char *name = malloc (dirlen + sizeof id_name); + if (unlikely (name == NULL)) + break; + memcpy (mempcpy (name, dir, dirlen), id_name, sizeof id_name); + + fd = TEMP_FAILURE_RETRY (open (name, O_RDONLY)); + if (fd >= 0) + { + if (*file_name != NULL) + free (*file_name); + *file_name = realpath (name, NULL); + if (*file_name == NULL) + { + *file_name = name; + name = NULL; + } + } + free (name); + } + + free (path); + + /* If we simply found nothing, clear errno. If we had some other error + with the file, report that. Possibly this should treat other errors + like ENOENT too. But ignoring all errors could mask some that should + be reported. */ + if (fd < 0 && errno == ENOENT) + errno = 0; + + return fd; +} + +int +internal_function +__libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, char **file_name) +{ + /* If *FILE_NAME was primed into the module, leave it there + as the fallback when we have nothing to offer. */ + errno = 0; + if (mod->build_id_len <= 0) + return -1; + + const size_t id_len = mod->build_id_len; + const uint8_t *id = mod->build_id_bits; + + return __libdwfl_open_by_build_id (mod, debug, file_name, id_len, id); +} + +int +dwfl_build_id_find_elf (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *modname __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + char **file_name, Elf **elfp) +{ + *elfp = NULL; + if (mod->is_executable + && mod->dwfl->user_core != NULL + && mod->dwfl->user_core->executable_for_core != NULL) + { + /* When dwfl_core_file_report was called with a non-NULL executable file + name this callback will replace the Dwfl_Module main.name with the + recorded executable file when MOD was identified as main executable + (which then triggers opening and reporting of the executable). */ + const char *executable = mod->dwfl->user_core->executable_for_core; + int fd = open (executable, O_RDONLY); + if (fd >= 0) + { + *file_name = strdup (executable); + if (*file_name != NULL) + return fd; + else + close (fd); + } + } + int fd = __libdwfl_open_mod_by_build_id (mod, false, file_name); + if (fd >= 0) + { + Dwfl_Error error = __libdw_open_file (&fd, elfp, true, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else if (__libdwfl_find_build_id (mod, false, *elfp) == 2) + { + /* This is a backdoor signal to short-circuit the ID refresh. */ + mod->main.valid = true; + return fd; + } + else + { + /* This file does not contain the ID it should! */ + elf_end (*elfp); + *elfp = NULL; + close (fd); + fd = -1; + } + free (*file_name); + *file_name = NULL; + } + else + { +#ifdef ENABLE_LIBDEBUGINFOD + /* If all else fails and a build-id is available, query the + debuginfo-server if enabled. */ + if (fd < 0 && mod->build_id_len > 0) + fd = __libdwfl_debuginfod_find_executable (mod->dwfl, + mod->build_id_bits, + mod->build_id_len); +#endif + } + + if (fd < 0 && errno == 0 && mod->build_id_len > 0) + /* Setting this with no file yet loaded is a marker that + the build ID is authoritative even if we also know a + putative *FILE_NAME. */ + mod->main.valid = true; + + return fd; +} +INTDEF (dwfl_build_id_find_elf) diff --git a/libdwfl/dwfl_cumodule.c b/libdwfl/dwfl_cumodule.c new file mode 100644 index 00000000..2b593f22 --- /dev/null +++ b/libdwfl/dwfl_cumodule.c @@ -0,0 +1,40 @@ +/* Find the module for a CU DIE previously returned by libdwfl. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwfl_Module * +dwfl_cumodule (Dwarf_Die *cudie) +{ + struct dwfl_cu *cu = (struct dwfl_cu *) cudie; + return cu->mod; +} diff --git a/libdwfl/dwfl_dwarf_line.c b/libdwfl/dwfl_dwarf_line.c new file mode 100644 index 00000000..e22e984c --- /dev/null +++ b/libdwfl/dwfl_dwarf_line.c @@ -0,0 +1,47 @@ +/* Get information from a source line record returned by libdwfl. + Copyright (C) 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/libdwP.h" + +Dwarf_Line * +dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias) +{ + if (line == NULL) + return NULL; + + struct dwfl_cu *cu = dwfl_linecu (line); + const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx]; + + *bias = dwfl_adjusted_dwarf_addr (cu->mod, 0); + return (Dwarf_Line *) info; +} diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c new file mode 100644 index 00000000..b1840191 --- /dev/null +++ b/libdwfl/dwfl_end.c @@ -0,0 +1,70 @@ +/* Finish a session using libdwfl. + Copyright (C) 2005, 2008, 2012-2013, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include + +void +dwfl_end (Dwfl *dwfl) +{ + if (dwfl == NULL) + return; + +#ifdef ENABLE_LIBDEBUGINFOD + __libdwfl_debuginfod_end (dwfl->debuginfod); +#endif + + if (dwfl->process) + __libdwfl_process_free (dwfl->process); + + free (dwfl->lookup_addr); + free (dwfl->lookup_module); + free (dwfl->lookup_segndx); + + Dwfl_Module *next = dwfl->modulelist; + while (next != NULL) + { + Dwfl_Module *dead = next; + next = dead->next; + __libdwfl_module_free (dead); + } + + if (dwfl->user_core != NULL) + { + free (dwfl->user_core->executable_for_core); + elf_end (dwfl->user_core->core); + if (dwfl->user_core->fd != -1) + close (dwfl->user_core->fd); + free (dwfl->user_core); + } + free (dwfl); +} diff --git a/libdwfl/dwfl_error.c b/libdwfl/dwfl_error.c new file mode 100644 index 00000000..a5c683a9 --- /dev/null +++ b/libdwfl/dwfl_error.c @@ -0,0 +1,186 @@ +/* Error handling in libdwfl. + Copyright (C) 2005-2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "libdwflP.h" + + +/* The error number. */ +static __thread int global_error; + + +int +dwfl_errno (void) +{ + int result = global_error; + global_error = DWFL_E_NOERROR; + return result; +} +INTDEF (dwfl_errno) + + +struct msgtable +{ +#define DWFL_ERROR(name, text) char msg_##name[sizeof text]; + DWFL_ERRORS +#undef DWFL_ERROR +}; + +static const union +{ + struct msgtable table; + char strings[ +#define DWFL_ERROR(name, text) + sizeof text + DWFL_ERRORS +#undef DWFL_ERROR + ]; +} msgtable = + { + .table = + { +#define DWFL_ERROR(name, text) text, + DWFL_ERRORS +#undef DWFL_ERROR + } + }; +#define msgstr (msgtable.strings) + +static const uint_fast16_t msgidx[] = +{ +#define DWFL_ERROR(name, text) \ + [DWFL_E_##name] = offsetof (struct msgtable, msg_##name), + DWFL_ERRORS +#undef DWFL_ERROR +}; +#define nmsgidx (sizeof msgidx / sizeof msgidx[0]) + + +static inline int +canonicalize (Dwfl_Error error) +{ + unsigned int value; + + switch (error) + { + default: + value = error; + if ((value &~ 0xffff) != 0) + break; + assert (value < nmsgidx); + break; + case DWFL_E_ERRNO: + value = DWFL_E (ERRNO, errno); + break; + case DWFL_E_LIBELF: + value = DWFL_E (LIBELF, elf_errno ()); + break; + case DWFL_E_LIBDW: + value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ()); + break; +#if 0 + DWFL_E_LIBEBL: + value = DWFL_E (LIBEBL, ebl_errno ()); + break; +#endif + } + + return value; +} + +int +internal_function +__libdwfl_canon_error (Dwfl_Error error) +{ + return canonicalize (error); +} + +void +internal_function +__libdwfl_seterrno (Dwfl_Error error) +{ + global_error = canonicalize (error); +} + + +static const char * +errnomsg(int error) +{ + /* Won't be changed by strerror_r, but not const so compiler doesn't throw warning */ + static char unknown[] = "unknown error"; + +#ifdef STRERROR_R_CHAR_P + return strerror_r (error, unknown, 0); +#else + /* To store the error message from strerror_r in a thread-safe manner */ + static __thread char msg[128]; + return strerror_r (error, msg, sizeof (msg)) ? unknown : msg; +#endif +} + +const char * +dwfl_errmsg (int error) +{ + if (error == 0 || error == -1) + { + int last_error = global_error; + + if (error == 0 && last_error == 0) + return NULL; + + error = last_error; + global_error = DWFL_E_NOERROR; + } + + switch (error &~ 0xffff) + { + case OTHER_ERROR (ERRNO): + return errnomsg (error & 0xffff); + case OTHER_ERROR (LIBELF): + return elf_errmsg (error & 0xffff); + case OTHER_ERROR (LIBDW): + return INTUSE(dwarf_errmsg) (error & 0xffff); +#if 0 + case OTHER_ERROR (LIBEBL): + return ebl_errmsg (error & 0xffff); +#endif + } + + return _(&msgstr[msgidx[(unsigned int) error < nmsgidx + ? error : DWFL_E_UNKNOWN_ERROR]]); +} +INTDEF (dwfl_errmsg) diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c new file mode 100644 index 00000000..77e0c5cb --- /dev/null +++ b/libdwfl/dwfl_frame.c @@ -0,0 +1,458 @@ +/* Get Dwarf Frame state for target PID or core file. + Copyright (C) 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libdwflP.h" +#include + +/* Set STATE->pc_set from STATE->regs according to the backend. Return true on + success, false on error. */ +static bool +state_fetch_pc (Dwfl_Frame *state) +{ + switch (state->pc_state) + { + case DWFL_FRAME_STATE_PC_SET: + return true; + case DWFL_FRAME_STATE_PC_UNDEFINED: + abort (); + case DWFL_FRAME_STATE_ERROR: + { + Ebl *ebl = state->thread->process->ebl; + Dwarf_CIE abi_info; + if (ebl_abi_cfi (ebl, &abi_info) != 0) + { + __libdwfl_seterrno (DWFL_E_LIBEBL); + return false; + } + unsigned ra = abi_info.return_address_register; + /* dwarf_frame_state_reg_is_set is not applied here. */ + if (ra >= ebl_frame_nregs (ebl)) + { + __libdwfl_seterrno (DWFL_E_LIBEBL_BAD); + return false; + } + state->pc = state->regs[ra] + ebl_ra_offset (ebl); + state->pc_state = DWFL_FRAME_STATE_PC_SET; + } + return true; + } + abort (); +} + +/* Do not call it on your own, to be used by thread_* functions only. */ + +static void +free_states (Dwfl_Frame *state) +{ + while (state) + { + Dwfl_Frame *next = state->unwound; + free(state); + state = next; + } +} + +static Dwfl_Frame * +state_alloc (Dwfl_Thread *thread) +{ + assert (thread->unwound == NULL); + Ebl *ebl = thread->process->ebl; + size_t nregs = ebl_frame_nregs (ebl); + if (nregs == 0) + return NULL; + assert (nregs < sizeof (((Dwfl_Frame *) NULL)->regs_set) * 8); + Dwfl_Frame *state = malloc (sizeof (*state) + sizeof (*state->regs) * nregs); + if (state == NULL) + return NULL; + state->thread = thread; + state->signal_frame = false; + state->initial_frame = true; + state->pc_state = DWFL_FRAME_STATE_ERROR; + memset (state->regs_set, 0, sizeof (state->regs_set)); + thread->unwound = state; + state->unwound = NULL; + return state; +} + +void +internal_function +__libdwfl_process_free (Dwfl_Process *process) +{ + Dwfl *dwfl = process->dwfl; + if (process->callbacks->detach != NULL) + process->callbacks->detach (dwfl, process->callbacks_arg); + assert (dwfl->process == process); + dwfl->process = NULL; + if (process->ebl_close) + ebl_closebackend (process->ebl); + free (process); + dwfl->attacherr = DWFL_E_NOERROR; +} + +/* Allocate new Dwfl_Process for DWFL. */ +static void +process_alloc (Dwfl *dwfl) +{ + Dwfl_Process *process = malloc (sizeof (*process)); + if (process == NULL) + return; + process->dwfl = dwfl; + dwfl->process = process; +} + +bool +dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid, + const Dwfl_Thread_Callbacks *thread_callbacks, void *arg) +{ + if (dwfl->process != NULL) + { + __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT); + return false; + } + + /* Reset any previous error, we are just going to try again. */ + dwfl->attacherr = DWFL_E_NOERROR; + /* thread_callbacks is declared NN */ + if (thread_callbacks->next_thread == NULL + || thread_callbacks->set_initial_registers == NULL) + { + dwfl->attacherr = DWFL_E_INVALID_ARGUMENT; + fail: + dwfl->attacherr = __libdwfl_canon_error (dwfl->attacherr); + __libdwfl_seterrno (dwfl->attacherr); + return false; + } + + Ebl *ebl; + bool ebl_close; + if (elf != NULL) + { + ebl = ebl_openbackend (elf); + ebl_close = true; + } + else + { + ebl = NULL; + for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next) + { + /* Reading of the vDSO or (deleted) modules may fail as + /proc/PID/mem is unreadable without PTRACE_ATTACH and + we may not be PTRACE_ATTACH-ed now. MOD would not be + re-read later to unwind it when we are already + PTRACE_ATTACH-ed to PID. This happens when this function + is called from dwfl_linux_proc_attach with elf == NULL. + __libdwfl_module_getebl will call __libdwfl_getelf which + will call the find_elf callback. */ + if (startswith (mod->name, "[vdso: ") + || strcmp (strrchr (mod->name, ' ') ?: "", + " (deleted)") == 0) + continue; + Dwfl_Error error = __libdwfl_module_getebl (mod); + if (error != DWFL_E_NOERROR) + continue; + ebl = mod->ebl; + break; + } + ebl_close = false; + } + if (ebl == NULL) + { + /* Not identified EBL from any of the modules. */ + dwfl->attacherr = DWFL_E_PROCESS_NO_ARCH; + goto fail; + } + process_alloc (dwfl); + Dwfl_Process *process = dwfl->process; + if (process == NULL) + { + if (ebl_close) + ebl_closebackend (ebl); + dwfl->attacherr = DWFL_E_NOMEM; + goto fail; + } + process->ebl = ebl; + process->ebl_close = ebl_close; + process->pid = pid; + process->callbacks = thread_callbacks; + process->callbacks_arg = arg; + return true; +} +INTDEF(dwfl_attach_state) + +pid_t +dwfl_pid (Dwfl *dwfl) +{ + if (dwfl->attacherr != DWFL_E_NOERROR) + { + __libdwfl_seterrno (dwfl->attacherr); + return -1; + } + + if (dwfl->process == NULL) + { + __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE); + return -1; + } + return dwfl->process->pid; +} +INTDEF(dwfl_pid) + +Dwfl * +dwfl_thread_dwfl (Dwfl_Thread *thread) +{ + return thread->process->dwfl; +} +INTDEF(dwfl_thread_dwfl) + +pid_t +dwfl_thread_tid (Dwfl_Thread *thread) +{ + return thread->tid; +} +INTDEF(dwfl_thread_tid) + +Dwfl_Thread * +dwfl_frame_thread (Dwfl_Frame *state) +{ + return state->thread; +} +INTDEF(dwfl_frame_thread) + +int +dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg), + void *arg) +{ + if (dwfl->attacherr != DWFL_E_NOERROR) + { + __libdwfl_seterrno (dwfl->attacherr); + return -1; + } + + Dwfl_Process *process = dwfl->process; + if (process == NULL) + { + __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE); + return -1; + } + + Dwfl_Thread thread; + thread.process = process; + thread.unwound = NULL; + thread.callbacks_arg = NULL; + for (;;) + { + thread.tid = process->callbacks->next_thread (dwfl, + process->callbacks_arg, + &thread.callbacks_arg); + if (thread.tid < 0) + return -1; + if (thread.tid == 0) + { + __libdwfl_seterrno (DWFL_E_NOERROR); + return 0; + } + int err = callback (&thread, arg); + if (err != DWARF_CB_OK) + return err; + assert (thread.unwound == NULL); + } + /* NOTREACHED */ +} +INTDEF(dwfl_getthreads) + +struct one_arg +{ + pid_t tid; + bool seen; + int (*callback) (Dwfl_Thread *thread, void *arg); + void *arg; + int ret; +}; + +static int +get_one_thread_cb (Dwfl_Thread *thread, void *arg) +{ + struct one_arg *oa = (struct one_arg *) arg; + if (! oa->seen && INTUSE(dwfl_thread_tid) (thread) == oa->tid) + { + oa->seen = true; + oa->ret = oa->callback (thread, oa->arg); + return DWARF_CB_ABORT; + } + + return DWARF_CB_OK; +} + +/* Note not currently exported, will be when there are more Dwfl_Thread + properties to query. Use dwfl_getthread_frames for now directly. */ +static int +getthread (Dwfl *dwfl, pid_t tid, + int (*callback) (Dwfl_Thread *thread, void *arg), + void *arg) +{ + if (dwfl->attacherr != DWFL_E_NOERROR) + { + __libdwfl_seterrno (dwfl->attacherr); + return -1; + } + + Dwfl_Process *process = dwfl->process; + if (process == NULL) + { + __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE); + return -1; + } + + if (process->callbacks->get_thread != NULL) + { + Dwfl_Thread thread; + thread.process = process; + thread.unwound = NULL; + thread.callbacks_arg = NULL; + + if (process->callbacks->get_thread (dwfl, tid, process->callbacks_arg, + &thread.callbacks_arg)) + { + thread.tid = tid; + return callback (&thread, arg); + } + + return -1; + } + + struct one_arg oa = { .tid = tid, .callback = callback, + .arg = arg, .seen = false }; + int err = INTUSE(dwfl_getthreads) (dwfl, get_one_thread_cb, &oa); + + if (err == DWARF_CB_ABORT && oa.seen) + return oa.ret; + + if (err == DWARF_CB_OK && ! oa.seen) + { + errno = ESRCH; + __libdwfl_seterrno (DWFL_E_ERRNO); + return -1; + } + + return err; +} + +struct one_thread +{ + int (*callback) (Dwfl_Frame *frame, void *arg); + void *arg; +}; + +static int +get_one_thread_frames_cb (Dwfl_Thread *thread, void *arg) +{ + struct one_thread *ot = (struct one_thread *) arg; + return INTUSE(dwfl_thread_getframes) (thread, ot->callback, ot->arg); +} + +int +dwfl_getthread_frames (Dwfl *dwfl, pid_t tid, + int (*callback) (Dwfl_Frame *frame, void *arg), + void *arg) +{ + struct one_thread ot = { .callback = callback, .arg = arg }; + return getthread (dwfl, tid, get_one_thread_frames_cb, &ot); +} +INTDEF(dwfl_getthread_frames) + +int +dwfl_thread_getframes (Dwfl_Thread *thread, + int (*callback) (Dwfl_Frame *state, void *arg), + void *arg) +{ + Ebl *ebl = thread->process->ebl; + if (ebl_frame_nregs (ebl) == 0) + { + __libdwfl_seterrno (DWFL_E_NO_UNWIND); + return -1; + } + if (state_alloc (thread) == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + Dwfl_Process *process = thread->process; + if (! process->callbacks->set_initial_registers (thread, + thread->callbacks_arg)) + { + free_states (thread->unwound); + thread->unwound = NULL; + return -1; + } + Dwfl_Frame *state = thread->unwound; + thread->unwound = NULL; + if (! state_fetch_pc (state)) + { + if (process->callbacks->thread_detach) + process->callbacks->thread_detach (thread, thread->callbacks_arg); + free_states (state); + return -1; + } + do + { + int err = callback (state, arg); + if (err != DWARF_CB_OK) + { + if (process->callbacks->thread_detach) + process->callbacks->thread_detach (thread, thread->callbacks_arg); + free_states (state); + return err; + } + __libdwfl_frame_unwind (state); + Dwfl_Frame *next = state->unwound; + /* The old frame is no longer needed. */ + free (state); + state = next; + } + while (state && state->pc_state == DWFL_FRAME_STATE_PC_SET); + + Dwfl_Error err = dwfl_errno (); + if (process->callbacks->thread_detach) + process->callbacks->thread_detach (thread, thread->callbacks_arg); + if (state == NULL || state->pc_state == DWFL_FRAME_STATE_ERROR) + { + free_states (state); + __libdwfl_seterrno (err); + return -1; + } + assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED); + free_states (state); + return 0; +} +INTDEF(dwfl_thread_getframes) diff --git a/libdwfl/dwfl_frame_pc.c b/libdwfl/dwfl_frame_pc.c new file mode 100644 index 00000000..296c815b --- /dev/null +++ b/libdwfl/dwfl_frame_pc.c @@ -0,0 +1,64 @@ +/* Get return address register value for frame. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +bool +dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation) +{ + assert (state->pc_state == DWFL_FRAME_STATE_PC_SET); + *pc = state->pc; + ebl_normalize_pc (state->thread->process->ebl, pc); + if (isactivation) + { + /* Bottom frame? */ + if (state->initial_frame) + *isactivation = true; + /* *ISACTIVATION is logical union of whether current or previous frame + state is SIGNAL_FRAME. */ + else if (state->signal_frame) + *isactivation = true; + else + { + /* If the previous frame has unwound unsuccessfully just silently do + not consider it could be a SIGNAL_FRAME. */ + __libdwfl_frame_unwind (state); + if (state->unwound == NULL + || state->unwound->pc_state != DWFL_FRAME_STATE_PC_SET) + *isactivation = false; + else + *isactivation = state->unwound->signal_frame; + } + } + return true; +} +INTDEF (dwfl_frame_pc) diff --git a/libdwfl/dwfl_frame_regs.c b/libdwfl/dwfl_frame_regs.c new file mode 100644 index 00000000..83b1abef --- /dev/null +++ b/libdwfl/dwfl_frame_regs.c @@ -0,0 +1,61 @@ +/* Get Dwarf Frame state from modules present in DWFL. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +bool +dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg, + unsigned nregs, const Dwarf_Word *regs) +{ + Dwfl_Frame *state = thread->unwound; + assert (state && state->unwound == NULL); + assert (state->initial_frame); + for (unsigned regno = firstreg; regno < firstreg + nregs; regno++) + if (! __libdwfl_frame_reg_set (state, regno, regs[regno - firstreg])) + { + __libdwfl_seterrno (DWFL_E_INVALID_REGISTER); + return false; + } + return true; +} +INTDEF(dwfl_thread_state_registers) + +void +dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc) +{ + Dwfl_Frame *state = thread->unwound; + assert (state && state->unwound == NULL); + assert (state->initial_frame); + state->pc = pc; + state->pc_state = DWFL_FRAME_STATE_PC_SET; +} +INTDEF(dwfl_thread_state_register_pc) diff --git a/libdwfl/dwfl_getdwarf.c b/libdwfl/dwfl_getdwarf.c new file mode 100644 index 00000000..edd088ec --- /dev/null +++ b/libdwfl/dwfl_getdwarf.c @@ -0,0 +1,63 @@ +/* Iterate through modules to fetch Dwarf information. + Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +struct module_callback_info +{ + int (*callback) (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + Dwarf *, Dwarf_Addr, void *); + void *arg; +}; + +static int +module_callback (Dwfl_Module *mod, void **userdata, + const char *name, Dwarf_Addr start, void *arg) +{ + const struct module_callback_info *info = arg; + Dwarf_Addr bias = 0; + Dwarf *dw = INTUSE(dwfl_module_getdwarf) (mod, &bias); + return (*info->callback) (mod, userdata, name, start, dw, bias, info->arg); +} + +ptrdiff_t +dwfl_getdwarf (Dwfl *dwfl, + int (*callback) (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + Dwarf *, Dwarf_Addr, void *), + void *arg, + ptrdiff_t offset) +{ + struct module_callback_info info = { callback, arg }; + return INTUSE(dwfl_getmodules) (dwfl, &module_callback, &info, offset); +} diff --git a/libdwfl/dwfl_getmodules.c b/libdwfl/dwfl_getmodules.c new file mode 100644 index 00000000..243cb04d --- /dev/null +++ b/libdwfl/dwfl_getmodules.c @@ -0,0 +1,96 @@ +/* Iterate through modules. + Copyright (C) 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +ptrdiff_t +dwfl_getmodules (Dwfl *dwfl, + int (*callback) (Dwfl_Module *, void **, + const char *, Dwarf_Addr, void *), + void *arg, + ptrdiff_t offset) +{ + if (dwfl == NULL) + return -1; + + /* We iterate through the linked list when it's all we have. + But continuing from an offset is slow that way. So when + DWFL->lookup_module is populated, we can instead keep our + place by jumping directly into the array. Since the actions + of a callback could cause it to get populated, we must + choose the style of place-holder when we return an offset, + and we encode the choice in the low bits of that value. */ + + Dwfl_Module *m = dwfl->modulelist; + + if ((offset & 3) == 1) + { + offset >>= 2; + for (ptrdiff_t pos = 0; pos < offset; ++pos) + if (m == NULL) + return -1; + else + m = m->next; + } + else if (((offset & 3) == 2) && likely (dwfl->lookup_module != NULL)) + { + offset >>= 2; + + if ((size_t) offset - 1 == dwfl->lookup_elts) + return 0; + + if (unlikely ((size_t) offset - 1 > dwfl->lookup_elts)) + return -1; + + m = dwfl->lookup_module[offset - 1]; + if (unlikely (m == NULL)) + return -1; + } + else if (offset != 0) + { + __libdwfl_seterrno (DWFL_E_BADSTROFF); + return -1; + } + + while (m != NULL) + { + int ok = (*callback) (MODCB_ARGS (m), arg); + ++offset; + m = m->next; + if (ok != DWARF_CB_OK) + return ((dwfl->lookup_module == NULL) ? ((offset << 2) | 1) + : (((m == NULL ? (ptrdiff_t) dwfl->lookup_elts + 1 + : m->segment + 1) << 2) | 2)); + } + return 0; +} +INTDEF (dwfl_getmodules) diff --git a/libdwfl/dwfl_getsrc.c b/libdwfl/dwfl_getsrc.c new file mode 100644 index 00000000..d853aed4 --- /dev/null +++ b/libdwfl/dwfl_getsrc.c @@ -0,0 +1,40 @@ +/* Find source location for PC address. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwfl_Line * +dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr) +{ + return INTUSE(dwfl_module_getsrc) (INTUSE(dwfl_addrmodule) (dwfl, addr), + addr); +} diff --git a/libdwfl/dwfl_getsrclines.c b/libdwfl/dwfl_getsrclines.c new file mode 100644 index 00000000..1ce78fcb --- /dev/null +++ b/libdwfl/dwfl_getsrclines.c @@ -0,0 +1,52 @@ +/* Fetch source line information for CU. + Copyright (C) 2005, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +int +dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines) +{ + struct dwfl_cu *cu = (struct dwfl_cu *) cudie; + + if (cu->lines == NULL) + { + Dwfl_Error error = __libdwfl_cu_getsrclines (cu); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return -1; + } + } + + *nlines = cu->die.cu->lines->nlines; + return 0; +} diff --git a/libdwfl/dwfl_line_comp_dir.c b/libdwfl/dwfl_line_comp_dir.c new file mode 100644 index 00000000..77c3fdf1 --- /dev/null +++ b/libdwfl/dwfl_line_comp_dir.c @@ -0,0 +1,47 @@ +/* Get information from a source line record returned by libdwfl. + Copyright (C) 2005, 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include + +const char * +dwfl_line_comp_dir (Dwfl_Line *line) +{ + if (line == NULL) + return NULL; + + struct dwfl_cu *cu = dwfl_linecu (line); + Dwarf_Attribute attr_mem; + return INTUSE(dwarf_formstring) (INTUSE(dwarf_attr) (&cu->die, + DW_AT_comp_dir, + &attr_mem)); +} diff --git a/libdwfl/dwfl_linecu.c b/libdwfl/dwfl_linecu.c new file mode 100644 index 00000000..2043b17f --- /dev/null +++ b/libdwfl/dwfl_linecu.c @@ -0,0 +1,45 @@ +/* Fetch the module containing a source line record returned by libdwfl. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +#undef dwfl_linecu + +Dwarf_Die * +dwfl_linecu (Dwfl_Line *line) +{ + if (line == NULL) + return NULL; + + struct dwfl_cu *cu = dwfl_linecu_inline (line); + return &cu->die; +} diff --git a/libdwfl/dwfl_lineinfo.c b/libdwfl/dwfl_lineinfo.c new file mode 100644 index 00000000..96187128 --- /dev/null +++ b/libdwfl/dwfl_lineinfo.c @@ -0,0 +1,65 @@ +/* Get information from a source line record returned by libdwfl. + Copyright (C) 2005-2010, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/libdwP.h" + +const char * +dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, int *linep, int *colp, + Dwarf_Word *mtime, Dwarf_Word *length) +{ + if (line == NULL) + return NULL; + + struct dwfl_cu *cu = dwfl_linecu (line); + const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx]; + + if (addr != NULL) + *addr = dwfl_adjusted_dwarf_addr (cu->mod, info->addr); + if (linep != NULL) + *linep = info->line; + if (colp != NULL) + *colp = info->column; + + if (unlikely (info->file >= info->files->nfiles)) + { + __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF)); + return NULL; + } + + struct Dwarf_Fileinfo_s *file = &info->files->info[info->file]; + if (mtime != NULL) + *mtime = file->mtime; + if (length != NULL) + *length = file->length; + return file->name; +} diff --git a/libdwfl/dwfl_linemodule.c b/libdwfl/dwfl_linemodule.c new file mode 100644 index 00000000..d243f0d2 --- /dev/null +++ b/libdwfl/dwfl_linemodule.c @@ -0,0 +1,42 @@ +/* Fetch the module containing a source line record returned by libdwfl. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwfl_Module * +dwfl_linemodule (Dwfl_Line *line) +{ + if (line == NULL) + return NULL; + + return dwfl_linecu (line)->mod; +} diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c new file mode 100644 index 00000000..e7dfdace --- /dev/null +++ b/libdwfl/dwfl_module.c @@ -0,0 +1,243 @@ +/* Maintenance of module list in libdwfl. + Copyright (C) 2005, 2006, 2007, 2008, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/cfi.h" +#include +#include + +static void +free_cu (struct dwfl_cu *cu) +{ + if (cu->lines != NULL) + free (cu->lines); + free (cu); +} + +static void +nofree (void *arg __attribute__ ((unused))) +{ +} + +static void +free_file (struct dwfl_file *file) +{ + free (file->name); + + /* Close the fd only on the last reference. */ + if (file->elf != NULL && elf_end (file->elf) == 0 && file->fd != -1) + close (file->fd); +} + +void +internal_function +__libdwfl_module_free (Dwfl_Module *mod) +{ + if (mod->lazy_cu_root != NULL) + tdestroy (mod->lazy_cu_root, nofree); + + if (mod->aranges != NULL) + free (mod->aranges); + + if (mod->cu != NULL) + { + for (size_t i = 0; i < mod->ncu; ++i) + free_cu (mod->cu[i]); + free (mod->cu); + } + + /* We might have primed the Dwarf_CFI ebl cache with our own ebl + in __libdwfl_set_cfi. Make sure we don't free it twice. */ + if (mod->eh_cfi != NULL) + { + if (mod->eh_cfi->ebl != NULL && mod->eh_cfi->ebl == mod->ebl) + mod->eh_cfi->ebl = NULL; + dwarf_cfi_end (mod->eh_cfi); + } + + if (mod->dwarf_cfi != NULL) + { + if (mod->dwarf_cfi->ebl != NULL && mod->dwarf_cfi->ebl == mod->ebl) + mod->dwarf_cfi->ebl = NULL; + /* We don't need to explicitly destroy the dwarf_cfi. + That will be done by dwarf_end. */ + } + + if (mod->dw != NULL) + { + INTUSE(dwarf_end) (mod->dw); + if (mod->alt != NULL) + { + INTUSE(dwarf_end) (mod->alt); + if (mod->alt_elf != NULL) + elf_end (mod->alt_elf); + if (mod->alt_fd != -1) + close (mod->alt_fd); + } + } + + if (mod->ebl != NULL) + ebl_closebackend (mod->ebl); + + if (mod->debug.elf != mod->main.elf) + free_file (&mod->debug); + free_file (&mod->main); + free_file (&mod->aux_sym); + + if (mod->build_id_bits != NULL) + free (mod->build_id_bits); + + if (mod->reloc_info != NULL) + free (mod->reloc_info); + + free (mod->name); + free (mod->elfdir); + free (mod); +} + +void +dwfl_report_begin_add (Dwfl *dwfl __attribute__ ((unused))) +{ + /* The lookup table will be cleared on demand, there is nothing we need + to do here. */ +} +INTDEF (dwfl_report_begin_add) + +void +dwfl_report_begin (Dwfl *dwfl) +{ + /* Clear the segment lookup table. */ + dwfl->lookup_elts = 0; + + for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next) + m->gc = true; + + dwfl->offline_next_address = OFFLINE_REDZONE; +} +INTDEF (dwfl_report_begin) + +static inline Dwfl_Module * +use (Dwfl_Module *mod, Dwfl_Module **tailp, Dwfl *dwfl) +{ + mod->next = *tailp; + *tailp = mod; + + if (unlikely (dwfl->lookup_module != NULL)) + { + free (dwfl->lookup_module); + dwfl->lookup_module = NULL; + } + + return mod; +} + +/* Report that a module called NAME spans addresses [START, END). + Returns the module handle, either existing or newly allocated, + or returns a null pointer for an allocation error. */ +Dwfl_Module * +dwfl_report_module (Dwfl *dwfl, const char *name, + GElf_Addr start, GElf_Addr end) +{ + Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp; + + for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next)) + { + if (m->low_addr == start && m->high_addr == end + && !strcmp (m->name, name)) + { + /* This module is still here. Move it to the place in the list + after the last module already reported. */ + *prevp = m->next; + m->gc = false; + return use (m, tailp, dwfl); + } + + if (! m->gc) + tailp = &m->next; + } + + Dwfl_Module *mod = calloc (1, sizeof *mod); + if (mod == NULL) + goto nomem; + + mod->name = strdup (name); + if (mod->name == NULL) + { + free (mod); + nomem: + __libdwfl_seterrno (DWFL_E_NOMEM); + return NULL; + } + + mod->low_addr = start; + mod->high_addr = end; + mod->dwfl = dwfl; + + return use (mod, tailp, dwfl); +} +INTDEF (dwfl_report_module) + + +/* Finish reporting the current set of modules to the library. + If REMOVED is not null, it's called for each module that + existed before but was not included in the current report. + Returns a nonzero return value from the callback. + DWFL cannot be used until this function has returned zero. */ +int +dwfl_report_end (Dwfl *dwfl, + int (*removed) (Dwfl_Module *, void *, + const char *, Dwarf_Addr, + void *arg), + void *arg) +{ + Dwfl_Module **tailp = &dwfl->modulelist; + while (*tailp != NULL) + { + Dwfl_Module *m = *tailp; + if (m->gc && removed != NULL) + { + int result = (*removed) (MODCB_ARGS (m), arg); + if (result != 0) + return result; + } + if (m->gc) + { + *tailp = m->next; + __libdwfl_module_free (m); + } + else + tailp = &m->next; + } + + return 0; +} +INTDEF (dwfl_report_end) diff --git a/libdwfl/dwfl_module_addrdie.c b/libdwfl/dwfl_module_addrdie.c new file mode 100644 index 00000000..b44ec139 --- /dev/null +++ b/libdwfl/dwfl_module_addrdie.c @@ -0,0 +1,49 @@ +/* Fetch the CU DIE for a PC address in a given module. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwarf_Die * +dwfl_module_addrdie (Dwfl_Module *mod, Dwarf_Addr addr, Dwarf_Addr *bias) +{ + if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL) + return NULL; + + struct dwfl_cu *cu; + Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu); + if (likely (error == DWFL_E_NOERROR)) + return &cu->die; + + __libdwfl_seterrno (error); + return NULL; +} +INTDEF (dwfl_module_addrdie) diff --git a/libdwfl/dwfl_module_addrname.c b/libdwfl/dwfl_module_addrname.c new file mode 100644 index 00000000..3142b3eb --- /dev/null +++ b/libdwfl/dwfl_module_addrname.c @@ -0,0 +1,42 @@ +/* Find debugging and symbol information for a module in libdwfl. + Copyright (C) 2005, 2006, 2007, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +const char * +dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr) +{ + GElf_Off off; + GElf_Sym sym; + return INTUSE(dwfl_module_addrinfo) (mod, addr, &off, &sym, + NULL, NULL, NULL); +} diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c new file mode 100644 index 00000000..2336b602 --- /dev/null +++ b/libdwfl/dwfl_module_addrsym.c @@ -0,0 +1,335 @@ +/* Find debugging and symbol information for a module in libdwfl. + Copyright (C) 2005-2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +struct search_state +{ + Dwfl_Module *mod; + GElf_Addr addr; + + GElf_Sym *closest_sym; + bool adjust_st_value; + GElf_Word addr_shndx; + Elf *addr_symelf; + + /* Keep track of the closest symbol we have seen so far. + Here we store only symbols with nonzero st_size. */ + const char *closest_name; + GElf_Addr closest_value; + GElf_Word closest_shndx; + Elf *closest_elf; + + /* Keep track of an eligible symbol with st_size == 0 as a fallback. */ + const char *sizeless_name; + GElf_Sym sizeless_sym; + GElf_Addr sizeless_value; + GElf_Word sizeless_shndx; + Elf *sizeless_elf; + + /* Keep track of the lowest address a relevant sizeless symbol could have. */ + GElf_Addr min_label; +}; + +/* Return true iff we consider ADDR to lie in the same section as SYM. */ +static inline bool +same_section (struct search_state *state, + GElf_Addr value, Elf *symelf, GElf_Word shndx) +{ + /* For absolute symbols and the like, only match exactly. */ + if (shndx >= SHN_LORESERVE) + return value == state->addr; + + /* If value might not be st_value, the shndx of the symbol might + not match the section of the value. Explicitly look both up. */ + if (! state->adjust_st_value) + { + Dwarf_Addr v; + if (state->addr_shndx == SHN_UNDEF) + { + v = state->addr; + state->addr_shndx = __libdwfl_find_section_ndx (state->mod, &v); + } + + v = value; + return state->addr_shndx == __libdwfl_find_section_ndx (state->mod, &v); + } + + /* Figure out what section ADDR lies in. */ + if (state->addr_shndx == SHN_UNDEF || state->addr_symelf != symelf) + { + GElf_Addr mod_addr = dwfl_deadjust_st_value (state->mod, symelf, + state->addr); + Elf_Scn *scn = NULL; + state->addr_shndx = SHN_ABS; + state->addr_symelf = symelf; + while ((scn = elf_nextscn (symelf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (likely (shdr != NULL) + && mod_addr >= shdr->sh_addr + && mod_addr < shdr->sh_addr + shdr->sh_size) + { + state->addr_shndx = elf_ndxscn (scn); + break; + } + } + } + + return shndx == state->addr_shndx && state->addr_symelf == symelf; +} + +/* Return GELF_ST_BIND as higher-is-better integer. */ +static inline int +binding_value (const GElf_Sym *symp) +{ + switch (GELF_ST_BIND (symp->st_info)) + { + case STB_GLOBAL: + return 3; + case STB_WEAK: + return 2; + case STB_LOCAL: + return 1; + default: + return 0; + } +} + +/* Try one symbol and associated value from the search table. */ +static inline void +try_sym_value (struct search_state *state, + GElf_Addr value, GElf_Sym *sym, + const char *name, GElf_Word shndx, + Elf *elf, bool resolved) +{ + /* Even if we don't choose this symbol, its existence excludes + any sizeless symbol (assembly label) that is below its upper + bound. */ + if (value + sym->st_size > state->min_label) + state->min_label = value + sym->st_size; + + if (sym->st_size == 0 || state->addr - value < sym->st_size) + { + /* This symbol is a better candidate than the current one + if it's closer to ADDR or is global when it was local. */ + if (state->closest_name == NULL + || state->closest_value < value + || binding_value (state->closest_sym) < binding_value (sym)) + { + if (sym->st_size != 0) + { + *state->closest_sym = *sym; + state->closest_value = value; + state->closest_shndx = shndx; + state->closest_elf = elf; + state->closest_name = name; + } + else if (state->closest_name == NULL + && value >= state->min_label + && same_section (state, value, + resolved ? state->mod->main.elf : elf, + shndx)) + { + /* Handwritten assembly symbols sometimes have no + st_size. If no symbol with proper size includes + the address, we'll use the closest one that is in + the same section as ADDR. */ + state->sizeless_sym = *sym; + state->sizeless_value = value; + state->sizeless_shndx = shndx; + state->sizeless_elf = elf; + state->sizeless_name = name; + } + } + /* When the beginning of its range is no closer, + the end of its range might be. Otherwise follow + GELF_ST_BIND preference. If all are equal prefer + the first symbol found. */ + else if (sym->st_size != 0 + && state->closest_value == value + && ((state->closest_sym->st_size > sym->st_size + && (binding_value (state->closest_sym) + <= binding_value (sym))) + || (state->closest_sym->st_size >= sym->st_size + && (binding_value (state->closest_sym) + < binding_value (sym))))) + { + *state->closest_sym = *sym; + state->closest_value = value; + state->closest_shndx = shndx; + state->closest_elf = elf; + state->closest_name = name; + } + } +} + +/* Look through the symbol table for a matching symbol. */ +static inline void +search_table (struct search_state *state, int start, int end) +{ + for (int i = start; i < end; ++i) + { + GElf_Sym sym; + GElf_Addr value; + GElf_Word shndx; + Elf *elf; + bool resolved; + const char *name = __libdwfl_getsym (state->mod, i, &sym, &value, + &shndx, &elf, NULL, + &resolved, + state->adjust_st_value); + if (name != NULL && name[0] != '\0' + && sym.st_shndx != SHN_UNDEF + && value <= state->addr + && GELF_ST_TYPE (sym.st_info) != STT_SECTION + && GELF_ST_TYPE (sym.st_info) != STT_FILE + && GELF_ST_TYPE (sym.st_info) != STT_TLS) + { + try_sym_value (state, value, &sym, name, shndx, elf, resolved); + + /* If this is an addrinfo variant and the value could be + resolved then also try matching the (adjusted) st_value. */ + if (resolved && state->mod->e_type != ET_REL) + { + GElf_Addr adjusted_st_value; + adjusted_st_value = dwfl_adjusted_st_value (state->mod, elf, + sym.st_value); + if (value != adjusted_st_value + && adjusted_st_value <= state->addr) + try_sym_value (state, adjusted_st_value, &sym, name, shndx, + elf, false); + } + } + } +} + +/* Returns the name of the symbol "closest" to ADDR. + Never returns symbols at addresses above ADDR. + + Wrapper for old dwfl_module_addrsym and new dwfl_module_addrinfo. + adjust_st_value set to true returns adjusted SYM st_value, set to false + it will not adjust SYM at all, but does match against resolved values. */ +static const char * +__libdwfl_addrsym (Dwfl_Module *_mod, GElf_Addr _addr, GElf_Off *off, + GElf_Sym *_closest_sym, GElf_Word *shndxp, + Elf **elfp, Dwarf_Addr *biasp, bool _adjust_st_value) +{ + int syments = INTUSE(dwfl_module_getsymtab) (_mod); + if (syments < 0) + return NULL; + + struct search_state state = + { + .addr = _addr, + .mod = _mod, + .closest_sym = _closest_sym, + .adjust_st_value = _adjust_st_value, + .addr_shndx = SHN_UNDEF, + .addr_symelf = NULL, + .closest_name = NULL, + .closest_value = 0, + .closest_shndx = SHN_UNDEF, + .closest_elf = NULL, + .sizeless_name = NULL, + .sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF }, + .sizeless_value = 0, + .sizeless_shndx = SHN_UNDEF, + .sizeless_elf = NULL, + .min_label = 0 + }; + + /* First go through global symbols. mod->first_global and + mod->aux_first_global are setup by dwfl_module_getsymtab to the + index of the first global symbol in those symbol tables. Both + are non-zero when the table exist, except when there is only a + dynsym table loaded through phdrs, then first_global is zero and + there will be no auxiliary table. All symbols with local binding + come first in the symbol table, then all globals. The zeroth, + null entry, in the auxiliary table is skipped if there is a main + table. */ + int first_global = INTUSE (dwfl_module_getsymtab_first_global) (state.mod); + if (first_global < 0) + return NULL; + search_table (&state, first_global == 0 ? 1 : first_global, syments); + + /* If we found nothing searching the global symbols, then try the locals. + Unless we have a global sizeless symbol that matches exactly. */ + if (state.closest_name == NULL && first_global > 1 + && (state.sizeless_name == NULL || state.sizeless_value != state.addr)) + search_table (&state, 1, first_global); + + /* If we found no proper sized symbol to use, fall back to the best + candidate sizeless symbol we found, if any. */ + if (state.closest_name == NULL + && state.sizeless_name != NULL + && state.sizeless_value >= state.min_label) + { + *state.closest_sym = state.sizeless_sym; + state.closest_value = state.sizeless_value; + state.closest_shndx = state.sizeless_shndx; + state.closest_elf = state.sizeless_elf; + state.closest_name = state.sizeless_name; + } + + *off = state.addr - state.closest_value; + + if (shndxp != NULL) + *shndxp = state.closest_shndx; + if (elfp != NULL) + *elfp = state.closest_elf; + if (biasp != NULL) + *biasp = dwfl_adjusted_st_value (state.mod, state.closest_elf, 0); + return state.closest_name; +} + + +const char * +dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, + GElf_Sym *closest_sym, GElf_Word *shndxp) +{ + GElf_Off off; + return __libdwfl_addrsym (mod, addr, &off, closest_sym, shndxp, + NULL, NULL, true); +} +INTDEF (dwfl_module_addrsym) + +const char +*dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address, + GElf_Off *offset, GElf_Sym *sym, + GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *bias) +{ + return __libdwfl_addrsym (mod, address, offset, sym, shndxp, elfp, bias, + false); +} +INTDEF (dwfl_module_addrinfo) diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c new file mode 100644 index 00000000..6ca93761 --- /dev/null +++ b/libdwfl/dwfl_module_build_id.c @@ -0,0 +1,121 @@ +/* Return build ID information for a module. + Copyright (C) 2007-2010, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +static int +found_build_id (Dwfl_Module *mod, bool set, + const void *bits, int len, GElf_Addr vaddr) +{ + if (!set) + /* When checking bits, we do not compare VADDR because the + address found in a debuginfo file may not match the main + file as modified by prelink. */ + return 1 + (mod->build_id_len == len + && !memcmp (bits, mod->build_id_bits, len)); + + void *copy = malloc (len); + if (unlikely (copy == NULL)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + + mod->build_id_bits = memcpy (copy, bits, len); + mod->build_id_vaddr = vaddr; + mod->build_id_len = len; + return len; +} + +int +internal_function +__libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf) +{ + const void *build_id_bits; + GElf_Addr build_id_elfaddr; + int build_id_len; + + /* For mod == NULL use dwelf_elf_gnu_build_id directly. */ + assert (mod != NULL); + + int result = __libdwfl_find_elf_build_id (mod, elf, &build_id_bits, + &build_id_elfaddr, &build_id_len); + if (result <= 0) + return result; + + GElf_Addr build_id_vaddr = build_id_elfaddr + (build_id_elfaddr != 0 + ? mod->main_bias : 0); + return found_build_id (mod, set, build_id_bits, build_id_len, build_id_vaddr); +} + +int +dwfl_module_build_id (Dwfl_Module *mod, + const unsigned char **bits, GElf_Addr *vaddr) +{ + if (mod == NULL) + return -1; + + if (mod->build_id_len == 0 && mod->main.elf != NULL) + { + /* We have the file, but have not examined it yet. */ + int result = __libdwfl_find_build_id (mod, true, mod->main.elf); + if (result <= 0) + { + mod->build_id_len = -1; /* Cache negative result. */ + return result; + } + } + + if (mod->build_id_len <= 0) + return 0; + + *bits = mod->build_id_bits; + *vaddr = mod->build_id_vaddr; + return mod->build_id_len; +} +INTDEF (dwfl_module_build_id) +NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138) + +#ifdef SYMBOL_VERSIONING +COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end) + +int +_compat_vaddr_at_end_dwfl_module_build_id (Dwfl_Module *mod, + const unsigned char **bits, + GElf_Addr *vaddr) +{ + int result = INTUSE(dwfl_module_build_id) (mod, bits, vaddr); + if (result > 0) + *vaddr += (result + 3) & -4; + return result; +} +#endif diff --git a/libdwfl/dwfl_module_dwarf_cfi.c b/libdwfl/dwfl_module_dwarf_cfi.c new file mode 100644 index 00000000..0e5b4356 --- /dev/null +++ b/libdwfl/dwfl_module_dwarf_cfi.c @@ -0,0 +1,73 @@ +/* Find DWARF CFI for a module in libdwfl. + Copyright (C) 2009-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/cfi.h" + +Dwarf_CFI * +internal_function +__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot, Dwarf_CFI *cfi) +{ + if (cfi != NULL && cfi->ebl == NULL) + { + Dwfl_Error error = __libdwfl_module_getebl (mod); + if (error == DWFL_E_NOERROR) + cfi->ebl = mod->ebl; + else + { + if (slot == &mod->eh_cfi) + INTUSE(dwarf_cfi_end) (cfi); + __libdwfl_seterrno (error); + return NULL; + } + } + + return *slot = cfi; +} + +Dwarf_CFI * +dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias) +{ + if (mod == NULL) + return NULL; + + if (mod->dwarf_cfi != NULL) + { + *bias = dwfl_adjusted_dwarf_addr (mod, 0); + return mod->dwarf_cfi; + } + + return __libdwfl_set_cfi (mod, &mod->dwarf_cfi, + INTUSE(dwarf_getcfi) + (INTUSE(dwfl_module_getdwarf) (mod, bias))); +} +INTDEF (dwfl_module_dwarf_cfi) diff --git a/libdwfl/dwfl_module_eh_cfi.c b/libdwfl/dwfl_module_eh_cfi.c new file mode 100644 index 00000000..c296e399 --- /dev/null +++ b/libdwfl/dwfl_module_eh_cfi.c @@ -0,0 +1,59 @@ +/* Find EH CFI for a module in libdwfl. + Copyright (C) 2009-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/cfi.h" + +Dwarf_CFI * +dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias) +{ + if (mod == NULL) + return NULL; + + if (mod->eh_cfi != NULL) + { + *bias = dwfl_adjusted_address (mod, 0); + return mod->eh_cfi; + } + + __libdwfl_getelf (mod); + if (mod->elferr != DWFL_E_NOERROR) + { + __libdwfl_seterrno (mod->elferr); + return NULL; + } + + *bias = dwfl_adjusted_address (mod, 0); + return __libdwfl_set_cfi (mod, &mod->eh_cfi, + INTUSE(dwarf_getcfi_elf) (mod->main.elf)); +} +INTDEF (dwfl_module_eh_cfi) diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c new file mode 100644 index 00000000..6f076057 --- /dev/null +++ b/libdwfl/dwfl_module_getdwarf.c @@ -0,0 +1,1507 @@ +/* Find debugging and symbol information for a module in libdwfl. + Copyright (C) 2005-2012, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include +#include +#include +#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */ +#include "../libelf/libelfP.h" +#include "system.h" + +static inline Dwfl_Error +open_elf_file (Elf **elf, int *fd, char **name) +{ + if (*elf == NULL) + { + /* CBFAIL uses errno if it's set, so clear it first in case we don't + set it with an open failure below. */ + errno = 0; + + /* If there was a pre-primed file name left that the callback left + behind, try to open that file name. */ + if (*fd < 0 && *name != NULL) + *fd = TEMP_FAILURE_RETRY (open (*name, O_RDONLY)); + + if (*fd < 0) + return CBFAIL; + + return __libdw_open_file (fd, elf, true, false); + } + else if (unlikely (elf_kind (*elf) != ELF_K_ELF)) + { + elf_end (*elf); + *elf = NULL; + close (*fd); + *fd = -1; + return DWFL_E_BADELF; + } + + /* Elf file already open and looks fine. */ + return DWFL_E_NOERROR; +} + +/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD. + When we return success, FILE->elf and FILE->vaddr are set up. */ +static inline Dwfl_Error +open_elf (Dwfl_Module *mod, struct dwfl_file *file) +{ + Dwfl_Error error = open_elf_file (&file->elf, &file->fd, &file->name); + if (error != DWFL_E_NOERROR) + return error; + + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem); + if (ehdr == NULL) + { + elf_error: + elf_end (file->elf); + file->elf = NULL; + close (file->fd); + file->fd = -1; + return DWFL_E (LIBELF, elf_errno ()); + } + + if (ehdr->e_type != ET_REL) + { + /* In any non-ET_REL file, we compute the "synchronization address". + + We start with the address at the end of the first PT_LOAD + segment. When prelink converts REL to RELA in an ET_DYN + file, it expands the space between the beginning of the + segment and the actual code/data addresses. Since that + change wasn't made in the debug file, the distance from + p_vaddr to an address of interest (in an st_value or DWARF + data) now differs between the main and debug files. The + distance from address_sync to an address of interest remains + consistent. + + If there are no section headers at all (full stripping), then + the end of the first segment is a valid synchronization address. + This cannot happen in a prelinked file, since prelink itself + relies on section headers for prelinking and for undoing it. + (If you do full stripping on a prelinked file, then you get what + you deserve--you can neither undo the prelinking, nor expect to + line it up with a debug file separated before prelinking.) + + However, when prelink processes an ET_EXEC file, it can do + something different. There it juggles the "special" sections + (SHT_DYNSYM et al) to make space for the additional prelink + special sections. Sometimes it will do this by moving a special + section like .dynstr after the real program sections in the first + PT_LOAD segment--i.e. to the end. That changes the end address of + the segment, so it no longer lines up correctly and is not a valid + synchronization address to use. Because of this, we need to apply + a different prelink-savvy means to discover the synchronization + address when there is a separate debug file and a prelinked main + file. That is done in find_debuginfo, below. */ + + size_t phnum; + if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0)) + goto elf_error; + + file->vaddr = file->address_sync = 0; + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr ph_mem; + GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem); + if (unlikely (ph == NULL)) + goto elf_error; + if (ph->p_type == PT_LOAD) + { + file->vaddr = ph->p_vaddr & -ph->p_align; + file->address_sync = ph->p_vaddr + ph->p_memsz; + break; + } + } + } + + /* We only want to set the module e_type explicitly once, derived from + the main ELF file. (It might be changed for the kernel, because + that is special - see below.) open_elf is always called first for + the main ELF file, because both find_dw and find_symtab call + __libdwfl_getelf first to open the main file. So don't let debug + or aux files override the module e_type. The kernel heuristic + below could otherwise trigger for non-kernel/non-main files, since + their phdrs might not match the actual load addresses. */ + if (file == &mod->main) + { + mod->e_type = ehdr->e_type; + + /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN. */ + if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr) + mod->e_type = ET_DYN; + } + else + assert (mod->main.elf != NULL); + + return DWFL_E_NOERROR; +} + +/* We have an authoritative build ID for this module MOD, so don't use + a file by name that doesn't match that ID. */ +static void +mod_verify_build_id (Dwfl_Module *mod) +{ + assert (mod->build_id_len > 0); + + switch (__builtin_expect (__libdwfl_find_build_id (mod, false, + mod->main.elf), 2)) + { + case 2: + /* Build ID matches as it should. */ + return; + + case -1: /* ELF error. */ + mod->elferr = INTUSE(dwfl_errno) (); + break; + + case 0: /* File has no build ID note. */ + case 1: /* FIle has a build ID that does not match. */ + mod->elferr = DWFL_E_WRONG_ID_ELF; + break; + + default: + abort (); + } + + /* We get here when it was the right ELF file. Clear it out. */ + elf_end (mod->main.elf); + mod->main.elf = NULL; + if (mod->main.fd >= 0) + { + close (mod->main.fd); + mod->main.fd = -1; + } +} + +/* Find the main ELF file for this module and open libelf on it. + When we return success, MOD->main.elf and MOD->main.bias are set up. */ +void +internal_function +__libdwfl_getelf (Dwfl_Module *mod) +{ + if (mod->main.elf != NULL /* Already done. */ + || mod->elferr != DWFL_E_NOERROR) /* Cached failure. */ + return; + + mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod), + &mod->main.name, + &mod->main.elf); + const bool fallback = mod->main.elf == NULL && mod->main.fd < 0; + mod->elferr = open_elf (mod, &mod->main); + if (mod->elferr != DWFL_E_NOERROR) + return; + + if (!mod->main.valid) + { + /* Clear any explicitly reported build ID, just in case it was wrong. + We'll fetch it from the file when asked. */ + free (mod->build_id_bits); + mod->build_id_bits = NULL; + mod->build_id_len = 0; + } + else if (fallback) + mod_verify_build_id (mod); + + mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr; +} + +static inline void +consider_shdr (GElf_Addr interp, + GElf_Word sh_type, + GElf_Xword sh_flags, + GElf_Addr sh_addr, + GElf_Xword sh_size, + GElf_Addr *phighest) +{ + if ((sh_flags & SHF_ALLOC) + && ((sh_type == SHT_PROGBITS && sh_addr != interp) + || sh_type == SHT_NOBITS)) + { + const GElf_Addr sh_end = sh_addr + sh_size; + if (sh_end > *phighest) + *phighest = sh_end; + } +} + +/* If the main file might have been prelinked, then we need to + discover the correct synchronization address between the main and + debug files. Because of prelink's section juggling, we cannot rely + on the address_sync computed from PT_LOAD segments (see open_elf). + + We will attempt to discover a synchronization address based on the + section headers instead. But finding a section address that is + safe to use requires identifying which sections are SHT_PROGBITS. + We can do that in the main file, but in the debug file all the + allocated sections have been transformed into SHT_NOBITS so we have + lost the means to match them up correctly. + + The only method left to us is to decode the .gnu.prelink_undo + section in the prelinked main file. This shows what the sections + looked like before prelink juggled them--when they still had a + direct correspondence to the debug file. */ +static Dwfl_Error +find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file) +{ + /* The magic section is only identified by name. */ + size_t shstrndx; + if (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0) + return DWFL_E_LIBELF; + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + return DWFL_E_LIBELF; + if (shdr->sh_type == SHT_PROGBITS + && !(shdr->sh_flags & SHF_ALLOC) + && shdr->sh_name != 0) + { + const char *secname = elf_strptr (mod->main.elf, shstrndx, + shdr->sh_name); + if (unlikely (secname == NULL)) + return DWFL_E_LIBELF; + if (!strcmp (secname, ".gnu.prelink_undo")) + break; + } + } + + if (scn == NULL) + /* There was no .gnu.prelink_undo section. */ + return DWFL_E_NOERROR; + + Elf_Data *undodata = elf_rawdata (scn, NULL); + if (unlikely (undodata == NULL)) + return DWFL_E_LIBELF; + + /* Decode the section. It consists of the original ehdr, phdrs, + and shdrs (but omits section 0). */ + + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr; + Elf_Data dst = + { + .d_buf = &ehdr, + .d_size = sizeof ehdr, + .d_type = ELF_T_EHDR, + .d_version = EV_CURRENT + }; + Elf_Data src = *undodata; + src.d_size = gelf_fsize (mod->main.elf, ELF_T_EHDR, 1, EV_CURRENT); + src.d_type = ELF_T_EHDR; + if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src, + elf_getident (mod->main.elf, NULL)[EI_DATA]) + == NULL)) + return DWFL_E_LIBELF; + + size_t shentsize = gelf_fsize (mod->main.elf, ELF_T_SHDR, 1, EV_CURRENT); + size_t phentsize = gelf_fsize (mod->main.elf, ELF_T_PHDR, 1, EV_CURRENT); + + uint_fast16_t phnum; + uint_fast16_t shnum; + if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) + { + if (ehdr.e32.e_shentsize != shentsize + || ehdr.e32.e_phentsize != phentsize) + return DWFL_E_BAD_PRELINK; + phnum = ehdr.e32.e_phnum; + shnum = ehdr.e32.e_shnum; + } + else + { + if (ehdr.e64.e_shentsize != shentsize + || ehdr.e64.e_phentsize != phentsize) + return DWFL_E_BAD_PRELINK; + phnum = ehdr.e64.e_phnum; + shnum = ehdr.e64.e_shnum; + } + + /* Since prelink does not store the zeroth section header in the undo + section, it cannot support SHN_XINDEX encoding. */ + if (unlikely (shnum >= SHN_LORESERVE) || unlikely(shnum == 0) + || unlikely (undodata->d_size != (src.d_size + + phnum * phentsize + + (shnum - 1) * shentsize))) + return DWFL_E_BAD_PRELINK; + + --shnum; + + /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections. (Most + every file will have some SHT_PROGBITS sections, but it's possible to + have one with nothing but .bss, i.e. SHT_NOBITS.) The special sections + that can be moved around have different sh_type values--except for + .interp, the section that became the PT_INTERP segment. So we exclude + the SHT_PROGBITS section whose address matches the PT_INTERP p_vaddr. + For this reason, we must examine the phdrs first to find PT_INTERP. */ + + GElf_Addr main_interp = 0; + { + size_t main_phnum; + if (unlikely (elf_getphdrnum (mod->main.elf, &main_phnum))) + return DWFL_E_LIBELF; + for (size_t i = 0; i < main_phnum; ++i) + { + GElf_Phdr phdr; + if (unlikely (gelf_getphdr (mod->main.elf, i, &phdr) == NULL)) + return DWFL_E_LIBELF; + if (phdr.p_type == PT_INTERP) + { + main_interp = phdr.p_vaddr; + break; + } + } + } + + src.d_buf += src.d_size; + src.d_type = ELF_T_PHDR; + src.d_size = phnum * phentsize; + + GElf_Addr undo_interp = 0; + bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; + { + size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); + if (unlikely (phnum > SIZE_MAX / phdr_size)) + return DWFL_E_NOMEM; + const size_t phdrs_bytes = phnum * phdr_size; + void *phdrs = malloc (phdrs_bytes); + if (unlikely (phdrs == NULL)) + return DWFL_E_NOMEM; + dst.d_buf = phdrs; + dst.d_size = phdrs_bytes; + if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src, + ehdr.e32.e_ident[EI_DATA]) == NULL)) + { + free (phdrs); + return DWFL_E_LIBELF; + } + if (class32) + { + Elf32_Phdr (*p32)[phnum] = phdrs; + for (uint_fast16_t i = 0; i < phnum; ++i) + if ((*p32)[i].p_type == PT_INTERP) + { + undo_interp = (*p32)[i].p_vaddr; + break; + } + } + else + { + Elf64_Phdr (*p64)[phnum] = phdrs; + for (uint_fast16_t i = 0; i < phnum; ++i) + if ((*p64)[i].p_type == PT_INTERP) + { + undo_interp = (*p64)[i].p_vaddr; + break; + } + } + free (phdrs); + } + + if (unlikely ((main_interp == 0) != (undo_interp == 0))) + return DWFL_E_BAD_PRELINK; + + src.d_buf += src.d_size; + src.d_type = ELF_T_SHDR; + src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum, EV_CURRENT); + + size_t shdr_size = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr); + if (unlikely (shnum > SIZE_MAX / shdr_size)) + return DWFL_E_NOMEM; + const size_t shdrs_bytes = shnum * shdr_size; + void *shdrs = malloc (shdrs_bytes); + if (unlikely (shdrs == NULL)) + return DWFL_E_NOMEM; + dst.d_buf = shdrs; + dst.d_size = shdrs_bytes; + if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src, + ehdr.e32.e_ident[EI_DATA]) == NULL)) + { + free (shdrs); + return DWFL_E_LIBELF; + } + + /* Now we can look at the original section headers of the main file + before it was prelinked. First we'll apply our method to the main + file sections as they are after prelinking, to calculate the + synchronization address of the main file. Then we'll apply that + same method to the saved section headers, to calculate the matching + synchronization address of the debug file. + + The method is to consider SHF_ALLOC sections that are either + SHT_PROGBITS or SHT_NOBITS, excluding the section whose sh_addr + matches the PT_INTERP p_vaddr. The special sections that can be + moved by prelink have other types, except for .interp (which + becomes PT_INTERP). The "real" sections cannot move as such, but + .bss can be split into .dynbss and .bss, with the total memory + image remaining the same but being spread across the two sections. + So we consider the highest section end, which still matches up. */ + + GElf_Addr highest; + + highest = 0; + scn = NULL; + while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) + { + GElf_Shdr sh_mem; + GElf_Shdr *sh = gelf_getshdr (scn, &sh_mem); + if (unlikely (sh == NULL)) + { + free (shdrs); + return DWFL_E_LIBELF; + } + consider_shdr (main_interp, sh->sh_type, sh->sh_flags, + sh->sh_addr, sh->sh_size, &highest); + } + if (highest > mod->main.vaddr) + { + mod->main.address_sync = highest; + + highest = 0; + if (class32) + { + Elf32_Shdr (*s32)[shnum] = shdrs; + for (size_t i = 0; i < shnum; ++i) + consider_shdr (undo_interp, (*s32)[i].sh_type, + (*s32)[i].sh_flags, (*s32)[i].sh_addr, + (*s32)[i].sh_size, &highest); + } + else + { + Elf64_Shdr (*s64)[shnum] = shdrs; + for (size_t i = 0; i < shnum; ++i) + consider_shdr (undo_interp, (*s64)[i].sh_type, + (*s64)[i].sh_flags, (*s64)[i].sh_addr, + (*s64)[i].sh_size, &highest); + } + + if (highest > file->vaddr) + file->address_sync = highest; + else + { + free (shdrs); + return DWFL_E_BAD_PRELINK; + } + } + + free (shdrs); + + return DWFL_E_NOERROR; +} + +/* Find the separate debuginfo file for this module and open libelf on it. + When we return success, MOD->debug is set up. */ +static Dwfl_Error +find_debuginfo (Dwfl_Module *mod) +{ + if (mod->debug.elf != NULL) + return DWFL_E_NOERROR; + + GElf_Word debuglink_crc = 0; + const char *debuglink_file; + debuglink_file = INTUSE(dwelf_elf_gnu_debuglink) (mod->main.elf, + &debuglink_crc); + + mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod), + mod->main.name, + debuglink_file, + debuglink_crc, + &mod->debug.name); + Dwfl_Error result = open_elf (mod, &mod->debug); + if (result == DWFL_E_NOERROR && mod->debug.address_sync != 0) + result = find_prelink_address_sync (mod, &mod->debug); + return result; +} + +/* Try to find the alternative debug link for the given DWARF and set + it if found. Only called when mod->dw is already setup but still + might need an alternative (dwz multi) debug file. filename is either + the main or debug name from which the Dwarf was created. */ +static void +find_debug_altlink (Dwfl_Module *mod, const char *filename) +{ + assert (mod->dw != NULL); + + const char *altname; + const void *build_id; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, + &altname, + &build_id); + + if (build_id_len > 0) + { + /* We could store altfile in the module, but don't really need it. */ + char *altfile = NULL; + mod->alt_fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod), + filename, + altname, + 0, + &altfile); + + /* The (internal) callbacks might just set mod->alt_elf directly + because they open the Elf anyway for sanity checking. + Otherwise open either the given file name or use the fd + returned. */ + Dwfl_Error error = open_elf_file (&mod->alt_elf, &mod->alt_fd, + &altfile); + if (error == DWFL_E_NOERROR) + { + mod->alt = INTUSE(dwarf_begin_elf) (mod->alt_elf, + DWARF_C_READ, NULL); + if (mod->alt == NULL) + { + elf_end (mod->alt_elf); + mod->alt_elf = NULL; + close (mod->alt_fd); + mod->alt_fd = -1; + } + else + dwarf_setalt (mod->dw, mod->alt); + } + + free (altfile); /* See above, we don't really need it. */ + } +} + +/* Try to find a symbol table in FILE. + Returns DWFL_E_NOERROR if a proper one is found. + Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM. */ +static Dwfl_Error +load_symtab (struct dwfl_file *file, struct dwfl_file **symfile, + Elf_Scn **symscn, Elf_Scn **xndxscn, + size_t *syments, int *first_global, GElf_Word *strshndx) +{ + bool symtab = false; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (file->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + switch (shdr->sh_type) + { + case SHT_SYMTAB: + if (shdr->sh_entsize == 0) + break; + symtab = true; + *symscn = scn; + *symfile = file; + *strshndx = shdr->sh_link; + *syments = shdr->sh_size / shdr->sh_entsize; + *first_global = shdr->sh_info; + if (*xndxscn != NULL) + return DWFL_E_NOERROR; + break; + + case SHT_DYNSYM: + if (symtab) + break; + /* Use this if need be, but keep looking for SHT_SYMTAB. */ + if (shdr->sh_entsize == 0) + break; + *symscn = scn; + *symfile = file; + *strshndx = shdr->sh_link; + *syments = shdr->sh_size / shdr->sh_entsize; + *first_global = shdr->sh_info; + break; + + case SHT_SYMTAB_SHNDX: + *xndxscn = scn; + if (symtab) + return DWFL_E_NOERROR; + break; + + default: + break; + } + } + + if (symtab) + /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */ + return DWFL_E_NOERROR; + + /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus. + We might have found an SHT_DYNSYM and set *SYMSCN et al though. */ + *xndxscn = NULL; + return DWFL_E_NO_SYMTAB; +} + + +/* Translate addresses into file offsets. + OFFS[*] start out zero and remain zero if unresolved. */ +static void +find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n, + GElf_Addr addrs[n], GElf_Off offs[n]) +{ + size_t unsolved = n; + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0) + for (size_t j = 0; j < n; ++j) + if (offs[j] == 0 + && addrs[j] >= phdr->p_vaddr + main_bias + && addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz) + { + offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset; + if (--unsolved == 0) + break; + } + } +} + +/* Various addresses we might want to pull from the dynamic segment. */ +enum +{ + i_symtab, + i_strtab, + i_hash, + i_gnu_hash, + i_max +}; + +/* Translate pointers into file offsets. ADJUST is either zero + in case the dynamic segment wasn't adjusted or mod->main_bias. + Will set mod->symfile if the translated offsets can be used as + symbol table. */ +static void +translate_offs (GElf_Addr adjust, + Dwfl_Module *mod, size_t phnum, + GElf_Addr addrs[i_max], GElf_Xword strsz, + GElf_Ehdr *ehdr) +{ + GElf_Off offs[i_max] = { 0, }; + find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs); + + /* Figure out the size of the symbol table. */ + if (offs[i_hash] != 0) + { + /* In the original format, .hash says the size of .dynsym. */ + + size_t entsz = SH_ENTSIZE_HASH (ehdr); + Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, + offs[i_hash] + entsz, entsz, + (entsz == 4 + ? ELF_T_WORD : ELF_T_XWORD)); + if (data != NULL) + mod->syments = (entsz == 4 + ? *(const GElf_Word *) data->d_buf + : *(const GElf_Xword *) data->d_buf); + } + if (offs[i_gnu_hash] != 0 && mod->syments == 0) + { + /* In the new format, we can derive it with some work. */ + + const struct + { + Elf32_Word nbuckets; + Elf32_Word symndx; + Elf32_Word maskwords; + Elf32_Word shift2; + } *header; + + Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash], + sizeof *header, ELF_T_WORD); + if (data != NULL) + { + header = data->d_buf; + Elf32_Word nbuckets = header->nbuckets; + Elf32_Word symndx = header->symndx; + GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header + + (gelf_getclass (mod->main.elf) + * sizeof (Elf32_Word) + * header->maskwords)); + + // elf_getdata_rawchunk takes a size_t, make sure it + // doesn't overflow. +#if SIZE_MAX <= UINT32_MAX + if (nbuckets > SIZE_MAX / sizeof (Elf32_Word)) + data = NULL; + else +#endif + data = elf_getdata_rawchunk (mod->main.elf, buckets_at, + nbuckets * sizeof (Elf32_Word), + ELF_T_WORD); + if (data != NULL && symndx < nbuckets) + { + const Elf32_Word *const buckets = data->d_buf; + Elf32_Word maxndx = symndx; + for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket) + if (buckets[bucket] > maxndx) + maxndx = buckets[bucket]; + + GElf_Off hasharr_at = (buckets_at + + nbuckets * sizeof (Elf32_Word)); + hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word); + do + { + data = elf_getdata_rawchunk (mod->main.elf, + hasharr_at, + sizeof (Elf32_Word), + ELF_T_WORD); + if (data != NULL + && (*(const Elf32_Word *) data->d_buf & 1u)) + { + mod->syments = maxndx + 1; + break; + } + ++maxndx; + hasharr_at += sizeof (Elf32_Word); + } + while (data != NULL); + } + } + } + if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0) + mod->syments = ((offs[i_strtab] - offs[i_symtab]) + / gelf_fsize (mod->main.elf, + ELF_T_SYM, 1, EV_CURRENT)); + + if (mod->syments > 0) + { + mod->symdata = elf_getdata_rawchunk (mod->main.elf, + offs[i_symtab], + gelf_fsize (mod->main.elf, + ELF_T_SYM, + mod->syments, + EV_CURRENT), + ELF_T_SYM); + if (mod->symdata != NULL) + { + mod->symstrdata = elf_getdata_rawchunk (mod->main.elf, + offs[i_strtab], + strsz, + ELF_T_BYTE); + if (mod->symstrdata == NULL) + mod->symdata = NULL; + } + if (mod->symdata == NULL) + mod->symerr = DWFL_E (LIBELF, elf_errno ()); + else + { + mod->symfile = &mod->main; + mod->symerr = DWFL_E_NOERROR; + } + } +} + +/* Try to find a dynamic symbol table via phdrs. */ +static void +find_dynsym (Dwfl_Module *mod) +{ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem); + + size_t phnum; + if (unlikely (elf_getphdrnum (mod->main.elf, &phnum) != 0)) + return; + + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem); + if (phdr == NULL) + break; + + if (phdr->p_type == PT_DYNAMIC) + { + /* Examine the dynamic section for the pointers we need. */ + + Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, + phdr->p_offset, phdr->p_filesz, + ELF_T_DYN); + if (data == NULL) + continue; + + GElf_Addr addrs[i_max] = { 0, }; + GElf_Xword strsz = 0; + size_t n = data->d_size / gelf_fsize (mod->main.elf, + ELF_T_DYN, 1, EV_CURRENT); + for (size_t j = 0; j < n; ++j) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); + if (dyn != NULL) + switch (dyn->d_tag) + { + case DT_SYMTAB: + addrs[i_symtab] = dyn->d_un.d_ptr; + continue; + + case DT_HASH: + addrs[i_hash] = dyn->d_un.d_ptr; + continue; + + case DT_GNU_HASH: + addrs[i_gnu_hash] = dyn->d_un.d_ptr; + continue; + + case DT_STRTAB: + addrs[i_strtab] = dyn->d_un.d_ptr; + continue; + + case DT_STRSZ: + strsz = dyn->d_un.d_val; + continue; + + default: + continue; + + case DT_NULL: + break; + } + break; + } + + /* First try unadjusted, like ELF files from disk, vdso. + Then try for already adjusted dynamic section, like ELF + from remote memory. */ + translate_offs (0, mod, phnum, addrs, strsz, ehdr); + if (mod->symfile == NULL) + translate_offs (mod->main_bias, mod, phnum, addrs, strsz, ehdr); + + return; + } + } +} + + +#if USE_LZMA +/* Try to find the offset between the main file and .gnu_debugdata. */ +static bool +find_aux_address_sync (Dwfl_Module *mod) +{ + /* Don't trust the phdrs in the minisymtab elf file to be setup correctly. + The address_sync is equal to the main file it is embedded in at first. */ + mod->aux_sym.address_sync = mod->main.address_sync; + + /* Adjust address_sync for the difference in entry addresses, attempting to + account for ELF relocation changes after aux was split. */ + GElf_Ehdr ehdr_main, ehdr_aux; + if (unlikely (gelf_getehdr (mod->main.elf, &ehdr_main) == NULL) + || unlikely (gelf_getehdr (mod->aux_sym.elf, &ehdr_aux) == NULL)) + return false; + mod->aux_sym.address_sync += ehdr_aux.e_entry - ehdr_main.e_entry; + + /* The shdrs are setup OK to make find_prelink_address_sync () do the right + thing, which is possibly more reliable, but it needs .gnu.prelink_undo. */ + if (mod->aux_sym.address_sync != 0) + return find_prelink_address_sync (mod, &mod->aux_sym) == DWFL_E_NOERROR; + + return true; +} +#endif + +/* Try to find the auxiliary symbol table embedded in the main elf file + section .gnu_debugdata. Only matters if the symbol information comes + from the main file dynsym. No harm done if not found. */ +static void +find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)), + Elf_Scn **aux_symscn __attribute__ ((unused)), + Elf_Scn **aux_xndxscn __attribute__ ((unused)), + GElf_Word *aux_strshndx __attribute__ ((unused))) +{ + /* Since a .gnu_debugdata section is compressed using lzma don't do + anything unless we have support for that. */ +#if USE_LZMA + Elf *elf = mod->main.elf; + + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) < 0) + return; + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + return; + + const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (name == NULL) + return; + + if (!strcmp (name, ".gnu_debugdata")) + break; + } + + if (scn == NULL) + return; + + /* Found the .gnu_debugdata section. Uncompress the lzma image and + turn it into an ELF image. */ + Elf_Data *rawdata = elf_rawdata (scn, NULL); + if (rawdata == NULL) + return; + + Dwfl_Error error; + void *buffer = NULL; + size_t size = 0; + error = __libdw_unlzma (-1, 0, rawdata->d_buf, rawdata->d_size, + &buffer, &size); + if (error == DWFL_E_NOERROR) + { + if (unlikely (size == 0)) + free (buffer); + else + { + mod->aux_sym.elf = elf_memory (buffer, size); + if (mod->aux_sym.elf == NULL) + free (buffer); + else + { + mod->aux_sym.fd = -1; + mod->aux_sym.elf->flags |= ELF_F_MALLOCED; + if (open_elf (mod, &mod->aux_sym) != DWFL_E_NOERROR) + return; + if (! find_aux_address_sync (mod)) + { + elf_end (mod->aux_sym.elf); + mod->aux_sym.elf = NULL; + return; + } + + /* So far, so good. Get minisymtab table data and cache it. */ + bool minisymtab = false; + scn = NULL; + while ((scn = elf_nextscn (mod->aux_sym.elf, scn)) != NULL) + { + GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + switch (shdr->sh_type) + { + case SHT_SYMTAB: + if (shdr->sh_entsize == 0) + return; + minisymtab = true; + *aux_symscn = scn; + *aux_strshndx = shdr->sh_link; + mod->aux_syments = shdr->sh_size / shdr->sh_entsize; + mod->aux_first_global = shdr->sh_info; + if (*aux_xndxscn != NULL) + return; + break; + + case SHT_SYMTAB_SHNDX: + *aux_xndxscn = scn; + if (minisymtab) + return; + break; + + default: + break; + } + } + + if (minisymtab) + /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */ + return; + + /* We found no SHT_SYMTAB, so everything else is bogus. */ + *aux_xndxscn = NULL; + *aux_strshndx = 0; + mod->aux_syments = 0; + elf_end (mod->aux_sym.elf); + mod->aux_sym.elf = NULL; + return; + } + } + } + else + free (buffer); +#endif +} + +/* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf. */ +static void +find_symtab (Dwfl_Module *mod) +{ + if (mod->symdata != NULL || mod->aux_symdata != NULL /* Already done. */ + || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */ + return; + + __libdwfl_getelf (mod); + mod->symerr = mod->elferr; + if (mod->symerr != DWFL_E_NOERROR) + return; + + /* First see if the main ELF file has the debugging information. */ + Elf_Scn *symscn = NULL, *xndxscn = NULL; + Elf_Scn *aux_symscn = NULL, *aux_xndxscn = NULL; + GElf_Word strshndx, aux_strshndx = 0; + mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn, + &xndxscn, &mod->syments, &mod->first_global, + &strshndx); + switch (mod->symerr) + { + default: + return; + + case DWFL_E_NOERROR: + break; + + case DWFL_E_NO_SYMTAB: + /* Now we have to look for a separate debuginfo file. */ + mod->symerr = find_debuginfo (mod); + switch (mod->symerr) + { + default: + return; + + case DWFL_E_NOERROR: + mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn, + &xndxscn, &mod->syments, + &mod->first_global, &strshndx); + break; + + case DWFL_E_CB: /* The find_debuginfo hook failed. */ + mod->symerr = DWFL_E_NO_SYMTAB; + break; + } + + switch (mod->symerr) + { + default: + return; + + case DWFL_E_NOERROR: + break; + + case DWFL_E_NO_SYMTAB: + /* There might be an auxiliary table. */ + find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx); + + if (symscn != NULL) + { + /* We still have the dynamic symbol table. */ + mod->symerr = DWFL_E_NOERROR; + break; + } + + if (aux_symscn != NULL) + { + /* We still have the auxiliary symbol table. */ + mod->symerr = DWFL_E_NOERROR; + goto aux_cache; + } + + /* Last ditch, look for dynamic symbols without section headers. */ + find_dynsym (mod); + return; + } + break; + } + + /* This does some sanity checks on the string table section. */ + if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL) + { + elferr: + mod->symdata = NULL; + mod->syments = 0; + mod->first_global = 0; + mod->symerr = DWFL_E (LIBELF, elf_errno ()); + goto aux_cleanup; /* This cleans up some more and tries find_dynsym. */ + } + + /* Cache the data; MOD->syments and MOD->first_global were set + above. If any of the sections is compressed, uncompress it + first. Only the string data section could theoretically be + compressed GNU style (as .zdebug_str). Everything else only ELF + gabi style (SHF_COMPRESSED). */ + + Elf_Scn *symstrscn = elf_getscn (mod->symfile->elf, strshndx); + if (symstrscn == NULL) + goto elferr; + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (symstrscn, &shdr_mem); + if (shdr == NULL) + goto elferr; + + size_t shstrndx; + if (elf_getshdrstrndx (mod->symfile->elf, &shstrndx) < 0) + goto elferr; + + const char *sname = elf_strptr (mod->symfile->elf, shstrndx, shdr->sh_name); + if (sname == NULL) + goto elferr; + + if (startswith (sname, ".zdebug")) + /* Try to uncompress, but it might already have been, an error + might just indicate, already uncompressed. */ + elf_compress_gnu (symstrscn, 0, 0); + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (symstrscn, 0, 0) < 0) + goto elferr; + + mod->symstrdata = elf_getdata (symstrscn, NULL); + if (mod->symstrdata == NULL || mod->symstrdata->d_buf == NULL) + goto elferr; + + if (xndxscn == NULL) + mod->symxndxdata = NULL; + else + { + shdr = gelf_getshdr (xndxscn, &shdr_mem); + if (shdr == NULL) + goto elferr; + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (xndxscn, 0, 0) < 0) + goto elferr; + + mod->symxndxdata = elf_getdata (xndxscn, NULL); + if (mod->symxndxdata == NULL || mod->symxndxdata->d_buf == NULL) + goto elferr; + } + + shdr = gelf_getshdr (symscn, &shdr_mem); + if (shdr == NULL) + goto elferr; + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (symscn, 0, 0) < 0) + goto elferr; + + mod->symdata = elf_getdata (symscn, NULL); + if (mod->symdata == NULL || mod->symdata->d_buf == NULL) + goto elferr; + + // Sanity check number of symbols. + shdr = gelf_getshdr (symscn, &shdr_mem); + if (shdr == NULL || shdr->sh_entsize == 0 + || mod->syments > mod->symdata->d_size / shdr->sh_entsize + || (size_t) mod->first_global > mod->syments) + goto elferr; + + /* Cache any auxiliary symbol info, when it fails, just ignore aux_sym. */ + if (aux_symscn != NULL) + { + aux_cache: + /* This does some sanity checks on the string table section. */ + if (elf_strptr (mod->aux_sym.elf, aux_strshndx, 0) == NULL) + { + aux_cleanup: + mod->aux_syments = 0; + elf_end (mod->aux_sym.elf); + mod->aux_sym.elf = NULL; + /* We thought we had something through shdrs, but it failed... + Last ditch, look for dynamic symbols without section headers. */ + find_dynsym (mod); + return; + } + + Elf_Scn *aux_strscn = elf_getscn (mod->aux_sym.elf, aux_strshndx); + if (aux_strscn == NULL) + goto elferr; + + shdr = gelf_getshdr (aux_strscn, &shdr_mem); + if (shdr == NULL) + goto elferr; + + size_t aux_shstrndx; + if (elf_getshdrstrndx (mod->aux_sym.elf, &aux_shstrndx) < 0) + goto elferr; + + sname = elf_strptr (mod->aux_sym.elf, aux_shstrndx, + shdr->sh_name); + if (sname == NULL) + goto elferr; + + if (startswith (sname, ".zdebug")) + /* Try to uncompress, but it might already have been, an error + might just indicate, already uncompressed. */ + elf_compress_gnu (aux_strscn, 0, 0); + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (aux_strscn, 0, 0) < 0) + goto elferr; + + mod->aux_symstrdata = elf_getdata (aux_strscn, NULL); + if (mod->aux_symstrdata == NULL || mod->aux_symstrdata->d_buf == NULL) + goto aux_cleanup; + + if (aux_xndxscn == NULL) + mod->aux_symxndxdata = NULL; + else + { + shdr = gelf_getshdr (aux_xndxscn, &shdr_mem); + if (shdr == NULL) + goto elferr; + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (aux_xndxscn, 0, 0) < 0) + goto elferr; + + mod->aux_symxndxdata = elf_getdata (aux_xndxscn, NULL); + if (mod->aux_symxndxdata == NULL + || mod->aux_symxndxdata->d_buf == NULL) + goto aux_cleanup; + } + + shdr = gelf_getshdr (aux_symscn, &shdr_mem); + if (shdr == NULL) + goto elferr; + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (aux_symscn, 0, 0) < 0) + goto elferr; + + mod->aux_symdata = elf_getdata (aux_symscn, NULL); + if (mod->aux_symdata == NULL || mod->aux_symdata->d_buf == NULL) + goto aux_cleanup; + + // Sanity check number of aux symbols. + shdr = gelf_getshdr (aux_symscn, &shdr_mem); + if (mod->aux_syments > mod->aux_symdata->d_size / shdr->sh_entsize + || (size_t) mod->aux_first_global > mod->aux_syments) + goto aux_cleanup; + } +} + + +/* Try to open a libebl backend for MOD. */ +Dwfl_Error +internal_function +__libdwfl_module_getebl (Dwfl_Module *mod) +{ + if (mod->ebl == NULL) + { + __libdwfl_getelf (mod); + if (mod->elferr != DWFL_E_NOERROR) + return mod->elferr; + + mod->ebl = ebl_openbackend (mod->main.elf); + if (mod->ebl == NULL) + return DWFL_E_LIBEBL; + } + return DWFL_E_NOERROR; +} + +/* Try to start up libdw on DEBUGFILE. */ +static Dwfl_Error +load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile) +{ + if (mod->e_type == ET_REL && !debugfile->relocated) + { + const Dwfl_Callbacks *const cb = mod->dwfl->callbacks; + + /* The debugging sections have to be relocated. */ + if (cb->section_address == NULL) + return DWFL_E_NOREL; + + Dwfl_Error error = __libdwfl_module_getebl (mod); + if (error != DWFL_E_NOERROR) + return error; + + find_symtab (mod); + Dwfl_Error result = mod->symerr; + if (result == DWFL_E_NOERROR) + result = __libdwfl_relocate (mod, debugfile->elf, true); + if (result != DWFL_E_NOERROR) + return result; + } + + mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL); + if (mod->dw == NULL) + { + int err = INTUSE(dwarf_errno) (); + return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err); + } + + /* Do this after dwarf_begin_elf has a chance to process the fd. */ + if (mod->e_type == ET_REL && !debugfile->relocated) + { + /* Don't keep the file descriptors around. */ + if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0) + { + close (mod->main.fd); + mod->main.fd = -1; + } + if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0) + { + close (debugfile->fd); + debugfile->fd = -1; + } + } + + /* We might have already closed the fd when we asked dwarf_begin_elf to + create an Dwarf. Help out a little in case we need to find an alt or + dwo file later. */ + if (mod->dw->debugdir == NULL && mod->elfdir != NULL + && debugfile == &mod->main) + mod->dw->debugdir = strdup (mod->elfdir); + + /* Until we have iterated through all CU's, we might do lazy lookups. */ + mod->lazycu = 1; + + return DWFL_E_NOERROR; +} + +/* Try to start up libdw on either the main file or the debuginfo file. */ +static void +find_dw (Dwfl_Module *mod) +{ + if (mod->dw != NULL /* Already done. */ + || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure. */ + return; + + __libdwfl_getelf (mod); + mod->dwerr = mod->elferr; + if (mod->dwerr != DWFL_E_NOERROR) + return; + + /* First see if the main ELF file has the debugging information. */ + mod->dwerr = load_dw (mod, &mod->main); + switch (mod->dwerr) + { + case DWFL_E_NOERROR: + mod->debug.elf = mod->main.elf; + mod->debug.address_sync = mod->main.address_sync; + + /* The Dwarf might need an alt debug file, find that now after + everything about the debug file has been setup (the + find_debuginfo callback might need it). */ + find_debug_altlink (mod, mod->main.name); + return; + + case DWFL_E_NO_DWARF: + break; + + default: + goto canonicalize; + } + + /* Now we have to look for a separate debuginfo file. */ + mod->dwerr = find_debuginfo (mod); + switch (mod->dwerr) + { + case DWFL_E_NOERROR: + mod->dwerr = load_dw (mod, &mod->debug); + if (mod->dwerr == DWFL_E_NOERROR) + { + /* The Dwarf might need an alt debug file, find that now after + everything about the debug file has been setup (the + find_debuginfo callback might need it). */ + find_debug_altlink (mod, mod->debug.name); + return; + } + + break; + + case DWFL_E_CB: /* The find_debuginfo hook failed. */ + mod->dwerr = DWFL_E_NO_DWARF; + return; + + default: + break; + } + + canonicalize: + mod->dwerr = __libdwfl_canon_error (mod->dwerr); +} + +Dwarf * +dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias) +{ + if (mod == NULL) + return NULL; + + find_dw (mod); + if (mod->dwerr == DWFL_E_NOERROR) + { + /* If dwfl_module_getelf was used previously, then partial apply + relocation to miscellaneous sections in the debug file too. */ + if (mod->e_type == ET_REL + && mod->main.relocated && ! mod->debug.relocated) + { + mod->debug.relocated = true; + if (mod->debug.elf != mod->main.elf) + (void) __libdwfl_relocate (mod, mod->debug.elf, false); + } + + *bias = dwfl_adjusted_dwarf_addr (mod, 0); + return mod->dw; + } + + __libdwfl_seterrno (mod->dwerr); + return NULL; +} +INTDEF (dwfl_module_getdwarf) + +int +dwfl_module_getsymtab (Dwfl_Module *mod) +{ + if (mod == NULL) + return -1; + + find_symtab (mod); + if (mod->symerr == DWFL_E_NOERROR) + /* We will skip the auxiliary zero entry if there is another one. */ + return (mod->syments + mod->aux_syments + - (mod->syments > 0 && mod->aux_syments > 0 ? 1 : 0)); + + __libdwfl_seterrno (mod->symerr); + return -1; +} +INTDEF (dwfl_module_getsymtab) + +int +dwfl_module_getsymtab_first_global (Dwfl_Module *mod) +{ + if (mod == NULL) + return -1; + + find_symtab (mod); + if (mod->symerr == DWFL_E_NOERROR) + { + /* All local symbols should come before all global symbols. If + we have an auxiliary table make sure all the main locals come + first, then all aux locals, then all main globals and finally all + aux globals. And skip the auxiliary table zero undefined + entry. */ + int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0; + return mod->first_global + mod->aux_first_global - skip_aux_zero; + } + + __libdwfl_seterrno (mod->symerr); + return -1; +} +INTDEF (dwfl_module_getsymtab_first_global) diff --git a/libdwfl/dwfl_module_getelf.c b/libdwfl/dwfl_module_getelf.c new file mode 100644 index 00000000..6358de4c --- /dev/null +++ b/libdwfl/dwfl_module_getelf.c @@ -0,0 +1,71 @@ +/* Find debugging and symbol information for a module in libdwfl. + Copyright (C) 2009-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Elf * +dwfl_module_getelf (Dwfl_Module *mod, GElf_Addr *loadbase) +{ + if (mod == NULL) + return NULL; + + __libdwfl_getelf (mod); + if (mod->elferr == DWFL_E_NOERROR) + { + if (mod->e_type == ET_REL && ! mod->main.relocated) + { + /* Before letting them get at the Elf handle, + apply all the relocations we know how to. */ + + mod->main.relocated = true; + if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR)) + { + (void) __libdwfl_relocate (mod, mod->main.elf, false); + + if (mod->debug.elf == mod->main.elf) + mod->debug.relocated = true; + else if (mod->debug.elf != NULL && ! mod->debug.relocated) + { + mod->debug.relocated = true; + (void) __libdwfl_relocate (mod, mod->debug.elf, false); + } + } + } + + *loadbase = dwfl_adjusted_address (mod, 0); + return mod->main.elf; + } + + __libdwfl_seterrno (mod->elferr); + return NULL; +} +INTDEF (dwfl_module_getelf) diff --git a/libdwfl/dwfl_module_getsrc.c b/libdwfl/dwfl_module_getsrc.c new file mode 100644 index 00000000..fc99b163 --- /dev/null +++ b/libdwfl/dwfl_module_getsrc.c @@ -0,0 +1,85 @@ +/* Find source location for PC address in module. + Copyright (C) 2005, 2008, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/libdwP.h" + +Dwfl_Line * +dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr) +{ + Dwarf_Addr bias; + if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL) + return NULL; + + struct dwfl_cu *cu; + Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu); + if (likely (error == DWFL_E_NOERROR)) + error = __libdwfl_cu_getsrclines (cu); + if (likely (error == DWFL_E_NOERROR)) + { + Dwarf_Lines *lines = cu->die.cu->lines; + size_t nlines = lines->nlines; + if (nlines > 0) + { + /* This is guaranteed for us by libdw read_srclines. */ + assert(lines->info[nlines - 1].end_sequence); + + /* Now we look at the module-relative address. */ + addr -= bias; + + /* The lines are sorted by address, so we can use binary search. */ + size_t l = 0, u = nlines - 1; + while (l < u) + { + size_t idx = u - (u - l) / 2; + Dwarf_Line *line = &lines->info[idx]; + if (addr < line->addr) + u = idx - 1; + else + l = idx; + } + + /* The last line which is less than or equal to addr is what + we want, unless it is the end_sequence which is after the + current line sequence. */ + Dwarf_Line *line = &lines->info[l]; + if (! line->end_sequence && line->addr <= addr) + return &cu->lines->idx[l]; + } + + error = DWFL_E_ADDR_OUTOFRANGE; + } + + __libdwfl_seterrno (error); + return NULL; +} +INTDEF (dwfl_module_getsrc) diff --git a/libdwfl/dwfl_module_getsrc_file.c b/libdwfl/dwfl_module_getsrc_file.c new file mode 100644 index 00000000..cea2ba41 --- /dev/null +++ b/libdwfl/dwfl_module_getsrc_file.c @@ -0,0 +1,178 @@ +/* Find matching source locations in a module. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/libdwP.h" + + +static inline const char * +dwfl_dwarf_line_file (const Dwarf_Line *line) +{ + return line->files->info[line->file].name; +} + +static inline Dwarf_Line * +dwfl_line (const Dwfl_Line *line) +{ + return &dwfl_linecu (line)->die.cu->lines->info[line->idx]; +} + +static inline const char * +dwfl_line_file (const Dwfl_Line *line) +{ + return dwfl_dwarf_line_file (dwfl_line (line)); +} + +int +dwfl_module_getsrc_file (Dwfl_Module *mod, + const char *fname, int lineno, int column, + Dwfl_Line ***srcsp, size_t *nsrcs) +{ + if (mod == NULL) + return -1; + + if (mod->dw == NULL) + { + Dwarf_Addr bias; + if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL) + return -1; + } + + bool is_basename = strchr (fname, '/') == NULL; + + size_t max_match = *nsrcs ?: ~0u; + size_t act_match = *nsrcs; + size_t cur_match = 0; + Dwfl_Line **match = *nsrcs == 0 ? NULL : *srcsp; + + struct dwfl_cu *cu = NULL; + Dwfl_Error error; + while ((error = __libdwfl_nextcu (mod, cu, &cu)) == DWFL_E_NOERROR + && cu != NULL + && (error = __libdwfl_cu_getsrclines (cu)) == DWFL_E_NOERROR) + { + /* Search through all the line number records for a matching + file and line/column number. If any of the numbers is zero, + no match is performed. */ + const char *lastfile = NULL; + bool lastmatch = false; + for (size_t cnt = 0; cnt < cu->die.cu->lines->nlines; ++cnt) + { + Dwarf_Line *line = &cu->die.cu->lines->info[cnt]; + + if (unlikely (line->file >= line->files->nfiles)) + { + if (*nsrcs == 0) + free (match); + __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF)); + return -1; + } + else + { + const char *file = dwfl_dwarf_line_file (line); + if (file != lastfile) + { + /* Match the name with the name the user provided. */ + lastfile = file; + lastmatch = !strcmp (is_basename ? basename (file) : file, + fname); + } + } + if (!lastmatch) + continue; + + /* See whether line and possibly column match. */ + if (lineno != 0 + && (lineno > line->line + || (column != 0 && column > line->column))) + /* Cannot match. */ + continue; + + /* Determine whether this is the best match so far. */ + size_t inner; + for (inner = 0; inner < cur_match; ++inner) + if (dwfl_line_file (match[inner]) + == dwfl_dwarf_line_file (line)) + break; + if (inner < cur_match + && (dwfl_line (match[inner])->line != line->line + || dwfl_line (match[inner])->line != lineno + || (column != 0 + && (dwfl_line (match[inner])->column != line->column + || dwfl_line (match[inner])->column != column)))) + { + /* We know about this file already. If this is a better + match for the line number, use it. */ + if (dwfl_line (match[inner])->line >= line->line + && (dwfl_line (match[inner])->line != line->line + || dwfl_line (match[inner])->column >= line->column)) + /* Use the new line. Otherwise the old one. */ + match[inner] = &cu->lines->idx[cnt]; + continue; + } + + if (cur_match < max_match) + { + if (cur_match == act_match) + { + /* Enlarge the array for the results. */ + act_match += 10; + Dwfl_Line **newp = realloc (match, + act_match + * sizeof (Dwfl_Line *)); + if (newp == NULL) + { + free (match); + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + match = newp; + } + + match[cur_match++] = &cu->lines->idx[cnt]; + } + } + } + + if (cur_match > 0) + { + assert (*nsrcs == 0 || *srcsp == match); + + *nsrcs = cur_match; + *srcsp = match; + + return 0; + } + + __libdwfl_seterrno (DWFL_E_NO_MATCH); + return -1; +} diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c new file mode 100644 index 00000000..8de9a3eb --- /dev/null +++ b/libdwfl/dwfl_module_getsym.c @@ -0,0 +1,220 @@ +/* Find debugging and symbol information for a module in libdwfl. + Copyright (C) 2006-2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +const char * +internal_function +__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym, GElf_Addr *addr, + GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *biasp, + bool *resolved, bool adjust_st_value) +{ + if (unlikely (mod == NULL)) + return NULL; + + if (unlikely (mod->symdata == NULL)) + { + int result = INTUSE(dwfl_module_getsymtab) (mod); + if (result < 0) + return NULL; + } + + /* All local symbols should come before all global symbols. If we + have an auxiliary table make sure all the main locals come first, + then all aux locals, then all main globals and finally all aux globals. + And skip the auxiliary table zero undefined entry. */ + GElf_Word shndx; + int tndx = ndx; + int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0; + Elf *elf; + Elf_Data *symdata; + Elf_Data *symxndxdata; + Elf_Data *symstrdata; + if (mod->aux_symdata == NULL + || ndx < mod->first_global) + { + /* main symbol table (locals). */ + tndx = ndx; + elf = mod->symfile->elf; + symdata = mod->symdata; + symxndxdata = mod->symxndxdata; + symstrdata = mod->symstrdata; + } + else if (ndx < mod->first_global + mod->aux_first_global - skip_aux_zero) + { + /* aux symbol table (locals). */ + tndx = ndx - mod->first_global + skip_aux_zero; + elf = mod->aux_sym.elf; + symdata = mod->aux_symdata; + symxndxdata = mod->aux_symxndxdata; + symstrdata = mod->aux_symstrdata; + } + else if ((size_t) ndx < mod->syments + mod->aux_first_global - skip_aux_zero) + { + /* main symbol table (globals). */ + tndx = ndx - mod->aux_first_global + skip_aux_zero; + elf = mod->symfile->elf; + symdata = mod->symdata; + symxndxdata = mod->symxndxdata; + symstrdata = mod->symstrdata; + } + else + { + /* aux symbol table (globals). */ + tndx = ndx - mod->syments + skip_aux_zero; + elf = mod->aux_sym.elf; + symdata = mod->aux_symdata; + symxndxdata = mod->aux_symxndxdata; + symstrdata = mod->aux_symstrdata; + } + sym = gelf_getsymshndx (symdata, symxndxdata, tndx, sym, &shndx); + + if (unlikely (sym == NULL)) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return NULL; + } + + if (sym->st_shndx != SHN_XINDEX) + shndx = sym->st_shndx; + + /* Figure out whether this symbol points into an SHF_ALLOC section. */ + bool alloc = true; + if ((shndxp != NULL || mod->e_type != ET_REL) + && (sym->st_shndx == SHN_XINDEX + || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF))) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, shndx), &shdr_mem); + alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC); + } + + /* In case of an value in an allocated section the main Elf Ebl + might know where the real value is (e.g. for function + descriptors). */ + + char *ident; + GElf_Addr st_value = sym->st_value & ebl_func_addr_mask (mod->ebl); + *resolved = false; + if (! adjust_st_value && mod->e_type != ET_REL && alloc + && (GELF_ST_TYPE (sym->st_info) == STT_FUNC + || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC + && (ident = elf_getident (elf, NULL)) != NULL + && ident[EI_OSABI] == ELFOSABI_LINUX))) + { + if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR)) + { + if (elf != mod->main.elf) + { + st_value = dwfl_adjusted_st_value (mod, elf, st_value); + st_value = dwfl_deadjust_st_value (mod, mod->main.elf, st_value); + } + + *resolved = ebl_resolve_sym_value (mod->ebl, &st_value); + if (! *resolved) + st_value = sym->st_value; + } + } + + if (shndxp != NULL) + /* Yield -1 in case of a non-SHF_ALLOC section. */ + *shndxp = alloc ? shndx : (GElf_Word) -1; + + switch (sym->st_shndx) + { + case SHN_ABS: /* XXX sometimes should use bias?? */ + case SHN_UNDEF: + case SHN_COMMON: + break; + + default: + if (mod->e_type == ET_REL) + { + /* In an ET_REL file, the symbol table values are relative + to the section, not to the module's load base. */ + size_t symshstrndx = SHN_UNDEF; + Dwfl_Error result = __libdwfl_relocate_value (mod, elf, + &symshstrndx, + shndx, &st_value); + if (unlikely (result != DWFL_E_NOERROR)) + { + __libdwfl_seterrno (result); + return NULL; + } + } + else if (alloc) + /* Apply the bias to the symbol value. */ + st_value = dwfl_adjusted_st_value (mod, + *resolved ? mod->main.elf : elf, + st_value); + break; + } + + if (adjust_st_value) + sym->st_value = st_value; + + if (addr != NULL) + *addr = st_value; + + if (unlikely (sym->st_name >= symstrdata->d_size)) + { + __libdwfl_seterrno (DWFL_E_BADSTROFF); + return NULL; + } + if (elfp) + *elfp = elf; + if (biasp) + *biasp = dwfl_adjusted_st_value (mod, elf, 0); + return (const char *) symstrdata->d_buf + sym->st_name; +} + +const char * +dwfl_module_getsym_info (Dwfl_Module *mod, int ndx, + GElf_Sym *sym, GElf_Addr *addr, + GElf_Word *shndxp, + Elf **elfp, Dwarf_Addr *bias) +{ + bool resolved; + return __libdwfl_getsym (mod, ndx, sym, addr, shndxp, elfp, bias, + &resolved, false); +} +INTDEF (dwfl_module_getsym_info) + +const char * +dwfl_module_getsym (Dwfl_Module *mod, int ndx, + GElf_Sym *sym, GElf_Word *shndxp) +{ + bool resolved; + return __libdwfl_getsym (mod, ndx, sym, NULL, shndxp, NULL, NULL, + &resolved, true); +} +INTDEF (dwfl_module_getsym) diff --git a/libdwfl/dwfl_module_info.c b/libdwfl/dwfl_module_info.c new file mode 100644 index 00000000..af1faab4 --- /dev/null +++ b/libdwfl/dwfl_module_info.c @@ -0,0 +1,65 @@ +/* Return information about a module. + Copyright (C) 2005-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +const char * +dwfl_module_info (Dwfl_Module *mod, void ***userdata, + Dwarf_Addr *start, Dwarf_Addr *end, + Dwarf_Addr *dwbias, Dwarf_Addr *symbias, + const char **mainfile, const char **debugfile) +{ + if (mod == NULL) + return NULL; + + if (userdata) + *userdata = &mod->userdata; + if (start) + *start = mod->low_addr; + if (end) + *end = mod->high_addr; + + if (dwbias) + *dwbias = (mod->debug.elf == NULL ? (Dwarf_Addr) -1 + : dwfl_adjusted_dwarf_addr (mod, 0)); + if (symbias) + *symbias = (mod->symfile == NULL ? (Dwarf_Addr) -1 + : dwfl_adjusted_st_value (mod, mod->symfile->elf, 0)); + + if (mainfile) + *mainfile = mod->main.name; + + if (debugfile) + *debugfile = mod->debug.name; + + return mod->name; +} diff --git a/libdwfl/dwfl_module_nextcu.c b/libdwfl/dwfl_module_nextcu.c new file mode 100644 index 00000000..32ee6bc2 --- /dev/null +++ b/libdwfl/dwfl_module_nextcu.c @@ -0,0 +1,48 @@ +/* Iterate through DWARF compilation units in a module. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwarf_Die * +dwfl_module_nextcu (Dwfl_Module *mod, Dwarf_Die *lastcu, Dwarf_Addr *bias) +{ + if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL) + return NULL; + + struct dwfl_cu *cu; + Dwfl_Error error = __libdwfl_nextcu (mod, (struct dwfl_cu *) lastcu, &cu); + if (likely (error == DWFL_E_NOERROR)) + return &cu->die; /* Same as a cast, so ok for null too. */ + + __libdwfl_seterrno (error); + return NULL; +} diff --git a/libdwfl/dwfl_module_register_names.c b/libdwfl/dwfl_module_register_names.c new file mode 100644 index 00000000..9ea09371 --- /dev/null +++ b/libdwfl/dwfl_module_register_names.c @@ -0,0 +1,82 @@ +/* Enumerate DWARF register numbers and their names. + Copyright (C) 2005, 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + + +int +dwfl_module_register_names (Dwfl_Module *mod, + int (*func) (void *, int, const char *, + const char *, const char *, + int, int), + void *arg) +{ + if (unlikely (mod == NULL)) + return -1; + + if (unlikely (mod->ebl == NULL)) + { + Dwfl_Error error = __libdwfl_module_getebl (mod); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return -1; + } + } + + int nregs = ebl_register_info (mod->ebl, -1, NULL, 0, + NULL, NULL, NULL, NULL); + int result = 0; + for (int regno = 0; regno < nregs && likely (result == 0); ++regno) + { + char name[32]; + const char *setname = NULL; + const char *prefix = NULL; + int bits = -1; + int type = -1; + ssize_t len = ebl_register_info (mod->ebl, regno, name, sizeof name, + &prefix, &setname, &bits, &type); + if (unlikely (len < 0)) + { + __libdwfl_seterrno (DWFL_E_LIBEBL); + result = -1; + break; + } + if (likely (len > 0)) + { + assert (len > 1); /* Backend should never yield "". */ + result = (*func) (arg, regno, setname, prefix, name, bits, type); + } + } + + return result; +} diff --git a/libdwfl/dwfl_module_report_build_id.c b/libdwfl/dwfl_module_report_build_id.c new file mode 100644 index 00000000..31e17c86 --- /dev/null +++ b/libdwfl/dwfl_module_report_build_id.c @@ -0,0 +1,84 @@ +/* Report build ID information for a module. + Copyright (C) 2007, 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +// XXX vs report changed module: punting old file +int +dwfl_module_report_build_id (Dwfl_Module *mod, + const unsigned char *bits, size_t len, + GElf_Addr vaddr) +{ + if (mod == NULL) + return -1; + + if (mod->main.elf != NULL) + { + /* Once we know about a file, we won't take any lies about + its contents. The only permissible call is a no-op. */ + + if ((size_t) mod->build_id_len == len + && (mod->build_id_vaddr == vaddr || vaddr == 0) + && !memcmp (bits, mod->build_id_bits, len)) + return 0; + + __libdwfl_seterrno (DWFL_E_ALREADY_ELF); + return -1; + } + + if (vaddr != 0 && (vaddr < mod->low_addr || vaddr + len > mod->high_addr)) + { + __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE); + return -1; + } + + void *copy = NULL; + if (len > 0) + { + copy = malloc (len); + if (unlikely (copy == NULL)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + memcpy (copy, bits, len); + } + + free (mod->build_id_bits); + + mod->build_id_bits = copy; + mod->build_id_len = len; + mod->build_id_vaddr = vaddr; + + return 0; +} +INTDEF (dwfl_module_report_build_id) diff --git a/libdwfl/dwfl_module_return_value_location.c b/libdwfl/dwfl_module_return_value_location.c new file mode 100644 index 00000000..ff6f56f8 --- /dev/null +++ b/libdwfl/dwfl_module_return_value_location.c @@ -0,0 +1,66 @@ +/* Return location expression to find return value given a function type DIE. + Copyright (C) 2005, 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + + +int +dwfl_module_return_value_location (Dwfl_Module *mod, Dwarf_Die *functypedie, + const Dwarf_Op **locops) +{ + if (mod == NULL) + return -1; + + if (mod->ebl == NULL) + { + Dwfl_Error error = __libdwfl_module_getebl (mod); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return -1; + } + } + + int nops = ebl_return_value_location (mod->ebl, functypedie, locops); + if (unlikely (nops < 0)) + { + if (nops == -1) + __libdwfl_seterrno (DWFL_E_LIBDW); + else if (nops == -2) + __libdwfl_seterrno (DWFL_E_WEIRD_TYPE); + else + __libdwfl_seterrno (DWFL_E_LIBEBL); + nops = -1; + } + + return nops; +} diff --git a/libdwfl/dwfl_nextcu.c b/libdwfl/dwfl_nextcu.c new file mode 100644 index 00000000..64bd5219 --- /dev/null +++ b/libdwfl/dwfl_nextcu.c @@ -0,0 +1,86 @@ +/* Iterate through DWARF compilation units across all modules. + Copyright (C) 2005-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwarf_Die * +dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias) +{ + if (dwfl == NULL) + return NULL; + + struct dwfl_cu *cu = (struct dwfl_cu *) lastcu; + Dwfl_Module *mod; + + if (cu == NULL) + { + mod = dwfl->modulelist; + goto nextmod; + } + else + mod = cu->mod; + + Dwfl_Error error; + do + { + error = __libdwfl_nextcu (mod, cu, &cu); + if (error != DWFL_E_NOERROR) + break; + + if (cu != NULL) + { + *bias = dwfl_adjusted_dwarf_addr (mod, 0); + return &cu->die; + } + + do + { + mod = mod->next; + + nextmod: + if (mod == NULL) + return NULL; + + if (mod->dwerr == DWFL_E_NOERROR + && (mod->dw != NULL + || INTUSE(dwfl_module_getdwarf) (mod, bias) != NULL)) + break; + } + while (mod->dwerr == DWFL_E_NO_DWARF); + error = mod->dwerr; + } + while (error == DWFL_E_NOERROR); + + __libdwfl_seterrno (error); + return NULL; +} +INTDEF (dwfl_nextcu) diff --git a/libdwfl/dwfl_onesrcline.c b/libdwfl/dwfl_onesrcline.c new file mode 100644 index 00000000..b1e70555 --- /dev/null +++ b/libdwfl/dwfl_onesrcline.c @@ -0,0 +1,60 @@ +/* Return one of the sources lines of a CU. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +Dwfl_Line * +dwfl_onesrcline (Dwarf_Die *cudie, size_t idx) +{ + struct dwfl_cu *cu = (struct dwfl_cu *) cudie; + + if (cudie == NULL) + return NULL; + + if (cu->lines == NULL) + { + Dwfl_Error error = __libdwfl_cu_getsrclines (cu); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return NULL; + } + } + + if (idx >= cu->die.cu->lines->nlines) + { + __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_LINE_IDX)); + return NULL; + } + + return &cu->lines->idx[idx]; +} diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c new file mode 100644 index 00000000..9da86698 --- /dev/null +++ b/libdwfl/dwfl_report_elf.c @@ -0,0 +1,342 @@ +/* Report a module to libdwfl based on ELF program headers. + Copyright (C) 2005-2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include + + +/* We start every ET_REL module at a moderately aligned boundary. + This keeps the low addresses easy to read compared to a layout + starting at 0 (as when using -e). It also makes it unlikely + that a middle section will have a larger alignment and require + rejiggering (see below). */ +#define REL_MIN_ALIGN ((GElf_Xword) 0x100) + +bool +internal_function +__libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr, + bool sanity, GElf_Addr *vaddrp, + GElf_Addr *address_syncp, GElf_Addr *startp, + GElf_Addr *endp, GElf_Addr *biasp, + GElf_Half *e_typep) +{ + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + elf_error: + __libdwfl_seterrno (DWFL_E_LIBELF); + return false; + } + + GElf_Addr vaddr = 0; + GElf_Addr address_sync = 0; + GElf_Addr start = 0, end = 0, bias = 0; + switch (ehdr->e_type) + { + case ET_REL: + /* For a relocatable object, we do an arbitrary section layout. + By updating the section header in place, we leave the layout + information to be found by relocation. */ + + start = end = base = (base + REL_MIN_ALIGN - 1) & -REL_MIN_ALIGN; + + bool first = true; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + goto elf_error; + + if (shdr->sh_flags & SHF_ALLOC) + { + const GElf_Xword align = shdr->sh_addralign ?: 1; + const GElf_Addr next = (end + align - 1) & -align; + if (shdr->sh_addr == 0 + /* Once we've started doing layout we have to do it all, + unless we just laid out the first section at 0 when + it already was at 0. */ + || (bias == 0 && end > start && end != next)) + { + shdr->sh_addr = next; + if (end == base) + /* This is the first section assigned a location. + Use its aligned address as the module's base. */ + start = base = shdr->sh_addr; + else if (unlikely (base & (align - 1))) + { + /* If BASE has less than the maximum alignment of + any section, we eat more than the optimal amount + of padding and so make the module's apparent + size come out larger than it would when placed + at zero. So reset the layout with a better base. */ + + start = end = base = (base + align - 1) & -align; + Elf_Scn *prev_scn = NULL; + do + { + prev_scn = elf_nextscn (elf, prev_scn); + GElf_Shdr prev_shdr_mem; + GElf_Shdr *prev_shdr = gelf_getshdr (prev_scn, + &prev_shdr_mem); + if (unlikely (prev_shdr == NULL)) + goto elf_error; + if (prev_shdr->sh_flags & SHF_ALLOC) + { + const GElf_Xword prev_align + = prev_shdr->sh_addralign ?: 1; + + prev_shdr->sh_addr + = (end + prev_align - 1) & -prev_align; + end = prev_shdr->sh_addr + prev_shdr->sh_size; + + if (unlikely (! gelf_update_shdr (prev_scn, + prev_shdr))) + goto elf_error; + } + } + while (prev_scn != scn); + continue; + } + + end = shdr->sh_addr + shdr->sh_size; + if (likely (shdr->sh_addr != 0) + && unlikely (! gelf_update_shdr (scn, shdr))) + goto elf_error; + } + else + { + /* The address is already assigned. Just track it. */ + if (first || end < shdr->sh_addr + shdr->sh_size) + end = shdr->sh_addr + shdr->sh_size; + if (first || bias > shdr->sh_addr) + /* This is the lowest address in the module. */ + bias = shdr->sh_addr; + + if ((shdr->sh_addr - bias + base) & (align - 1)) + /* This section winds up misaligned using BASE. + Adjust BASE upwards to make it congruent to + the lowest section address in the file modulo ALIGN. */ + base = (((base + align - 1) & -align) + + (bias & (align - 1))); + } + + first = false; + } + } + + if (bias != 0) + { + /* The section headers had nonzero sh_addr values. The layout + was already done. We've just collected the total span. + Now just compute the bias from the requested base. */ + start = base; + end = end - bias + start; + bias = start - bias; + } + break; + + /* Everything else has to have program headers. */ + + case ET_EXEC: + case ET_CORE: + /* An assigned base address is meaningless for these. */ + base = 0; + add_p_vaddr = true; + FALLTHROUGH; + case ET_DYN: + default:; + size_t phnum; + if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) + goto elf_error; + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem); + if (unlikely (ph == NULL)) + goto elf_error; + if (ph->p_type == PT_LOAD) + { + vaddr = ph->p_vaddr & -ph->p_align; + address_sync = ph->p_vaddr + ph->p_memsz; + break; + } + } + if (add_p_vaddr) + { + start = base + vaddr; + bias = base; + } + else + { + start = base; + bias = base - vaddr; + } + + for (size_t i = phnum; i-- > 0;) + { + GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem); + if (unlikely (ph == NULL)) + goto elf_error; + if (ph->p_type == PT_LOAD + && ph->p_vaddr + ph->p_memsz > 0) + { + end = bias + (ph->p_vaddr + ph->p_memsz); + break; + } + } + + if (end == 0 && sanity) + { + __libdwfl_seterrno (DWFL_E_NO_PHDR); + return false; + } + break; + } + if (vaddrp) + *vaddrp = vaddr; + if (address_syncp) + *address_syncp = address_sync; + if (startp) + *startp = start; + if (endp) + *endp = end; + if (biasp) + *biasp = bias; + if (e_typep) + *e_typep = ehdr->e_type; + return true; +} + +Dwfl_Module * +internal_function +__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, + int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr, + bool sanity) +{ + GElf_Addr vaddr, address_sync, start, end, bias; + GElf_Half e_type; + if (! __libdwfl_elf_address_range (elf, base, add_p_vaddr, sanity, &vaddr, + &address_sync, &start, &end, &bias, + &e_type)) + return NULL; + Dwfl_Module *m = INTUSE(dwfl_report_module) (dwfl, name, start, end); + if (m != NULL) + { + if (m->main.name == NULL) + { + m->main.name = strdup (file_name); + m->main.fd = fd; + } + else if ((fd >= 0 && m->main.fd != fd) + || strcmp (m->main.name, file_name)) + { + overlap: + m->gc = true; + __libdwfl_seterrno (DWFL_E_OVERLAP); + return NULL; + } + + /* Preinstall the open ELF handle for the module. */ + if (m->main.elf == NULL) + { + m->main.elf = elf; + m->main.vaddr = vaddr; + m->main.address_sync = address_sync; + m->main_bias = bias; + m->e_type = e_type; + } + else + { + elf_end (elf); + if (m->main_bias != bias + || m->main.vaddr != vaddr || m->main.address_sync != address_sync) + goto overlap; + } + } + return m; +} + +Dwfl_Module * +dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, + GElf_Addr base, bool add_p_vaddr) +{ + bool closefd = false; + if (fd < 0) + { + closefd = true; + fd = open (file_name, O_RDONLY); + if (fd < 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return NULL; + } + } + + Elf *elf; + Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, false); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return NULL; + } + + Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, + fd, elf, base, add_p_vaddr, true); + if (mod == NULL) + { + elf_end (elf); + if (closefd) + close (fd); + } + + return mod; +} +INTDEF (dwfl_report_elf) +NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156) + +#ifdef SYMBOL_VERSIONING +Dwfl_Module * + _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base); +COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr) + +Dwfl_Module * +_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base) +{ + return dwfl_report_elf (dwfl, name, file_name, fd, base, true); +} +#endif diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c new file mode 100644 index 00000000..ee9cfa2e --- /dev/null +++ b/libdwfl/dwfl_segment_report_module.c @@ -0,0 +1,985 @@ +/* Sniff out modules from ELF headers visible in memory segments. + Copyright (C) 2008-2012, 2014, 2015, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include "../libelf/libelfP.h" /* For NOTE_ALIGN4 and NOTE_ALIGN8. */ +#undef _ +#include "libdwflP.h" +#include "common.h" + +#include +#include +#include +#include +#include +#include + +#include + + +/* A good size for the initial read from memory, if it's not too costly. + This more than covers the phdrs and note segment in the average 64-bit + binary. */ + +#define INITIAL_READ 1024 + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define MY_ELFDATA ELFDATA2LSB +#else +# define MY_ELFDATA ELFDATA2MSB +#endif + +struct elf_build_id +{ + void *memory; + size_t len; + GElf_Addr vaddr; +}; + +struct read_state +{ + Dwfl *dwfl; + Dwfl_Memory_Callback *memory_callback; + void *memory_callback_arg; + void **buffer; + size_t *buffer_available; +}; + +/* Return user segment index closest to ADDR but not above it. + If NEXT, return the closest to ADDR but not below it. */ +static int +addr_segndx (Dwfl *dwfl, size_t segment, GElf_Addr addr, bool next) +{ + int ndx = -1; + do + { + if (dwfl->lookup_segndx[segment] >= 0) + ndx = dwfl->lookup_segndx[segment]; + if (++segment >= dwfl->lookup_elts - 1) + return next ? ndx + 1 : ndx; + } + while (dwfl->lookup_addr[segment] < addr); + + if (next) + { + while (dwfl->lookup_segndx[segment] < 0) + if (++segment >= dwfl->lookup_elts - 1) + return ndx + 1; + ndx = dwfl->lookup_segndx[segment]; + } + + return ndx; +} + +/* Return whether there is SZ bytes available at PTR till END. */ + +static bool +buf_has_data (const void *ptr, const void *end, size_t sz) +{ + return ptr < end && (size_t) (end - ptr) >= sz; +} + +/* Read SZ bytes into *RETP from *PTRP (limited by END) in format EI_DATA. + Function comes from src/readelf.c . */ + +static bool +buf_read_ulong (unsigned char ei_data, size_t sz, + const void **ptrp, const void *end, uint64_t *retp) +{ + if (! buf_has_data (*ptrp, end, sz)) + return false; + + union + { + uint64_t u64; + uint32_t u32; + } u; + + memcpy (&u, *ptrp, sz); + (*ptrp) += sz; + + if (retp == NULL) + return true; + + if (MY_ELFDATA != ei_data) + { + if (sz == 4) + CONVERT (u.u32); + else + CONVERT (u.u64); + } + if (sz == 4) + *retp = u.u32; + else + *retp = u.u64; + return true; +} + +/* Try to find matching entry for module from address MODULE_START to + MODULE_END in NT_FILE note located at NOTE_FILE of NOTE_FILE_SIZE + bytes in format EI_CLASS and EI_DATA. */ + +static const char * +handle_file_note (GElf_Addr module_start, GElf_Addr module_end, + unsigned char ei_class, unsigned char ei_data, + const void *note_file, size_t note_file_size) +{ + if (note_file == NULL) + return NULL; + + size_t sz; + switch (ei_class) + { + case ELFCLASS32: + sz = 4; + break; + case ELFCLASS64: + sz = 8; + break; + default: + return NULL; + } + + const void *ptr = note_file; + const void *end = note_file + note_file_size; + uint64_t count; + if (! buf_read_ulong (ei_data, sz, &ptr, end, &count)) + return NULL; + if (! buf_read_ulong (ei_data, sz, &ptr, end, NULL)) // page_size + return NULL; + + uint64_t maxcount = (size_t) (end - ptr) / (3 * sz); + if (count > maxcount) + return NULL; + + /* Where file names are stored. */ + const char *fptr = ptr + 3 * count * sz; + + ssize_t firstix = -1; + ssize_t lastix = -1; + for (size_t mix = 0; mix < count; mix++) + { + uint64_t mstart, mend, moffset; + if (! buf_read_ulong (ei_data, sz, &ptr, fptr, &mstart) + || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &mend) + || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &moffset)) + return NULL; + if (mstart == module_start && moffset == 0) + firstix = lastix = mix; + if (firstix != -1 && mstart < module_end) + lastix = mix; + if (mend >= module_end) + break; + } + if (firstix == -1) + return NULL; + + const char *retval = NULL; + for (ssize_t mix = 0; mix <= lastix; mix++) + { + const char *fnext = memchr (fptr, 0, (const char *) end - fptr); + if (fnext == NULL) + return NULL; + if (mix == firstix) + retval = fptr; + if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0) + return NULL; + fptr = fnext + 1; + } + return retval; +} + +/* Return true iff we are certain ELF cannot match BUILD_ID of + BUILD_ID_LEN bytes. Pass DISK_FILE_HAS_BUILD_ID as false if it is + certain ELF does not contain build-id (it is only a performance hit + to pass it always as true). */ + +static bool +invalid_elf (Elf *elf, bool disk_file_has_build_id, + struct elf_build_id *build_id) +{ + if (! disk_file_has_build_id && build_id->len > 0) + { + /* Module found in segments with build-id is more reliable + than a module found via DT_DEBUG on disk without any + build-id. */ + return true; + } + if (disk_file_has_build_id && build_id->len > 0) + { + const void *elf_build_id; + ssize_t elf_build_id_len; + + /* If there is a build id in the elf file, check it. */ + elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id); + if (elf_build_id_len > 0) + { + if (build_id->len != (size_t) elf_build_id_len + || memcmp (build_id->memory, elf_build_id, build_id->len) != 0) + return true; + } + } + return false; +} + +static void +finish_portion (struct read_state *read_state, + void **data, size_t *data_size) +{ + if (*data_size != 0 && *data != NULL) + (*read_state->memory_callback) (read_state->dwfl, -1, data, data_size, + 0, 0, read_state->memory_callback_arg); +} + +static inline bool +read_portion (struct read_state *read_state, + void **data, size_t *data_size, + GElf_Addr start, size_t segment, + GElf_Addr vaddr, size_t filesz) +{ + /* Check whether we will have to read the segment data, or if it + can be returned from the existing buffer. */ + if (filesz > *read_state->buffer_available + || vaddr - start > *read_state->buffer_available - filesz + /* If we're in string mode, then don't consider the buffer we have + sufficient unless it contains the terminator of the string. */ + || (filesz == 0 && memchr (vaddr - start + *read_state->buffer, '\0', + (*read_state->buffer_available + - (vaddr - start))) == NULL)) + { + *data = NULL; + *data_size = filesz; + return !(*read_state->memory_callback) (read_state->dwfl, + addr_segndx (read_state->dwfl, + segment, vaddr, + false), + data, data_size, vaddr, filesz, + read_state->memory_callback_arg); + } + + /* We already have this whole note segment from our initial read. */ + *data = vaddr - start + (*read_state->buffer); + *data_size = 0; + return false; +} + +int +dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg, + Dwfl_Module_Callback *read_eagerly, + void *read_eagerly_arg, + const void *note_file, size_t note_file_size, + const struct r_debug_info *r_debug_info) +{ + size_t segment = ndx; + struct read_state read_state; + + if (segment >= dwfl->lookup_elts) + segment = dwfl->lookup_elts - 1; + + while (segment > 0 + && (dwfl->lookup_segndx[segment] > ndx + || dwfl->lookup_segndx[segment] == -1)) + --segment; + + while (dwfl->lookup_segndx[segment] < ndx) + if (++segment == dwfl->lookup_elts) + return 0; + + GElf_Addr start = dwfl->lookup_addr[segment]; + + /* First read in the file header and check its sanity. */ + + void *buffer = NULL; + size_t buffer_available = INITIAL_READ; + Elf *elf = NULL; + int fd = -1; + + read_state.dwfl = dwfl; + read_state.memory_callback = memory_callback; + read_state.memory_callback_arg = memory_callback_arg; + read_state.buffer = &buffer; + read_state.buffer_available = &buffer_available; + + /* We might have to reserve some memory for the phdrs. Set to NULL + here so we can always safely free it. */ + void *phdrsp = NULL; + + if (! (*memory_callback) (dwfl, ndx, &buffer, &buffer_available, + start, sizeof (Elf64_Ehdr), memory_callback_arg) + || memcmp (buffer, ELFMAG, SELFMAG) != 0) + goto out; + + /* Extract the information we need from the file header. */ + const unsigned char *e_ident; + unsigned char ei_class; + unsigned char ei_data; + uint16_t e_type; + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr; + GElf_Off phoff; + uint_fast16_t phnum; + uint_fast16_t phentsize; + GElf_Off shdrs_end; + Elf_Data xlatefrom = + { + .d_type = ELF_T_EHDR, + .d_buf = (void *) buffer, + .d_version = EV_CURRENT, + }; + Elf_Data xlateto = + { + .d_type = ELF_T_EHDR, + .d_buf = &ehdr, + .d_size = sizeof ehdr, + .d_version = EV_CURRENT, + }; + e_ident = ((const unsigned char *) buffer); + ei_class = e_ident[EI_CLASS]; + ei_data = e_ident[EI_DATA]; + switch (ei_class) + { + case ELFCLASS32: + xlatefrom.d_size = sizeof (Elf32_Ehdr); + if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) + goto out; + e_type = ehdr.e32.e_type; + phoff = ehdr.e32.e_phoff; + phnum = ehdr.e32.e_phnum; + phentsize = ehdr.e32.e_phentsize; + if (phentsize != sizeof (Elf32_Phdr)) + goto out; + /* NOTE if the number of sections is > 0xff00 then e_shnum + is zero and the actual number would come from the section + zero sh_size field. We ignore this here because getting shdrs + is just a nice bonus (see below in the type == PT_LOAD case + where we trim the last segment). */ + shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize; + break; + + case ELFCLASS64: + xlatefrom.d_size = sizeof (Elf64_Ehdr); + if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) + goto out; + e_type = ehdr.e64.e_type; + phoff = ehdr.e64.e_phoff; + phnum = ehdr.e64.e_phnum; + phentsize = ehdr.e64.e_phentsize; + if (phentsize != sizeof (Elf64_Phdr)) + goto out; + /* See the NOTE above for shdrs_end and ehdr.e32.e_shnum. */ + shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize; + break; + + default: + goto out; + } + + /* The file header tells where to find the program headers. + These are what we need to find the boundaries of the module. + Without them, we don't have a module to report. */ + + if (phnum == 0) + goto out; + + xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR; + xlatefrom.d_size = phnum * phentsize; + + void *ph_buffer = NULL; + size_t ph_buffer_size = 0; + if (read_portion (&read_state, &ph_buffer, &ph_buffer_size, + start, segment, + start + phoff, xlatefrom.d_size)) + goto out; + + /* ph_buffer_size will be zero if we got everything from the initial + buffer, otherwise it will be the size of the new buffer that + could be read. */ + if (ph_buffer_size != 0) + xlatefrom.d_size = ph_buffer_size; + + xlatefrom.d_buf = ph_buffer; + + bool class32 = ei_class == ELFCLASS32; + size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); + if (unlikely (phnum > SIZE_MAX / phdr_size)) + goto out; + const size_t phdrsp_bytes = phnum * phdr_size; + phdrsp = malloc (phdrsp_bytes); + if (unlikely (phdrsp == NULL)) + goto out; + + xlateto.d_buf = phdrsp; + xlateto.d_size = phdrsp_bytes; + + /* Track the bounds of the file visible in memory. */ + GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */ + GElf_Off file_end = 0; /* Rounded up to effective page size. */ + GElf_Off contiguous = 0; /* Visible as contiguous file from START. */ + GElf_Off total_filesz = 0; /* Total size of data to read. */ + + /* Collect the bias between START and the containing PT_LOAD's p_vaddr. */ + GElf_Addr bias = 0; + bool found_bias = false; + + /* Collect the unbiased bounds of the module here. */ + GElf_Addr module_start = -1l; + GElf_Addr module_end = 0; + GElf_Addr module_address_sync = 0; + + /* If we see PT_DYNAMIC, record it here. */ + GElf_Addr dyn_vaddr = 0; + GElf_Xword dyn_filesz = 0; + + /* Collect the build ID bits here. */ + struct elf_build_id build_id; + build_id.memory = NULL; + build_id.len = 0; + build_id.vaddr =0; + + Elf32_Phdr *p32 = phdrsp; + Elf64_Phdr *p64 = phdrsp; + if ((ei_class == ELFCLASS32 + && elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) + || (ei_class == ELFCLASS64 + && elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)) + { + found_bias = false; /* Trigger error check */ + } + else + { + /* Consider each of the program headers we've read from the image. */ + for (uint_fast16_t i = 0; i < phnum; ++i) + { + bool is32 = (ei_class == ELFCLASS32); + GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type; + GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr; + GElf_Xword memsz = is32 ? p32[i].p_memsz : p64[i].p_memsz; + GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset; + GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz; + GElf_Xword align = is32 ? p32[i].p_align : p64[i].p_align; + + if (type == PT_DYNAMIC) + { + dyn_vaddr = vaddr; + dyn_filesz = filesz; + } + else if (type == PT_NOTE) + { + /* If we have already seen a build ID, we don't care any more. */ + if (build_id.memory != NULL || filesz == 0) + continue; /* Next header */ + + /* We calculate from the p_offset of the note segment, + because we don't yet know the bias for its p_vaddr. */ + const GElf_Addr note_vaddr = start + offset; + void *data; + size_t data_size; + if (read_portion (&read_state, &data, &data_size, + start, segment, note_vaddr, filesz)) + continue; /* Next header */ + + /* data_size will be zero if we got everything from the initial + buffer, otherwise it will be the size of the new buffer that + could be read. */ + if (data_size != 0) + filesz = data_size; + + assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); + + void *notes; + if (ei_data == MY_ELFDATA) + notes = data; + else + { + const unsigned int xencoding = ehdr.e32.e_ident[EI_DATA]; + + notes = malloc (filesz); + if (unlikely (notes == NULL)) + continue; /* Next header */ + xlatefrom.d_type = xlateto.d_type = (align == 8 + ? ELF_T_NHDR8 + : ELF_T_NHDR); + xlatefrom.d_buf = (void *) data; + xlatefrom.d_size = filesz; + xlateto.d_buf = notes; + xlateto.d_size = filesz; + if (elf32_xlatetom (&xlateto, &xlatefrom, xencoding) == NULL) + { + free (notes); + finish_portion (&read_state, &data, &data_size); + continue; + } + } + + const GElf_Nhdr *nh = notes; + size_t len = 0; + while (filesz > len + sizeof (*nh)) + { + const void *note_name; + const void *note_desc; + + len += sizeof (*nh); + note_name = notes + len; + + len += nh->n_namesz; + len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len); + note_desc = notes + len; + + if (unlikely (filesz < len + nh->n_descsz)) + break; + + if (nh->n_type == NT_GNU_BUILD_ID + && nh->n_descsz > 0 + && nh->n_namesz == sizeof "GNU" + && !memcmp (note_name, "GNU", sizeof "GNU")) + { + build_id.vaddr = (note_desc + - (const void *) notes + + note_vaddr); + build_id.len = nh->n_descsz; + build_id.memory = malloc (build_id.len); + if (likely (build_id.memory != NULL)) + memcpy (build_id.memory, note_desc, build_id.len); + break; + } + + len += nh->n_descsz; + len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len); + nh = (void *) notes + len; + } + + if (notes != data) + free (notes); + finish_portion (&read_state, &data, &data_size); + } + else if (type == PT_LOAD) + { + align = (dwfl->segment_align > 1 + ? dwfl->segment_align : (align ?: 1)); + + GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align; + GElf_Addr filesz_vaddr = (filesz < memsz + ? vaddr + filesz : vaddr_end); + GElf_Off filesz_offset = filesz_vaddr - vaddr + offset; + + if (file_trimmed_end < offset + filesz) + { + file_trimmed_end = offset + filesz; + + /* Trim the last segment so we don't bother with zeros + in the last page that are off the end of the file. + However, if the extra bit in that page includes the + section headers, keep them. */ + if (shdrs_end <= filesz_offset + && shdrs_end > file_trimmed_end) + { + filesz += shdrs_end - file_trimmed_end; + file_trimmed_end = shdrs_end; + } + } + + total_filesz += filesz; + + if (file_end < filesz_offset) + { + file_end = filesz_offset; + if (filesz_vaddr - start == filesz_offset) + contiguous = file_end; + } + + if (!found_bias && (offset & -align) == 0 + && likely (filesz_offset >= phoff + phnum * phentsize)) + { + bias = start - vaddr; + found_bias = true; + } + + if ((vaddr & -align) < module_start) + { + module_start = vaddr & -align; + module_address_sync = vaddr + memsz; + } + + if (module_end < vaddr_end) + module_end = vaddr_end; + } + } + } + + finish_portion (&read_state, &ph_buffer, &ph_buffer_size); + + /* We must have seen the segment covering offset 0, or else the ELF + header we read at START was not produced by these program headers. */ + if (unlikely (!found_bias)) + { + free (build_id.memory); + goto out; + } + + /* Now we know enough to report a module for sure: its bounds. */ + module_start += bias; + module_end += bias; + + dyn_vaddr += bias; + + /* NAME found from link map has precedence over DT_SONAME possibly read + below. */ + bool name_is_final = false; + + /* Try to match up DYN_VADDR against L_LD as found in link map. + Segments sniffing may guess invalid address as the first read-only memory + mapping may not be dumped to the core file (if ELF headers are not dumped) + and the ELF header is dumped first with the read/write mapping of the same + file at higher addresses. */ + if (r_debug_info != NULL) + for (const struct r_debug_info_module *module = r_debug_info->module; + module != NULL; module = module->next) + if (module_start <= module->l_ld && module->l_ld < module_end) + { + /* L_LD read from link map must be right while DYN_VADDR is unsafe. + Therefore subtract DYN_VADDR and add L_LD to get a possibly + corrective displacement for all addresses computed so far. */ + GElf_Addr fixup = module->l_ld - dyn_vaddr; + if ((fixup & (dwfl->segment_align - 1)) == 0 + && module_start + fixup <= module->l_ld + && module->l_ld < module_end + fixup) + { + module_start += fixup; + module_end += fixup; + dyn_vaddr += fixup; + bias += fixup; + if (module->name[0] != '\0') + { + name = basename (module->name); + name_is_final = true; + } + break; + } + } + + if (r_debug_info != NULL) + { + bool skip_this_module = false; + for (struct r_debug_info_module *module = r_debug_info->module; + module != NULL; module = module->next) + if ((module_end > module->start && module_start < module->end) + || dyn_vaddr == module->l_ld) + { + if (module->elf != NULL + && invalid_elf (module->elf, module->disk_file_has_build_id, + &build_id)) + { + elf_end (module->elf); + close (module->fd); + module->elf = NULL; + module->fd = -1; + } + if (module->elf != NULL) + { + /* Ignore this found module if it would conflict in address + space with any already existing module of DWFL. */ + skip_this_module = true; + } + } + if (skip_this_module) + { + free (build_id.memory); + goto out; + } + } + + const char *file_note_name = handle_file_note (module_start, module_end, + ei_class, ei_data, + note_file, note_file_size); + if (file_note_name) + { + name = file_note_name; + name_is_final = true; + bool invalid = false; + fd = open (name, O_RDONLY); + if (fd >= 0) + { + Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false); + if (error == DWFL_E_NOERROR) + invalid = invalid_elf (elf, true /* disk_file_has_build_id */, + &build_id); + } + if (invalid) + { + /* The file was there, but the build_id didn't match. We + still want to report the module, but need to get the ELF + some other way if possible. */ + close (fd); + fd = -1; + elf_end (elf); + elf = NULL; + } + } + + /* Our return value now says to skip the segments contained + within the module. */ + ndx = addr_segndx (dwfl, segment, module_end, true); + + /* Examine its .dynamic section to get more interesting details. + If it has DT_SONAME, we'll use that as the module name. + If it has a DT_DEBUG, then it's actually a PIE rather than a DSO. + We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME, + and they also tell us the essential portion of the file + for fetching symbols. */ + GElf_Addr soname_stroff = 0; + GElf_Addr dynstr_vaddr = 0; + GElf_Xword dynstrsz = 0; + bool execlike = false; + const size_t dyn_entsize = (ei_class == ELFCLASS32 + ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn)); + void *dyn_data = NULL; + size_t dyn_data_size = 0; + if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0 + && ! read_portion (&read_state, &dyn_data, &dyn_data_size, + start, segment, dyn_vaddr, dyn_filesz)) + { + /* dyn_data_size will be zero if we got everything from the initial + buffer, otherwise it will be the size of the new buffer that + could be read. */ + if (dyn_data_size != 0) + dyn_filesz = dyn_data_size; + + void *dyns = malloc (dyn_filesz); + Elf32_Dyn *d32 = dyns; + Elf64_Dyn *d64 = dyns; + if (unlikely (dyns == NULL)) + goto out; + + xlatefrom.d_type = xlateto.d_type = ELF_T_DYN; + xlatefrom.d_buf = (void *) dyn_data; + xlatefrom.d_size = dyn_filesz; + xlateto.d_buf = dyns; + xlateto.d_size = dyn_filesz; + + bool is32 = (ei_class == ELFCLASS32); + if ((is32 && elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL) + || (!is32 && elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)) + { + size_t n = (is32 + ? (dyn_filesz / sizeof (Elf32_Dyn)) + : (dyn_filesz / sizeof (Elf64_Dyn))); + for (size_t i = 0; i < n; ++i) + { + GElf_Sxword tag = is32 ? d32[i].d_tag : d64[i].d_tag; + GElf_Xword val = is32 ? d32[i].d_un.d_val : d64[i].d_un.d_val; + + if (tag == DT_DEBUG) + execlike = true; + else if (tag == DT_SONAME) + soname_stroff = val; + else if (tag == DT_STRTAB) + dynstr_vaddr = val; + else if (tag == DT_STRSZ) + dynstrsz = val; + else + continue; + + if (soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0) + break; + } + } + free (dyns); + } + finish_portion (&read_state, &dyn_data, &dyn_data_size); + + /* We'll use the name passed in or a stupid default if not DT_SONAME. */ + if (name == NULL) + name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]"; + + void *soname = NULL; + size_t soname_size = 0; + if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0) + { + /* We know the bounds of the .dynstr section. + + The DYNSTR_VADDR pointer comes from the .dynamic section + (DT_STRTAB, detected above). Ordinarily the dynamic linker + will have adjusted this pointer in place so it's now an + absolute address. But sometimes .dynamic is read-only (in + vDSOs and odd architectures), and sometimes the adjustment + just hasn't happened yet in the memory image we looked at. + So treat DYNSTR_VADDR as an absolute address if it falls + within the module bounds, or try applying the phdr bias + when that adjusts it to fall within the module bounds. */ + + if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end) + && dynstr_vaddr + bias >= module_start + && dynstr_vaddr + bias < module_end) + dynstr_vaddr += bias; + + if (unlikely (dynstr_vaddr + dynstrsz > module_end)) + dynstrsz = 0; + + /* Try to get the DT_SONAME string. */ + if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz + && ! read_portion (&read_state, &soname, &soname_size, + start, segment, + dynstr_vaddr + soname_stroff, 0)) + name = soname; + } + + /* Now that we have chosen the module's name and bounds, report it. + If we found a build ID, report that too. */ + + Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name, + module_start, module_end); + + // !execlike && ET_EXEC is PIE. + // execlike && !ET_EXEC is a static executable. + if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC)) + mod->is_executable = true; + + if (likely (mod != NULL) && build_id.memory != NULL + && unlikely (INTUSE(dwfl_module_report_build_id) (mod, + build_id.memory, + build_id.len, + build_id.vaddr))) + { + mod->gc = true; + mod = NULL; + } + + /* At this point we do not need BUILD_ID or NAME any more. + They have been copied. */ + free (build_id.memory); + finish_portion (&read_state, &soname, &soname_size); + + if (unlikely (mod == NULL)) + { + ndx = -1; + goto out; + } + + /* We have reported the module. Now let the caller decide whether we + should read the whole thing in right now. */ + + const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz + : buffer_available >= contiguous ? 0 + : contiguous - buffer_available); + const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0 + : dynstr_vaddr + dynstrsz - start); + const GElf_Off whole = MAX (file_trimmed_end, shdrs_end); + + if (elf == NULL + && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available, + cost, worthwhile, whole, contiguous, + read_eagerly_arg, &elf) + && elf == NULL) + { + /* The caller wants to read the whole file in right now, but hasn't + done it for us. Fill in a local image of the virtual file. */ + + void *contents = calloc (1, file_trimmed_end); + if (unlikely (contents == NULL)) + goto out; + + if (contiguous < file_trimmed_end) + { + /* We can't use the memory image verbatim as the file image. + So we'll be reading into a local image of the virtual file. */ + for (uint_fast16_t i = 0; i < phnum; ++i) + { + bool is32 = (ei_class == ELFCLASS32); + GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type; + + if (type != PT_LOAD) + continue; + + GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr; + GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset; + GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz; + + void *into = contents + offset; + size_t read_size = filesz; + (*memory_callback) (dwfl, addr_segndx (dwfl, segment, + vaddr + bias, false), + &into, &read_size, vaddr + bias, read_size, + memory_callback_arg); + } + } + else + { + /* The whole file sits contiguous in memory, + but the caller didn't want to just do it. */ + + const size_t have = MIN (buffer_available, file_trimmed_end); + memcpy (contents, buffer, have); + + if (have < file_trimmed_end) + { + void *into = contents + have; + size_t read_size = file_trimmed_end - have; + (*memory_callback) (dwfl, + addr_segndx (dwfl, segment, + start + have, false), + &into, &read_size, start + have, + read_size, memory_callback_arg); + } + } + + elf = elf_memory (contents, file_trimmed_end); + if (unlikely (elf == NULL)) + free (contents); + else + elf->flags |= ELF_F_MALLOCED; + } + + if (elf != NULL) + { + /* Install the file in the module. */ + mod->main.elf = elf; + mod->main.fd = fd; + elf = NULL; + fd = -1; + mod->main.vaddr = module_start - bias; + mod->main.address_sync = module_address_sync; + mod->main_bias = bias; + } + +out: + free (phdrsp); + if (buffer != NULL) + (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0, + memory_callback_arg); + + if (elf != NULL) + elf_end (elf); + if (fd != -1) + close (fd); + return ndx; +} diff --git a/libdwfl/dwfl_validate_address.c b/libdwfl/dwfl_validate_address.c new file mode 100644 index 00000000..15e2602a --- /dev/null +++ b/libdwfl/dwfl_validate_address.c @@ -0,0 +1,65 @@ +/* Validate an address and the relocatability of an offset from it. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +int +dwfl_validate_address (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Sword offset) +{ + Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (dwfl, address); + if (mod == NULL) + return -1; + + Dwarf_Addr relative = address; + int idx = INTUSE(dwfl_module_relocate_address) (mod, &relative); + if (idx < 0) + return -1; + + if (offset != 0) + { + int offset_idx = -1; + relative = address + offset; + if (relative >= mod->low_addr && relative <= mod->high_addr) + { + offset_idx = INTUSE(dwfl_module_relocate_address) (mod, &relative); + if (offset_idx < 0) + return -1; + } + if (offset_idx != idx) + { + __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE); + return -1; + } + } + + return 0; +} diff --git a/libdwfl/dwfl_version.c b/libdwfl/dwfl_version.c new file mode 100644 index 00000000..c27d4f6d --- /dev/null +++ b/libdwfl/dwfl_version.c @@ -0,0 +1,39 @@ +/* Return implementation's version string suitable for printing. + Copyright (C) 2006, 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +const char * +dwfl_version (Dwfl *dwfl __attribute__ ((unused))) +{ + return PACKAGE_VERSION; +} diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c new file mode 100644 index 00000000..a0ef0014 --- /dev/null +++ b/libdwfl/elf-from-memory.c @@ -0,0 +1,372 @@ +/* Reconstruct an ELF file by reading the segments out of remote memory. + Copyright (C) 2005-2011, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include "../libelf/libelfP.h" +#undef _ + +#include "libdwflP.h" + +#include +#include +#include +#include +#include + +/* Reconstruct an ELF file by reading the segments out of remote memory + based on the ELF file header at EHDR_VMA and the ELF program headers it + points to. If not null, *LOADBASEP is filled in with the difference + between the addresses from which the segments were read, and the + addresses the file headers put them at. + + The function READ_MEMORY is called to copy at least MINREAD and at most + MAXREAD bytes from the remote memory at target address ADDRESS into the + local buffer at DATA; it should return -1 for errors (with code in + `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or + the number of bytes read if >= MINREAD. ARG is passed through. + + PAGESIZE is the minimum page size and alignment used for the PT_LOAD + segments. */ + +Elf * +elf_from_remote_memory (GElf_Addr ehdr_vma, + GElf_Xword pagesize, + GElf_Addr *loadbasep, + ssize_t (*read_memory) (void *arg, void *data, + GElf_Addr address, + size_t minread, + size_t maxread), + void *arg) +{ + /* We might have to reserve some memory for the phdrs. Set to NULL + here so we can always safely free it. */ + void *phdrsp = NULL; + + /* First read in the file header and check its sanity. */ + + const size_t initial_bufsize = 256; + unsigned char *buffer = malloc (initial_bufsize); + if (unlikely (buffer == NULL)) + { + no_memory: + __libdwfl_seterrno (DWFL_E_NOMEM); + return NULL; + } + + ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma, + sizeof (Elf32_Ehdr), initial_bufsize); + if (nread <= 0) + { + read_error: + free (buffer); + free (phdrsp); + __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED); + return NULL; + } + + if (memcmp (buffer, ELFMAG, SELFMAG) != 0) + { + bad_elf: + free (buffer); + free (phdrsp); + __libdwfl_seterrno (DWFL_E_BADELF); + return NULL; + } + + /* Extract the information we need from the file header. */ + + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr; + Elf_Data xlatefrom = + { + .d_type = ELF_T_EHDR, + .d_buf = buffer, + .d_version = EV_CURRENT, + }; + Elf_Data xlateto = + { + .d_type = ELF_T_EHDR, + .d_buf = &ehdr, + .d_size = sizeof ehdr, + .d_version = EV_CURRENT, + }; + + GElf_Off phoff; + uint_fast16_t phnum; + uint_fast16_t phentsize; + GElf_Off shdrs_end; + + switch (buffer[EI_CLASS]) + { + case ELFCLASS32: + xlatefrom.d_size = sizeof (Elf32_Ehdr); + if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL) + { + libelf_error: + __libdwfl_seterrno (DWFL_E_LIBELF); + return NULL; + } + phoff = ehdr.e32.e_phoff; + phnum = ehdr.e32.e_phnum; + phentsize = ehdr.e32.e_phentsize; + if (phentsize != sizeof (Elf32_Phdr) || phnum == 0) + goto bad_elf; + /* NOTE if the number of sections is > 0xff00 then e_shnum + is zero and the actual number would come from the section + zero sh_size field. We ignore this here because getting shdrs + is just a nice bonus (see below where we trim the last phdrs + PT_LOAD segment). */ + shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize; + break; + + case ELFCLASS64: + xlatefrom.d_size = sizeof (Elf64_Ehdr); + if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL) + goto libelf_error; + phoff = ehdr.e64.e_phoff; + phnum = ehdr.e64.e_phnum; + phentsize = ehdr.e64.e_phentsize; + if (phentsize != sizeof (Elf64_Phdr) || phnum == 0) + goto bad_elf; + /* See the NOTE above for shdrs_end and ehdr.e32.e_shnum. */ + shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize; + break; + + default: + goto bad_elf; + } + + + /* The file header tells where to find the program headers. + These are what we use to actually choose what to read. */ + + xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR; + xlatefrom.d_size = phnum * phentsize; + + if ((size_t) nread >= phoff + phnum * phentsize) + /* We already have all the phdrs from the initial read. */ + xlatefrom.d_buf = buffer + phoff; + else + { + /* Read in the program headers. */ + + if (initial_bufsize < (size_t)phnum * phentsize) + { + unsigned char *newbuf = realloc (buffer, phnum * phentsize); + if (newbuf == NULL) + { + free (buffer); + free (phdrsp); + goto no_memory; + } + buffer = newbuf; + } + nread = (*read_memory) (arg, buffer, ehdr_vma + phoff, + phnum * phentsize, phnum * phentsize); + if (nread <= 0) + goto read_error; + + xlatefrom.d_buf = buffer; + } + + bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; + size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); + if (unlikely (phnum > SIZE_MAX / phdr_size)) + { + free (buffer); + goto no_memory; + } + const size_t phdrsp_bytes = phnum * phdr_size; + phdrsp = malloc (phdrsp_bytes); + if (unlikely (phdrsp == NULL)) + { + free (buffer); + goto no_memory; + } + + xlateto.d_buf = phdrsp; + xlateto.d_size = phdrsp_bytes; + + /* Scan for PT_LOAD segments to find the total size of the file image. */ + size_t contents_size = 0; + GElf_Off segments_end = 0; + GElf_Off segments_end_mem = 0; + GElf_Addr loadbase = ehdr_vma; + bool found_base = false; + Elf32_Phdr (*p32)[phnum] = phdrsp; + Elf64_Phdr (*p64)[phnum] = phdrsp; + + if (class32) + { + if (! elf32_xlatetom (&xlateto, &xlatefrom, ehdr.e32.e_ident[EI_DATA])) + goto libelf_error; + } + else + { + if (! elf64_xlatetom (&xlateto, &xlatefrom, ehdr.e64.e_ident[EI_DATA])) + goto libelf_error; + } + + for (uint_fast16_t i = 0; i < phnum; ++i) + { + GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type; + + if (type != PT_LOAD) + continue; + + GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr; + GElf_Xword memsz = class32 ? (*p32)[i].p_memsz : (*p64)[i].p_memsz; + GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset; + GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz; + + /* Sanity check the segment load aligns with the pagesize. */ + if (((vaddr - offset) & (pagesize - 1)) != 0) + goto bad_elf; + + GElf_Off segment_end = ((offset + filesz + pagesize - 1) + & -pagesize); + + if (segment_end > (GElf_Off) contents_size) + contents_size = segment_end; + + if (!found_base && (offset & -pagesize) == 0) + { + loadbase = ehdr_vma - (vaddr & -pagesize); + found_base = true; + } + + segments_end = offset + filesz; + segments_end_mem = offset + memsz; + } + + /* Trim the last segment so we don't bother with zeros in the last page + that are off the end of the file. However, if the extra bit in that + page includes the section headers and the memory isn't extended (which + might indicate it will have been reused otherwise), keep them. */ + if ((GElf_Off) contents_size > segments_end + && (GElf_Off) contents_size >= shdrs_end + && segments_end == segments_end_mem) + { + contents_size = segments_end; + if ((GElf_Off) contents_size < shdrs_end) + contents_size = shdrs_end; + } + else + contents_size = segments_end; + + free (buffer); + + /* Now we know the size of the whole image we want read in. */ + buffer = calloc (1, contents_size); + if (buffer == NULL) + { + free (phdrsp); + goto no_memory; + } + + for (uint_fast16_t i = 0; i < phnum; ++i) + { + GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type; + + if (type != PT_LOAD) + continue; + + GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr; + GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset; + GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz; + + GElf_Off start = offset & -pagesize; + GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize; + if (end > (GElf_Off) contents_size) + end = contents_size; + nread = (*read_memory) (arg, buffer + start, + (loadbase + vaddr) & -pagesize, + end - start, end - start); + if (nread <= 0) + goto read_error; + } + + /* If the segments visible in memory didn't include the section + headers, then clear them from the file header. */ + if (contents_size < shdrs_end) + { + if (class32) + { + ehdr.e32.e_shoff = 0; + ehdr.e32.e_shnum = 0; + ehdr.e32.e_shstrndx = 0; + } + else + { + ehdr.e64.e_shoff = 0; + ehdr.e64.e_shnum = 0; + ehdr.e64.e_shstrndx = 0; + } + } + + /* This will normally have been in the first PT_LOAD segment. But it + conceivably could be missing, and we might have just changed it. */ + xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR; + xlateto.d_buf = buffer; + if (class32) + { + xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32; + xlatefrom.d_buf = &ehdr.e32; + if (elf32_xlatetof (&xlateto, &xlatefrom, + ehdr.e32.e_ident[EI_DATA]) == NULL) + goto libelf_error; + } + else + { + xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64; + xlatefrom.d_buf = &ehdr.e64; + if (elf64_xlatetof (&xlateto, &xlatefrom, + ehdr.e64.e_ident[EI_DATA]) == NULL) + goto libelf_error; + } + + free (phdrsp); + phdrsp = NULL; + + /* Now we have the image. Open libelf on it. */ + + Elf *elf = elf_memory ((char *) buffer, contents_size); + if (elf == NULL) + { + free (buffer); + goto libelf_error; + } + + elf->flags |= ELF_F_MALLOCED; + if (loadbasep != NULL) + *loadbasep = loadbase; + return elf; +} diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c new file mode 100644 index 00000000..449df5a1 --- /dev/null +++ b/libdwfl/find-debuginfo.c @@ -0,0 +1,430 @@ +/* Standard find_debuginfo callback for libdwfl. + Copyright (C) 2005-2010, 2014, 2015, 2019 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include +#include +#include +#include "system.h" + + +/* Try to open [DIR/][SUBDIR/]DEBUGLINK, return file descriptor or -1. + On success, *DEBUGINFO_FILE_NAME has the malloc'd name of the open file. */ +static int +try_open (const struct stat *main_stat, + const char *dir, const char *subdir, const char *debuglink, + char **debuginfo_file_name) +{ + char *fname; + if (dir == NULL && subdir == NULL) + { + fname = strdup (debuglink); + if (unlikely (fname == NULL)) + return -1; + } + else if ((subdir == NULL ? asprintf (&fname, "%s/%s", dir, debuglink) + : dir == NULL ? asprintf (&fname, "%s/%s", subdir, debuglink) + : asprintf (&fname, "%s/%s/%s", dir, subdir, debuglink)) < 0) + return -1; + + struct stat st; + int fd = TEMP_FAILURE_RETRY (open (fname, O_RDONLY)); + if (fd < 0) + free (fname); + else if (fstat (fd, &st) == 0 + && st.st_ino == main_stat->st_ino + && st.st_dev == main_stat->st_dev) + { + /* This is the main file by another name. Don't look at it again. */ + free (fname); + close (fd); + errno = ENOENT; + fd = -1; + } + else + *debuginfo_file_name = fname; + + return fd; +} + +/* Return true iff the FD's contents CRC matches DEBUGLINK_CRC. */ +static inline bool +check_crc (int fd, GElf_Word debuglink_crc) +{ + uint32_t file_crc; + return (__libdwfl_crc32_file (fd, &file_crc) == 0 + && file_crc == debuglink_crc); +} + +static bool +validate (Dwfl_Module *mod, int fd, bool check, GElf_Word debuglink_crc) +{ + /* For alt debug files always check the build-id from the Dwarf and alt. */ + if (mod->dw != NULL) + { + bool valid = false; + const void *build_id; + const char *altname; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, + &altname, + &build_id); + if (build_id_len > 0) + { + /* We need to open an Elf handle on the file so we can check its + build ID note for validation. Backdoor the handle into the + module data structure since we had to open it early anyway. */ + Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf, + false, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else + { + const void *alt_build_id; + ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf, + &alt_build_id); + if (alt_len > 0 && alt_len == build_id_len + && memcmp (build_id, alt_build_id, alt_len) == 0) + valid = true; + else + { + /* A mismatch! */ + elf_end (mod->alt_elf); + mod->alt_elf = NULL; + close (fd); + fd = -1; + } + } + } + return valid; + } + + /* If we have a build ID, check only that. */ + if (mod->build_id_len > 0) + { + /* We need to open an Elf handle on the file so we can check its + build ID note for validation. Backdoor the handle into the + module data structure since we had to open it early anyway. */ + + mod->debug.valid = false; + Dwfl_Error error = __libdw_open_file (&fd, &mod->debug.elf, false, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else if (likely (__libdwfl_find_build_id (mod, false, + mod->debug.elf) == 2)) + /* Also backdoor the gratuitous flag. */ + mod->debug.valid = true; + else + { + /* A mismatch! */ + elf_end (mod->debug.elf); + mod->debug.elf = NULL; + close (fd); + fd = -1; + } + + return mod->debug.valid; + } + + return !check || check_crc (fd, debuglink_crc); +} + +static int +find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, + const char *debuglink_file, GElf_Word debuglink_crc, + char **debuginfo_file_name) +{ + bool cancheck = debuglink_crc != (GElf_Word) 0; + + const char *file_basename = file_name == NULL ? NULL : basename (file_name); + char *localname = NULL; + + /* We invent a debuglink .debug name if NULL, but then want to try the + basename too. */ + bool debuglink_null = debuglink_file == NULL; + if (debuglink_null) + { + /* For a alt debug multi file we need a name, for a separate debug + name we may be able to fall back on file_basename.debug. */ + if (file_basename == NULL || mod->dw != NULL) + { + errno = 0; + return -1; + } + + size_t len = strlen (file_basename); + localname = malloc (len + sizeof ".debug"); + if (unlikely (localname == NULL)) + return -1; + memcpy (localname, file_basename, len); + memcpy (&localname[len], ".debug", sizeof ".debug"); + debuglink_file = localname; + cancheck = false; + } + + /* Look for a file named DEBUGLINK_FILE in the directories + indicated by the debug directory path setting. */ + + const Dwfl_Callbacks *const cb = mod->dwfl->callbacks; + char *localpath = strdup ((cb->debuginfo_path ? *cb->debuginfo_path : NULL) + ?: DEFAULT_DEBUGINFO_PATH); + if (unlikely (localpath == NULL)) + { + free (localname); + return -1; + } + + /* A leading - or + in the whole path sets whether to check file CRCs. */ + bool defcheck = true; + char *path = localpath; + if (path[0] == '-' || path[0] == '+') + { + defcheck = path[0] == '+'; + ++path; + } + + /* XXX dev/ino should be cached in struct dwfl_file. */ + struct stat main_stat; + if (unlikely ((mod->main.fd != -1 ? fstat (mod->main.fd, &main_stat) + : file_name != NULL ? stat (file_name, &main_stat) + : -1) < 0)) + { + main_stat.st_dev = 0; + main_stat.st_ino = 0; + } + + char *file_dirname = (file_basename == file_name ? NULL + : strndup (file_name, file_basename - 1 - file_name)); + if (file_basename != file_name && file_dirname == NULL) + { + free (localpath); + free (localname); + return -1; + } + char *p; + while ((p = strsep (&path, ":")) != NULL) + { + /* A leading - or + says whether to check file CRCs for this element. */ + bool check = defcheck; + if (*p == '+' || *p == '-') + check = *p++ == '+'; + check = check && cancheck; + + /* Try the basename too, if we made up the debuglink name and this + is not the main directory. */ + bool try_file_basename; + + const char *dir, *subdir, *file; + switch (p[0]) + { + case '\0': + /* An empty entry says to try the main file's directory. */ + dir = file_dirname; + subdir = NULL; + file = debuglink_file; + try_file_basename = false; + break; + case '/': + /* An absolute path says to look there for a subdirectory + named by the main file's absolute directory. This cannot + be applied to a relative file name. For alt debug files + it means to look for the basename file in that dir or the + .dwz subdir (see below). */ + if (mod->dw == NULL + && (file_dirname == NULL || file_dirname[0] != '/')) + continue; + dir = p; + if (mod->dw == NULL) + { + subdir = file_dirname; + /* We want to explore all sub-subdirs. Chop off one slash + at a time. */ + explore_dir: + subdir = strchr (subdir, '/'); + if (subdir != NULL) + subdir = subdir + 1; + if (subdir && *subdir == 0) + continue; + file = debuglink_file; + } + else + { + subdir = NULL; + file = basename (debuglink_file); + } + try_file_basename = debuglink_null; + break; + default: + /* A relative path says to try a subdirectory of that name + in the main file's directory. */ + dir = file_dirname; + subdir = p; + file = debuglink_file; + try_file_basename = debuglink_null; + break; + } + + char *fname = NULL; + int fd = try_open (&main_stat, dir, subdir, file, &fname); + if (fd < 0 && try_file_basename) + fd = try_open (&main_stat, dir, subdir, file_basename, &fname); + if (fd < 0) + switch (errno) + { + case ENOENT: + case ENOTDIR: + /* If we are looking for the alt file also try the .dwz subdir. + But only if this is the empty or absolute path. */ + if (mod->dw != NULL && (p[0] == '\0' || p[0] == '/')) + { + fd = try_open (&main_stat, dir, ".dwz", + basename (file), &fname); + if (fd < 0) + { + if (errno != ENOENT && errno != ENOTDIR) + goto fail_free; + else + continue; + } + break; + } + /* If possible try again with a sub-subdir. */ + if (mod->dw == NULL && subdir) + goto explore_dir; + continue; + default: + goto fail_free; + } + if (validate (mod, fd, check, debuglink_crc)) + { + free (localpath); + free (localname); + free (file_dirname); + *debuginfo_file_name = fname; + return fd; + } + free (fname); + close (fd); + } + + /* No dice. */ + errno = 0; +fail_free: + free (localpath); + free (localname); + free (file_dirname); + return -1; +} + +int +dwfl_standard_find_debuginfo (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *modname __attribute__ ((unused)), + GElf_Addr base __attribute__ ((unused)), + const char *file_name, + const char *debuglink_file, + GElf_Word debuglink_crc, + char **debuginfo_file_name) +{ + if (mod == NULL) + return -1; + + /* First try by build ID if we have one. If that succeeds or fails + other than just by finding nothing, that's all we do. */ + const unsigned char *bits = NULL; + GElf_Addr vaddr; + int bits_len; + if ((bits_len = INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr)) > 0) + { + /* Dropping most arguments means we cannot rely on them in + dwfl_build_id_find_debuginfo. But leave it that way since + some user code out there also does this, so we'll have to + handle it anyway. */ + int fd = INTUSE(dwfl_build_id_find_debuginfo) (mod, + NULL, NULL, 0, + NULL, NULL, 0, + debuginfo_file_name); + + /* Did the build_id callback find something or report an error? + Then we are done. Otherwise fallback on path based search. */ + if (fd >= 0 + || (mod->dw == NULL && mod->debug.elf != NULL) + || (mod->dw != NULL && mod->alt_elf != NULL) + || errno != 0) + return fd; + } + + /* Failing that, search the path by name. */ + int fd = find_debuginfo_in_path (mod, file_name, + debuglink_file, debuglink_crc, + debuginfo_file_name); + + if (fd < 0 && errno == 0 && file_name != NULL) + { + /* If FILE_NAME is a symlink, the debug file might be associated + with the symlink target name instead. */ + + char *canon = realpath (file_name, NULL); + if (canon != NULL && strcmp (file_name, canon)) + fd = find_debuginfo_in_path (mod, canon, + debuglink_file, debuglink_crc, + debuginfo_file_name); + free (canon); + } + +#ifdef ENABLE_LIBDEBUGINFOD + /* Still nothing? Try if we can use the debuginfod client. + But note that we might be looking for the alt file. + We use the same trick as dwfl_build_id_find_debuginfo. + If the debug file (dw) is already set, then we must be + looking for the altfile. But we cannot use the actual + file/path name given as hint. We'll have to lookup the + alt file "build-id". Because the debuginfod client only + handles build-ids. */ + if (fd < 0) + { + if (mod->dw != NULL) + { + const char *altname; + bits_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, &altname, + (const void **) + &bits); + } + + if (bits_len > 0) + fd = __libdwfl_debuginfod_find_debuginfo (mod->dwfl, bits, bits_len); + } +#endif + + return fd; +} +INTDEF (dwfl_standard_find_debuginfo) diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c new file mode 100644 index 00000000..9ac33833 --- /dev/null +++ b/libdwfl/frame_unwind.c @@ -0,0 +1,777 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2013, 2014, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "cfi.h" +#include +#include "libdwflP.h" +#include "../libdw/dwarf.h" +#include + +/* Maximum number of DWARF expression stack slots before returning an error. */ +#define DWARF_EXPR_STACK_MAX 0x100 + +/* Maximum number of DWARF expression executed operations before returning an + error. */ +#define DWARF_EXPR_STEPS_MAX 0x1000 + +bool +internal_function +__libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val) +{ + Ebl *ebl = state->thread->process->ebl; + if (! ebl_dwarf_to_regno (ebl, ®no)) + return false; + if (regno >= ebl_frame_nregs (ebl)) + return false; + if ((state->regs_set[regno / sizeof (*state->regs_set) / 8] + & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0) + return false; + if (val) + *val = state->regs[regno]; + return true; +} + +bool +internal_function +__libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val) +{ + Ebl *ebl = state->thread->process->ebl; + if (! ebl_dwarf_to_regno (ebl, ®no)) + return false; + if (regno >= ebl_frame_nregs (ebl)) + return false; + /* For example i386 user_regs_struct has signed fields. */ + if (ebl_get_elfclass (ebl) == ELFCLASS32) + val &= 0xffffffff; + state->regs_set[regno / sizeof (*state->regs_set) / 8] |= + ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8))); + state->regs[regno] = val; + return true; +} + +static bool +state_get_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val) +{ + if (! __libdwfl_frame_reg_get (state, regno, val)) + { + __libdwfl_seterrno (DWFL_E_INVALID_REGISTER); + return false; + } + return true; +} + +static int +bra_compar (const void *key_voidp, const void *elem_voidp) +{ + Dwarf_Word offset = (uintptr_t) key_voidp; + const Dwarf_Op *op = elem_voidp; + return (offset > op->offset) - (offset < op->offset); +} + +struct eval_stack { + Dwarf_Addr *addrs; + size_t used; + size_t allocated; +}; + +static bool +do_push (struct eval_stack *stack, Dwarf_Addr val) +{ + if (stack->used >= DWARF_EXPR_STACK_MAX) + { + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + if (stack->used == stack->allocated) + { + stack->allocated = MAX (stack->allocated * 2, 32); + Dwarf_Addr *new_addrs; + new_addrs = realloc (stack->addrs, + stack->allocated * sizeof (*stack->addrs)); + if (new_addrs == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return false; + } + stack->addrs = new_addrs; + } + stack->addrs[stack->used++] = val; + return true; +} + +static bool +do_pop (struct eval_stack *stack, Dwarf_Addr *val) +{ + if (stack->used == 0) + { + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + *val = stack->addrs[--stack->used]; + return true; +} + +/* If FRAME is NULL is are computing CFI frame base. In such case another + DW_OP_call_frame_cfa is no longer permitted. */ + +static bool +expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops, + size_t nops, Dwarf_Addr *result, Dwarf_Addr bias) +{ + Dwfl_Process *process = state->thread->process; + if (nops == 0) + { + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + struct eval_stack stack = + { + .addrs = NULL, + .used = 0, + .allocated = 0 + }; + +#define pop(x) do_pop(&stack, x) +#define push(x) do_push(&stack, x) + + Dwarf_Addr val1, val2; + bool is_location = false; + size_t steps_count = 0; + for (const Dwarf_Op *op = ops; op < ops + nops; op++) + { + if (++steps_count > DWARF_EXPR_STEPS_MAX) + { + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + switch (op->atom) + { + /* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op: */ + case DW_OP_lit0 ... DW_OP_lit31: + if (! push (op->atom - DW_OP_lit0)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_addr: + if (! push (op->number + bias)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_GNU_encoded_addr: + /* Missing support in the rest of elfutils. */ + __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF); + return false; + case DW_OP_const1u: + case DW_OP_const1s: + case DW_OP_const2u: + case DW_OP_const2s: + case DW_OP_const4u: + case DW_OP_const4s: + case DW_OP_const8u: + case DW_OP_const8s: + case DW_OP_constu: + case DW_OP_consts: + if (! push (op->number)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_reg0 ... DW_OP_reg31: + if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1) + || ! push (val1)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_regx: + if (! state_get_reg (state, op->number, &val1) || ! push (val1)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_breg0 ... DW_OP_breg31: + if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1)) + { + free (stack.addrs); + return false; + } + val1 += op->number; + if (! push (val1)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_bregx: + if (! state_get_reg (state, op->number, &val1)) + { + free (stack.addrs); + return false; + } + val1 += op->number2; + if (! push (val1)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_dup: + if (! pop (&val1) || ! push (val1) || ! push (val1)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_drop: + if (! pop (&val1)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_pick: + if (stack.used <= op->number) + { + free (stack.addrs); + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + if (! push (stack.addrs[stack.used - 1 - op->number])) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_over: + if (! pop (&val1) || ! pop (&val2) + || ! push (val2) || ! push (val1) || ! push (val2)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_swap: + if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2)) + { + free (stack.addrs); + return false; + } + break; + case DW_OP_rot: + { + Dwarf_Addr val3; + if (! pop (&val1) || ! pop (&val2) || ! pop (&val3) + || ! push (val1) || ! push (val3) || ! push (val2)) + { + free (stack.addrs); + return false; + } + } + break; + case DW_OP_deref: + case DW_OP_deref_size: + if (process->callbacks->memory_read == NULL) + { + free (stack.addrs); + __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT); + return false; + } + if (! pop (&val1) + || ! process->callbacks->memory_read (process->dwfl, val1, &val1, + process->callbacks_arg)) + { + free (stack.addrs); + return false; + } + if (op->atom == DW_OP_deref_size) + { + const int elfclass = frame->cache->e_ident[EI_CLASS]; + const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8; + if (op->number > addr_bytes) + { + free (stack.addrs); + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } +#if BYTE_ORDER == BIG_ENDIAN + if (op->number == 0) + val1 = 0; + else + val1 >>= (addr_bytes - op->number) * 8; +#else + if (op->number < 8) + val1 &= (1ULL << (op->number * 8)) - 1; +#endif + } + if (! push (val1)) + { + free (stack.addrs); + return false; + } + break; +#define UNOP(atom, expr) \ + case atom: \ + if (! pop (&val1) || ! push (expr)) \ + { \ + free (stack.addrs); \ + return false; \ + } \ + break; + UNOP (DW_OP_abs, llabs ((int64_t) val1)) + UNOP (DW_OP_neg, -(int64_t) val1) + UNOP (DW_OP_not, ~val1) +#undef UNOP + case DW_OP_plus_uconst: + if (! pop (&val1) || ! push (val1 + op->number)) + { + free (stack.addrs); + return false; + } + break; +#define BINOP(atom, op) \ + case atom: \ + if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \ + { \ + free (stack.addrs); \ + return false; \ + } \ + break; +#define BINOP_SIGNED(atom, op) \ + case atom: \ + if (! pop (&val2) || ! pop (&val1) \ + || ! push ((int64_t) val1 op (int64_t) val2)) \ + { \ + free (stack.addrs); \ + return false; \ + } \ + break; + BINOP (DW_OP_and, &) + case DW_OP_div: + if (! pop (&val2) || ! pop (&val1)) + { + free (stack.addrs); + return false; + } + if (val2 == 0) + { + free (stack.addrs); + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + if (! push ((int64_t) val1 / (int64_t) val2)) + { + free (stack.addrs); + return false; + } + break; + BINOP (DW_OP_minus, -) + case DW_OP_mod: + if (! pop (&val2) || ! pop (&val1)) + { + free (stack.addrs); + return false; + } + if (val2 == 0) + { + free (stack.addrs); + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + if (! push (val1 % val2)) + { + free (stack.addrs); + return false; + } + break; + BINOP (DW_OP_mul, *) + BINOP (DW_OP_or, |) + BINOP (DW_OP_plus, +) + BINOP (DW_OP_shl, <<) + BINOP (DW_OP_shr, >>) + BINOP_SIGNED (DW_OP_shra, >>) + BINOP (DW_OP_xor, ^) + BINOP_SIGNED (DW_OP_le, <=) + BINOP_SIGNED (DW_OP_ge, >=) + BINOP_SIGNED (DW_OP_eq, ==) + BINOP_SIGNED (DW_OP_lt, <) + BINOP_SIGNED (DW_OP_gt, >) + BINOP_SIGNED (DW_OP_ne, !=) +#undef BINOP +#undef BINOP_SIGNED + case DW_OP_bra: + if (! pop (&val1)) + { + free (stack.addrs); + return false; + } + if (val1 == 0) + break; + FALLTHROUGH; + case DW_OP_skip:; + Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number; + const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops, + sizeof (*ops), bra_compar); + if (found == NULL) + { + free (stack.addrs); + /* PPC32 vDSO has such invalid operations. */ + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + /* Undo the 'for' statement increment. */ + op = found - 1; + break; + case DW_OP_nop: + break; + /* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op: */ + case DW_OP_call_frame_cfa:; + // Not used by CFI itself but it is synthetized by elfutils internation. + Dwarf_Op *cfa_ops; + size_t cfa_nops; + Dwarf_Addr cfa; + if (frame == NULL + || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0 + || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias) + || ! push (cfa)) + { + __libdwfl_seterrno (DWFL_E_LIBDW); + free (stack.addrs); + return false; + } + is_location = true; + break; + case DW_OP_stack_value: + // Not used by CFI itself but it is synthetized by elfutils internation. + is_location = false; + break; + default: + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + return false; + } + } + if (! pop (result)) + { + free (stack.addrs); + return false; + } + free (stack.addrs); + if (is_location) + { + if (process->callbacks->memory_read == NULL) + { + __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT); + return false; + } + if (! process->callbacks->memory_read (process->dwfl, *result, result, + process->callbacks_arg)) + return false; + } + return true; +#undef push +#undef pop +} + +static Dwfl_Frame * +new_unwound (Dwfl_Frame *state) +{ + assert (state->unwound == NULL); + Dwfl_Thread *thread = state->thread; + Dwfl_Process *process = thread->process; + Ebl *ebl = process->ebl; + size_t nregs = ebl_frame_nregs (ebl); + assert (nregs > 0); + Dwfl_Frame *unwound; + unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs); + if (unlikely (unwound == NULL)) + return NULL; + state->unwound = unwound; + unwound->thread = thread; + unwound->unwound = NULL; + unwound->signal_frame = false; + unwound->initial_frame = false; + unwound->pc_state = DWFL_FRAME_STATE_ERROR; + memset (unwound->regs_set, 0, sizeof (unwound->regs_set)); + return unwound; +} + +/* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation + error so one can easily catch the problem with a debugger. Still there are + archs with invalid CFI for some registers where the registers are never used + later. Therefore we continue unwinding leaving the registers undefined. */ + +static void +handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias) +{ + Dwarf_Frame *frame; + if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0) + { + __libdwfl_seterrno (DWFL_E_LIBDW); + return; + } + + Dwfl_Frame *unwound = new_unwound (state); + if (unwound == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return; + } + + unwound->signal_frame = frame->fde->cie->signal_frame; + Dwfl_Thread *thread = state->thread; + Dwfl_Process *process = thread->process; + Ebl *ebl = process->ebl; + size_t nregs = ebl_frame_nregs (ebl); + assert (nregs > 0); + + /* The return register is special for setting the unwound->pc_state. */ + unsigned ra = frame->fde->cie->return_address_register; + bool ra_set = false; + if (! ebl_dwarf_to_regno (ebl, &ra)) + { + __libdwfl_seterrno (DWFL_E_INVALID_REGISTER); + return; + } + + for (unsigned regno = 0; regno < nregs; regno++) + { + Dwarf_Op reg_ops_mem[3], *reg_ops; + size_t reg_nops; + if (dwarf_frame_register (frame, regno, reg_ops_mem, ®_ops, + ®_nops) != 0) + { + __libdwfl_seterrno (DWFL_E_LIBDW); + continue; + } + Dwarf_Addr regval; + if (reg_nops == 0) + { + if (reg_ops == reg_ops_mem) + { + /* REGNO is undefined. */ + if (regno == ra) + unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED; + continue; + } + else if (reg_ops == NULL) + { + /* REGNO is same-value. */ + if (! state_get_reg (state, regno, ®val)) + continue; + } + else + { + __libdwfl_seterrno (DWFL_E_INVALID_DWARF); + continue; + } + } + else if (! expr_eval (state, frame, reg_ops, reg_nops, ®val, bias)) + { + /* PPC32 vDSO has various invalid operations, ignore them. The + register will look as unset causing an error later, if used. + But PPC32 does not use such registers. */ + continue; + } + + /* Some architectures encode some extra info in the return address. */ + if (regno == frame->fde->cie->return_address_register) + regval &= ebl_func_addr_mask (ebl); + + /* This is another strange PPC[64] case. There are two + registers numbers that can represent the same DWARF return + register number. We only want one to actually set the return + register value. But we always want to override the value if + the register is the actual CIE return address register. */ + if (ra_set && regno != frame->fde->cie->return_address_register) + { + unsigned r = regno; + if (ebl_dwarf_to_regno (ebl, &r) && r == ra) + continue; + } + + if (! __libdwfl_frame_reg_set (unwound, regno, regval)) + { + __libdwfl_seterrno (DWFL_E_INVALID_REGISTER); + continue; + } + else if (! ra_set) + { + unsigned r = regno; + if (ebl_dwarf_to_regno (ebl, &r) && r == ra) + ra_set = true; + } + } + if (unwound->pc_state == DWFL_FRAME_STATE_ERROR) + { + if (__libdwfl_frame_reg_get (unwound, + frame->fde->cie->return_address_register, + &unwound->pc)) + { + /* PPC32 __libc_start_main properly CFI-unwinds PC as zero. + Currently none of the archs supported for unwinding have + zero as a valid PC. */ + if (unwound->pc == 0) + unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED; + else + { + unwound->pc_state = DWFL_FRAME_STATE_PC_SET; + /* In SPARC the return address register actually contains + the address of the call instruction instead of the return + address. Therefore we add here an offset defined by the + backend. Most likely 0. */ + unwound->pc += ebl_ra_offset (ebl); + } + } + else + { + /* We couldn't set the return register, either it was bogus, + or the return pc is undefined, maybe end of call stack. */ + unsigned pcreg = frame->fde->cie->return_address_register; + if (! ebl_dwarf_to_regno (ebl, &pcreg) + || pcreg >= ebl_frame_nregs (ebl)) + __libdwfl_seterrno (DWFL_E_INVALID_REGISTER); + else + unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED; + } + } + free (frame); +} + +static bool +setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg) +{ + Dwfl_Frame *state = arg; + Dwfl_Frame *unwound = state->unwound; + if (firstreg < 0) + { + assert (firstreg == -1); + assert (nregs == 1); + assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED); + unwound->pc = *regs; + unwound->pc_state = DWFL_FRAME_STATE_PC_SET; + return true; + } + while (nregs--) + if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++)) + return false; + return true; +} + +static bool +getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg) +{ + Dwfl_Frame *state = arg; + assert (firstreg >= 0); + while (nregs--) + if (! __libdwfl_frame_reg_get (state, firstreg++, regs++)) + return false; + return true; +} + +static bool +readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg) +{ + Dwfl_Frame *state = arg; + Dwfl_Thread *thread = state->thread; + Dwfl_Process *process = thread->process; + return process->callbacks->memory_read (process->dwfl, addr, datap, + process->callbacks_arg); +} + +void +internal_function +__libdwfl_frame_unwind (Dwfl_Frame *state) +{ + if (state->unwound) + return; + /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE + which would deadlock us. */ + Dwarf_Addr pc; + bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL); + if (!ok) + return; + /* Check whether this is the initial frame or a signal frame. + Then we need to unwind from the original, unadjusted PC. */ + if (! state->initial_frame && ! state->signal_frame) + pc--; + Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc); + if (mod == NULL) + __libdwfl_seterrno (DWFL_E_NO_DWARF); + else + { + Dwarf_Addr bias; + Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias); + if (cfi_eh) + { + handle_cfi (state, pc - bias, cfi_eh, bias); + if (state->unwound) + return; + } + Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias); + if (cfi_dwarf) + { + handle_cfi (state, pc - bias, cfi_dwarf, bias); + if (state->unwound) + return; + } + } + assert (state->unwound == NULL); + Dwfl_Thread *thread = state->thread; + Dwfl_Process *process = thread->process; + Ebl *ebl = process->ebl; + if (new_unwound (state) == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return; + } + state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED; + // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield. + bool signal_frame = false; + if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame)) + { + // Discard the unwind attempt. During next __libdwfl_frame_unwind call + // we may have for example the appropriate Dwfl_Module already mapped. + assert (state->unwound->unwound == NULL); + free (state->unwound); + state->unwound = NULL; + // __libdwfl_seterrno has been called above. + return; + } + assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET); + state->unwound->signal_frame = signal_frame; +} diff --git a/libdwfl/gzip.c b/libdwfl/gzip.c new file mode 100644 index 00000000..ba8ecfba --- /dev/null +++ b/libdwfl/gzip.c @@ -0,0 +1,404 @@ +/* Decompression support for libdwfl: zlib (gzip) and/or bzlib (bzip2). + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "system.h" + +#include + +#ifdef LZMA +# define USE_INFLATE 1 +# include +# define unzip __libdw_unlzma +# define DWFL_E_ZLIB DWFL_E_LZMA +# define MAGIC "\xFD" "7zXZ\0" /* XZ file format. */ +# define MAGIC2 "\x5d\0" /* Raw LZMA format. */ +# define Z(what) LZMA_##what +# define LZMA_ERRNO LZMA_PROG_ERROR +# define z_stream lzma_stream +# define inflateInit(z) lzma_auto_decoder (z, 1 << 30, 0) +# define do_inflate(z) lzma_code (z, LZMA_RUN) +# define inflateEnd(z) lzma_end (z) +#elif defined ZSTD +# define USE_INFLATE 1 +# include +# define unzip __libdw_unzstd +# define DWFL_E_ZLIB DWFL_E_ZSTD +# define MAGIC "\x28\xb5\x2f\xfd" +#elif defined BZLIB +# define USE_INFLATE 1 +# include +# define unzip __libdw_bunzip2 +# define DWFL_E_ZLIB DWFL_E_BZLIB +# define MAGIC "BZh" +# define Z(what) BZ_##what +# define BZ_ERRNO BZ_IO_ERROR +# define z_stream bz_stream +# define inflateInit(z) BZ2_bzDecompressInit (z, 0, 0) +# define do_inflate(z) BZ2_bzDecompress (z) +# define inflateEnd(z) BZ2_bzDecompressEnd (z) +#else +# define USE_INFLATE 0 +# define crc32 loser_crc32 +# include +# define unzip __libdw_gunzip +# define MAGIC "\037\213" +# define Z(what) Z_##what +#endif + +#define READ_SIZE (1 << 20) + +struct unzip_state { +#if !USE_INFLATE + gzFile zf; +#endif + size_t mapped_size; + void **whole; + void *buffer; + size_t size; + void *input_buffer; + off_t input_pos; +}; + +static inline bool +bigger_buffer (struct unzip_state *state, size_t start) +{ + size_t more = state->size ? state->size * 2 : start; + char *b = realloc (state->buffer, more); + while (unlikely (b == NULL) && more >= state->size + 1024) + b = realloc (state->buffer, more -= 1024); + if (unlikely (b == NULL)) + return false; + state->buffer = b; + state->size = more; + return true; +} + +static inline void +smaller_buffer (struct unzip_state *state, size_t end) +{ + state->buffer = + realloc (state->buffer, end) ?: end == 0 ? NULL : state->buffer; + state->size = end; +} + +static inline Dwfl_Error +fail (struct unzip_state *state, Dwfl_Error failure) +{ + if (state->input_pos == (off_t) state->mapped_size) + *state->whole = state->input_buffer; + else + { + free (state->input_buffer); + *state->whole = NULL; + } + free (state->buffer); + return failure; +} + +#ifndef ZSTD +static inline Dwfl_Error +zlib_fail (struct unzip_state *state, int result) +{ + switch (result) + { + case Z (MEM_ERROR): + return fail (state, DWFL_E_NOMEM); + case Z (ERRNO): + return fail (state, DWFL_E_ERRNO); + default: + return fail (state, DWFL_E_ZLIB); + } +} +#endif + +#if !USE_INFLATE +static Dwfl_Error +open_stream (int fd, off_t start_offset, struct unzip_state *state) +{ + int d = dup (fd); + if (unlikely (d < 0)) + return DWFL_E_ERRNO; + if (start_offset != 0) + { + off_t off = lseek (d, start_offset, SEEK_SET); + if (off != start_offset) + { + close (d); + return DWFL_E_ERRNO; + } + } + state->zf = gzdopen (d, "r"); + if (unlikely (state->zf == NULL)) + { + close (d); + return DWFL_E_NOMEM; + } + + /* From here on, zlib will close D. */ + + return DWFL_E_NOERROR; +} +#endif + +/* If this is not a compressed image, return DWFL_E_BADELF. + If we uncompressed it into *WHOLE, *WHOLE_SIZE, return DWFL_E_NOERROR. + Otherwise return an error for bad compressed data or I/O failure. + If we return an error after reading the first part of the file, + leave that portion malloc'd in *WHOLE, *WHOLE_SIZE. If *WHOLE + is not null on entry, we'll use it in lieu of repeating a read. */ + +Dwfl_Error internal_function +unzip (int fd, off_t start_offset, + void *mapped, size_t _mapped_size, + void **_whole, size_t *whole_size) +{ + struct unzip_state state = + { +#if !USE_INFLATE + .zf = NULL, +#endif + .mapped_size = _mapped_size, + .whole = _whole, + .buffer = NULL, + .size = 0, + .input_buffer = NULL, + .input_pos = 0 + }; + + if (mapped == NULL) + { + if (*state.whole == NULL) + { + state.input_buffer = malloc (READ_SIZE); + if (unlikely (state.input_buffer == NULL)) + return DWFL_E_NOMEM; + + ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE, start_offset); + if (unlikely (n < 0)) + return fail (&state, DWFL_E_ERRNO); + + state.input_pos = n; + mapped = state.input_buffer; + state.mapped_size = n; + } + else + { + state.input_buffer = *state.whole; + state.input_pos = state.mapped_size = *whole_size; + } + } + +#define NOMAGIC(magic) \ + (state.mapped_size <= sizeof magic || \ + memcmp (mapped, magic, sizeof magic - 1)) + + /* First, look at the header. */ + if (NOMAGIC (MAGIC) +#ifdef MAGIC2 + && NOMAGIC (MAGIC2) +#endif + ) + /* Not a compressed file. */ + return DWFL_E_BADELF; + +#ifdef ZSTD + /* special case for libzstd since it is slightly different from the + API provided by bzlib and liblzma. */ + + void *next_in = mapped; + size_t avail_in = state.mapped_size; + void *next_out = NULL; + size_t avail_out = 0; + size_t total_out = 0; + + size_t result; + ZSTD_DCtx *dctx = ZSTD_createDCtx(); + if (dctx == NULL) + return fail (&state, DWFL_E_NOMEM); + + do + { + if (avail_in == 0 && state.input_buffer != NULL) + { + ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE, + start_offset + state.input_pos); + if (unlikely (n < 0)) + { + ZSTD_freeDCtx (dctx); + return fail (&state, DWFL_E_ERRNO); + } + next_in = state.input_buffer; + avail_in = n; + state.input_pos += n; + } + if (avail_out == 0) + { + ptrdiff_t pos = (void *) next_out - state.buffer; + if (!bigger_buffer (&state, avail_in)) + { + ZSTD_freeDCtx (dctx); + return fail (&state, DWFL_E_NOMEM); + } + next_out = state.buffer + pos; + avail_out = state.size - pos; + } + + ZSTD_inBuffer input = { next_in, avail_in, 0 }; + ZSTD_outBuffer output = { next_out, avail_out, 0 }; + result = ZSTD_decompressStream (dctx, &output, &input); + + if (! ZSTD_isError (result)) + { + total_out += output.pos; + next_out += output.pos; + avail_out -= output.pos; + next_in += input.pos; + avail_in -= input.pos; + } + + if (result == 0) + break; + } + while (avail_in > 0 && ! ZSTD_isError (result)); + + ZSTD_freeDCtx (dctx); + + if (ZSTD_isError (result)) + return fail (&state, DWFL_E_ZSTD); + + smaller_buffer (&state, total_out); + +#elif USE_INFLATE + + /* This style actually only works with bzlib and liblzma. + The stupid zlib interface has nothing to grok the + gzip file headers except the slow gzFile interface. */ + + z_stream z = { .next_in = mapped, .avail_in = state.mapped_size }; + int result = inflateInit (&z); + if (result != Z (OK)) + { + inflateEnd (&z); + return zlib_fail (&state, result); + } + + do + { + if (z.avail_in == 0 && state.input_buffer != NULL) + { + ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE, + start_offset + state.input_pos); + if (unlikely (n < 0)) + { + inflateEnd (&z); + return zlib_fail (&state, Z (ERRNO)); + } + z.next_in = state.input_buffer; + z.avail_in = n; + state.input_pos += n; + } + if (z.avail_out == 0) + { + ptrdiff_t pos = (void *) z.next_out - state.buffer; + if (!bigger_buffer (&state, z.avail_in)) + { + result = Z (MEM_ERROR); + break; + } + z.next_out = state.buffer + pos; + z.avail_out = state.size - pos; + } + } + while ((result = do_inflate (&z)) == Z (OK)); + +#ifdef BZLIB + uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32) + | z.total_out_lo32); + smaller_buffer (&state, total_out); +#else + smaller_buffer (&state, z.total_out); +#endif + + inflateEnd (&z); + + if (result != Z (STREAM_END)) + return zlib_fail (&state, result); + +#else /* gzip only. */ + + /* Let the decompression library read the file directly. */ + + Dwfl_Error result = open_stream (fd, start_offset, &state); + + if (result == DWFL_E_NOERROR && gzdirect (state.zf)) + { + gzclose (state.zf); + /* Not a compressed stream after all. */ + return fail (&state, DWFL_E_BADELF); + } + + if (result != DWFL_E_NOERROR) + return fail (&state, result); + + ptrdiff_t pos = 0; + while (1) + { + if (!bigger_buffer (&state, 1024)) + { + gzclose (state.zf); + return zlib_fail (&state, Z (MEM_ERROR)); + } + int n = gzread (state.zf, state.buffer + pos, state.size - pos); + if (n < 0) + { + int code; + gzerror (state.zf, &code); + gzclose (state.zf); + return zlib_fail (&state, code); + } + if (n == 0) + break; + pos += n; + } + + gzclose (state.zf); + smaller_buffer (&state, pos); +#endif + + free (state.input_buffer); + + *state.whole = state.buffer; + *whole_size = state.size; + + return DWFL_E_NOERROR; +} diff --git a/libdwfl/image-header.c b/libdwfl/image-header.c new file mode 100644 index 00000000..25fbfd99 --- /dev/null +++ b/libdwfl/image-header.c @@ -0,0 +1,105 @@ +/* Linux kernel image support for libdwfl. + Copyright (C) 2009-2011 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "system.h" + +#include +#include + +#if BYTE_ORDER == LITTLE_ENDIAN +# define LE16(x) (x) +#else +# define LE16(x) bswap_16 (x) +#endif + +/* See Documentation/x86/boot.txt in Linux kernel sources + for an explanation of these format details. */ + +#define MAGIC1 0xaa55 +#define MAGIC2 0x53726448 /* "HdrS" little-endian */ +#define MIN_VERSION 0x0208 + +#define H_START (H_SETUP_SECTS & -4) +#define H_SETUP_SECTS 0x1f1 +#define H_MAGIC1 0x1fe +#define H_MAGIC2 0x202 +#define H_VERSION 0x206 +#define H_PAYLOAD_OFFSET 0x248 +#define H_PAYLOAD_LENGTH 0x24c +#define H_END 0x250 +#define H_READ_SIZE (H_END - H_START) + +Dwfl_Error +internal_function +__libdw_image_header (int fd, off_t *start_offset, + void *mapped, size_t mapped_size) +{ + if (likely (mapped_size > H_END)) + { + const void *header = mapped; + char header_buffer[H_READ_SIZE]; + if (header == NULL) + { + ssize_t n = pread_retry (fd, header_buffer, H_READ_SIZE, + *start_offset + H_START); + if (n < 0) + return DWFL_E_ERRNO; + if (n < H_READ_SIZE) + return DWFL_E_BADELF; + + header = header_buffer - H_START; + } + + if (*(uint16_t *) (header + H_MAGIC1) == LE16 (MAGIC1) + && *(uint32_t *) (header + H_MAGIC2) == LE32 (MAGIC2) + && LE16 (*(uint16_t *) (header + H_VERSION)) >= MIN_VERSION) + { + /* The magic numbers match and the version field is sufficient. + Extract the payload bounds. */ + + uint32_t offset = LE32 (*(uint32_t *) (header + H_PAYLOAD_OFFSET)); + uint32_t length = LE32 (*(uint32_t *) (header + H_PAYLOAD_LENGTH)); + + offset += ((*(uint8_t *) (header + H_SETUP_SECTS) ?: 4) + 1) * 512; + + if (offset > H_END && offset < mapped_size + && mapped_size - offset >= length) + { + /* It looks kosher. Use it! */ + *start_offset += offset; + return DWFL_E_NOERROR; + } + } + } + return DWFL_E_BADELF; +} diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h new file mode 100644 index 00000000..f98f1d52 --- /dev/null +++ b/libdwfl/libdwfl.h @@ -0,0 +1,802 @@ +/* Interfaces for libdwfl. + Copyright (C) 2005-2010, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBDWFL_H +#define _LIBDWFL_H 1 + +#include "libdw.h" +#include + +/* Handle for a session using the library. */ +typedef struct Dwfl Dwfl; + +/* Handle for a module. */ +typedef struct Dwfl_Module Dwfl_Module; + +/* Handle describing a line record. */ +typedef struct Dwfl_Line Dwfl_Line; + +/* This holds information common for all the frames of one backtrace for + a particular thread/task/TID. Several threads belong to one Dwfl. */ +typedef struct Dwfl_Thread Dwfl_Thread; + +/* This holds everything we know about the state of the frame at a particular + PC location described by an FDE belonging to Dwfl_Thread. */ +typedef struct Dwfl_Frame Dwfl_Frame; + +/* Callbacks. */ +typedef struct +{ + int (*find_elf) (Dwfl_Module *mod, void **userdata, + const char *modname, Dwarf_Addr base, + char **file_name, Elf **elfp); + + int (*find_debuginfo) (Dwfl_Module *mod, void **userdata, + const char *modname, Dwarf_Addr base, + const char *file_name, + const char *debuglink_file, GElf_Word debuglink_crc, + char **debuginfo_file_name); + + /* Fill *ADDR with the loaded address of the section called SECNAME in + the given module. Use (Dwarf_Addr) -1 if this section is omitted from + accessible memory. This is called exactly once for each SHF_ALLOC + section that relocations affecting DWARF data refer to, so it can + easily be used to collect state about the sections referenced. */ + int (*section_address) (Dwfl_Module *mod, void **userdata, + const char *modname, Dwarf_Addr base, + const char *secname, + GElf_Word shndx, const GElf_Shdr *shdr, + Dwarf_Addr *addr); + + char **debuginfo_path; /* See dwfl_standard_find_debuginfo. */ +} Dwfl_Callbacks; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Start a new session with the library. */ +extern Dwfl *dwfl_begin (const Dwfl_Callbacks *callbacks) + __nonnull_attribute__ (1); + + +/* End a session. */ +extern void dwfl_end (Dwfl *); + +/* Return implementation's version string suitable for printing. */ +extern const char *dwfl_version (Dwfl *); + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int dwfl_errno (void); + +/* Return error string for ERROR. If ERROR is zero, return error string + for most recent error or NULL if none occurred. If ERROR is -1 the + behaviour is similar to the last case except that not NULL but a legal + string is returned. */ +extern const char *dwfl_errmsg (int err); + + +/* Start reporting the current set of segments and modules to the library. + All existing segments are wiped. Existing modules are marked to be + deleted, and will not be found via dwfl_addrmodule et al if they are not + re-reported before dwfl_report_end is called. */ +extern void dwfl_report_begin (Dwfl *dwfl); + +/* Report that segment NDX begins at PHDR->p_vaddr + BIAS. + If NDX is < 0, the value succeeding the last call's NDX + is used instead (zero on the first call). IDENT is ignored. + + If nonzero, the smallest PHDR->p_align value seen sets the + effective page size for the address space DWFL describes. + This is the granularity at which reported module boundary + addresses will be considered to fall in or out of a segment. + + Returns -1 for errors, or NDX (or its assigned replacement) on success. + + Reporting segments at all is optional. Its only benefit to the caller is to + offer this quick lookup via dwfl_addrsegment, or use other segment-based + calls. */ +extern int dwfl_report_segment (Dwfl *dwfl, int ndx, + const GElf_Phdr *phdr, GElf_Addr bias, + const void *ident); + +/* Report that a module called NAME spans addresses [START, END). + Returns the module handle, either existing or newly allocated, + or returns a null pointer for an allocation error. */ +extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name, + Dwarf_Addr start, Dwarf_Addr end); + +/* Report a module to address BASE with start and end addresses computed + from the ELF program headers in the given file - see the table below. + FD may be -1 to open FILE_NAME. On success, FD is consumed by the + library, and the `find_elf' callback will not be used for this module. + ADD_P_VADDR BASE + ET_EXEC ignored ignored + ET_DYN false absolute address where to place the file + true start address relative to ELF's phdr p_vaddr + ET_REL ignored absolute address where to place the file + ET_CORE ignored ignored + ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library + has been prelinked by tool prelink(8). */ +extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base, bool add_p_vaddr); + +/* Similar, but report the module for offline use. All ET_EXEC files + being reported must be reported before any relocatable objects. + If this is used, dwfl_report_module and dwfl_report_elf may not be + used in the same reporting session. */ +extern Dwfl_Module *dwfl_report_offline (Dwfl *dwfl, const char *name, + const char *file_name, int fd); + + +/* Finish reporting the current set of modules to the library. + If REMOVED is not null, it's called for each module that + existed before but was not included in the current report. + Returns a nonzero return value from the callback. + The callback may call dwfl_report_module; doing so with the + details of the module being removed prevents its removal. + DWFL cannot be used until this function has returned zero. */ +extern int dwfl_report_end (Dwfl *dwfl, + int (*removed) (Dwfl_Module *, void *, + const char *, Dwarf_Addr, + void *arg), + void *arg); + +/* Start reporting additional modules to the library. No calls but + dwfl_report_* can be made on DWFL until dwfl_report_end is called. + This is like dwfl_report_begin, but all the old modules are kept on. + More dwfl_report_* calls can follow to add more modules. + When dwfl_report_end is called, no old modules will be removed. */ +extern void dwfl_report_begin_add (Dwfl *dwfl); + + +/* Return the name of the module, and for each non-null argument store + interesting details: *USERDATA is a location for storing your own + pointer, **USERDATA is initially null; *START and *END give the address + range covered by the module; *DWBIAS is the address bias for debugging + information, and *SYMBIAS for symbol table entries (either is -1 if not + yet accessed); *MAINFILE is the name of the ELF file, and *DEBUGFILE the + name of the debuginfo file (might be equal to *MAINFILE; either is null + if not yet accessed). */ +extern const char *dwfl_module_info (Dwfl_Module *mod, void ***userdata, + Dwarf_Addr *start, Dwarf_Addr *end, + Dwarf_Addr *dwbias, Dwarf_Addr *symbias, + const char **mainfile, + const char **debugfile); + +/* Iterate through the modules, starting the walk with OFFSET == 0. + Calls *CALLBACK for each module as long as it returns DWARF_CB_OK. + When *CALLBACK returns another value, the walk stops and the + return value can be passed as OFFSET to resume it. Returns 0 when + there are no more modules, or -1 for errors. */ +extern ptrdiff_t dwfl_getmodules (Dwfl *dwfl, + int (*callback) (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + void *arg), + void *arg, + ptrdiff_t offset); + +/* Find the module containing the given address. */ +extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address); + +/* Find the segment, if any, and module, if any, containing ADDRESS. + Returns a segment index returned by dwfl_report_segment, or -1 + if no segment matches the address. Regardless of the return value, + *MOD is always set to the module containing ADDRESS, or to null. */ +extern int dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod); + + + +/* Report the known build ID bits associated with a module. + If VADDR is nonzero, it gives the absolute address where those + bits are found within the module. This can be called at any + time, but is usually used immediately after dwfl_report_module. + Once the module's main ELF file is opened, the ID note found + there takes precedence and cannot be changed. */ +extern int dwfl_module_report_build_id (Dwfl_Module *mod, + const unsigned char *bits, size_t len, + GElf_Addr vaddr) + __nonnull_attribute__ (2); + +/* Extract the build ID bits associated with a module. + Returns -1 for errors, 0 if no ID is known, or the number of ID bytes. + When an ID is found, *BITS points to it; *VADDR is the absolute address + at which the ID bits are found within the module, or 0 if unknown. + + This returns 0 when the module's main ELF file has not yet been loaded + and its build ID bits were not reported. To ensure the ID is always + returned when determinable, call dwfl_module_getelf first. */ +extern int dwfl_module_build_id (Dwfl_Module *mod, + const unsigned char **bits, GElf_Addr *vaddr) + __nonnull_attribute__ (2, 3); + + +/*** Standard callbacks ***/ + +/* These standard find_elf and find_debuginfo callbacks are + controlled by a string specifying directories to look in. + If `debuginfo_path' is set in the Dwfl_Callbacks structure + and the char * it points to is not null, that supplies the + string. Otherwise a default path is used. + + If the first character of the string is + or - that enables or + disables CRC32 checksum validation when it's necessary. The + remainder of the string is composed of elements separated by + colons. Each element can start with + or - to override the + global checksum behavior. This flag is never relevant when + working with build IDs, but it's always parsed in the path + string. The remainder of the element indicates a directory. + + Searches by build ID consult only the elements naming absolute + directory paths. They look under those directories for a link + named ".build-id/xx/yy" or ".build-id/xx/yy.debug", where "xxyy" + is the lower-case hexadecimal representation of the ID bytes. + + In searches for debuginfo by name, if the remainder of the + element is empty, the directory containing the main file is + tried; if it's an absolute path name, the absolute directory path + (and any subdirectory of that path) containing the main file is + taken as a subdirectory of this path; a relative path name is taken + as a subdirectory of the directory containing the main file. + Hence for /usr/bin/ls, the default string ":.debug:/usr/lib/debug" + says to look in /usr/bin, then /usr/bin/.debug, then the path subdirs + under /usr/lib/debug, in the order /usr/lib/debug/usr/bin, then + /usr/lib/debug/bin, and finally /usr/lib/debug, for the file name in + the .gnu_debuglink section (or "ls.debug" if none was found). */ + +/* Standard find_elf callback function working solely on build ID. + This can be tried first by any find_elf callback, to use the + bits passed to dwfl_module_report_build_id, if any. */ +extern int dwfl_build_id_find_elf (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + char **, Elf **); + +/* Standard find_debuginfo callback function working solely on build ID. + This can be tried first by any find_debuginfo callback, + to use the build ID bits from the main file when present. */ +extern int dwfl_build_id_find_debuginfo (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + const char *, const char *, + GElf_Word, char **); + +/* Standard find_debuginfo callback function. + If a build ID is available, this tries first to use that. + If there is no build ID or no valid debuginfo found by ID, + it searches the debuginfo path by name, as described above. + Any file found in the path is validated by build ID if possible, + or else by CRC32 checksum if enabled, and skipped if it does not match. */ +extern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + const char *, const char *, + GElf_Word, char **); + + +/* This callback must be used when using dwfl_offline_* to report modules, + if ET_REL is to be supported. */ +extern int dwfl_offline_section_address (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + const char *, GElf_Word, + const GElf_Shdr *, + Dwarf_Addr *addr); + + +/* Callbacks for working with kernel modules in the running Linux kernel. */ +extern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + char **, Elf **); +extern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + const char *, GElf_Word, + const GElf_Shdr *, + Dwarf_Addr *addr); + +/* Call dwfl_report_elf for the running Linux kernel. + Returns zero on success, -1 if dwfl_report_module failed, + or an errno code if opening the kernel binary failed. */ +extern int dwfl_linux_kernel_report_kernel (Dwfl *dwfl); + +/* Call dwfl_report_module for each kernel module in the running Linux kernel. + Returns zero on success, -1 if dwfl_report_module failed, + or an errno code if reading the list of modules failed. */ +extern int dwfl_linux_kernel_report_modules (Dwfl *dwfl); + +/* Report a kernel and its modules found on disk, for offline use. + If RELEASE starts with '/', it names a directory to look in; + if not, it names a directory to find under /lib/modules/; + if null, /lib/modules/`uname -r` is used. + Returns zero on success, -1 if dwfl_report_module failed, + or an errno code if finding the files on disk failed. + + If PREDICATE is not null, it is called with each module to be reported; + its arguments are the module name, and the ELF file name or null if unknown, + and its return value should be zero to skip the module, one to report it, + or -1 to cause the call to fail and return errno. */ +extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release, + int (*predicate) (const char *, + const char *)); + +/* Examine an ET_CORE file and report modules based on its contents. + This can follow a dwfl_report_offline call to bootstrap the + DT_DEBUG method of following the dynamic linker link_map chain, in + case the core file does not contain enough of the executable's text + segment to locate its PT_DYNAMIC in the dump. In such case you need to + supply non-NULL EXECUTABLE, otherwise dynamic libraries will not be loaded + into the DWFL map. This might call dwfl_report_elf on file names found in + the dump if reading some link_map files is the only way to ascertain those + modules' addresses. Returns the number of modules reported, or -1 for + errors. */ +extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable); + +/* Call dwfl_report_module for each file mapped into the address space of PID. + Returns zero on success, -1 if dwfl_report_module failed, + or an errno code if opening the proc files failed. */ +extern int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid); + +/* Similar, but reads an input stream in the format of Linux /proc/PID/maps + files giving module layout, not the file for a live process. */ +extern int dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *); + +/* Trivial find_elf callback for use with dwfl_linux_proc_report. + This uses the module name as a file name directly and tries to open it + if it begin with a slash, or handles the magic string "[vdso]". */ +extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata, + const char *module_name, Dwarf_Addr base, + char **file_name, Elf **); + +/* Standard argument parsing for using a standard callback set. */ +struct argp; +extern const struct argp *dwfl_standard_argp (void) __const_attribute__; + + +/*** Relocation of addresses from Dwfl ***/ + +/* Return the number of relocatable bases associated with the module, + which is zero for ET_EXEC and one for ET_DYN. Returns -1 for errors. */ +extern int dwfl_module_relocations (Dwfl_Module *mod); + +/* Return the relocation base index associated with the *ADDRESS location, + and adjust *ADDRESS to be an offset relative to that base. + Returns -1 for errors. */ +extern int dwfl_module_relocate_address (Dwfl_Module *mod, + Dwarf_Addr *address); + +/* Return the ELF section name for the given relocation base index; + if SHNDXP is not null, set *SHNDXP to the ELF section index. + For ET_DYN, returns "" and sets *SHNDXP to SHN_ABS; the relocation + base is the runtime start address reported for the module. + Returns null for errors. */ +extern const char *dwfl_module_relocation_info (Dwfl_Module *mod, + unsigned int idx, + GElf_Word *shndxp); + +/* Validate that ADDRESS and ADDRESS+OFFSET lie in a known module + and both within the same contiguous region for relocation purposes. + Returns zero for success and -1 for errors. */ +extern int dwfl_validate_address (Dwfl *dwfl, + Dwarf_Addr address, Dwarf_Sword offset); + + +/*** ELF access functions ***/ + +/* Fetch the module main ELF file (where the allocated sections + are found) for use with libelf. If successful, fills in *BIAS + with the difference between addresses within the loaded module + and those in symbol tables or Dwarf information referring to it. */ +extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias) + __nonnull_attribute__ (2); + +/* Return the number of symbols in the module's symbol table, + or -1 for errors. */ +extern int dwfl_module_getsymtab (Dwfl_Module *mod); + +/* Return the index of the first global symbol in the module's symbol + table, or -1 for errors. In each symbol table, all symbols with + STB_LOCAL binding precede the weak and global symbols. This + function returns the symbol table index one greater than the last + local symbol. */ +extern int dwfl_module_getsymtab_first_global (Dwfl_Module *mod); + +/* Fetch one entry from the module's symbol table. On errors, returns + NULL. If successful, fills in *SYM and returns the string for st_name. + This works like gelf_getsym except that st_value is always adjusted to + an absolute value based on the module's location, when the symbol is in + an SHF_ALLOC section. If SHNDXP is non-null, it's set with the section + index (whether from st_shndx or extended index table); in case of a + symbol in a non-allocated section, *SHNDXP is instead set to -1. + Note that since symbols can come from either the main, debug or auxiliary + ELF symbol file (either dynsym or symtab) the section index can only + be reliably used to compare against special section constants like + SHN_UNDEF or SHN_ABS. It is recommended to use dwfl_module_getsym_info + which doesn't have these deficiencies. */ +extern const char *dwfl_module_getsym (Dwfl_Module *mod, int ndx, + GElf_Sym *sym, GElf_Word *shndxp) + __nonnull_attribute__ (3); + +/* Fetch one entry from the module's symbol table and the associated + address value. On errors, returns NULL. If successful, fills in + *SYM, *ADDR and returns the string for st_name. This works like + gelf_getsym. *ADDR is set to the st_value adjusted to an absolute + value based on the module's location, when the symbol is in an + SHF_ALLOC section. For non-ET_REL files, if the arch uses function + descriptors, and the st_value points to one, *ADDR will be resolved + to the actual function entry address. The SYM->ST_VALUE itself + isn't adjusted in any way. Fills in ELFP, if not NULL, with the + ELF file the symbol originally came from. Note that symbols can + come from either the main, debug or auxiliary ELF symbol file + (either dynsym or symtab). If SHNDXP is non-null, it's set with + the section index (whether from st_shndx or extended index table); + in case of a symbol in a non-allocated section, *SHNDXP is instead + set to -1. Fills in BIAS, if not NULL, with the difference between + addresses within the loaded module and those in symbol table of the + ELF file. Note that the address associated with the symbol might + be in a different section than the returned symbol. The section in + the main elf file in which returned ADDR falls can be found with + dwfl_module_address_section. */ +extern const char *dwfl_module_getsym_info (Dwfl_Module *mod, int ndx, + GElf_Sym *sym, GElf_Addr *addr, + GElf_Word *shndxp, + Elf **elfp, Dwarf_Addr *bias) + __nonnull_attribute__ (3, 4); + +/* Find the symbol that ADDRESS lies inside, and return its name. */ +extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address); + +/* Find the symbol associated with ADDRESS. Return its name or NULL + when nothing was found. If the architecture uses function + descriptors, and symbol st_value points to one, ADDRESS will be + matched against either the adjusted st_value or the associated + function entry value as described in dwfl_module_getsym_info. If + OFFSET is not NULL it will be filled in with the difference from + the start of the symbol (or function entry). If SYM is not NULL it + is filled in with the symbol associated with the matched ADDRESS. + The SYM->ST_VALUE itself isn't adjusted in any way. Fills in ELFP, + if not NULL, with the ELF file the symbol originally came from. + Note that symbols can come from either the main, debug or auxiliary + ELF symbol file (either dynsym or symtab). If SHNDXP is non-null, + it's set with the section index (whether from st_shndx or extended + index table). Fills in BIAS, if not NULL, with the difference + between addresses within the loaded module and those in symbol + table of the ELF file. Note that the address matched against the + symbol might be in a different section than the returned symbol. + The section in the main elf file in ADDRESS falls can be found with + dwfl_module_address_section. */ +extern const char *dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address, + GElf_Off *offset, GElf_Sym *sym, + GElf_Word *shndxp, Elf **elfp, + Dwarf_Addr *bias) + __nonnull_attribute__ (3); + +/* Find the symbol that ADDRESS lies inside, and return detailed + information as for dwfl_module_getsym (above). Note that like + dwfl_module_getsym this function also adjusts SYM->ST_VALUE to an + absolute value based on the module's location. ADDRESS is only + matched against this adjusted SYM->ST_VALUE. This means that + depending on architecture this might only match symbols that + represent function descriptor addresses (and not function entry + addresses). For these reasons it is recommended to use + dwfl_module_addrinfo instead. */ +extern const char *dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr address, + GElf_Sym *sym, GElf_Word *shndxp) + __nonnull_attribute__ (3); + +/* Find the ELF section that *ADDRESS lies inside and return it. + On success, adjusts *ADDRESS to be relative to the section, + and sets *BIAS to the difference between addresses used in + the returned section's headers and run-time addresses. */ +extern Elf_Scn *dwfl_module_address_section (Dwfl_Module *mod, + Dwarf_Addr *address, + Dwarf_Addr *bias) + __nonnull_attribute__ (2, 3); + + +/*** Dwarf access functions ***/ + +/* Fetch the module's debug information for use with libdw. + If successful, fills in *BIAS with the difference between + addresses within the loaded module and those to use with libdw. */ +extern Dwarf *dwfl_module_getdwarf (Dwfl_Module *, Dwarf_Addr *bias) + __nonnull_attribute__ (2); + +/* Get the libdw handle for each module. */ +extern ptrdiff_t dwfl_getdwarf (Dwfl *, + int (*callback) (Dwfl_Module *, void **, + const char *, Dwarf_Addr, + Dwarf *, Dwarf_Addr, void *), + void *arg, ptrdiff_t offset); + +/* Look up the module containing ADDR and return its debugging information, + loading it if necessary. */ +extern Dwarf *dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) + __nonnull_attribute__ (3); + + +/* Find the CU containing ADDR and return its DIE. */ +extern Dwarf_Die *dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) + __nonnull_attribute__ (3); +extern Dwarf_Die *dwfl_module_addrdie (Dwfl_Module *mod, + Dwarf_Addr addr, Dwarf_Addr *bias) + __nonnull_attribute__ (3); + +/* Iterate through the CUs, start with null for LASTCU. */ +extern Dwarf_Die *dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias) + __nonnull_attribute__ (3); +extern Dwarf_Die *dwfl_module_nextcu (Dwfl_Module *mod, + Dwarf_Die *lastcu, Dwarf_Addr *bias) + __nonnull_attribute__ (3); + +/* Return the module containing the CU DIE. */ +extern Dwfl_Module *dwfl_cumodule (Dwarf_Die *cudie); + + +/* Cache the source line information for the CU and return the + number of Dwfl_Line entries it has. */ +extern int dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines); + +/* Access one line number entry within the CU. */ +extern Dwfl_Line *dwfl_onesrcline (Dwarf_Die *cudie, size_t idx); + +/* Get source for address. */ +extern Dwfl_Line *dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr); +extern Dwfl_Line *dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr); + +/* Get address for source. */ +extern int dwfl_module_getsrc_file (Dwfl_Module *mod, + const char *fname, int lineno, int column, + Dwfl_Line ***srcsp, size_t *nsrcs); + +/* Return the module containing this line record. */ +extern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line); + +/* Return the CU containing this line record. */ +extern Dwarf_Die *dwfl_linecu (Dwfl_Line *line); + +/* Return the source file name and fill in other information. + Arguments may be null for unneeded fields. */ +extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, + int *linep, int *colp, + Dwarf_Word *mtime, Dwarf_Word *length); + + /* Return the equivalent Dwarf_Line and the bias to apply to its address. */ +extern Dwarf_Line *dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias); + +/* Return the compilation directory (AT_comp_dir) from this line's CU. */ +extern const char *dwfl_line_comp_dir (Dwfl_Line *line); + + +/*** Machine backend access functions ***/ + +/* Return location expression to find return value given a + DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing + function itself (whose DW_AT_type attribute describes its return type). + The given DIE must come from the given module. Returns -1 for errors. + Returns zero if the function has no return value (e.g. "void" in C). + Otherwise, *LOCOPS gets a location expression to find the return value, + and returns the number of operations in the expression. The pointer is + permanently allocated at least as long as the module is live. */ +extern int dwfl_module_return_value_location (Dwfl_Module *mod, + Dwarf_Die *functypedie, + const Dwarf_Op **locops); + +/* Enumerate the DWARF register numbers and their names. + For each register, CALLBACK gets its DWARF number, a string describing + the register set (such as "integer" or "FPU"), a prefix used in + assembler syntax (such as "%" or "$", may be ""), and the name for the + register (contains identifier characters only, possibly all digits). + The REGNAME string is valid only during the callback. */ +extern int dwfl_module_register_names (Dwfl_Module *mod, + int (*callback) (void *arg, + int regno, + const char *setname, + const char *prefix, + const char *regname, + int bits, int type), + void *arg); + + +/* Find the CFI for this module. Returns NULL if there is no CFI. + On success, fills in *BIAS with the difference between addresses + within the loaded module and those in the CFI referring to it. + The pointer returned can be used until the module is cleaned up. + Calling these more than once returns the same pointers. + + dwfl_module_dwarf_cfi gets the '.debug_frame' information found with the + rest of the DWARF information. dwfl_module_eh_cfi gets the '.eh_frame' + information found linked into the text. A module might have either or + both. */ +extern Dwarf_CFI *dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias); +extern Dwarf_CFI *dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias); + + +typedef struct +{ + /* Called to iterate through threads. Returns next TID (thread ID) on + success, a negative number on failure and zero if there are no more + threads. dwfl_errno () should be set if negative number has been + returned. *THREAD_ARGP is NULL on first call, and may be optionally + set by the implementation. The value set by the implementation will + be passed in on the next call to NEXT_THREAD. THREAD_ARGP is never + NULL. *THREAD_ARGP will be passed to set_initial_registers or + thread_detach callbacks together with Dwfl_Thread *thread. This + method must not be NULL. */ + pid_t (*next_thread) (Dwfl *dwfl, void *dwfl_arg, void **thread_argp) + __nonnull_attribute__ (1); + + /* Called to get a specific thread. Returns true if there is a + thread with the given thread id number, returns false if no such + thread exists and will set dwfl_errno in that case. THREAD_ARGP + is never NULL. *THREAD_ARGP will be passed to + set_initial_registers or thread_detach callbacks together with + Dwfl_Thread *thread. This method may be NULL and will then be + emulated using the next_thread callback. */ + bool (*get_thread) (Dwfl *dwfl, pid_t tid, void *dwfl_arg, + void **thread_argp) + __nonnull_attribute__ (1); + + /* Called during unwinding to access memory (stack) state. Returns true for + successfully read *RESULT or false and sets dwfl_errno () on failure. + This method may be NULL - in such case dwfl_thread_getframes will return + only the initial frame. */ + bool (*memory_read) (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, + void *dwfl_arg) + __nonnull_attribute__ (1, 3); + + /* Called on initial unwind to get the initial register state of the first + frame. Should call dwfl_thread_state_registers, possibly multiple times + for different ranges and possibly also dwfl_thread_state_register_pc, to + fill in initial (DWARF) register values. After this call, till at least + thread_detach is called, the thread is assumed to be frozen, so that it is + safe to unwind. Returns true on success or false and sets dwfl_errno () + on failure. In the case of a failure thread_detach will not be called. + This method must not be NULL. */ + bool (*set_initial_registers) (Dwfl_Thread *thread, void *thread_arg) + __nonnull_attribute__ (1); + + /* Called by dwfl_end. All thread_detach method calls have been already + done. This method may be NULL. */ + void (*detach) (Dwfl *dwfl, void *dwfl_arg) + __nonnull_attribute__ (1); + + /* Called when unwinding is done. No callback will be called after + this method has been called. Iff set_initial_registers was called for + a TID and it returned success thread_detach will be called before the + detach method above. This method may be NULL. */ + void (*thread_detach) (Dwfl_Thread *thread, void *thread_arg) + __nonnull_attribute__ (1); +} Dwfl_Thread_Callbacks; + +/* PID is the process id associated with the DWFL state. Architecture of DWFL + modules is specified by ELF, ELF must remain valid during DWFL lifetime. + Use NULL ELF to detect architecture from DWFL, the function will then detect + it from arbitrary Dwfl_Module of DWFL. DWFL_ARG is the callback backend + state. DWFL_ARG will be provided to the callbacks. *THREAD_CALLBACKS + function pointers must remain valid during lifetime of DWFL. Function + returns true on success, false otherwise. */ +bool dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid, + const Dwfl_Thread_Callbacks *thread_callbacks, + void *dwfl_arg) + __nonnull_attribute__ (1, 4); + +/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting + thread state from the ELF core file. Returns the pid number extracted + from the core file, or -1 for errors. */ +extern int dwfl_core_file_attach (Dwfl *dwfl, Elf *elf); + +/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting + thread state from the proc file system. Uses ptrace to attach and stop + the thread under inspection and detaches when thread_detach is called + and unwinding for the thread is done, unless ASSUME_PTRACE_STOPPED is + true. If ASSUME_PTRACE_STOPPED is true the caller should make sure that + the thread is ptrace attached and stopped before unwinding by calling + either dwfl_thread_getframes or dwfl_getthread_frames. Returns zero on + success, -1 if dwfl_attach_state failed, or an errno code if opening the + proc files failed. */ +extern int dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, + bool assume_ptrace_stopped); + +/* Return PID for the process associated with DWFL. Function returns -1 if + dwfl_attach_state was not called for DWFL. */ +pid_t dwfl_pid (Dwfl *dwfl) + __nonnull_attribute__ (1); + +/* Return DWFL from which THREAD was created using dwfl_getthreads. */ +Dwfl *dwfl_thread_dwfl (Dwfl_Thread *thread) + __nonnull_attribute__ (1); + +/* Return positive TID (thread ID) for THREAD. This function never fails. */ +pid_t dwfl_thread_tid (Dwfl_Thread *thread) + __nonnull_attribute__ (1); + +/* Return thread for frame STATE. This function never fails. */ +Dwfl_Thread *dwfl_frame_thread (Dwfl_Frame *state) + __nonnull_attribute__ (1); + +/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation. + For every known continuous block of registers . */ + +#ifndef _LIBDWFLP_H +#define _LIBDWFLP_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../libdw/libdwP.h" /* We need its INTDECLs. */ +#include "../libdwelf/libdwelfP.h" + +#ifdef ENABLE_LIBDEBUGINFOD +#include "../debuginfod/debuginfod.h" +#endif + +typedef struct Dwfl_Process Dwfl_Process; + +#define DWFL_ERRORS \ + DWFL_ERROR (NOERROR, N_("no error")) \ + DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error")) \ + DWFL_ERROR (NOMEM, N_("out of memory")) \ + DWFL_ERROR (ERRNO, N_("See errno")) \ + DWFL_ERROR (LIBELF, N_("See elf_errno")) \ + DWFL_ERROR (LIBDW, N_("See dwarf_errno")) \ + DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)")) \ + DWFL_ERROR (ZLIB, N_("gzip decompression failed")) \ + DWFL_ERROR (BZLIB, N_("bzip2 decompression failed")) \ + DWFL_ERROR (LZMA, N_("LZMA decompression failed")) \ + DWFL_ERROR (ZSTD, N_("zstd decompression failed")) \ + DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine")) \ + DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file")) \ + DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type")) \ + DWFL_ERROR (BADRELOFF, N_("r_offset is bogus")) \ + DWFL_ERROR (BADSTROFF, N_("offset out of range")) \ + DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol")) \ + DWFL_ERROR (CB, N_("Callback returned failure")) \ + DWFL_ERROR (NO_DWARF, N_("No DWARF information found")) \ + DWFL_ERROR (NO_SYMTAB, N_("No symbol table found")) \ + DWFL_ERROR (NO_PHDR, N_("No ELF program headers")) \ + DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module")) \ + DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \ + DWFL_ERROR (NO_MATCH, N_("no matching address range")) \ + DWFL_ERROR (TRUNCATED, N_("image truncated")) \ + DWFL_ERROR (ALREADY_ELF, N_("ELF file opened")) \ + DWFL_ERROR (BADELF, N_("not a valid ELF file")) \ + DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description")) \ + DWFL_ERROR (WRONG_ID_ELF, N_("ELF file does not match build ID")) \ + DWFL_ERROR (BAD_PRELINK, N_("corrupt .gnu.prelink_undo section data")) \ + DWFL_ERROR (LIBEBL_BAD, N_("Internal error due to ebl")) \ + DWFL_ERROR (CORE_MISSING, N_("Missing data in core file")) \ + DWFL_ERROR (INVALID_REGISTER, N_("Invalid register")) \ + DWFL_ERROR (PROCESS_MEMORY_READ, N_("Error reading process memory")) \ + DWFL_ERROR (PROCESS_NO_ARCH, N_("Couldn't find architecture of any ELF")) \ + DWFL_ERROR (PARSE_PROC, N_("Error parsing /proc filesystem")) \ + DWFL_ERROR (INVALID_DWARF, N_("Invalid DWARF")) \ + DWFL_ERROR (UNSUPPORTED_DWARF, N_("Unsupported DWARF")) \ + DWFL_ERROR (NEXT_THREAD_FAIL, N_("Unable to find more threads")) \ + DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state")) \ + DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state")) \ + DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \ + DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument")) \ + DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file")) + +#define DWFL_ERROR(name, text) DWFL_E_##name, +typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error; +#undef DWFL_ERROR + +#define OTHER_ERROR(name) ((unsigned int) DWFL_E_##name << 16) +#define DWFL_E(name, errno) (OTHER_ERROR (name) | (errno)) + +extern int __libdwfl_canon_error (Dwfl_Error) internal_function; +extern void __libdwfl_seterrno (Dwfl_Error) internal_function; + +/* Resources we might keep for the user about the core file that the + Dwfl might have been created from. Can currently only be set + through std-argp. */ +struct Dwfl_User_Core +{ + char *executable_for_core; /* --executable if --core was specified. */ + Elf *core; /* non-NULL if we need to free it. */ + int fd; /* close if >= 0. */ +}; + +struct Dwfl +{ + const Dwfl_Callbacks *callbacks; +#ifdef ENABLE_LIBDEBUGINFOD + debuginfod_client *debuginfod; +#endif + Dwfl_Module *modulelist; /* List in order used by full traversals. */ + + Dwfl_Process *process; + Dwfl_Error attacherr; /* Previous error attaching process. */ + + GElf_Addr offline_next_address; + + GElf_Addr segment_align; /* Smallest granularity of segments. */ + + /* Binary search table in three parallel malloc'd arrays. */ + size_t lookup_elts; /* Elements in use. */ + size_t lookup_alloc; /* Elements allococated. */ + GElf_Addr *lookup_addr; /* Start address of segment. */ + Dwfl_Module **lookup_module; /* Module associated with segment, or null. */ + int *lookup_segndx; /* User segment index, or -1. */ + int next_segndx; + + struct Dwfl_User_Core *user_core; +}; + +#define OFFLINE_REDZONE 0x10000 + +struct dwfl_file +{ + char *name; + int fd; + bool valid; /* The build ID note has been matched. */ + bool relocated; /* Partial relocation of all sections done. */ + + Elf *elf; + + /* This is the lowest p_vaddr in this ELF file, aligned to p_align. + For a file without phdrs, this is zero. */ + GElf_Addr vaddr; + + /* This is an address chosen for synchronization between the main file + and the debug file. See dwfl_module_getdwarf.c for how it's chosen. */ + GElf_Addr address_sync; +}; + +struct Dwfl_Module +{ + Dwfl *dwfl; + struct Dwfl_Module *next; /* Link on Dwfl.modulelist. */ + + void *userdata; + + char *name; /* Iterator name for this module. */ + GElf_Addr low_addr, high_addr; + + struct dwfl_file main, debug, aux_sym; + GElf_Addr main_bias; + Ebl *ebl; + GElf_Half e_type; /* GElf_Ehdr.e_type cache. */ + Dwfl_Error elferr; /* Previous failure to open main file. */ + + struct dwfl_relocation *reloc_info; /* Relocatable sections. */ + + struct dwfl_file *symfile; /* Either main or debug. */ + Elf_Data *symdata; /* Data in the ELF symbol table section. */ + Elf_Data *aux_symdata; /* Data in the auxiliary ELF symbol table. */ + size_t syments; /* sh_size / sh_entsize of that section. */ + size_t aux_syments; /* sh_size / sh_entsize of aux_sym section. */ + int first_global; /* Index of first global symbol of table. */ + int aux_first_global; /* Index of first global of aux_sym table. */ + Elf_Data *symstrdata; /* Data for its string table. */ + Elf_Data *aux_symstrdata; /* Data for aux_sym string table. */ + Elf_Data *symxndxdata; /* Data in the extended section index table. */ + Elf_Data *aux_symxndxdata; /* Data in the extended auxiliary table. */ + + char *elfdir; /* The dir where we found the main Elf. */ + + Dwarf *dw; /* libdw handle for its debugging info. */ + Dwarf *alt; /* Dwarf used for dwarf_setalt, or NULL. */ + int alt_fd; /* descriptor, only valid when alt != NULL. */ + Elf *alt_elf; /* Elf for alt Dwarf. */ + + Dwfl_Error symerr; /* Previous failure to load symbols. */ + Dwfl_Error dwerr; /* Previous failure to load DWARF. */ + + /* Known CU's in this module. */ + struct dwfl_cu *first_cu, **cu; + + void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */ + + struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */ + + void *build_id_bits; /* malloc'd copy of build ID bits. */ + GElf_Addr build_id_vaddr; /* Address where they reside, 0 if unknown. */ + int build_id_len; /* -1 for prior failure, 0 if unset. */ + + unsigned int ncu; + unsigned int lazycu; /* Possible users, deleted when none left. */ + unsigned int naranges; + + Dwarf_CFI *dwarf_cfi; /* Cached DWARF CFI for this module. */ + Dwarf_CFI *eh_cfi; /* Cached EH CFI for this module. */ + + int segment; /* Index of first segment table entry. */ + bool gc; /* Mark/sweep flag. */ + bool is_executable; /* Use Dwfl::executable_for_core? */ +}; + +/* This holds information common for all the threads/tasks/TIDs of one process + for backtraces. */ + +struct Dwfl_Process +{ + struct Dwfl *dwfl; + pid_t pid; + const Dwfl_Thread_Callbacks *callbacks; + void *callbacks_arg; + struct ebl *ebl; + bool ebl_close:1; +}; + +/* See its typedef in libdwfl.h. */ + +struct Dwfl_Thread +{ + Dwfl_Process *process; + pid_t tid; + /* Bottom (innermost) frame while we're initializing, NULL afterwards. */ + Dwfl_Frame *unwound; + void *callbacks_arg; +}; + +/* See its typedef in libdwfl.h. */ + +struct Dwfl_Frame +{ + Dwfl_Thread *thread; + /* Previous (outer) frame. */ + Dwfl_Frame *unwound; + bool signal_frame : 1; + bool initial_frame : 1; + enum + { + /* This structure is still being initialized or there was an error + initializing it. */ + DWFL_FRAME_STATE_ERROR, + /* PC field is valid. */ + DWFL_FRAME_STATE_PC_SET, + /* PC field is undefined, this means the next (inner) frame was the + outermost frame. */ + DWFL_FRAME_STATE_PC_UNDEFINED + } pc_state; + /* Either initialized from appropriate REGS element or on some archs + initialized separately as the return address has no DWARF register. */ + Dwarf_Addr pc; + /* (1 << X) bitmask where 0 <= X < ebl_frame_nregs. */ + uint64_t regs_set[3]; + /* REGS array size is ebl_frame_nregs. + REGS_SET tells which of the REGS are valid. */ + Dwarf_Addr regs[]; +}; + +/* Fetch value from Dwfl_Frame->regs indexed by DWARF REGNO. + No error code is set if the function returns FALSE. */ +bool __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, + Dwarf_Addr *val) + internal_function; + +/* Store value to Dwfl_Frame->regs indexed by DWARF REGNO. + No error code is set if the function returns FALSE. */ +bool __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, + Dwarf_Addr val) + internal_function; + +/* Information cached about each CU in Dwfl_Module.dw. */ +struct dwfl_cu +{ + /* This caches libdw information about the CU. It's also the + address passed back to users, so we take advantage of the + fact that it's placed first to cast back. */ + Dwarf_Die die; + + Dwfl_Module *mod; /* Pointer back to containing module. */ + + struct dwfl_cu *next; /* CU immediately following in the file. */ + + struct Dwfl_Lines *lines; +}; + +struct Dwfl_Lines +{ + struct dwfl_cu *cu; + + /* This is what the opaque Dwfl_Line * pointers we pass to users are. + We need to recover pointers to our struct dwfl_cu and a record in + libdw's Dwarf_Line table. To minimize the memory used in addition + to libdw's Dwarf_Lines buffer, we just point to our own index in + this table, and have one pointer back to the CU. The indices here + match those in libdw's Dwarf_CU.lines->info table. */ + struct Dwfl_Line + { + unsigned int idx; /* My index in the dwfl_cu.lines table. */ + } idx[0]; +}; + +static inline struct dwfl_cu * +dwfl_linecu_inline (const Dwfl_Line *line) +{ + const struct Dwfl_Lines *lines = ((const void *) line + - offsetof (struct Dwfl_Lines, + idx[line->idx])); + return lines->cu; +} +#define dwfl_linecu dwfl_linecu_inline + +static inline GElf_Addr +dwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr) +{ + return addr + mod->main_bias; +} + +static inline GElf_Addr +dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr) +{ + return addr - mod->main_bias; +} + +static inline Dwarf_Addr +dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr) +{ + return dwfl_adjusted_address (mod, (addr + - mod->debug.address_sync + + mod->main.address_sync)); +} + +static inline Dwarf_Addr +dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr) +{ + return (dwfl_deadjust_address (mod, addr) + - mod->main.address_sync + + mod->debug.address_sync); +} + +static inline Dwarf_Addr +dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr) +{ + return dwfl_adjusted_address (mod, (addr + - mod->aux_sym.address_sync + + mod->main.address_sync)); +} + +static inline Dwarf_Addr +dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr) +{ + return (dwfl_deadjust_address (mod, addr) + - mod->main.address_sync + + mod->aux_sym.address_sync); +} + +static inline GElf_Addr +dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr) +{ + if (symelf == mod->main.elf) + return dwfl_adjusted_address (mod, addr); + if (symelf == mod->debug.elf) + return dwfl_adjusted_dwarf_addr (mod, addr); + return dwfl_adjusted_aux_sym_addr (mod, addr); +} + +static inline GElf_Addr +dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr) +{ + if (symelf == mod->main.elf) + return dwfl_deadjust_address (mod, addr); + if (symelf == mod->debug.elf) + return dwfl_deadjust_dwarf_addr (mod, addr); + return dwfl_deadjust_aux_sym_addr (mod, addr); +} + +/* This describes a contiguous address range that lies in a single CU. + We condense runs of Dwarf_Arange entries for the same CU into this. */ +struct dwfl_arange +{ + struct dwfl_cu *cu; + size_t arange; /* Index in Dwarf_Aranges. */ +}; + +#define __LIBDWFL_REMOTE_MEM_CACHE_SIZE 4096 +/* Structure for caching remote memory reads as used by __libdwfl_pid_arg. */ +struct __libdwfl_remote_mem_cache +{ + Dwarf_Addr addr; /* Remote address. */ + Dwarf_Off len; /* Zero if cleared, otherwise likely 4K. */ + unsigned char buf[__LIBDWFL_REMOTE_MEM_CACHE_SIZE]; /* The actual cache. */ +}; + +/* Structure used for keeping track of ptrace attaching a thread. + Shared by linux-pid-attach and linux-proc-maps. If it has been setup + then get the instance through __libdwfl_get_pid_arg. */ +struct __libdwfl_pid_arg +{ + /* /proc/PID/task/. */ + DIR *dir; + /* Elf for /proc/PID/exe. Set to NULL if it couldn't be opened. */ + Elf *elf; + /* Remote memory cache, NULL if there is no memory cached. + Should be cleared on detachment (because that makes the thread + runnable and the cache invalid). */ + struct __libdwfl_remote_mem_cache *mem_cache; + /* fd for /proc/PID/exe. Set to -1 if it couldn't be opened. */ + int elf_fd; + /* It is 0 if not used. */ + pid_t tid_attached; + /* Valid only if TID_ATTACHED is not zero. */ + bool tid_was_stopped; + /* True if threads are ptrace stopped by caller. */ + bool assume_ptrace_stopped; +}; + +/* If DWfl is not NULL and a Dwfl_Process has been setup that has + Dwfl_Thread_Callbacks set to pid_thread_callbacks, then return the + callbacks_arg, which will be a struct __libdwfl_pid_arg. Otherwise + returns NULL. */ +extern struct __libdwfl_pid_arg *__libdwfl_get_pid_arg (Dwfl *dwfl) + internal_function; + +/* Makes sure the given tid is attached. On success returns true and + sets tid_was_stopped. */ +extern bool __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp) + internal_function; + +/* Detaches a tid that was attached through + __libdwfl_ptrace_attach. Must be given the tid_was_stopped as set + by __libdwfl_ptrace_attach. */ +extern void __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped) + internal_function; + + +/* Internal wrapper for old dwfl_module_getsym and new dwfl_module_getsym_info. + adjust_st_value set to true returns adjusted SYM st_value, set to false + it will not adjust SYM at all, but does match against resolved *ADDR. */ +extern const char *__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym, + GElf_Addr *addr, GElf_Word *shndxp, + Elf **elfp, Dwarf_Addr *biasp, + bool *resolved, bool adjust_st_value) + internal_function; + +extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function; + +/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf. */ +extern void __libdwfl_getelf (Dwfl_Module *mod) internal_function; + +/* Process relocations in debugging sections in an ET_REL file. + FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ, + to make it possible to relocate the data in place (or ELF_C_RDWR or + ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk). After + this, dwarf_begin_elf on FILE will read the relocated data. + + When DEBUG is false, apply partial relocation to all sections. */ +extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug) + internal_function; + +/* Find the section index in mod->main.elf that contains the given + *ADDR. Adjusts *ADDR to be section relative on success, returns + SHN_UNDEF on failure. */ +extern size_t __libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr) + internal_function; + +/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file. + RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section. */ +extern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated, + Elf_Scn *relocscn, Elf_Scn *tscn, + bool partial) + internal_function; + +/* Adjust *VALUE from section-relative to absolute. + MOD->dwfl->callbacks->section_address is called to determine the actual + address of a loaded section. */ +extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, + size_t *shstrndx_cache, + Elf32_Word shndx, + GElf_Addr *value) + internal_function; + +/* Ensure that MOD->ebl is set up. */ +extern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function; + +/* Install a new Dwarf_CFI in *SLOT (MOD->eh_cfi or MOD->dwarf_cfi). */ +extern Dwarf_CFI *__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot, + Dwarf_CFI *cfi) + internal_function; + +/* Iterate through all the CU's in the module. Start by passing a null + LASTCU, and then pass the last *CU returned. Success return with null + *CU no more CUs. */ +extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu, + struct dwfl_cu **cu) internal_function; + +/* Find the CU by address. */ +extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr, + struct dwfl_cu **cu) internal_function; + +/* Ensure that CU->lines (and CU->cu->lines) is set up. */ +extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu) + internal_function; + +/* Look in ELF for an NT_GNU_BUILD_ID note. Store it to BUILD_ID_BITS, + its vaddr in ELF to BUILD_ID_VADDR (it is unrelocated, even if MOD is not + NULL) and store length to BUILD_ID_LEN. Returns -1 for errors, 1 if it was + stored and 0 if no note is found. MOD may be NULL, MOD must be non-NULL + only if ELF is ET_REL. */ +extern int __libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf, + const void **build_id_bits, + GElf_Addr *build_id_elfaddr, + int *build_id_len) + internal_function; + +/* Look in ELF for an NT_GNU_BUILD_ID note. If SET is true, store it + in MOD and return its length. If SET is false, instead compare it + to that stored in MOD and return 2 if they match, 1 if they do not. + Returns -1 for errors, 0 if no note is found. */ +extern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf) + internal_function; + +/* Open a main or debuginfo file by its build ID, returns the fd. */ +extern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, + char **file_name) internal_function; + +/* Same, but takes an explicit build_id, can also be used for alt debug. */ +extern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, + char **file_name, const size_t id_len, + const uint8_t *id) internal_function; + +extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len) + attribute_hidden; +extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden; + + +/* Given ELF and some parameters return TRUE if the *P return value parameters + have been successfully filled in. Any of the *P parameters can be NULL. */ +extern bool __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, + bool add_p_vaddr, bool sanity, + GElf_Addr *vaddrp, + GElf_Addr *address_syncp, + GElf_Addr *startp, GElf_Addr *endp, + GElf_Addr *biasp, GElf_Half *e_typep) + internal_function; + +/* Meat of dwfl_report_elf, given elf_begin just called. + Consumes ELF on success, not on failure. */ +extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + Elf *elf, GElf_Addr base, + bool add_p_vaddr, bool sanity) + internal_function; + +/* Meat of dwfl_report_offline. */ +extern Dwfl_Module *__libdwfl_report_offline (Dwfl *dwfl, const char *name, + const char *file_name, + int fd, bool closefd, + int (*predicate) (const char *, + const char *)) + internal_function; + +/* Free PROCESS. Unlink and free also any structures it references. */ +extern void __libdwfl_process_free (Dwfl_Process *process) + internal_function; + +/* Update STATE->unwound for the unwound frame. + On error STATE->unwound == NULL + or STATE->unwound->pc_state == DWFL_FRAME_STATE_ERROR; + in such case dwfl_errno () is set. + If STATE->unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED + then STATE was the last valid frame. */ +extern void __libdwfl_frame_unwind (Dwfl_Frame *state) + internal_function; + +/* Align segment START downwards or END upwards addresses according to DWFL. */ +extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start) + internal_function; +extern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end) + internal_function; + +/* Decompression wrappers: decompress whole file into memory. */ +extern Dwfl_Error __libdw_gunzip (int fd, off_t start_offset, + void *mapped, size_t mapped_size, + void **whole, size_t *whole_size) + internal_function; +extern Dwfl_Error __libdw_bunzip2 (int fd, off_t start_offset, + void *mapped, size_t mapped_size, + void **whole, size_t *whole_size) + internal_function; +extern Dwfl_Error __libdw_unlzma (int fd, off_t start_offset, + void *mapped, size_t mapped_size, + void **whole, size_t *whole_size) + internal_function; +extern Dwfl_Error __libdw_unzstd (int fd, off_t start_offset, + void *mapped, size_t mapped_size, + void **whole, size_t *whole_size) + internal_function; + +/* Skip the image header before a file image: updates *START_OFFSET. */ +extern Dwfl_Error __libdw_image_header (int fd, off_t *start_offset, + void *mapped, size_t mapped_size) + internal_function; + +/* Open Elf handle on *FDP. This handles decompression and checks + elf_kind. Succeed only for ELF_K_ELF, or also ELF_K_AR if ARCHIVE_OK. + Returns DWFL_E_NOERROR and sets *ELFP on success, resets *FDP to -1 if + it's no longer used. Resets *FDP on failure too iff CLOSE_ON_FAIL. */ +extern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp, + bool close_on_fail, bool archive_ok) + internal_function; + +/* Same as __libdw_open_file, but never closes the given file + descriptor and ELF_K_AR is always an acceptable type. */ +extern Dwfl_Error __libdw_open_elf (int fd, Elf **elfp) internal_function; + +/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP. Return success. + *VADDRP is not modified if the function fails. */ +extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp) + internal_function; + +#ifdef ENABLE_LIBDEBUGINFOD +/* Internal interface to libdebuginfod (if installed). */ +int +__libdwfl_debuginfod_find_executable (Dwfl *dwfl, + const unsigned char *build_id_bits, + size_t build_id_len); +int +__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl, + const unsigned char *build_id_bits, + size_t build_id_len); +void +__libdwfl_debuginfod_end (debuginfod_client *c); +#endif + + +/* These are working nicely for --core, but are not ready to be + exported interfaces quite yet. */ + +/* Type of callback function ... + */ +typedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx, + void **buffer, size_t *buffer_available, + GElf_Addr vaddr, size_t minread, void *arg); + +/* Type of callback function ... + */ +typedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata, + const char *name, Dwarf_Addr base, + void **buffer, size_t *buffer_available, + GElf_Off cost, GElf_Off worthwhile, + GElf_Off whole, GElf_Off contiguous, + void *arg, Elf **elfp); + +/* One shared library (or executable) info from DT_DEBUG link map. */ +struct r_debug_info_module +{ + struct r_debug_info_module *next; + /* FD is -1 iff ELF is NULL. */ + int fd; + Elf *elf; + GElf_Addr l_ld; + /* START and END are both zero if not valid. */ + GElf_Addr start, end; + bool disk_file_has_build_id; + char name[0]; +}; + +/* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to + dwfl_segment_report_module. */ +struct r_debug_info +{ + struct r_debug_info_module *module; +}; + +/* ... + */ +extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg, + Dwfl_Module_Callback *read_eagerly, + void *read_eagerly_arg, + const void *note_file, + size_t note_file_size, + const struct r_debug_info *r_debug_info); + +/* Report a module for entry in the dynamic linker's struct link_map list. + For each link_map entry, if an existing module resides at its address, + this just modifies that module's name and suggested file name. If + no such module exists, this calls dwfl_report_elf on the l_name string. + + If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector + data as contained in an NT_AUXV note or read from a /proc/pid/auxv + file. When this is available, it guides the search. If AUXV is null + or the memory it points to is not accessible, then this search can + only find where to begin if the correct executable file was + previously reported and preloaded as with dwfl_report_elf. + + Fill in R_DEBUG_INFO if it is not NULL. It should be cleared by the + caller, this function does not touch fields it does not need to modify. + If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller + has to add them from filled in R_DEBUG_INFO. + + Returns the number of modules found, or -1 for errors. */ +extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg, + struct r_debug_info *r_debug_info); + + +/* Avoid PLT entries. */ +INTDECL (dwfl_begin) +INTDECL (dwfl_errmsg) +INTDECL (dwfl_errno) +INTDECL (dwfl_addrmodule) +INTDECL (dwfl_addrsegment) +INTDECL (dwfl_addrdwarf) +INTDECL (dwfl_addrdie) +INTDECL (dwfl_core_file_attach) +INTDECL (dwfl_core_file_report) +INTDECL (dwfl_getmodules) +INTDECL (dwfl_module_addrdie) +INTDECL (dwfl_module_address_section) +INTDECL (dwfl_module_addrinfo) +INTDECL (dwfl_module_addrsym) +INTDECL (dwfl_module_build_id) +INTDECL (dwfl_module_getdwarf) +INTDECL (dwfl_module_getelf) +INTDECL (dwfl_module_getsym) +INTDECL (dwfl_module_getsym_info) +INTDECL (dwfl_module_getsymtab) +INTDECL (dwfl_module_getsymtab_first_global) +INTDECL (dwfl_module_getsrc) +INTDECL (dwfl_module_report_build_id) +INTDECL (dwfl_report_elf) +INTDECL (dwfl_report_begin) +INTDECL (dwfl_report_begin_add) +INTDECL (dwfl_report_module) +INTDECL (dwfl_report_segment) +INTDECL (dwfl_report_offline) +INTDECL (dwfl_report_end) +INTDECL (dwfl_build_id_find_elf) +INTDECL (dwfl_build_id_find_debuginfo) +INTDECL (dwfl_standard_find_debuginfo) +INTDECL (dwfl_link_map_report) +INTDECL (dwfl_linux_kernel_find_elf) +INTDECL (dwfl_linux_kernel_module_section_address) +INTDECL (dwfl_linux_proc_attach) +INTDECL (dwfl_linux_proc_report) +INTDECL (dwfl_linux_proc_maps_report) +INTDECL (dwfl_linux_proc_find_elf) +INTDECL (dwfl_linux_kernel_report_kernel) +INTDECL (dwfl_linux_kernel_report_modules) +INTDECL (dwfl_linux_kernel_report_offline) +INTDECL (dwfl_offline_section_address) +INTDECL (dwfl_module_relocate_address) +INTDECL (dwfl_module_dwarf_cfi) +INTDECL (dwfl_module_eh_cfi) +INTDECL (dwfl_attach_state) +INTDECL (dwfl_pid) +INTDECL (dwfl_thread_dwfl) +INTDECL (dwfl_thread_tid) +INTDECL (dwfl_frame_thread) +INTDECL (dwfl_thread_state_registers) +INTDECL (dwfl_thread_state_register_pc) +INTDECL (dwfl_getthread_frames) +INTDECL (dwfl_getthreads) +INTDECL (dwfl_thread_getframes) +INTDECL (dwfl_frame_pc) + +/* Leading arguments standard to callbacks passed a Dwfl_Module. */ +#define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr +#define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB); + + +/* The default used by dwfl_standard_find_debuginfo. */ +#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug" + + +#endif /* libdwflP.h */ diff --git a/libdwfl/libdwfl_crc32.c b/libdwfl/libdwfl_crc32.c new file mode 100644 index 00000000..b89d0d36 --- /dev/null +++ b/libdwfl/libdwfl_crc32.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define crc32 attribute_hidden __libdwfl_crc32 +#define LIB_SYSTEM_H 1 +#include +#include "../lib/crc32.c" diff --git a/libdwfl/libdwfl_crc32_file.c b/libdwfl/libdwfl_crc32_file.c new file mode 100644 index 00000000..f849128d --- /dev/null +++ b/libdwfl/libdwfl_crc32_file.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define crc32_file attribute_hidden __libdwfl_crc32_file +#define crc32 __libdwfl_crc32 +#include +#include "../lib/crc32_file.c" diff --git a/libdwfl/lines.c b/libdwfl/lines.c new file mode 100644 index 00000000..128c0c97 --- /dev/null +++ b/libdwfl/lines.c @@ -0,0 +1,56 @@ +/* Fetch source line info for CU. + Copyright (C) 2005, 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include "../libdw/libdwP.h" + +Dwfl_Error +internal_function +__libdwfl_cu_getsrclines (struct dwfl_cu *cu) +{ + if (cu->lines == NULL) + { + Dwarf_Lines *lines; + size_t nlines; + if (INTUSE(dwarf_getsrclines) (&cu->die, &lines, &nlines) != 0) + return DWFL_E_LIBDW; + + cu->lines = malloc (offsetof (struct Dwfl_Lines, idx[nlines])); + if (cu->lines == NULL) + return DWFL_E_NOMEM; + cu->lines->cu = cu; + for (unsigned int i = 0; i < nlines; ++i) + cu->lines->idx[i].idx = i; + } + + return DWFL_E_NOERROR; +} diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c new file mode 100644 index 00000000..0d8d1c17 --- /dev/null +++ b/libdwfl/link_map.c @@ -0,0 +1,1057 @@ +/* Report modules by examining dynamic linker data structures. + Copyright (C) 2008-2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include "libdwflP.h" +#include "../libdw/memory-access.h" +#include "system.h" + +#include +#include +#include + +/* This element is always provided and always has a constant value. + This makes it an easy thing to scan for to discern the format. */ +#define PROBE_TYPE AT_PHENT +#define PROBE_VAL32 sizeof (Elf32_Phdr) +#define PROBE_VAL64 sizeof (Elf64_Phdr) + + +static inline bool +do_check64 (const char *a64, uint_fast8_t *elfdata) +{ + /* The AUXV pointer might not even be naturally aligned for 64-bit + data, because note payloads in a core file are not aligned. */ + const char *typep = a64 + offsetof (Elf64_auxv_t, a_type); + uint64_t type = read_8ubyte_unaligned_noncvt (typep); + const char *valp = a64 + offsetof (Elf64_auxv_t, a_un.a_val); + uint64_t val = read_8ubyte_unaligned_noncvt (valp); + + if (type == BE64 (PROBE_TYPE) + && val == BE64 (PROBE_VAL64)) + { + *elfdata = ELFDATA2MSB; + return true; + } + + if (type == LE64 (PROBE_TYPE) + && val == LE64 (PROBE_VAL64)) + { + *elfdata = ELFDATA2LSB; + return true; + } + + return false; +} + +static inline bool +do_check32 (const char *a32, uint_fast8_t *elfdata) +{ + /* The AUXV pointer might not even be naturally aligned for 32-bit + data, because note payloads in a core file are not aligned. */ + const char *typep = a32 + offsetof (Elf32_auxv_t, a_type); + uint32_t type = read_4ubyte_unaligned_noncvt (typep); + const char *valp = a32 + offsetof (Elf32_auxv_t, a_un.a_val); + uint32_t val = read_4ubyte_unaligned_noncvt (valp); + + if (type == BE32 (PROBE_TYPE) + && val == BE32 (PROBE_VAL32)) + { + *elfdata = ELFDATA2MSB; + return true; + } + + if (type == LE32 (PROBE_TYPE) + && val == LE32 (PROBE_VAL32)) + { + *elfdata = ELFDATA2LSB; + return true; + } + + return false; +} + +/* Examine an auxv data block and determine its format. + Return true iff we figured it out. */ +static bool +auxv_format_probe (const void *auxv, size_t size, + uint_fast8_t *elfclass, uint_fast8_t *elfdata) +{ + for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i) + { + if (do_check64 (auxv + i * sizeof (Elf64_auxv_t), elfdata)) + { + *elfclass = ELFCLASS64; + return true; + } + + if (do_check32 (auxv + (i * 2) * sizeof (Elf32_auxv_t), elfdata) + || do_check32 (auxv + (i * 2 + 1) * sizeof (Elf32_auxv_t), elfdata)) + { + *elfclass = ELFCLASS32; + return true; + } + } + + return false; +} + +/* This is a Dwfl_Memory_Callback that wraps another memory callback. + If the underlying callback cannot fill the data, then this will + fall back to fetching data from module files. */ + +struct integrated_memory_callback +{ + Dwfl_Memory_Callback *memory_callback; + void *memory_callback_arg; + void *buffer; +}; + +static bool +integrated_memory_callback (Dwfl *dwfl, int ndx, + void **buffer, size_t *buffer_available, + GElf_Addr vaddr, + size_t minread, + void *arg) +{ + struct integrated_memory_callback *info = arg; + + if (ndx == -1) + { + /* Called for cleanup. */ + if (info->buffer != NULL) + { + /* The last probe buffer came from the underlying callback. + Let it do its cleanup. */ + assert (*buffer == info->buffer); /* XXX */ + *buffer = info->buffer; + info->buffer = NULL; + return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available, + vaddr, minread, + info->memory_callback_arg); + } + *buffer = NULL; + *buffer_available = 0; + return false; + } + + if (*buffer != NULL) + /* For a final-read request, we only use the underlying callback. */ + return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available, + vaddr, minread, info->memory_callback_arg); + + /* Let the underlying callback try to fill this request. */ + if ((*info->memory_callback) (dwfl, ndx, &info->buffer, buffer_available, + vaddr, minread, info->memory_callback_arg)) + { + *buffer = info->buffer; + return true; + } + + /* Now look for module text covering this address. */ + + Dwfl_Module *mod; + (void) INTUSE(dwfl_addrsegment) (dwfl, vaddr, &mod); + if (mod == NULL) + return false; + + Dwarf_Addr bias; + Elf_Scn *scn = INTUSE(dwfl_module_address_section) (mod, &vaddr, &bias); + if (unlikely (scn == NULL)) + { +#if 0 // XXX would have to handle ndx=-1 cleanup calls passed down. + /* If we have no sections we can try to fill it from the module file + based on its phdr mappings. */ + if (likely (mod->e_type != ET_REL) && mod->main.elf != NULL) + return INTUSE(dwfl_elf_phdr_memory_callback) + (dwfl, 0, buffer, buffer_available, + vaddr - mod->main.bias, minread, mod->main.elf); +#endif + return false; + } + + Elf_Data *data = elf_rawdata (scn, NULL); + if (unlikely (data == NULL)) + // XXX throw error? + return false; + + if (unlikely (data->d_size < vaddr)) + return false; + + /* Provide as much data as we have. */ + void *contents = data->d_buf + vaddr; + size_t avail = data->d_size - vaddr; + if (unlikely (avail < minread)) + return false; + + /* If probing for a string, make sure it's terminated. */ + if (minread == 0 && unlikely (memchr (contents, '\0', avail) == NULL)) + return false; + + /* We have it! */ + *buffer = contents; + *buffer_available = avail; + return true; +} + +static size_t +addrsize (uint_fast8_t elfclass) +{ + return elfclass * 4; +} + +struct memory_closure +{ + Dwfl *dwfl; + Dwfl_Memory_Callback *callback; + void *arg; +}; + +static inline int +release_buffer (struct memory_closure *closure, + void **buffer, size_t *buffer_available, int result) +{ + if (*buffer != NULL) + (*closure->callback) (closure->dwfl, -1, buffer, buffer_available, 0, 0, + closure->arg); + + return result; +} + +static inline bool +read_addrs (struct memory_closure *closure, + uint_fast8_t elfclass, uint_fast8_t elfdata, + void **buffer, size_t *buffer_available, + GElf_Addr vaddr, GElf_Addr *read_vaddr, + size_t n, GElf_Addr *addrs /* [4] */) +{ + size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read. */ + Dwfl *dwfl = closure->dwfl; + + /* Read a new buffer if the old one doesn't cover these words. */ + if (buffer == NULL + || vaddr < *read_vaddr + || vaddr - (*read_vaddr) + nb > *buffer_available) + { + release_buffer (closure, buffer, buffer_available, 0); + + *read_vaddr = vaddr; + int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL); + if (unlikely (segndx < 0) + || unlikely (! (*closure->callback) (dwfl, segndx, + buffer, buffer_available, + vaddr, nb, closure->arg))) + return true; + } + + Elf32_Addr (*a32)[n] = vaddr - (*read_vaddr) + (*buffer); + Elf64_Addr (*a64)[n] = (void *) a32; + + if (elfclass == ELFCLASS32) + { + if (elfdata == ELFDATA2MSB) + for (size_t i = 0; i < n; ++i) + addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i])); + else + for (size_t i = 0; i < n; ++i) + addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i])); + } + else + { + if (elfdata == ELFDATA2MSB) + for (size_t i = 0; i < n; ++i) + addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i])); + else + for (size_t i = 0; i < n; ++i) + addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i])); + } + + return false; +} + +/* Report a module for each struct link_map in the linked list at r_map + in the struct r_debug at R_DEBUG_VADDR. For r_debug_info description + see dwfl_link_map_report in libdwflP.h. If R_DEBUG_INFO is not NULL then no + modules get added to DWFL, caller has to add them from filled in + R_DEBUG_INFO. + + For each link_map entry, if an existing module resides at its address, + this just modifies that module's name and suggested file name. If + no such module exists, this calls dwfl_report_elf on the l_name string. + + Returns the number of modules found, or -1 for errors. */ + +static int +report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, + Dwfl *dwfl, GElf_Addr r_debug_vaddr, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg, + struct r_debug_info *r_debug_info) +{ + /* Skip r_version, to aligned r_map field. */ + GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass); + + void *buffer = NULL; + size_t buffer_available = 0; + GElf_Addr addrs[4]; + struct memory_closure memory_closure = { dwfl, memory_callback, + memory_callback_arg }; + if (unlikely (read_addrs (&memory_closure, elfclass, elfdata, + &buffer, &buffer_available, read_vaddr, &read_vaddr, + 1, addrs))) + return release_buffer (&memory_closure, &buffer, &buffer_available, -1); + + GElf_Addr next = addrs[0]; + + Dwfl_Module **lastmodp = &dwfl->modulelist; + int result = 0; + + /* There can't be more elements in the link_map list than there are + segments. DWFL->lookup_elts is probably twice that number, so it + is certainly above the upper bound. If we iterate too many times, + there must be a loop in the pointers due to link_map clobberation. */ + size_t iterations = 0; + while (next != 0 && ++iterations < dwfl->lookup_elts) + { + if (read_addrs (&memory_closure, elfclass, elfdata, + &buffer, &buffer_available, next, &read_vaddr, + 4, addrs)) + return release_buffer (&memory_closure, &buffer, &buffer_available, -1); + + /* Unused: l_addr is the difference between the address in memory + and the ELF file when the core was created. We need to + recalculate the difference below because the ELF file we use + might be differently pre-linked. */ + // GElf_Addr l_addr = addrs[0]; + GElf_Addr l_name = addrs[1]; + GElf_Addr l_ld = addrs[2]; + next = addrs[3]; + + /* If a clobbered or truncated memory image has no useful pointer, + just skip this element. */ + if (l_ld == 0) + continue; + + /* Fetch the string at the l_name address. */ + const char *name = NULL; + if (buffer != NULL + && read_vaddr <= l_name + && l_name + 1 - read_vaddr < buffer_available + && memchr (l_name - read_vaddr + buffer, '\0', + buffer_available - (l_name - read_vaddr)) != NULL) + name = l_name - read_vaddr + buffer; + else + { + release_buffer (&memory_closure, &buffer, &buffer_available, 0); + read_vaddr = l_name; + int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_name, NULL); + if (likely (segndx >= 0) + && (*memory_callback) (dwfl, segndx, + &buffer, &buffer_available, + l_name, 0, memory_callback_arg)) + name = buffer; + } + + if (name != NULL && name[0] == '\0') + name = NULL; + + if (iterations == 1 + && dwfl->user_core != NULL + && dwfl->user_core->executable_for_core != NULL) + name = dwfl->user_core->executable_for_core; + + struct r_debug_info_module *r_debug_info_module = NULL; + if (r_debug_info != NULL) + { + /* Save link map information about valid shared library (or + executable) which has not been found on disk. */ + const char *name1 = name == NULL ? "" : name; + r_debug_info_module = malloc (sizeof (*r_debug_info_module) + + strlen (name1) + 1); + if (unlikely (r_debug_info_module == NULL)) + release_buffer (&memory_closure, &buffer, + &buffer_available, result); + r_debug_info_module->fd = -1; + r_debug_info_module->elf = NULL; + r_debug_info_module->l_ld = l_ld; + r_debug_info_module->start = 0; + r_debug_info_module->end = 0; + r_debug_info_module->disk_file_has_build_id = false; + strcpy (r_debug_info_module->name, name1); + r_debug_info_module->next = r_debug_info->module; + r_debug_info->module = r_debug_info_module; + } + + Dwfl_Module *mod = NULL; + if (name != NULL) + { + /* This code is mostly inlined dwfl_report_elf. */ + // XXX hook for sysroot + int fd = open (name, O_RDONLY); + if (fd >= 0) + { + Elf *elf; + Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false); + GElf_Addr elf_dynamic_vaddr; + if (error == DWFL_E_NOERROR + && __libdwfl_dynamic_vaddr_get (elf, &elf_dynamic_vaddr)) + { + const void *build_id_bits; + GElf_Addr build_id_elfaddr; + int build_id_len; + bool valid = true; + + if (__libdwfl_find_elf_build_id (NULL, elf, &build_id_bits, + &build_id_elfaddr, + &build_id_len) > 0 + && build_id_elfaddr != 0) + { + if (r_debug_info_module != NULL) + r_debug_info_module->disk_file_has_build_id = true; + GElf_Addr build_id_vaddr = (build_id_elfaddr + - elf_dynamic_vaddr + l_ld); + + release_buffer (&memory_closure, &buffer, + &buffer_available, 0); + int segndx = INTUSE(dwfl_addrsegment) (dwfl, + build_id_vaddr, + NULL); + if (! (*memory_callback) (dwfl, segndx, + &buffer, &buffer_available, + build_id_vaddr, build_id_len, + memory_callback_arg)) + { + /* File has valid build-id which cannot be read from + memory. This happens for core files without bit 4 + (0x10) set in Linux /proc/PID/coredump_filter. */ + } + else + { + if (memcmp (build_id_bits, buffer, build_id_len) != 0) + /* File has valid build-id which does not match + the one in memory. */ + valid = false; + release_buffer (&memory_closure, &buffer, + &buffer_available, 0); + + } + } + + if (valid) + { + // It is like l_addr but it handles differently prelinked + // files at core dumping vs. core loading time. + GElf_Addr base = l_ld - elf_dynamic_vaddr; + if (r_debug_info_module == NULL) + { + // XXX hook for sysroot + mod = __libdwfl_report_elf (dwfl, basename (name), + name, fd, elf, base, + true, true); + if (mod != NULL) + { + elf = NULL; + fd = -1; + } + } + else if (__libdwfl_elf_address_range (elf, base, true, + true, NULL, NULL, + &r_debug_info_module->start, + &r_debug_info_module->end, + NULL, NULL)) + { + r_debug_info_module->elf = elf; + r_debug_info_module->fd = fd; + elf = NULL; + fd = -1; + } + } + if (elf != NULL) + elf_end (elf); + if (fd != -1) + close (fd); + } + } + } + + if (mod != NULL) + { + ++result; + + /* Move this module to the end of the list, so that we end + up with a list in the same order as the link_map chain. */ + if (mod->next != NULL) + { + if (*lastmodp != mod) + { + lastmodp = &dwfl->modulelist; + while (*lastmodp != mod) + lastmodp = &(*lastmodp)->next; + } + *lastmodp = mod->next; + mod->next = NULL; + while (*lastmodp != NULL) + lastmodp = &(*lastmodp)->next; + *lastmodp = mod; + } + + lastmodp = &mod->next; + } + } + + return release_buffer (&memory_closure, &buffer, &buffer_available, result); +} + +static GElf_Addr +consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry, + uint_fast8_t *elfclass, uint_fast8_t *elfdata, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg) +{ + GElf_Ehdr ehdr; + if (unlikely (gelf_getehdr (mod->main.elf, &ehdr) == NULL)) + return 0; + + if (at_entry != 0) + { + /* If we have an AT_ENTRY value, reject this executable if + its entry point address could not have supplied that. */ + + if (ehdr.e_entry == 0) + return 0; + + if (mod->e_type == ET_EXEC) + { + if (ehdr.e_entry != at_entry) + return 0; + } + else + { + /* It could be a PIE. */ + } + } + + // XXX this could be saved in the file cache: phdr vaddr, DT_DEBUG d_val vaddr + /* Find the vaddr of the DT_DEBUG's d_ptr. This is the memory + address where &r_debug was written at runtime. */ + GElf_Xword align = mod->dwfl->segment_align; + GElf_Addr d_val_vaddr = 0; + size_t phnum; + if (elf_getphdrnum (mod->main.elf, &phnum) != 0) + return 0; + + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem); + if (phdr == NULL) + break; + + if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align)) + align = phdr->p_align; + + if (at_phdr != 0 + && phdr->p_type == PT_LOAD + && (phdr->p_offset & -align) == (ehdr.e_phoff & -align)) + { + /* This is the segment that would map the phdrs. + If we have an AT_PHDR value, reject this executable + if its phdr mapping could not have supplied that. */ + if (mod->e_type == ET_EXEC) + { + if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr) + return 0; + } + else + { + /* It could be a PIE. If the AT_PHDR value and our + phdr address don't match modulo ALIGN, then this + could not have been the right PIE. */ + if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align) + != (at_phdr & -align)) + return 0; + + /* Calculate the bias applied to the PIE's p_vaddr values. */ + GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset + + phdr->p_vaddr)); + + /* Final sanity check: if we have an AT_ENTRY value, + reject this PIE unless its biased e_entry matches. */ + if (at_entry != 0 && at_entry != ehdr.e_entry + bias) + return 0; + + /* If we're changing the module's address range, + we've just invalidated the module lookup table. */ + GElf_Addr mod_bias = dwfl_adjusted_address (mod, 0); + if (bias != mod_bias) + { + mod->low_addr -= mod_bias; + mod->high_addr -= mod_bias; + mod->low_addr += bias; + mod->high_addr += bias; + + free (mod->dwfl->lookup_module); + mod->dwfl->lookup_module = NULL; + } + } + } + + if (phdr->p_type == PT_DYNAMIC) + { + Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset, + phdr->p_filesz, ELF_T_DYN); + if (data == NULL) + continue; + const size_t entsize = gelf_fsize (mod->main.elf, + ELF_T_DYN, 1, EV_CURRENT); + const size_t n = data->d_size / entsize; + for (size_t j = 0; j < n; ++j) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); + if (dyn != NULL && dyn->d_tag == DT_DEBUG) + { + d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2; + break; + } + } + } + } + + if (d_val_vaddr != 0) + { + /* Now we have the final address from which to read &r_debug. */ + d_val_vaddr = dwfl_adjusted_address (mod, d_val_vaddr); + + void *buffer = NULL; + size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]); + + int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, NULL); + + if ((*memory_callback) (mod->dwfl, segndx, + &buffer, &buffer_available, + d_val_vaddr, buffer_available, + memory_callback_arg)) + { + const union + { + Elf32_Addr a32; + Elf64_Addr a64; + } *u = buffer; + + GElf_Addr vaddr; + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) + vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB + ? BE32 (u->a32) : LE32 (u->a32)); + else + vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB + ? BE64 (u->a64) : LE64 (u->a64)); + + (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0, + memory_callback_arg); + + if (*elfclass == ELFCLASSNONE) + *elfclass = ehdr.e_ident[EI_CLASS]; + else if (*elfclass != ehdr.e_ident[EI_CLASS]) + return 0; + + if (*elfdata == ELFDATANONE) + *elfdata = ehdr.e_ident[EI_DATA]; + else if (*elfdata != ehdr.e_ident[EI_DATA]) + return 0; + + return vaddr; + } + } + + return 0; +} + +/* Try to find an existing executable module with a DT_DEBUG. */ +static GElf_Addr +find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry, + uint_fast8_t *elfclass, uint_fast8_t *elfdata, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg) +{ + for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next) + if (mod->main.elf != NULL) + { + GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry, + elfclass, elfdata, + memory_callback, + memory_callback_arg); + if (r_debug_vaddr != 0) + return r_debug_vaddr; + } + + return 0; +} + + +int +dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg, + struct r_debug_info *r_debug_info) +{ + GElf_Addr r_debug_vaddr = 0; + + uint_fast8_t elfclass = ELFCLASSNONE; + uint_fast8_t elfdata = ELFDATANONE; + if (likely (auxv != NULL) + && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata))) + { + GElf_Addr entry = 0; + GElf_Addr phdr = 0; + GElf_Xword phent = 0; + GElf_Xword phnum = 0; + +#define READ_AUXV32(ptr) read_4ubyte_unaligned_noncvt (ptr) +#define READ_AUXV64(ptr) read_8ubyte_unaligned_noncvt (ptr) +#define AUXV_SCAN(NN, BL) do \ + { \ + const Elf##NN##_auxv_t *av = auxv; \ + for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i) \ + { \ + const char *typep = auxv + i * sizeof (Elf##NN##_auxv_t); \ + typep += offsetof (Elf##NN##_auxv_t, a_type); \ + uint##NN##_t type = READ_AUXV##NN (typep); \ + const char *valp = auxv + i * sizeof (Elf##NN##_auxv_t); \ + valp += offsetof (Elf##NN##_auxv_t, a_un.a_val); \ + uint##NN##_t val = BL##NN (READ_AUXV##NN (valp)); \ + if (type == BL##NN (AT_ENTRY)) \ + entry = val; \ + else if (type == BL##NN (AT_PHDR)) \ + phdr = val; \ + else if (type == BL##NN (AT_PHNUM)) \ + phnum = val; \ + else if (type == BL##NN (AT_PHENT)) \ + phent = val; \ + else if (type == BL##NN (AT_PAGESZ)) \ + { \ + if (val > 1 \ + && (dwfl->segment_align == 0 \ + || val < dwfl->segment_align)) \ + dwfl->segment_align = val; \ + } \ + } \ + } \ + while (0) + + if (elfclass == ELFCLASS32) + { + if (elfdata == ELFDATA2MSB) + AUXV_SCAN (32, BE); + else + AUXV_SCAN (32, LE); + } + else + { + if (elfdata == ELFDATA2MSB) + AUXV_SCAN (64, BE); + else + AUXV_SCAN (64, LE); + } + + /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC. */ + GElf_Addr dyn_vaddr = 0; + GElf_Xword dyn_filesz = 0; + GElf_Addr dyn_bias = (GElf_Addr) -1; + + if (phdr != 0 && phnum != 0) + { + Dwfl_Module *phdr_mod; + int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod); + Elf_Data in = + { + .d_type = ELF_T_PHDR, + .d_version = EV_CURRENT, + .d_size = phnum * phent, + .d_buf = NULL + }; + bool in_ok = (*memory_callback) (dwfl, phdr_segndx, &in.d_buf, + &in.d_size, phdr, phnum * phent, + memory_callback_arg); + bool in_from_exec = false; + if (! in_ok + && dwfl->user_core != NULL + && dwfl->user_core->executable_for_core != NULL) + { + /* AUXV -> PHDR -> DYNAMIC + Both AUXV and DYNAMIC should be always present in a core file. + PHDR may be missing in core file, try to read it from + EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the + core file. */ + + int fd = open (dwfl->user_core->executable_for_core, O_RDONLY); + Elf *elf; + Dwfl_Error error = DWFL_E_ERRNO; + if (fd != -1) + error = __libdw_open_file (&fd, &elf, true, false); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return false; + } + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + elf_end (elf); + close (fd); + __libdwfl_seterrno (DWFL_E_LIBELF); + return false; + } + size_t e_phnum; + if (elf_getphdrnum (elf, &e_phnum) != 0) + { + elf_end (elf); + close (fd); + __libdwfl_seterrno (DWFL_E_LIBELF); + return false; + } + if (e_phnum != phnum || ehdr->e_phentsize != phent) + { + elf_end (elf); + close (fd); + __libdwfl_seterrno (DWFL_E_BADELF); + return false; + } + off_t off = ehdr->e_phoff; + assert (in.d_buf == NULL); + /* Note this in the !in_ok path. That means memory_callback + failed. But the callback might still have reset the d_size + value (to zero). So explicitly set it here again. */ + in.d_size = phnum * phent; + in.d_buf = malloc (in.d_size); + if (unlikely (in.d_buf == NULL)) + { + elf_end (elf); + close (fd); + __libdwfl_seterrno (DWFL_E_NOMEM); + return false; + } + ssize_t nread = pread_retry (fd, in.d_buf, in.d_size, off); + elf_end (elf); + close (fd); + if (nread != (ssize_t) in.d_size) + { + free (in.d_buf); + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; + } + in_ok = true; + in_from_exec = true; + } + if (in_ok) + { + if (unlikely (phnum > SIZE_MAX / phent)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return false; + } + size_t nbytes = phnum * phent; + void *buf = malloc (nbytes); + Elf32_Phdr (*p32)[phnum] = buf; + Elf64_Phdr (*p64)[phnum] = buf; + if (unlikely (buf == NULL)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return false; + } + Elf_Data out = + { + .d_type = ELF_T_PHDR, + .d_version = EV_CURRENT, + .d_size = phnum * phent, + .d_buf = buf + }; + in.d_size = out.d_size; + if (likely ((elfclass == ELFCLASS32 + ? elf32_xlatetom : elf64_xlatetom) + (&out, &in, elfdata) != NULL)) + { + bool is32 = (elfclass == ELFCLASS32); + for (size_t i = 0; i < phnum; ++i) + { + GElf_Word type = (is32 + ? (*p32)[i].p_type + : (*p64)[i].p_type); + GElf_Addr vaddr = (is32 + ? (*p32)[i].p_vaddr + : (*p64)[i].p_vaddr); + GElf_Xword filesz = (is32 + ? (*p32)[i].p_filesz + : (*p64)[i].p_filesz); + + if (type == PT_PHDR) + { + if (dyn_bias == (GElf_Addr) -1 + /* Do a sanity check on the putative address. */ + && ((vaddr & (dwfl->segment_align - 1)) + == (phdr & (dwfl->segment_align - 1)))) + { + dyn_bias = phdr - vaddr; + if (dyn_vaddr != 0) + break; + } + + } + else if (type == PT_DYNAMIC) + { + dyn_vaddr = vaddr; + dyn_filesz = filesz; + if (dyn_bias != (GElf_Addr) -1) + break; + } + } + } + + if (in_from_exec) + free (in.d_buf); + else + (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0, + memory_callback_arg); + free (buf); + } + else + /* We could not read the executable's phdrs from the + memory image. If we have a presupplied executable, + we can still use the AT_PHDR and AT_ENTRY values to + verify it, and to adjust its bias if it's a PIE. + + If there was an ET_EXEC module presupplied that contains + the AT_PHDR address, then we only consider that one. + We'll either accept it if its phdr location and e_entry + make sense or reject it if they don't. If there is no + presupplied ET_EXEC, then look for a presupplied module, + which might be a PIE (ET_DYN) that needs its bias adjusted. */ + r_debug_vaddr = ((phdr_mod == NULL + || phdr_mod->main.elf == NULL + || phdr_mod->e_type != ET_EXEC) + ? find_executable (dwfl, phdr, entry, + &elfclass, &elfdata, + memory_callback, + memory_callback_arg) + : consider_executable (phdr_mod, phdr, entry, + &elfclass, &elfdata, + memory_callback, + memory_callback_arg)); + } + + /* If we found PT_DYNAMIC, search it for DT_DEBUG. */ + if (dyn_filesz != 0) + { + if (dyn_bias != (GElf_Addr) -1) + dyn_vaddr += dyn_bias; + + Elf_Data in = + { + .d_type = ELF_T_DYN, + .d_version = EV_CURRENT, + .d_size = dyn_filesz, + .d_buf = NULL + }; + int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL); + if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size, + dyn_vaddr, dyn_filesz, memory_callback_arg)) + { + void *buf = malloc (dyn_filesz); + Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = buf; + Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = buf; + if (unlikely (buf == NULL)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return false; + } + Elf_Data out = + { + .d_type = ELF_T_DYN, + .d_version = EV_CURRENT, + .d_size = dyn_filesz, + .d_buf = buf + }; + in.d_size = out.d_size; + if (likely ((elfclass == ELFCLASS32 + ? elf32_xlatetom : elf64_xlatetom) + (&out, &in, elfdata) != NULL)) + { + /* We are looking for DT_DEBUG. */ + if (elfclass == ELFCLASS32) + { + size_t n = dyn_filesz / sizeof (Elf32_Dyn); + for (size_t i = 0; i < n; ++i) + if ((*d32)[i].d_tag == DT_DEBUG) + { + r_debug_vaddr = (*d32)[i].d_un.d_val; + break; + } + } + else + { + size_t n = dyn_filesz / sizeof (Elf64_Dyn); + for (size_t i = 0; i < n; ++i) + if ((*d64)[i].d_tag == DT_DEBUG) + { + r_debug_vaddr = (*d64)[i].d_un.d_val; + break; + } + } + } + + (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0, + memory_callback_arg); + free (buf); + } + } + } + else + /* We have to look for a presupplied executable file to determine + the vaddr of its dynamic section and DT_DEBUG therein. */ + r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata, + memory_callback, memory_callback_arg); + + if (r_debug_vaddr == 0) + return 0; + + /* For following pointers from struct link_map, we will use an + integrated memory access callback that can consult module text + elided from the core file. This is necessary when the l_name + pointer for the dynamic linker's own entry is a pointer into the + executable's .interp section. */ + struct integrated_memory_callback mcb = + { + .memory_callback = memory_callback, + .memory_callback_arg = memory_callback_arg + }; + + /* Now we can follow the dynamic linker's library list. */ + return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr, + &integrated_memory_callback, &mcb, r_debug_info); +} +INTDEF (dwfl_link_map_report) diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c new file mode 100644 index 00000000..f68062f0 --- /dev/null +++ b/libdwfl/linux-core-attach.c @@ -0,0 +1,434 @@ +/* Get Dwarf Frame state for target core file. + Copyright (C) 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include "system.h" + +#include "../libdw/memory-access.h" + +struct core_arg +{ + Elf *core; + Elf_Data *note_data; + size_t thread_note_offset; + Ebl *ebl; +}; + +struct thread_arg +{ + struct core_arg *core_arg; + size_t note_offset; +}; + +static bool +core_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, + void *dwfl_arg) +{ + Dwfl_Process *process = dwfl->process; + struct core_arg *core_arg = dwfl_arg; + Elf *core = core_arg->core; + assert (core != NULL); + static size_t phnum; + if (elf_getphdrnum (core, &phnum) < 0) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return false; + } + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem); + if (phdr == NULL || phdr->p_type != PT_LOAD) + continue; + /* Bias is zero here, a core file itself has no bias. */ + GElf_Addr start = __libdwfl_segment_start (dwfl, phdr->p_vaddr); + GElf_Addr end = __libdwfl_segment_end (dwfl, + phdr->p_vaddr + phdr->p_memsz); + unsigned bytes = ebl_get_elfclass (process->ebl) == ELFCLASS64 ? 8 : 4; + if (addr < start || addr + bytes > end) + continue; + Elf_Data *data; + data = elf_getdata_rawchunk (core, phdr->p_offset + addr - start, + bytes, ELF_T_ADDR); + if (data == NULL) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + return false; + } + assert (data->d_size == bytes); + if (bytes == 8) + *result = read_8ubyte_unaligned_noncvt (data->d_buf); + else + *result = read_4ubyte_unaligned_noncvt (data->d_buf); + return true; + } + __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE); + return false; +} + +static pid_t +core_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg, + void **thread_argp) +{ + struct core_arg *core_arg = dwfl_arg; + Elf *core = core_arg->core; + GElf_Nhdr nhdr; + size_t name_offset; + size_t desc_offset; + Elf_Data *note_data = core_arg->note_data; + size_t offset; + + struct thread_arg *thread_arg; + if (*thread_argp == NULL) + { + core_arg->thread_note_offset = 0; + thread_arg = malloc (sizeof (*thread_arg)); + if (thread_arg == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + thread_arg->core_arg = core_arg; + *thread_argp = thread_arg; + } + else + thread_arg = (struct thread_arg *) *thread_argp; + + while (offset = core_arg->thread_note_offset, offset < note_data->d_size + && (core_arg->thread_note_offset = gelf_getnote (note_data, offset, + &nhdr, &name_offset, + &desc_offset)) > 0) + { + /* Do not check NAME for now, help broken Linux kernels. */ + const char *name = (nhdr.n_namesz == 0 + ? "" : note_data->d_buf + name_offset); + const char *desc = note_data->d_buf + desc_offset; + GElf_Word regs_offset; + size_t nregloc; + const Ebl_Register_Location *reglocs; + size_t nitems; + const Ebl_Core_Item *items; + if (! ebl_core_note (core_arg->ebl, &nhdr, name, desc, + ®s_offset, &nregloc, ®locs, &nitems, &items)) + { + /* This note may be just not recognized, skip it. */ + continue; + } + if (nhdr.n_type != NT_PRSTATUS) + continue; + const Ebl_Core_Item *item; + for (item = items; item < items + nitems; item++) + if (strcmp (item->name, "pid") == 0) + break; + if (item == items + nitems) + continue; + uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset); + val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be32toh (val32) : le32toh (val32)); + pid_t tid = (int32_t) val32; + eu_static_assert (sizeof val32 <= sizeof tid); + thread_arg->note_offset = offset; + return tid; + } + + free (thread_arg); + return 0; +} + +static bool +core_set_initial_registers (Dwfl_Thread *thread, void *thread_arg_voidp) +{ + struct thread_arg *thread_arg = thread_arg_voidp; + struct core_arg *core_arg = thread_arg->core_arg; + Elf *core = core_arg->core; + size_t offset = thread_arg->note_offset; + GElf_Nhdr nhdr; + size_t name_offset; + size_t desc_offset; + Elf_Data *note_data = core_arg->note_data; + size_t nregs = ebl_frame_nregs (core_arg->ebl); + assert (nregs > 0); + assert (offset < note_data->d_size); + size_t getnote_err = gelf_getnote (note_data, offset, &nhdr, &name_offset, + &desc_offset); + /* __libdwfl_attach_state_for_core already verified the note is there. */ + if (getnote_err == 0) + return false; + /* Do not check NAME for now, help broken Linux kernels. */ + const char *name = (nhdr.n_namesz == 0 + ? "" : note_data->d_buf + name_offset); + const char *desc = note_data->d_buf + desc_offset; + GElf_Word regs_offset; + size_t nregloc; + const Ebl_Register_Location *reglocs; + size_t nitems; + const Ebl_Core_Item *items; + int core_note_err = ebl_core_note (core_arg->ebl, &nhdr, name, desc, + ®s_offset, &nregloc, ®locs, + &nitems, &items); + /* __libdwfl_attach_state_for_core already verified the note is there. */ + if (core_note_err == 0 || nhdr.n_type != NT_PRSTATUS) + return false; + const Ebl_Core_Item *item; + for (item = items; item < items + nitems; item++) + if (strcmp (item->name, "pid") == 0) + break; + assert (item < items + nitems); + pid_t tid; + { + uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset); + val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be32toh (val32) : le32toh (val32)); + tid = (int32_t) val32; + eu_static_assert (sizeof val32 <= sizeof tid); + } + /* core_next_thread already found this TID there. */ + assert (tid == INTUSE(dwfl_thread_tid) (thread)); + for (item = items; item < items + nitems; item++) + if (item->pc_register) + break; + if (item < items + nitems) + { + Dwarf_Word pc; + switch (gelf_getclass (core) == ELFCLASS32 ? 32 : 64) + { + case 32:; + uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset); + val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be32toh (val32) : le32toh (val32)); + /* Do a host width conversion. */ + pc = val32; + break; + case 64:; + uint64_t val64 = read_8ubyte_unaligned_noncvt (desc + item->offset); + val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be64toh (val64) : le64toh (val64)); + pc = val64; + break; + default: + abort (); + } + INTUSE(dwfl_thread_state_register_pc) (thread, pc); + } + desc += regs_offset; + for (size_t regloci = 0; regloci < nregloc; regloci++) + { + const Ebl_Register_Location *regloc = reglocs + regloci; + // Iterate even regs out of NREGS range so that we can find pc_register. + if (regloc->bits != 32 && regloc->bits != 64) + continue; + const char *reg_desc = desc + regloc->offset; + for (unsigned regno = regloc->regno; + regno < regloc->regno + (regloc->count ?: 1U); + regno++) + { + /* PPC provides DWARF register 65 irrelevant for + CFI which clashes with register 108 (LR) we need. + LR (108) is provided earlier (in NT_PRSTATUS) than the # 65. + FIXME: It depends now on their order in core notes. + FIXME: It uses private function. */ + if (regno < nregs + && __libdwfl_frame_reg_get (thread->unwound, regno, NULL)) + continue; + Dwarf_Word val; + switch (regloc->bits) + { + case 32:; + uint32_t val32 = read_4ubyte_unaligned_noncvt (reg_desc); + reg_desc += sizeof val32; + val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be32toh (val32) : le32toh (val32)); + /* Do a host width conversion. */ + val = val32; + break; + case 64:; + uint64_t val64 = read_8ubyte_unaligned_noncvt (reg_desc); + reg_desc += sizeof val64; + val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be64toh (val64) : le64toh (val64)); + assert (sizeof (*thread->unwound->regs) == sizeof val64); + val = val64; + break; + default: + abort (); + } + /* Registers not valid for CFI are just ignored. */ + if (regno < nregs) + INTUSE(dwfl_thread_state_registers) (thread, regno, 1, &val); + if (regloc->pc_register) + INTUSE(dwfl_thread_state_register_pc) (thread, val); + reg_desc += regloc->pad; + } + } + return true; +} + +static void +core_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg) +{ + struct core_arg *core_arg = dwfl_arg; + ebl_closebackend (core_arg->ebl); + free (core_arg); +} + +static const Dwfl_Thread_Callbacks core_thread_callbacks = +{ + core_next_thread, + NULL, /* get_thread */ + core_memory_read, + core_set_initial_registers, + core_detach, + NULL, /* core_thread_detach */ +}; + +int +dwfl_core_file_attach (Dwfl *dwfl, Elf *core) +{ + Dwfl_Error err = DWFL_E_NOERROR; + Ebl *ebl = ebl_openbackend (core); + if (ebl == NULL) + { + err = DWFL_E_LIBEBL; + fail_err: + if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR) + dwfl->attacherr = __libdwfl_canon_error (err); + __libdwfl_seterrno (err); + return -1; + } + size_t nregs = ebl_frame_nregs (ebl); + if (nregs == 0) + { + err = DWFL_E_NO_UNWIND; + fail: + ebl_closebackend (ebl); + goto fail_err; + } + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (core, &ehdr_mem); + if (ehdr == NULL) + { + err = DWFL_E_LIBELF; + goto fail; + } + if (ehdr->e_type != ET_CORE) + { + err = DWFL_E_NO_CORE_FILE; + goto fail; + } + size_t phnum; + if (elf_getphdrnum (core, &phnum) < 0) + { + err = DWFL_E_LIBELF; + goto fail; + } + pid_t pid = -1; + Elf_Data *note_data = NULL; + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem); + if (phdr != NULL && phdr->p_type == PT_NOTE) + { + note_data = elf_getdata_rawchunk (core, phdr->p_offset, + phdr->p_filesz, (phdr->p_align == 8 + ? ELF_T_NHDR8 + : ELF_T_NHDR)); + break; + } + } + if (note_data == NULL) + { + err = DWFL_E_LIBELF; + goto fail; + } + size_t offset = 0; + GElf_Nhdr nhdr; + size_t name_offset; + size_t desc_offset; + while (offset < note_data->d_size + && (offset = gelf_getnote (note_data, offset, + &nhdr, &name_offset, &desc_offset)) > 0) + { + /* Do not check NAME for now, help broken Linux kernels. */ + const char *name = (nhdr.n_namesz == 0 + ? "" : note_data->d_buf + name_offset); + const char *desc = note_data->d_buf + desc_offset; + GElf_Word regs_offset; + size_t nregloc; + const Ebl_Register_Location *reglocs; + size_t nitems; + const Ebl_Core_Item *items; + if (! ebl_core_note (ebl, &nhdr, name, desc, + ®s_offset, &nregloc, ®locs, &nitems, &items)) + { + /* This note may be just not recognized, skip it. */ + continue; + } + if (nhdr.n_type != NT_PRPSINFO) + continue; + const Ebl_Core_Item *item; + for (item = items; item < items + nitems; item++) + if (strcmp (item->name, "pid") == 0) + break; + if (item == items + nitems) + continue; + uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset); + val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB + ? be32toh (val32) : le32toh (val32)); + pid = (int32_t) val32; + eu_static_assert (sizeof val32 <= sizeof pid); + break; + } + if (pid == -1) + { + /* No valid NT_PRPSINFO recognized in this CORE. */ + err = DWFL_E_BADELF; + goto fail; + } + struct core_arg *core_arg = malloc (sizeof *core_arg); + if (core_arg == NULL) + { + err = DWFL_E_NOMEM; + goto fail; + } + core_arg->core = core; + core_arg->note_data = note_data; + core_arg->thread_note_offset = 0; + core_arg->ebl = ebl; + if (! INTUSE(dwfl_attach_state) (dwfl, core, pid, &core_thread_callbacks, + core_arg)) + { + free (core_arg); + ebl_closebackend (ebl); + return -1; + } + return pid; +} +INTDEF (dwfl_core_file_attach) diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c new file mode 100644 index 00000000..c0f8dfa4 --- /dev/null +++ b/libdwfl/linux-kernel-modules.c @@ -0,0 +1,1040 @@ +/* Standard libdwfl callbacks for debugging the running Linux kernel. + Copyright (C) 2005-2011, 2013, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* In case we have a bad fts we include this before config.h because it + can't handle _FILE_OFFSET_BITS. + Everything we need here is fine if its declarations just come first. + Also, include sys/types.h before fts. On some systems fts.h is not self + contained. */ +#ifdef BAD_FTS + #include + #include +#endif + +#include +#include + +#include "libelfP.h" +#include "libdwflP.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* If fts.h is included before config.h, its indirect inclusions may not + give us the right LFS aliases of these functions, so map them manually. */ +#ifdef BAD_FTS + #ifdef _FILE_OFFSET_BITS + #define open open64 + #define fopen fopen64 + #endif +#else + #include + #include +#endif + + +#define KERNEL_MODNAME "kernel" + +#define MODULEDIRFMT "/lib/modules/%s" + +#define KNOTESFILE "/sys/kernel/notes" +#define MODNOTESFMT "/sys/module/%s/notes" +#define KSYMSFILE "/proc/kallsyms" +#define MODULELIST "/proc/modules" +#define SECADDRDIRFMT "/sys/module/%s/sections/" +#define MODULE_SECT_NAME_LEN 32 /* Minimum any linux/module.h has had. */ + + +static const char *vmlinux_suffixes[] = + { + ".gz", +#ifdef USE_BZLIB + ".bz2", +#endif +#ifdef USE_LZMA + ".xz", +#endif + }; + +/* Try to open the given file as it is or under the debuginfo directory. */ +static int +try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug) +{ + if (*fname == NULL) + return -1; + + /* Don't bother trying *FNAME itself here if the path will cause it to be + tried because we give its own basename as DEBUGLINK_FILE. */ + int fd = ((((dwfl->callbacks->debuginfo_path + ? *dwfl->callbacks->debuginfo_path : NULL) + ?: DEFAULT_DEBUGINFO_PATH)[0] == ':') ? -1 + : TEMP_FAILURE_RETRY (open (*fname, O_RDONLY))); + + if (fd < 0) + { + Dwfl_Module fakemod = { .dwfl = dwfl }; + + if (try_debug) + /* Passing NULL for DEBUGLINK_FILE searches for both the basenamer + "vmlinux" and the default of basename + ".debug", to look for + "vmlinux.debug" files. */ + fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0, + *fname, NULL, 0, + &fakemod.debug.name); + else + /* Try the file's unadorned basename as DEBUGLINK_FILE, + to look only for "vmlinux" files. */ + fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0, + *fname, basename (*fname), + 0, &fakemod.debug.name); + + if (fakemod.debug.name != NULL) + { + free (*fname); + *fname = fakemod.debug.name; + } + } + + if (fd < 0) + for (size_t i = 0; + i < sizeof vmlinux_suffixes / sizeof vmlinux_suffixes[0] && fd < 0; + ++i) + { + char *zname; + if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0) + { + fd = TEMP_FAILURE_RETRY (open (zname, O_RDONLY)); + if (fd < 0) + free (zname); + else + { + free (*fname); + *fname = zname; + } + } + } + + if (fd < 0) + { + free (*fname); + *fname = NULL; + } + + return fd; +} + +static inline const char * +kernel_release (void) +{ +#ifdef __linux__ + /* Cache the `uname -r` string we'll use. */ + static struct utsname utsname; + if (utsname.release[0] == '\0' && uname (&utsname) != 0) + return NULL; + return utsname.release; +#else + /* Used for finding the running linux kernel, which isn't supported + on non-linux kernel systems. */ + errno = ENOTSUP; + return NULL; +#endif +} + +static int +find_kernel_elf (Dwfl *dwfl, const char *release, char **fname) +{ + /* First try to find an uncompressed vmlinux image. Possibly + including debuginfo. */ + if (release == NULL + || ((release[0] == '/' + ? asprintf (fname, "%s/vmlinux", release) + : asprintf (fname, "/boot/vmlinux-%s", release)) < 0)) + return -1; + + int fd = try_kernel_name (dwfl, fname, true); + if (fd < 0 && release[0] != '/') + { + free (*fname); + if (asprintf (fname, MODULEDIRFMT "/vmlinux", release) < 0) + return -1; + fd = try_kernel_name (dwfl, fname, true); + } + + /* There might be a compressed vmlinuz image. Probably without + debuginfo, but try to find it under the debug path also, just in + case. */ + if (fd < 0) + { + free (*fname); + if ((release[0] == '/' + ? asprintf (fname, "%s/vmlinuz", release) + : asprintf (fname, "/boot/vmlinuz-%s", release)) < 0) + return -1; + + fd = try_kernel_name (dwfl, fname, true); + if (fd < 0 && release[0] != '/') + { + free (*fname); + if (asprintf (fname, MODULEDIRFMT "/vmlinuz", release) < 0) + return -1; + fd = try_kernel_name (dwfl, fname, true); + } + } + + return fd; +} + +static int +get_release (Dwfl *dwfl, const char **release) +{ + if (dwfl == NULL) + return -1; + + const char *release_string = release == NULL ? NULL : *release; + if (release_string == NULL) + { + release_string = kernel_release (); + if (release_string == NULL) + return errno; + if (release != NULL) + *release = release_string; + } + + return 0; +} + +static int +report_kernel (Dwfl *dwfl, const char **release, + int (*predicate) (const char *module, const char *file)) +{ + int result = get_release (dwfl, release); + if (unlikely (result != 0)) + return result; + + if (release == NULL || *release == NULL) + return EINVAL; + + char *fname; + int fd = find_kernel_elf (dwfl, *release, &fname); + + if (fd < 0) + result = ((predicate != NULL && !(*predicate) (KERNEL_MODNAME, NULL)) + ? 0 : errno ?: ENOENT); + else + { + bool report = true; + + if (predicate != NULL) + { + /* Let the predicate decide whether to use this one. */ + int want = (*predicate) (KERNEL_MODNAME, fname); + if (want < 0) + result = errno; + report = want > 0; + } + + if (report) + { + /* Note that on some architectures (e.g. x86_64) the vmlinux + is ET_EXEC, while on others (e.g. ppc64) it is ET_DYN. + In both cases the phdr p_vaddr load address will be non-zero. + We want the image to be placed as if it was ET_DYN, so + pass true for add_p_vaddr which will do the right thing + (in combination with a zero base) in either case. */ + Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME, + fname, fd, 0, true); + if (mod == NULL) + result = -1; + else + /* The kernel is ET_EXEC, but always treat it as relocatable. */ + mod->e_type = ET_DYN; + } + + free (fname); + + if (!report || result < 0) + close (fd); + } + + return result; +} + +/* Look for a kernel debug archive. If we find one, report all its modules. + If not, return ENOENT. */ +static int +report_kernel_archive (Dwfl *dwfl, const char **release, + int (*predicate) (const char *module, const char *file)) +{ + int result = get_release (dwfl, release); + if (unlikely (result != 0)) + return result; + + if (release == NULL || *release == NULL) + return EINVAL; + + char *archive; + int res = (((*release)[0] == '/') + ? asprintf (&archive, "%s/debug.a", *release) + : asprintf (&archive, MODULEDIRFMT "/debug.a", *release)); + if (unlikely (res < 0)) + return ENOMEM; + + int fd = try_kernel_name (dwfl, &archive, false); + if (fd < 0) + result = errno ?: ENOENT; + else + { + /* We have the archive file open! */ + Dwfl_Module *last = __libdwfl_report_offline (dwfl, NULL, archive, fd, + true, predicate); + if (unlikely (last == NULL)) + result = -1; + else + { + /* Find the kernel and move it to the head of the list. */ + Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp; + for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next)) + if (!m->gc && m->e_type != ET_REL && !strcmp (m->name, "kernel")) + { + *prevp = m->next; + m->next = *tailp; + *tailp = m; + break; + } + } + } + + free (archive); + return result; +} + +static size_t +check_suffix (const FTSENT *f, size_t namelen) +{ +#define TRY(sfx) \ + if ((namelen ? f->fts_namelen == namelen + sizeof sfx - 1 \ + : f->fts_namelen >= sizeof sfx) \ + && !memcmp (f->fts_name + f->fts_namelen - (sizeof sfx - 1), \ + sfx, sizeof sfx)) \ + return sizeof sfx - 1 + + TRY (".ko"); + TRY (".ko.gz"); +#if USE_BZLIB + TRY (".ko.bz2"); +#endif +#if USE_LZMA + TRY (".ko.xz"); +#endif +#if USE_ZSTD + TRY (".ko.zst"); +#endif + + return 0; + +#undef TRY +} + +/* Report a kernel and all its modules found on disk, for offline use. + If RELEASE starts with '/', it names a directory to look in; + if not, it names a directory to find under /lib/modules/; + if null, /lib/modules/`uname -r` is used. + Returns zero on success, -1 if dwfl_report_module failed, + or an errno code if finding the files on disk failed. */ +int +dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release, + int (*predicate) (const char *module, + const char *file)) +{ + int result = report_kernel_archive (dwfl, &release, predicate); + if (result != ENOENT) + return result; + + /* First report the kernel. */ + result = report_kernel (dwfl, &release, predicate); + if (result == 0) + { + /* Do "find /lib/modules/RELEASE -name *.ko". */ + + char *modulesdir[] = { NULL, NULL }; + if (release[0] == '/') + modulesdir[0] = (char *) release; + else + { + if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0) + return errno; + } + + FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL); + if (modulesdir[0] == (char *) release) + modulesdir[0] = NULL; + if (fts == NULL) + { + free (modulesdir[0]); + return errno; + } + + FTSENT *f; + while ((f = fts_read (fts)) != NULL) + { + /* Skip a "source" subtree, which tends to be large. + This insane hard-coding of names is what depmod does too. */ + if (f->fts_namelen == sizeof "source" - 1 + && !strcmp (f->fts_name, "source")) + { + fts_set (fts, f, FTS_SKIP); + continue; + } + + switch (f->fts_info) + { + case FTS_F: + case FTS_SL: + case FTS_NSOK:; + /* See if this file name matches "*.ko". */ + const size_t suffix = check_suffix (f, 0); + if (suffix) + { + /* We have a .ko file to report. Following the algorithm + by which the kernel makefiles set KBUILD_MODNAME, we + replace all ',' or '-' with '_' in the file name and + call that the module name. Modules could well be + built using different embedded names than their file + names. To handle that, we would have to look at the + __this_module.name contents in the module's text. */ + + char *name = strndup (f->fts_name, f->fts_namelen - suffix); + if (unlikely (name == NULL)) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + result = -1; + break; + } + for (size_t i = 0; i < f->fts_namelen - suffix; ++i) + if (name[i] == '-' || name[i] == ',') + name[i] = '_'; + + if (predicate != NULL) + { + /* Let the predicate decide whether to use this one. */ + int want = (*predicate) (name, f->fts_path); + if (want < 0) + { + result = -1; + free (name); + break; + } + if (!want) + { + free (name); + continue; + } + } + + if (dwfl_report_offline (dwfl, name, f->fts_path, -1) == NULL) + { + free (name); + result = -1; + break; + } + free (name); + } + continue; + + case FTS_ERR: + case FTS_DNR: + case FTS_NS: + result = f->fts_errno; + break; + + case FTS_SLNONE: + default: + continue; + } + + /* We only get here in error cases. */ + break; + } + fts_close (fts); + free (modulesdir[0]); + } + + return result; +} +INTDEF (dwfl_linux_kernel_report_offline) + + +/* State of read_address used by intuit_kernel_bounds. */ +struct read_address_state { + FILE *f; + char *line; + size_t linesz; + size_t n; + char *p; + const char *type; +}; + +static inline bool +read_address (struct read_address_state *state, Dwarf_Addr *addr) +{ + if ((state->n = getline (&state->line, &state->linesz, state->f)) < 1 || + state->line[state->n - 2] == ']') + return false; + *addr = strtoull (state->line, &state->p, 16); + state->p += strspn (state->p, " \t"); + state->type = strsep (&state->p, " \t\n"); + if (state->type == NULL) + return false; + return state->p != NULL && state->p != state->line; +} + + +/* Grovel around to guess the bounds of the runtime kernel image. */ +static int +intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes) +{ + struct read_address_state state = { NULL, NULL, 0, 0, NULL, NULL }; + + *notes = 0; + + state.f = fopen (KSYMSFILE, "r"); + if (state.f == NULL) + return errno; + + (void) __fsetlocking (state.f, FSETLOCKING_BYCALLER); + + int result; + do + result = read_address (&state, start) ? 0 : -1; + while (result == 0 && strchr ("TtRr", *state.type) == NULL); + + if (result == 0) + { + Dwarf_Addr addr; + *end = *start; + while (read_address (&state, &addr) && addr >= *end) + { + *end = addr; + if (*notes == 0 && !strcmp (state.p, "__start_notes\n")) + *notes = *end; + } + + Dwarf_Addr round_kernel = sysconf (_SC_PAGESIZE); + *start &= -(Dwarf_Addr) round_kernel; + *end += round_kernel - 1; + *end &= -(Dwarf_Addr) round_kernel; + if (*start >= *end || *end - *start < round_kernel) + result = -1; + } + free (state.line); + + if (result == -1) + result = ferror_unlocked (state.f) ? errno : ENOEXEC; + + fclose (state.f); + + return result; +} + + +/* Look for a build ID note in NOTESFILE and associate the ID with MOD. */ +static int +check_notes (Dwfl_Module *mod, const char *notesfile, + Dwarf_Addr vaddr, const char *secname) +{ + int fd = open (notesfile, O_RDONLY); + if (fd < 0) + return 1; + + assert (sizeof (Elf32_Nhdr) == sizeof (GElf_Nhdr)); + assert (sizeof (Elf64_Nhdr) == sizeof (GElf_Nhdr)); + union + { + GElf_Nhdr nhdr; + unsigned char data[8192]; + } buf; + + ssize_t n = read (fd, buf.data, sizeof buf); + close (fd); + + if (n <= 0) + return 1; + + unsigned char *p = buf.data; + size_t len = 0; + while (p < &buf.data[n]) + { + /* No translation required since we are reading the native kernel. */ + GElf_Nhdr *nhdr = (void *) p; + len += sizeof *nhdr; + p += len; + unsigned char *name = p; + unsigned char *bits; + /* This is somewhat ugly, GNU Property notes use different padding, + but all we have is the file content, so we have to actually check + the name and type. */ + if (nhdr->n_type == NT_GNU_PROPERTY_TYPE_0 + && nhdr->n_namesz == sizeof "GNU" + && name + nhdr->n_namesz < &buf.data[n] + && !memcmp (name, "GNU", sizeof "GNU")) + { + len += nhdr->n_namesz; + len = NOTE_ALIGN8 (len); + p = buf.data + len; + bits = p; + len += nhdr->n_descsz; + len = NOTE_ALIGN8 (len); + p = buf.data + len; + } + else + { + len += nhdr->n_namesz; + len = NOTE_ALIGN4 (len); + p = buf.data + len; + bits = p; + len += nhdr->n_descsz; + len = NOTE_ALIGN4 (len); + p = buf.data + len; + } + + if (p <= &buf.data[n] + && nhdr->n_type == NT_GNU_BUILD_ID + && nhdr->n_namesz == sizeof "GNU" + && !memcmp (name, "GNU", sizeof "GNU")) + { + /* Found it. For a module we must figure out its VADDR now. */ + + if (secname != NULL + && (INTUSE(dwfl_linux_kernel_module_section_address) + (mod, NULL, mod->name, 0, secname, 0, NULL, &vaddr) != 0 + || vaddr == (GElf_Addr) -1l)) + vaddr = 0; + + if (vaddr != 0) + vaddr += bits - buf.data; + return INTUSE(dwfl_module_report_build_id) (mod, bits, + nhdr->n_descsz, vaddr); + } + } + + return 0; +} + +/* Look for a build ID for the kernel. */ +static int +check_kernel_notes (Dwfl_Module *kernelmod, GElf_Addr vaddr) +{ + return check_notes (kernelmod, KNOTESFILE, vaddr, NULL) < 0 ? -1 : 0; +} + +/* Look for a build ID for a loaded kernel module. */ +static int +check_module_notes (Dwfl_Module *mod) +{ + char *dirs[2] = { NULL, NULL }; + if (asprintf (&dirs[0], MODNOTESFMT, mod->name) < 0) + return ENOMEM; + + FTS *fts = fts_open (dirs, FTS_NOSTAT | FTS_LOGICAL, NULL); + if (fts == NULL) + { + free (dirs[0]); + return 0; + } + + int result = 0; + FTSENT *f; + while ((f = fts_read (fts)) != NULL) + { + switch (f->fts_info) + { + case FTS_F: + case FTS_SL: + case FTS_NSOK: + result = check_notes (mod, f->fts_accpath, 0, f->fts_name); + if (result > 0) /* Nothing found. */ + { + result = 0; + continue; + } + break; + + case FTS_ERR: + case FTS_DNR: + result = f->fts_errno; + break; + + case FTS_NS: + case FTS_SLNONE: + default: + continue; + } + + /* We only get here when finished or in error cases. */ + break; + } + fts_close (fts); + free (dirs[0]); + + return result; +} + +int +dwfl_linux_kernel_report_kernel (Dwfl *dwfl) +{ + Dwarf_Addr start = 0; + Dwarf_Addr end = 0; + + #define report() \ + (INTUSE(dwfl_report_module) (dwfl, KERNEL_MODNAME, start, end)) + + /* This is a bit of a kludge. If we already reported the kernel, + don't bother figuring it out again--it never changes. */ + for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next) + if (!strcmp (m->name, KERNEL_MODNAME)) + { + start = m->low_addr; + end = m->high_addr; + return report () == NULL ? -1 : 0; + } + + /* Try to figure out the bounds of the kernel image without + looking for any vmlinux file. */ + Dwarf_Addr notes; + int result = intuit_kernel_bounds (&start, &end, ¬es); + if (result == 0) + { + Dwfl_Module *mod = report (); + return unlikely (mod == NULL) ? -1 : check_kernel_notes (mod, notes); + } + if (result != ENOENT) + return result; + + /* Find the ELF file for the running kernel and dwfl_report_elf it. */ + return report_kernel (dwfl, NULL, NULL); +} +INTDEF (dwfl_linux_kernel_report_kernel) + + +static inline bool +subst_name (char from, char to, + const char * const module_name, + char * const alternate_name, + const size_t namelen) +{ + const char *n = memchr (module_name, from, namelen); + if (n == NULL) + return false; + char *a = mempcpy (alternate_name, module_name, n - module_name); + *a++ = to; + ++n; + const char *p; + while ((p = memchr (n, from, namelen - (n - module_name))) != NULL) + { + a = mempcpy (a, n, p - n); + *a++ = to; + n = p + 1; + } + memcpy (a, n, namelen - (n - module_name) + 1); + return true; +} + +/* Dwfl_Callbacks.find_elf for the running Linux kernel and its modules. */ + +int +dwfl_linux_kernel_find_elf (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *module_name, + Dwarf_Addr base __attribute__ ((unused)), + char **file_name, Elf **elfp) +{ + if (mod->build_id_len > 0) + { + int fd = INTUSE(dwfl_build_id_find_elf) (mod, NULL, NULL, 0, + file_name, elfp); + if (fd >= 0 || mod->main.elf != NULL || errno != 0) + return fd; + } + + const char *release = kernel_release (); + if (release == NULL) + return errno; + + if (!strcmp (module_name, KERNEL_MODNAME)) + return find_kernel_elf (mod->dwfl, release, file_name); + + /* Do "find /lib/modules/`uname -r` -name MODULE_NAME.ko". */ + + char *modulesdir[] = { NULL, NULL }; + if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0) + return -1; + + FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL); + if (fts == NULL) + { + free (modulesdir[0]); + return -1; + } + + size_t namelen = strlen (module_name); + + /* This is a kludge. There is no actual necessary relationship between + the name of the .ko file installed and the module name the kernel + knows it by when it's loaded. The kernel's only idea of the module + name comes from the name embedded in the object's magic + .gnu.linkonce.this_module section. + + In practice, these module names match the .ko file names except for + some using '_' and some using '-'. So our cheap kludge is to look for + two files when either a '_' or '-' appears in a module name, one using + only '_' and one only using '-'. */ + + char *alternate_name = malloc (namelen + 1); + if (unlikely (alternate_name == NULL)) + { + free (modulesdir[0]); + return ENOMEM; + } + if (!subst_name ('-', '_', module_name, alternate_name, namelen) && + !subst_name ('_', '-', module_name, alternate_name, namelen)) + alternate_name[0] = '\0'; + + FTSENT *f; + int error = ENOENT; + while ((f = fts_read (fts)) != NULL) + { + /* Skip a "source" subtree, which tends to be large. + This insane hard-coding of names is what depmod does too. */ + if (f->fts_namelen == sizeof "source" - 1 + && !strcmp (f->fts_name, "source")) + { + fts_set (fts, f, FTS_SKIP); + continue; + } + + error = ENOENT; + switch (f->fts_info) + { + case FTS_F: + case FTS_SL: + case FTS_NSOK: + /* See if this file name is "MODULE_NAME.ko". */ + if (check_suffix (f, namelen) + && (!memcmp (f->fts_name, module_name, namelen) + || !memcmp (f->fts_name, alternate_name, namelen))) + { + int fd = open (f->fts_accpath, O_RDONLY); + *file_name = strdup (f->fts_path); + fts_close (fts); + free (modulesdir[0]); + free (alternate_name); + if (fd < 0) + free (*file_name); + else if (*file_name == NULL) + { + close (fd); + fd = -1; + } + return fd; + } + break; + + case FTS_ERR: + case FTS_DNR: + case FTS_NS: + error = f->fts_errno; + break; + + case FTS_SLNONE: + default: + break; + } + } + + fts_close (fts); + free (modulesdir[0]); + free (alternate_name); + errno = error; + return -1; +} +INTDEF (dwfl_linux_kernel_find_elf) + + +/* Dwfl_Callbacks.section_address for kernel modules in the running Linux. + We read the information from /sys/module directly. */ + +int +dwfl_linux_kernel_module_section_address +(Dwfl_Module *mod __attribute__ ((unused)), + void **userdata __attribute__ ((unused)), + const char *modname, Dwarf_Addr base __attribute__ ((unused)), + const char *secname, Elf32_Word shndx __attribute__ ((unused)), + const GElf_Shdr *shdr __attribute__ ((unused)), + Dwarf_Addr *addr) +{ + char *sysfile; + if (asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname) < 0) + return DWARF_CB_ABORT; + + FILE *f = fopen (sysfile, "r"); + free (sysfile); + + if (f == NULL) + { + if (errno == ENOENT) + { + /* The .modinfo and .data.percpu sections are never kept + loaded in the kernel. If the kernel was compiled without + CONFIG_MODULE_UNLOAD, the .exit.* sections are not + actually loaded at all. + + Setting *ADDR to -1 tells the caller this section is + actually absent from memory. */ + + if (!strcmp (secname, ".modinfo") + || !strcmp (secname, ".data.percpu") + || startswith (secname, ".exit")) + { + *addr = (Dwarf_Addr) -1l; + return DWARF_CB_OK; + } + + /* The goofy PPC64 module_frob_arch_sections function tweaks + the section names as a way to control other kernel code's + behavior, and this cruft leaks out into the /sys information. + The file name for ".init*" may actually look like "_init*". */ + + const bool is_init = startswith (secname, ".init"); + if (is_init) + { + if (asprintf (&sysfile, SECADDRDIRFMT "_%s", + modname, &secname[1]) < 0) + return ENOMEM; + f = fopen (sysfile, "r"); + free (sysfile); + if (f != NULL) + goto ok; + } + + /* The kernel truncates section names to MODULE_SECT_NAME_LEN - 1. + In case that size increases in the future, look for longer + truncated names first. */ + size_t namelen = strlen (secname); + if (namelen >= MODULE_SECT_NAME_LEN) + { + int len = asprintf (&sysfile, SECADDRDIRFMT "%s", + modname, secname); + if (len < 0) + return DWARF_CB_ABORT; + char *end = sysfile + len; + do + { + *--end = '\0'; + f = fopen (sysfile, "r"); + if (is_init && f == NULL && errno == ENOENT) + { + sysfile[len - namelen] = '_'; + f = fopen (sysfile, "r"); + sysfile[len - namelen] = '.'; + } + } + while (f == NULL && errno == ENOENT + && end - &sysfile[len - namelen] >= MODULE_SECT_NAME_LEN); + free (sysfile); + + if (f != NULL) + goto ok; + } + } + + return DWARF_CB_ABORT; + } + + ok: + (void) __fsetlocking (f, FSETLOCKING_BYCALLER); + + int result = (fscanf (f, "%" PRIx64 "\n", addr) == 1 ? 0 + : ferror_unlocked (f) ? errno : ENOEXEC); + fclose (f); + + if (result == 0) + return DWARF_CB_OK; + + errno = result; + return DWARF_CB_ABORT; +} +INTDEF (dwfl_linux_kernel_module_section_address) + +int +dwfl_linux_kernel_report_modules (Dwfl *dwfl) +{ + FILE *f = fopen (MODULELIST, "r"); + if (f == NULL) + return errno; + + (void) __fsetlocking (f, FSETLOCKING_BYCALLER); + + int result = 0; + Dwarf_Addr modaddr; + unsigned long int modsz; + char modname[128]; + char *line = NULL; + size_t linesz = 0; + /* We can't just use fscanf here because it's not easy to distinguish \n + from other whitespace so as to take the optional word following the + address but always stop at the end of the line. */ + while (getline (&line, &linesz, f) > 0 + && sscanf (line, "%128s %lu %*s %*s %*s %" PRIx64 " %*s\n", + modname, &modsz, &modaddr) == 3) + { + Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, modname, + modaddr, modaddr + modsz); + if (mod == NULL) + { + result = -1; + break; + } + + result = check_module_notes (mod); + } + free (line); + + if (result == 0) + result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC; + + fclose (f); + + return result; +} +INTDEF (dwfl_linux_kernel_report_modules) diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c new file mode 100644 index 00000000..cd534825 --- /dev/null +++ b/libdwfl/linux-pid-attach.c @@ -0,0 +1,540 @@ +/* Get Dwarf Frame state for target live PID process. + Copyright (C) 2013, 2014, 2015, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libelfP.h" +#include "libdwflP.h" +#include +#include +#include +#include +#include + +#ifdef __linux__ + +#include +#include +#include +#include + +static bool +linux_proc_pid_is_stopped (pid_t pid) +{ + char buffer[64]; + FILE *procfile; + bool retval, have_state; + + snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid); + procfile = fopen (buffer, "r"); + if (procfile == NULL) + return false; + + have_state = false; + while (fgets (buffer, sizeof (buffer), procfile) != NULL) + if (startswith (buffer, "State:")) + { + have_state = true; + break; + } + retval = (have_state && strstr (buffer, "T (stopped)") != NULL); + fclose (procfile); + return retval; +} + +bool +internal_function +__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp) +{ + if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; + } + *tid_was_stoppedp = linux_proc_pid_is_stopped (tid); + if (*tid_was_stoppedp) + { + /* Make sure there is a SIGSTOP signal pending even when the process is + already State: T (stopped). Older kernels might fail to generate + a SIGSTOP notification in that case in response to our PTRACE_ATTACH + above. Which would make the waitpid below wait forever. So emulate + it. Since there can only be one SIGSTOP notification pending this is + safe. See also gdb/linux-nat.c linux_nat_post_attach_wait. */ + syscall (__NR_tkill, tid, SIGSTOP); + ptrace (PTRACE_CONT, tid, NULL, NULL); + } + for (;;) + { + int status; + if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status)) + { + int saved_errno = errno; + ptrace (PTRACE_DETACH, tid, NULL, NULL); + errno = saved_errno; + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; + } + if (WSTOPSIG (status) == SIGSTOP) + break; + if (ptrace (PTRACE_CONT, tid, NULL, + (void *) (uintptr_t) WSTOPSIG (status)) != 0) + { + int saved_errno = errno; + ptrace (PTRACE_DETACH, tid, NULL, NULL); + errno = saved_errno; + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; + } + } + return true; +} + +#ifdef HAVE_PROCESS_VM_READV +/* Note that the result word size depends on the architecture word size. + That is sizeof long. */ +static bool +read_cached_memory (struct __libdwfl_pid_arg *pid_arg, + Dwarf_Addr addr, Dwarf_Word *result) +{ + /* Let the ptrace fallback deal with the corner case of the address + possibly crossing a page boundary. */ + if ((addr & ((Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - 1)) + > (Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - sizeof (unsigned long)) + return false; + + struct __libdwfl_remote_mem_cache *mem_cache = pid_arg->mem_cache; + if (mem_cache == NULL) + { + size_t mem_cache_size = sizeof (struct __libdwfl_remote_mem_cache); + mem_cache = (struct __libdwfl_remote_mem_cache *) malloc (mem_cache_size); + if (mem_cache == NULL) + return false; + + mem_cache->addr = 0; + mem_cache->len = 0; + pid_arg->mem_cache = mem_cache; + } + + unsigned char *d; + if (addr >= mem_cache->addr && addr - mem_cache->addr < mem_cache->len) + { + d = &mem_cache->buf[addr - mem_cache->addr]; + if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0) + *result = *(unsigned long *) d; + else + memcpy (result, d, sizeof (unsigned long)); + return true; + } + + struct iovec local, remote; + mem_cache->addr = addr & ~((Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - 1); + local.iov_base = mem_cache->buf; + local.iov_len = __LIBDWFL_REMOTE_MEM_CACHE_SIZE; + remote.iov_base = (void *) (uintptr_t) mem_cache->addr; + remote.iov_len = __LIBDWFL_REMOTE_MEM_CACHE_SIZE; + + ssize_t res = process_vm_readv (pid_arg->tid_attached, + &local, 1, &remote, 1, 0); + if (res != __LIBDWFL_REMOTE_MEM_CACHE_SIZE) + { + mem_cache->len = 0; + return false; + } + + mem_cache->len = res; + d = &mem_cache->buf[addr - mem_cache->addr]; + if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0) + *result = *(unsigned long *) d; + else + memcpy (result, d, sizeof (unsigned long)); + return true; +} +#endif /* HAVE_PROCESS_VM_READV */ + +static void +clear_cached_memory (struct __libdwfl_pid_arg *pid_arg) +{ + struct __libdwfl_remote_mem_cache *mem_cache = pid_arg->mem_cache; + if (mem_cache != NULL) + mem_cache->len = 0; +} + +/* Note that the result word size depends on the architecture word size. + That is sizeof long. */ +static bool +pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg) +{ + struct __libdwfl_pid_arg *pid_arg = arg; + pid_t tid = pid_arg->tid_attached; + Dwfl_Process *process = dwfl->process; + assert (tid > 0); + +#ifdef HAVE_PROCESS_VM_READV + if (read_cached_memory (pid_arg, addr, result)) + { +#if SIZEOF_LONG == 8 +# if BYTE_ORDER == BIG_ENDIAN + if (ebl_get_elfclass (process->ebl) == ELFCLASS32) + *result >>= 32; +# endif +#endif + return true; + } +#endif + + if (ebl_get_elfclass (process->ebl) == ELFCLASS64) + { +#if SIZEOF_LONG == 8 + errno = 0; + *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL); + return errno == 0; +#else /* SIZEOF_LONG != 8 */ + /* This should not happen. */ + return false; +#endif /* SIZEOF_LONG != 8 */ + } +#if SIZEOF_LONG == 8 + /* We do not care about reads unaliged to 4 bytes boundary. + But 0x...ffc read of 8 bytes could overrun a page. */ + bool lowered = (addr & 4) != 0; + if (lowered) + addr -= 4; +#endif /* SIZEOF_LONG == 8 */ + errno = 0; + *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL); + if (errno != 0) + return false; +#if SIZEOF_LONG == 8 +# if BYTE_ORDER == BIG_ENDIAN + if (! lowered) + *result >>= 32; +# else + if (lowered) + *result >>= 32; +# endif +#endif /* SIZEOF_LONG == 8 */ + *result &= 0xffffffff; + return true; +} + +static pid_t +pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg, + void **thread_argp) +{ + struct __libdwfl_pid_arg *pid_arg = dwfl_arg; + struct dirent *dirent; + /* Start fresh on first traversal. */ + if (*thread_argp == NULL) + rewinddir (pid_arg->dir); + do + { + errno = 0; + dirent = readdir (pid_arg->dir); + if (dirent == NULL) + { + if (errno != 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return -1; + } + return 0; + } + } + while (strcmp (dirent->d_name, ".") == 0 + || strcmp (dirent->d_name, "..") == 0); + char *end; + errno = 0; + long tidl = strtol (dirent->d_name, &end, 10); + if (errno != 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return -1; + } + pid_t tid = tidl; + if (tidl <= 0 || (end && *end) || tid != tidl) + { + __libdwfl_seterrno (DWFL_E_PARSE_PROC); + return -1; + } + *thread_argp = dwfl_arg; + return tid; +} + +/* Just checks that the thread id exists. */ +static bool +pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid, + void *dwfl_arg, void **thread_argp) +{ + *thread_argp = dwfl_arg; + if (kill (tid, 0) < 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; + } + return true; +} + +/* Implement the ebl_set_initial_registers_tid setfunc callback. */ + +static bool +pid_thread_state_registers_cb (int firstreg, unsigned nregs, + const Dwarf_Word *regs, void *arg) +{ + Dwfl_Thread *thread = (Dwfl_Thread *) arg; + if (firstreg < 0) + { + assert (firstreg == -1); + assert (nregs == 1); + INTUSE(dwfl_thread_state_register_pc) (thread, *regs); + return true; + } + assert (nregs > 0); + return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs); +} + +static bool +pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg) +{ + struct __libdwfl_pid_arg *pid_arg = thread_arg; + assert (pid_arg->tid_attached == 0); + pid_t tid = INTUSE(dwfl_thread_tid) (thread); + if (! pid_arg->assume_ptrace_stopped + && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped)) + return false; + pid_arg->tid_attached = tid; + Dwfl_Process *process = thread->process; + Ebl *ebl = process->ebl; + return ebl_set_initial_registers_tid (ebl, tid, + pid_thread_state_registers_cb, thread); +} + +static void +pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg) +{ + struct __libdwfl_pid_arg *pid_arg = dwfl_arg; + elf_end (pid_arg->elf); + free (pid_arg->mem_cache); + close (pid_arg->elf_fd); + closedir (pid_arg->dir); + free (pid_arg); +} + +void +internal_function +__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped) +{ + /* This handling is needed only on older Linux kernels such as + 2.6.32-358.23.2.el6.ppc64. Later kernels such as + 3.11.7-200.fc19.x86_64 remember the T (stopped) state + themselves and no longer need to pass SIGSTOP during + PTRACE_DETACH. */ + ptrace (PTRACE_DETACH, tid, NULL, + (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0)); +} + +static void +pid_thread_detach (Dwfl_Thread *thread, void *thread_arg) +{ + struct __libdwfl_pid_arg *pid_arg = thread_arg; + pid_t tid = INTUSE(dwfl_thread_tid) (thread); + assert (pid_arg->tid_attached == tid); + pid_arg->tid_attached = 0; + clear_cached_memory (pid_arg); + if (! pid_arg->assume_ptrace_stopped) + __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped); +} + +static const Dwfl_Thread_Callbacks pid_thread_callbacks = +{ + pid_next_thread, + pid_getthread, + pid_memory_read, + pid_set_initial_registers, + pid_detach, + pid_thread_detach, +}; + +int +dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped) +{ + char buffer[36]; + FILE *procfile; + int err = 0; /* The errno to return and set for dwfl->attcherr. */ + + /* Make sure to report the actual PID (thread group leader) to + dwfl_attach_state. */ + snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid); + procfile = fopen (buffer, "r"); + if (procfile == NULL) + { + err = errno; + fail: + if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR) + { + errno = err; + dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO); + } + return err; + } + + char *line = NULL; + size_t linelen = 0; + while (getline (&line, &linelen, procfile) >= 0) + if (startswith (line, "Tgid:")) + { + errno = 0; + char *endptr; + long val = strtol (&line[5], &endptr, 10); + if ((errno == ERANGE && val == LONG_MAX) + || *endptr != '\n' || val < 0 || val != (pid_t) val) + pid = 0; + else + pid = (pid_t) val; + break; + } + free (line); + fclose (procfile); + + if (pid == 0) + { + err = ESRCH; + goto fail; + } + + char name[64]; + int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid); + if (i <= 0 || i >= (ssize_t) sizeof (name) - 1) + { + errno = -ENOMEM; + goto fail; + } + DIR *dir = opendir (name); + if (dir == NULL) + { + err = errno; + goto fail; + } + + Elf *elf; + i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid); + assert (i > 0 && i < (ssize_t) sizeof (name) - 1); + int elf_fd = open (name, O_RDONLY); + if (elf_fd >= 0) + { + elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + { + /* Just ignore, dwfl_attach_state will fall back to trying + to associate the Dwfl with one of the existing DWfl_Module + ELF images (to know the machine/class backend to use). */ + close (elf_fd); + elf_fd = -1; + } + } + else + elf = NULL; + struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg); + if (pid_arg == NULL) + { + elf_end (elf); + close (elf_fd); + closedir (dir); + err = ENOMEM; + goto fail; + } + pid_arg->dir = dir; + pid_arg->elf = elf; + pid_arg->elf_fd = elf_fd; + pid_arg->mem_cache = NULL; + pid_arg->tid_attached = 0; + pid_arg->assume_ptrace_stopped = assume_ptrace_stopped; + if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks, + pid_arg)) + { + elf_end (elf); + close (elf_fd); + closedir (dir); + free (pid_arg); + return -1; + } + return 0; +} +INTDEF (dwfl_linux_proc_attach) + +struct __libdwfl_pid_arg * +internal_function +__libdwfl_get_pid_arg (Dwfl *dwfl) +{ + if (dwfl != NULL && dwfl->process != NULL + && dwfl->process->callbacks == &pid_thread_callbacks) + return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg; + + return NULL; +} + +#else /* __linux__ */ + +bool +internal_function +__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)), + bool *tid_was_stoppedp __attribute__ ((unused))) +{ + errno = ENOSYS; + __libdwfl_seterrno (DWFL_E_ERRNO); + return false; +} + +void +internal_function +__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)), + bool tid_was_stopped __attribute__ ((unused))) +{ +} + +int +dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)), + pid_t pid __attribute__ ((unused)), + bool assume_ptrace_stopped __attribute__ ((unused))) +{ + return ENOSYS; +} +INTDEF (dwfl_linux_proc_attach) + +struct __libdwfl_pid_arg * +internal_function +__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused))) +{ + return NULL; +} + +#endif /* ! __linux __ */ + diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c new file mode 100644 index 00000000..719cba68 --- /dev/null +++ b/libdwfl/linux-proc-maps.c @@ -0,0 +1,440 @@ +/* Standard libdwfl callbacks for debugging a live Linux process. + Copyright (C) 2005-2010, 2013, 2014, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "system.h" + + +#define PROCMAPSFMT "/proc/%d/maps" +#define PROCMEMFMT "/proc/%d/mem" +#define PROCAUXVFMT "/proc/%d/auxv" +#define PROCEXEFMT "/proc/%d/exe" + + +/* Return ELFCLASS64 or ELFCLASS32 for the main ELF executable. Return + ELFCLASSNONE for an error. */ + +static unsigned char +get_pid_class (pid_t pid) +{ + char *fname; + if (asprintf (&fname, PROCEXEFMT, pid) < 0) + return ELFCLASSNONE; + + int fd = open (fname, O_RDONLY); + free (fname); + if (fd < 0) + return ELFCLASSNONE; + + unsigned char buf[EI_CLASS + 1]; + ssize_t nread = pread_retry (fd, &buf, sizeof buf, 0); + close (fd); + if (nread != sizeof buf || buf[EI_MAG0] != ELFMAG0 + || buf[EI_MAG1] != ELFMAG1 || buf[EI_MAG2] != ELFMAG2 + || buf[EI_MAG3] != ELFMAG3 + || (buf[EI_CLASS] != ELFCLASS64 && buf[EI_CLASS] != ELFCLASS32)) + return ELFCLASSNONE; + + return buf[EI_CLASS]; +} + +/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag. + + It would be easiest to call get_pid_class and parse everything according to + the 32-bit or 64-bit class. But this would bring the overhead of syscalls + to open and read the "/proc/%d/exe" file. + + Therefore this function tries to parse the "/proc/%d/auxv" content both + ways, as if it were the 32-bit format and also if it were the 64-bit format. + Only if it gives some valid data in both cases get_pid_class gets called. + In most cases only one of the format bit sizes gives valid data and the + get_pid_class call overhead can be saved. */ + +static int +grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr) +{ + char *fname; + if (asprintf (&fname, PROCAUXVFMT, pid) < 0) + return ENOMEM; + + int fd = open (fname, O_RDONLY); + free (fname); + if (fd < 0) + return errno == ENOENT ? 0 : errno; + + GElf_Addr sysinfo_ehdr64 = 0; + GElf_Addr sysinfo_ehdr32 = 0; + GElf_Addr segment_align64 = dwfl->segment_align; + GElf_Addr segment_align32 = dwfl->segment_align; + off_t offset = 0; + ssize_t nread; + union + { + Elf64_auxv_t a64[64]; + Elf32_auxv_t a32[128]; + } d; + do + { + eu_static_assert (sizeof d.a64 == sizeof d.a32); + nread = pread_retry (fd, d.a64, sizeof d.a64, offset); + if (nread < 0) + { + int ret = errno; + close (fd); + return ret; + } + for (size_t a32i = 0; a32i < nread / sizeof d.a32[0]; a32i++) + { + const Elf32_auxv_t *a32 = d.a32 + a32i; + switch (a32->a_type) + { + case AT_SYSINFO_EHDR: + sysinfo_ehdr32 = a32->a_un.a_val; + break; + case AT_PAGESZ: + segment_align32 = a32->a_un.a_val; + break; + } + } + for (size_t a64i = 0; a64i < nread / sizeof d.a64[0]; a64i++) + { + const Elf64_auxv_t *a64 = d.a64 + a64i; + switch (a64->a_type) + { + case AT_SYSINFO_EHDR: + sysinfo_ehdr64 = a64->a_un.a_val; + break; + case AT_PAGESZ: + segment_align64 = a64->a_un.a_val; + break; + } + } + offset += nread; + } + while (nread == sizeof d.a64); + + close (fd); + + bool valid64 = sysinfo_ehdr64 != 0 || segment_align64 != dwfl->segment_align; + bool valid32 = sysinfo_ehdr32 != 0 || segment_align32 != dwfl->segment_align; + + unsigned char pid_class = ELFCLASSNONE; + if (valid64 && valid32) + pid_class = get_pid_class (pid); + + if (pid_class == ELFCLASS64 || (valid64 && ! valid32)) + { + *sysinfo_ehdr = sysinfo_ehdr64; + dwfl->segment_align = segment_align64; + return 0; + } + if (pid_class == ELFCLASS32 || (! valid64 && valid32)) + { + *sysinfo_ehdr = sysinfo_ehdr32; + dwfl->segment_align = segment_align32; + return 0; + } + return ENOEXEC; +} + +static inline bool +do_report (Dwfl *dwfl, char **plast_file, Dwarf_Addr low, Dwarf_Addr high) +{ + if (*plast_file != NULL) + { + Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, *plast_file, + low, high); + free (*plast_file); + *plast_file = NULL; + if (unlikely (mod == NULL)) + return true; + } + return false; +} + +#define report() do_report(dwfl, &last_file, low, high) + +static int +proc_maps_report (Dwfl *dwfl, FILE *f, GElf_Addr sysinfo_ehdr, pid_t pid) +{ + unsigned int last_dmajor = -1, last_dminor = -1; + uint64_t last_ino = -1; + char *last_file = NULL; + Dwarf_Addr low = 0, high = 0; + + char *line = NULL; + size_t linesz; + ssize_t len; + while ((len = getline (&line, &linesz, f)) > 0) + { + if (line[len - 1] == '\n') + line[len - 1] = '\0'; + + Dwarf_Addr start, end, offset; + unsigned int dmajor, dminor; + uint64_t ino; + int nread = -1; + if (sscanf (line, "%" PRIx64 "-%" PRIx64 " %*s %" PRIx64 + " %x:%x %" PRIu64 " %n", + &start, &end, &offset, &dmajor, &dminor, &ino, &nread) < 6 + || nread <= 0) + { + free (line); + free (last_file); + return ENOEXEC; + } + + /* If this is the special mapping AT_SYSINFO_EHDR pointed us at, + report the last one and then this special one. */ + if (start == sysinfo_ehdr && start != 0) + { + if (report ()) + { + bad_report: + free (line); + return -1; + } + + low = start; + high = end; + if (asprintf (&last_file, "[vdso: %d]", (int) pid) < 0 + || report ()) + goto bad_report; + } + + char *file = line + nread + strspn (line + nread, " \t"); + if (file[0] != '/' || (ino == 0 && dmajor == 0 && dminor == 0)) + /* This line doesn't indicate a file mapping. */ + continue; + + if (last_file != NULL + && ino == last_ino && dmajor == last_dmajor && dminor == last_dminor) + { + /* This is another portion of the same file's mapping. */ + if (strcmp (last_file, file) != 0) + { + free (last_file); + goto bad_report; + } + high = end; + } + else + { + /* This is a different file mapping. Report the last one. */ + if (report ()) + goto bad_report; + low = start; + high = end; + last_file = strdup (file); + last_ino = ino; + last_dmajor = dmajor; + last_dminor = dminor; + } + } + free (line); + + int result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC; + + /* Report the final one. */ + bool lose = report (); + + return result != 0 ? result : lose ? -1 : 0; +} + +int +dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *f) +{ + return proc_maps_report (dwfl, f, 0, 0); +} +INTDEF (dwfl_linux_proc_maps_report) + +int +dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid) +{ + if (dwfl == NULL) + return -1; + + /* We'll notice the AT_SYSINFO_EHDR address specially when we hit it. */ + GElf_Addr sysinfo_ehdr = 0; + int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr); + if (result != 0) + return result; + + char *fname; + if (asprintf (&fname, PROCMAPSFMT, pid) < 0) + return ENOMEM; + + FILE *f = fopen (fname, "r"); + free (fname); + if (f == NULL) + return errno; + + (void) __fsetlocking (f, FSETLOCKING_BYCALLER); + + result = proc_maps_report (dwfl, f, sysinfo_ehdr, pid); + + fclose (f); + + return result; +} +INTDEF (dwfl_linux_proc_report) + +static ssize_t +read_proc_memory (void *arg, void *data, GElf_Addr address, + size_t minread, size_t maxread) +{ + const int fd = *(const int *) arg; + + /* This code relies on the fact the Linux kernel accepts negative + offsets when seeking /dev/$$/mem files, as a special case. In + particular pread cannot be used here, because it will always + return EINVAL when passed a negative offset. */ + + if (lseek (fd, (off_t) address, SEEK_SET) == -1) + return -1; + + ssize_t nread = read (fd, data, maxread); + + if (nread > 0 && (size_t) nread < minread) + nread = 0; + return nread; +} + +extern Elf *elf_from_remote_memory (GElf_Addr ehdr_vma, + GElf_Xword pagesize, + GElf_Addr *loadbasep, + ssize_t (*read_memory) (void *arg, + void *data, + GElf_Addr address, + size_t minread, + size_t maxread), + void *arg); + + +/* Dwfl_Callbacks.find_elf */ + +int +dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)), + void **userdata __attribute__ ((unused)), + const char *module_name, Dwarf_Addr base, + char **file_name, Elf **elfp) +{ + int pid = -1; + if (module_name[0] == '/') + { + /* When this callback is used together with dwfl_linux_proc_report + then we might see mappings of special character devices. Make + sure we only open and return regular files. Special devices + might hang on open or read. (deleted) files are super special. + The image might come from memory if we are attached. */ + struct stat sb; + if (stat (module_name, &sb) == -1 || (sb.st_mode & S_IFMT) != S_IFREG) + { + if (strcmp (strrchr (module_name, ' ') ?: "", " (deleted)") == 0) + pid = INTUSE(dwfl_pid) (mod->dwfl); + else + return -1; + } + + if (pid == -1) + { + int fd = open (module_name, O_RDONLY); + if (fd >= 0) + { + *file_name = strdup (module_name); + if (*file_name == NULL) + { + close (fd); + return ENOMEM; + } + } + return fd; + } + } + + if (pid != -1 || sscanf (module_name, "[vdso: %d]", &pid) == 1) + { + /* Special case for in-memory ELF image. */ + + bool detach = false; + bool tid_was_stopped = false; + struct __libdwfl_pid_arg *pid_arg = __libdwfl_get_pid_arg (mod->dwfl); + if (pid_arg != NULL && ! pid_arg->assume_ptrace_stopped) + { + /* If any thread is already attached we are fine. Read + through that thread. It doesn't have to be the main + thread pid. */ + pid_t tid = pid_arg->tid_attached; + if (tid != 0) + pid = tid; + else + detach = __libdwfl_ptrace_attach (pid, &tid_was_stopped); + } + + char *fname; + if (asprintf (&fname, PROCMEMFMT, pid) < 0) + goto detach; + + int fd = open (fname, O_RDONLY); + free (fname); + if (fd < 0) + goto detach; + + *elfp = elf_from_remote_memory (base, sysconf (_SC_PAGESIZE), NULL, + &read_proc_memory, &fd); + + close (fd); + + *file_name = NULL; + + detach: + if (detach) + __libdwfl_ptrace_detach (pid, tid_was_stopped); + return -1; + } + + return -1; +} +INTDEF (dwfl_linux_proc_find_elf) diff --git a/libdwfl/lzma.c b/libdwfl/lzma.c new file mode 100644 index 00000000..3edfdc22 --- /dev/null +++ b/libdwfl/lzma.c @@ -0,0 +1,4 @@ +/* liblzma is pretty close to zlib and bzlib. */ + +#define LZMA +#include "gzip.c" diff --git a/libdwfl/offline.c b/libdwfl/offline.c new file mode 100644 index 00000000..d8697cf2 --- /dev/null +++ b/libdwfl/offline.c @@ -0,0 +1,318 @@ +/* Recover relocatibility for addresses computed from debug information. + Copyright (C) 2005-2009, 2012 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" +#include +#include + +/* Since dwfl_report_elf lays out the sections already, this will only be + called when the section headers of the debuginfo file are being + consulted instead, or for the section placed at 0. With binutils + strip-to-debug, the symbol table is in the debuginfo file and relocation + looks there. */ +int +dwfl_offline_section_address (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *modname __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + const char *secname __attribute__ ((unused)), + Elf32_Word shndx, + const GElf_Shdr *shdr __attribute__ ((unused)), + Dwarf_Addr *addr) +{ + assert (mod->e_type == ET_REL); + assert (shdr->sh_addr == 0); + assert (shdr->sh_flags & SHF_ALLOC); + assert (shndx != 0); + + if (mod->debug.elf == NULL) + /* We are only here because sh_addr is zero even though layout is complete. + The first section in the first file under -e is placed at 0. */ + return 0; + + /* The section numbers might not match between the two files. + The best we can rely on is the order of SHF_ALLOC sections. */ + + Elf_Scn *ourscn = elf_getscn (mod->debug.elf, shndx); + Elf_Scn *scn = NULL; + uint_fast32_t skip_alloc = 0; + while ((scn = elf_nextscn (mod->debug.elf, scn)) != ourscn) + { + assert (scn != NULL); + GElf_Shdr shdr_mem; + GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem); + if (unlikely (sh == NULL)) + return -1; + if (sh->sh_flags & SHF_ALLOC) + ++skip_alloc; + } + + scn = NULL; + while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *main_shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (main_shdr == NULL)) + return -1; + if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0) + { + assert (main_shdr->sh_flags == shdr->sh_flags); + *addr = main_shdr->sh_addr; + return 0; + } + } + + /* This should never happen. */ + return -1; +} +INTDEF (dwfl_offline_section_address) + +/* Forward declarations. */ +static Dwfl_Module *process_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, Elf *elf); +static Dwfl_Module *process_archive (Dwfl *dwfl, const char *name, + const char *file_name, int fd, Elf *elf, + int (*predicate) (const char *module, + const char *file)); + +/* Report one module for an ELF file, or many for an archive. + Always consumes ELF and FD. */ +static Dwfl_Module * +process_file (Dwfl *dwfl, const char *name, const char *file_name, int fd, + Elf *elf, int (*predicate) (const char *module, + const char *file)) +{ + switch (elf_kind (elf)) + { + default: + case ELF_K_NONE: + __libdwfl_seterrno (elf == NULL ? DWFL_E_LIBELF : DWFL_E_BADELF); + return NULL; + + case ELF_K_ELF: + return process_elf (dwfl, name, file_name, fd, elf); + + case ELF_K_AR: + return process_archive (dwfl, name, file_name, fd, elf, predicate); + } +} + +/* Report the open ELF file as a module. Always consumes ELF and FD. */ +static Dwfl_Module * +process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, + Elf *elf) +{ + Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, + dwfl->offline_next_address, true, + false); + if (mod != NULL) + { + /* If this is an ET_EXEC file with fixed addresses, the address range + it consumed may or may not intersect with the arbitrary range we + will use for relocatable modules. Make sure we always use a free + range for the offline allocations. If this module did use + offline_next_address, it may have rounded it up for the module's + alignment requirements. */ + if ((dwfl->offline_next_address >= mod->low_addr + || mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE) + && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE) + dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE; + + /* Don't keep the file descriptor around. */ + if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0) + { + /* Grab the dir path in case we want to report this file as + Dwarf later. */ + mod->elfdir = __libdw_debugdir (mod->main.fd); + close (mod->main.fd); + mod->main.fd = -1; + } + } + + return mod; +} + +/* Always consumes MEMBER. Returns elf_next result on success. + For errors returns ELF_C_NULL with *MOD set to null. */ +static Elf_Cmd +process_archive_member (Dwfl *dwfl, const char *name, const char *file_name, + int (*predicate) (const char *module, const char *file), + int fd, Elf *member, Dwfl_Module **mod) +{ + const Elf_Arhdr *h = elf_getarhdr (member); + if (unlikely (h == NULL)) + { + __libdwfl_seterrno (DWFL_E_LIBELF); + fail: + elf_end (member); + *mod = NULL; + return ELF_C_NULL; + } + + if (!strcmp (h->ar_name, "/") || !strcmp (h->ar_name, "//") + || !strcmp (h->ar_name, "/SYM64/")) + { + skip:; + /* Skip this and go to the next. */ + Elf_Cmd result = elf_next (member); + elf_end (member); + return result; + } + + char *member_name; + if (unlikely (asprintf (&member_name, "%s(%s)", file_name, h->ar_name) < 0)) + { + nomem: + __libdwfl_seterrno (DWFL_E_NOMEM); + elf_end (member); + *mod = NULL; + return ELF_C_NULL; + } + + char *module_name = NULL; + if (name == NULL || name[0] == '\0') + name = h->ar_name; + else if (unlikely (asprintf (&module_name, "%s:%s", name, h->ar_name) < 0)) + { + free (member_name); + goto nomem; + } + else + name = module_name; + + if (predicate != NULL) + { + /* Let the predicate decide whether to use this one. */ + int want = (*predicate) (name, member_name); + if (want <= 0) + { + free (member_name); + free (module_name); + if (unlikely (want < 0)) + { + __libdwfl_seterrno (DWFL_E_CB); + goto fail; + } + goto skip; + } + } + + /* We let __libdwfl_report_elf cache the fd in mod->main.fd, + though it's the same fd for all the members. + On module teardown we will close it only on the last Elf reference. */ + *mod = process_file (dwfl, name, member_name, fd, member, predicate); + free (member_name); + free (module_name); + + if (*mod == NULL) /* process_file called elf_end. */ + return ELF_C_NULL; + + /* Advance the archive-reading offset for the next iteration. */ + return elf_next (member); +} + +/* Report each member of the archive as its own module. */ +static Dwfl_Module * +process_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd, + Elf *archive, + int (*predicate) (const char *module, const char *file)) + +{ + Dwfl_Module *mod = NULL; + Elf *member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive); + if (unlikely (member == NULL)) /* Empty archive. */ + { + __libdwfl_seterrno (DWFL_E_BADELF); + return NULL; + } + + while (process_archive_member (dwfl, name, file_name, predicate, + fd, member, &mod) != ELF_C_NULL) + member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive); + + /* We can drop the archive Elf handle even if we're still using members + in live modules. When the last module's elf_end on a member returns + zero, that module will close FD. If no modules survived the predicate, + we are all done with the file right here. */ + if (mod != NULL /* If no modules, caller will clean up. */ + && elf_end (archive) == 0) + close (fd); + + return mod; +} + +Dwfl_Module * +internal_function +__libdwfl_report_offline (Dwfl *dwfl, const char *name, + const char *file_name, int fd, bool closefd, + int (*predicate) (const char *module, + const char *file)) +{ + Elf *elf; + Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, true); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return NULL; + } + Dwfl_Module *mod = process_file (dwfl, name, file_name, fd, elf, predicate); + if (mod == NULL) + { + elf_end (elf); + if (closefd) + close (fd); + } + return mod; +} + +Dwfl_Module * +dwfl_report_offline (Dwfl *dwfl, const char *name, + const char *file_name, int fd) +{ + if (dwfl == NULL) + return NULL; + + bool closefd = false; + if (fd < 0) + { + closefd = true; + fd = open (file_name, O_RDONLY); + if (fd < 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return NULL; + } + } + + return __libdwfl_report_offline (dwfl, name, file_name, fd, closefd, NULL); +} +INTDEF (dwfl_report_offline) diff --git a/libdwfl/open.c b/libdwfl/open.c new file mode 100644 index 00000000..77bd2bd9 --- /dev/null +++ b/libdwfl/open.c @@ -0,0 +1,204 @@ +/* Decompression support for libdwfl: zlib (gzip), bzlib (bzip2) or lzma (xz). + Copyright (C) 2009, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "../libelf/libelfP.h" +#undef _ +#include "libdwflP.h" + +#include + +#if !USE_BZLIB +# define __libdw_bunzip2(...) DWFL_E_BADELF +#endif + +#if !USE_LZMA +# define __libdw_unlzma(...) DWFL_E_BADELF +#endif + +#if !USE_ZSTD +# define __libdw_unzstd(...) DWFL_E_BADELF +#endif + +/* Consumes and replaces *ELF only on success. */ +static Dwfl_Error +decompress (int fd __attribute__ ((unused)), Elf **elf) +{ + Dwfl_Error error = DWFL_E_BADELF; + void *buffer = NULL; + size_t size = 0; + + const off_t offset = (*elf)->start_offset; + void *const mapped = ((*elf)->map_address == NULL ? NULL + : (*elf)->map_address + offset); + const size_t mapped_size = (*elf)->maximum_size; + if (mapped_size == 0) + return error; + + error = __libdw_gunzip (fd, offset, mapped, mapped_size, &buffer, &size); + if (error == DWFL_E_BADELF) + error = __libdw_bunzip2 (fd, offset, mapped, mapped_size, &buffer, &size); + if (error == DWFL_E_BADELF) + error = __libdw_unlzma (fd, offset, mapped, mapped_size, &buffer, &size); + if (error == DWFL_E_BADELF) + error = __libdw_unzstd (fd, offset, mapped, mapped_size, &buffer, &size); + + if (error == DWFL_E_NOERROR) + { + if (unlikely (size == 0)) + { + error = DWFL_E_BADELF; + free (buffer); + } + else + { + Elf *memelf = elf_memory (buffer, size); + if (memelf == NULL) + { + error = DWFL_E_LIBELF; + free (buffer); + } + else + { + memelf->flags |= ELF_F_MALLOCED; + elf_end (*elf); + *elf = memelf; + } + } + } + else + free (buffer); + + return error; +} + +static Dwfl_Error +what_kind (int fd, Elf **elfp, Elf_Kind *kind, bool *may_close_fd) +{ + Dwfl_Error error = DWFL_E_NOERROR; + *kind = elf_kind (*elfp); + if (unlikely (*kind == ELF_K_NONE)) + { + if (unlikely (*elfp == NULL)) + error = DWFL_E_LIBELF; + else + { + error = decompress (fd, elfp); + if (error == DWFL_E_NOERROR) + { + *may_close_fd = true; + *kind = elf_kind (*elfp); + } + } + } + return error; +} + +static Dwfl_Error +libdw_open_elf (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok, + bool never_close_fd, bool bad_elf_ok) +{ + bool may_close_fd = false; + + Elf *elf = elf_begin (*fdp, ELF_C_READ_MMAP_PRIVATE, NULL); + + Elf_Kind kind; + Dwfl_Error error = what_kind (*fdp, &elf, &kind, &may_close_fd); + if (error == DWFL_E_BADELF) + { + /* It's not an ELF file or a compressed file. + See if it's an image with a header preceding the real file. */ + + off_t offset = elf->start_offset; + error = __libdw_image_header (*fdp, &offset, + (elf->map_address == NULL ? NULL + : elf->map_address + offset), + elf->maximum_size); + if (error == DWFL_E_NOERROR) + { + /* Pure evil. libelf needs some better interfaces. */ + elf->kind = ELF_K_AR; + elf->state.ar.elf_ar_hdr.ar_name = "libdwfl is faking you out"; + elf->state.ar.elf_ar_hdr.ar_size = elf->maximum_size - offset; + elf->state.ar.offset = offset - sizeof (struct ar_hdr); + Elf *subelf = elf_begin (-1, ELF_C_READ_MMAP_PRIVATE, elf); + elf->kind = ELF_K_NONE; + if (unlikely (subelf == NULL)) + error = DWFL_E_LIBELF; + else + { + subelf->parent = NULL; + subelf->flags |= elf->flags & (ELF_F_MMAPPED | ELF_F_MALLOCED); + elf->flags &= ~(ELF_F_MMAPPED | ELF_F_MALLOCED); + elf_end (elf); + elf = subelf; + error = what_kind (*fdp, &elf, &kind, &may_close_fd); + } + } + } + + if (error == DWFL_E_NOERROR + && kind != ELF_K_ELF + && !(archive_ok && kind == ELF_K_AR)) + error = DWFL_E_BADELF; + + /* This basically means, we keep a ELF_K_NONE Elf handle and return it. */ + if (bad_elf_ok && error == DWFL_E_BADELF) + error = DWFL_E_NOERROR; + + if (error != DWFL_E_NOERROR) + { + elf_end (elf); + elf = NULL; + } + + if (! never_close_fd + && error == DWFL_E_NOERROR ? may_close_fd : close_on_fail) + { + close (*fdp); + *fdp = -1; + } + + *elfp = elf; + return error; +} + +Dwfl_Error internal_function +__libdw_open_file (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok) +{ + return libdw_open_elf (fdp, elfp, close_on_fail, archive_ok, false, false); +} + +Dwfl_Error internal_function +__libdw_open_elf (int fd, Elf **elfp) +{ + return libdw_open_elf (&fd, elfp, false, true, true, true); +} diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c new file mode 100644 index 00000000..0497bd4f --- /dev/null +++ b/libdwfl/relocate.c @@ -0,0 +1,824 @@ +/* Relocate debug information. + Copyright (C) 2005-2011, 2014, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libelfP.h" +#include "libdwflP.h" + +typedef uint8_t GElf_Byte; + +/* Adjust *VALUE to add the load address of the SHNDX section. + We update the section header in place to cache the result. */ + +Dwfl_Error +internal_function +__libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx, + Elf32_Word shndx, GElf_Addr *value) +{ + /* No adjustment needed for section zero, it is never loaded. + Handle it first, just in case the ELF file has strange section + zero flags set. */ + if (shndx == 0) + return DWFL_E_NOERROR; + + Elf_Scn *refscn = elf_getscn (elf, shndx); + GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem); + if (refshdr == NULL) + return DWFL_E_LIBELF; + + if (refshdr->sh_addr == 0 && (refshdr->sh_flags & SHF_ALLOC)) + { + /* This is a loaded section. Find its actual + address and update the section header. */ + + if (*shstrndx == SHN_UNDEF + && unlikely (elf_getshdrstrndx (elf, shstrndx) < 0)) + return DWFL_E_LIBELF; + + const char *name = elf_strptr (elf, *shstrndx, refshdr->sh_name); + if (unlikely (name == NULL)) + return DWFL_E_LIBELF; + + if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod), + name, shndx, refshdr, + &refshdr->sh_addr)) + return CBFAIL; + + if (refshdr->sh_addr == (Dwarf_Addr) -1l) + /* The callback indicated this section wasn't really loaded but we + don't really care. */ + refshdr->sh_addr = 0; /* Make no adjustment below. */ + + /* Update the in-core file's section header to show the final + load address (or unloadedness). This serves as a cache, + so we won't get here again for the same section. */ + if (likely (refshdr->sh_addr != 0) + && unlikely (! gelf_update_shdr (refscn, refshdr))) + return DWFL_E_LIBELF; + } + + if (refshdr->sh_flags & SHF_ALLOC) + /* Apply the adjustment. */ + *value += dwfl_adjusted_address (mod, refshdr->sh_addr); + + return DWFL_E_NOERROR; +} + + +/* Cache used by relocate_getsym. */ +struct reloc_symtab_cache +{ + Elf *symelf; + Elf_Data *symdata; + Elf_Data *symxndxdata; + Elf_Data *symstrdata; + size_t symshstrndx; + size_t strtabndx; +}; +#define RELOC_SYMTAB_CACHE(cache) \ + struct reloc_symtab_cache cache = \ + { NULL, NULL, NULL, NULL, SHN_UNDEF, SHN_UNDEF } + +/* This is just doing dwfl_module_getsym, except that we must always use + the symbol table in RELOCATED itself when it has one, not MOD->symfile. */ +static Dwfl_Error +relocate_getsym (Dwfl_Module *mod, + Elf *relocated, struct reloc_symtab_cache *cache, + int symndx, GElf_Sym *sym, GElf_Word *shndx) +{ + if (cache->symdata == NULL) + { + if (mod->symfile == NULL || mod->symfile->elf != relocated) + { + /* We have to look up the symbol table in the file we are + relocating, if it has its own. These reloc sections refer to + the symbol table in this file, and a symbol table in the main + file might not match. However, some tools did produce ET_REL + .debug files with relocs but no symtab of their own. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (relocated, scn)) != NULL) + { + GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + { + /* We need uncompressed data. */ + if ((shdr->sh_type == SHT_SYMTAB + || shdr->sh_type == SHT_SYMTAB_SHNDX) + && (shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (scn, 0, 0) < 0) + return DWFL_E_LIBELF; + + switch (shdr->sh_type) + { + default: + continue; + case SHT_SYMTAB: + cache->symelf = relocated; + cache->symdata = elf_getdata (scn, NULL); + cache->strtabndx = shdr->sh_link; + if (unlikely (cache->symdata == NULL)) + return DWFL_E_LIBELF; + break; + case SHT_SYMTAB_SHNDX: + cache->symxndxdata = elf_getdata (scn, NULL); + if (unlikely (cache->symxndxdata == NULL)) + return DWFL_E_LIBELF; + break; + } + } + if (cache->symdata != NULL && cache->symxndxdata != NULL) + break; + } + } + if (cache->symdata == NULL) + { + /* We might not have looked for a symbol table file yet, + when coming from __libdwfl_relocate_section. */ + if (unlikely (mod->symfile == NULL) + && unlikely (INTUSE(dwfl_module_getsymtab) (mod) < 0)) + return dwfl_errno (); + + /* The symbol table we have already cached is the one from + the file being relocated, so it's what we need. Or else + this is an ET_REL .debug file with no .symtab of its own; + the symbols refer to the section indices in the main file. */ + cache->symelf = mod->symfile->elf; + cache->symdata = mod->symdata; + cache->symxndxdata = mod->symxndxdata; + cache->symstrdata = mod->symstrdata; + } + } + + if (unlikely (gelf_getsymshndx (cache->symdata, cache->symxndxdata, + symndx, sym, shndx) == NULL)) + return DWFL_E_LIBELF; + + if (sym->st_shndx != SHN_XINDEX) + *shndx = sym->st_shndx; + + switch (sym->st_shndx) + { + case SHN_ABS: + case SHN_UNDEF: + return DWFL_E_NOERROR; + + case SHN_COMMON: + sym->st_value = 0; /* Value is size, not helpful. */ + return DWFL_E_NOERROR; + } + + return __libdwfl_relocate_value (mod, cache->symelf, &cache->symshstrndx, + *shndx, &sym->st_value); +} + +/* Handle an undefined symbol. We really only support ET_REL for Linux + kernel modules, and offline archives. The behavior of the Linux module + loader is very simple and easy to mimic. It only matches magically + exported symbols, and we match any defined symbols. But we get the same + answer except when the module's symbols are undefined and would prevent + it from being loaded. */ +static Dwfl_Error +resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab, + GElf_Sym *sym, GElf_Word shndx) +{ + /* First we need its name. */ + if (sym->st_name != 0) + { + if (symtab->symstrdata == NULL) + { + /* Cache the strtab for this symtab. */ + assert (referer->symfile == NULL + || referer->symfile->elf != symtab->symelf); + + Elf_Scn *scn = elf_getscn (symtab->symelf, symtab->strtabndx); + if (scn == NULL) + return DWFL_E_LIBELF; + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + return DWFL_E_LIBELF; + + if (symtab->symshstrndx == SHN_UNDEF + && elf_getshdrstrndx (symtab->symelf, &symtab->symshstrndx) < 0) + return DWFL_E_LIBELF; + + const char *sname = elf_strptr (symtab->symelf, symtab->symshstrndx, + shdr->sh_name); + if (sname == NULL) + return DWFL_E_LIBELF; + + /* If the section is already decompressed, that isn't an error. */ + if (startswith (sname, ".zdebug")) + elf_compress_gnu (scn, 0, 0); + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (scn, 0, 0) < 0) + return DWFL_E_LIBELF; + + symtab->symstrdata = elf_getdata (scn, NULL); + if (unlikely (symtab->symstrdata == NULL + || symtab->symstrdata->d_buf == NULL)) + return DWFL_E_LIBELF; + } + if (unlikely (sym->st_name >= symtab->symstrdata->d_size)) + return DWFL_E_BADSTROFF; + + const char *name = symtab->symstrdata->d_buf; + name += sym->st_name; + + for (Dwfl_Module *m = referer->dwfl->modulelist; m != NULL; m = m->next) + if (m != referer) + { + /* Get this module's symtab. + If we got a fresh error reading the table, report it. + If we just have no symbols in this module, no harm done. */ + if (m->symdata == NULL + && m->symerr == DWFL_E_NOERROR + && INTUSE(dwfl_module_getsymtab) (m) < 0 + && m->symerr != DWFL_E_NO_SYMTAB) + return m->symerr; + + for (size_t ndx = 1; ndx < m->syments; ++ndx) + { + sym = gelf_getsymshndx (m->symdata, m->symxndxdata, + ndx, sym, &shndx); + if (unlikely (sym == NULL)) + return DWFL_E_LIBELF; + if (sym->st_shndx != SHN_XINDEX) + shndx = sym->st_shndx; + + /* We are looking for a defined global symbol with a name. */ + if (shndx == SHN_UNDEF || shndx == SHN_COMMON + || GELF_ST_BIND (sym->st_info) == STB_LOCAL + || sym->st_name == 0) + continue; + + /* Get this candidate symbol's name. */ + if (unlikely (sym->st_name >= m->symstrdata->d_size)) + return DWFL_E_BADSTROFF; + const char *n = m->symstrdata->d_buf; + n += sym->st_name; + + /* Does the name match? */ + if (strcmp (name, n)) + continue; + + /* We found it! */ + if (shndx == SHN_ABS) /* XXX maybe should apply bias? */ + return DWFL_E_NOERROR; + + if (m->e_type != ET_REL) + { + sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf, + sym->st_value); + return DWFL_E_NOERROR; + } + + /* In an ET_REL file, the symbol table values are relative + to the section, not to the module's load base. */ + size_t symshstrndx = SHN_UNDEF; + return __libdwfl_relocate_value (m, m->symfile->elf, + &symshstrndx, + shndx, &sym->st_value); + } + } + } + + return DWFL_E_RELUNDEF; +} + +/* Apply one relocation. Returns true for any invalid data. */ +static Dwfl_Error +relocate (Dwfl_Module * const mod, + Elf * const relocated, + struct reloc_symtab_cache * const reloc_symtab, + Elf_Data * const tdata, + const GElf_Ehdr * const ehdr, + GElf_Addr offset, + const GElf_Sxword *addend, + int rtype, + int symndx) +{ + /* First see if this is a reloc we can handle. + If we are skipping it, don't bother resolving the symbol. */ + + if (unlikely (rtype == 0)) + /* In some odd situations, the linker can leave R_*_NONE relocs + behind. This is probably bogus ld -r behavior, but the only + cases it's known to appear in are harmless: DWARF data + referring to addresses in a section that has been discarded. + So we just pretend it's OK without further relocation. */ + return DWFL_E_NOERROR; + + int addsub = 0; + Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype, &addsub); + if (unlikely (type == ELF_T_NUM)) + return DWFL_E_BADRELTYPE; + + /* First, resolve the symbol to an absolute value. */ + GElf_Addr value; + + if (symndx == STN_UNDEF) + /* When strip removes a section symbol referring to a + section moved into the debuginfo file, it replaces + that symbol index in relocs with STN_UNDEF. We + don't actually need the symbol, because those relocs + are always references relative to the nonallocated + debugging sections, which start at zero. */ + value = 0; + else + { + GElf_Sym sym; + GElf_Word shndx; + Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab, + symndx, &sym, &shndx); + if (unlikely (error != DWFL_E_NOERROR)) + return error; + + if (shndx == SHN_UNDEF || shndx == SHN_COMMON) + { + /* Maybe we can figure it out anyway. */ + error = resolve_symbol (mod, reloc_symtab, &sym, shndx); + if (error != DWFL_E_NOERROR + && !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON)) + return error; + } + + value = sym.st_value; + } + + /* These are the types we can relocate. */ +#define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \ + DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \ + DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword) + size_t size; + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + if (addsub != 0 && addend == NULL) \ + /* These do not make sense with SHT_REL. */ \ + return DWFL_E_BADRELTYPE; \ + size = sizeof (GElf_##Name); \ + break + TYPES; +#undef DO_TYPE + default: + return DWFL_E_BADRELTYPE; + } + + if (offset > tdata->d_size || tdata->d_size - offset < size) + return DWFL_E_BADRELOFF; + +#define DO_TYPE(NAME, Name) GElf_##Name Name; + union { TYPES; } tmpbuf; +#undef DO_TYPE + Elf_Data tmpdata = + { + .d_type = type, + .d_buf = &tmpbuf, + .d_size = size, + .d_version = EV_CURRENT, + }; + Elf_Data rdata = + { + .d_type = type, + .d_buf = tdata->d_buf + offset, + .d_size = size, + .d_version = EV_CURRENT, + }; + + /* XXX check for overflow? */ + if (addend) + { + /* For the addend form, we have the value already. */ + value += *addend; + /* For ADD/SUB relocations we need to fetch the section + contents. */ + if (addsub != 0) + { + Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata, + ehdr->e_ident[EI_DATA]); + if (d == NULL) + return DWFL_E_LIBELF; + assert (d == &tmpdata); + } + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + if (addsub != 0) \ + tmpbuf.Name += value * addsub; \ + else \ + tmpbuf.Name = value; \ + break + TYPES; +#undef DO_TYPE + default: + abort (); + } + } + else + { + /* Extract the original value and apply the reloc. */ + Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata, + ehdr->e_ident[EI_DATA]); + if (d == NULL) + return DWFL_E_LIBELF; + assert (d == &tmpdata); + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + tmpbuf.Name += (GElf_##Name) value; \ + break + TYPES; +#undef DO_TYPE + default: + abort (); + } + } + + /* Now convert the relocated datum back to the target + format. This will write into rdata.d_buf, which + points into the raw section data being relocated. */ + Elf_Data *s = gelf_xlatetof (relocated, &rdata, &tmpdata, + ehdr->e_ident[EI_DATA]); + if (s == NULL) + return DWFL_E_LIBELF; + assert (s == &rdata); + + /* We have applied this relocation! */ + return DWFL_E_NOERROR; +} + +static inline void +check_badreltype (bool *first_badreltype, + Dwfl_Module *mod, + Dwfl_Error *result) +{ + if (*first_badreltype) + { + *first_badreltype = false; + if (ebl_get_elfmachine (mod->ebl) == EM_NONE) + /* This might be because ebl_openbackend failed to find + any libebl_CPU.so library. Diagnose that clearly. */ + *result = DWFL_E_UNKNOWN_MACHINE; + } +} + +static Dwfl_Error +relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr, + size_t shstrndx, struct reloc_symtab_cache *reloc_symtab, + Elf_Scn *scn, GElf_Shdr *shdr, + Elf_Scn *tscn, bool debugscn, bool partial) +{ + /* First, fetch the name of the section these relocations apply to. + Then try to decompress both relocation and target section. */ + GElf_Shdr tshdr_mem; + GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem); + if (tshdr == NULL) + return DWFL_E_LIBELF; + + const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name); + if (tname == NULL) + return DWFL_E_LIBELF; + + if (debugscn && ! ebl_debugscn_p (mod->ebl, tname)) + /* This relocation section is not for a debugging section. + Nothing to do here. */ + return DWFL_E_NOERROR; + + if (startswith (tname, ".zdebug")) + elf_compress_gnu (tscn, 0, 0); + + if ((tshdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (tscn, 0, 0) < 0) + return DWFL_E_LIBELF; + + /* Reload Shdr in case section was just decompressed. */ + tshdr = gelf_getshdr (tscn, &tshdr_mem); + if (tshdr == NULL) + return DWFL_E_LIBELF; + + if (unlikely (tshdr->sh_type == SHT_NOBITS) + || unlikely (tshdr->sh_size == 0)) + /* No contents to relocate. */ + return DWFL_E_NOERROR; + + const char *sname = elf_strptr (relocated, shstrndx, shdr->sh_name); + if (sname == NULL) + return DWFL_E_LIBELF; + + if (startswith (sname, ".zdebug")) + elf_compress_gnu (scn, 0, 0); + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + if (elf_compress (scn, 0, 0) < 0) + return DWFL_E_LIBELF; + + /* Reload Shdr in case section was just decompressed. */ + GElf_Shdr shdr_mem; + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + return DWFL_E_LIBELF; + + /* Fetch the section data that needs the relocations applied. */ + Elf_Data *tdata = elf_rawdata (tscn, NULL); + if (tdata == NULL) + return DWFL_E_LIBELF; + + /* If either the section that needs the relocation applied, or the + section that the relocations come from overlap one of the ehdrs, + shdrs or phdrs data then we refuse to do the relocations. It + isn't illegal for ELF section data to overlap the header data, + but updating the (relocation) data might corrupt the in-memory + libelf headers causing strange corruptions or errors. + + This is only an issue if the ELF is mmapped and the section data + comes from the mmapped region (is not malloced or decompressed). + */ + if (relocated->map_address != NULL) + { + size_t ehsize = gelf_fsize (relocated, ELF_T_EHDR, 1, EV_CURRENT); + if (unlikely (shdr->sh_offset < ehsize + || tshdr->sh_offset < ehsize)) + return DWFL_E_BADELF; + + GElf_Off shdrs_start = ehdr->e_shoff; + size_t shnums; + if (elf_getshdrnum (relocated, &shnums) < 0) + return DWFL_E_LIBELF; + /* Overflows will have been checked by elf_getshdrnum/get|rawdata. */ + size_t shentsize = gelf_fsize (relocated, ELF_T_SHDR, 1, EV_CURRENT); + GElf_Off shdrs_end = shdrs_start + shnums * shentsize; + if (unlikely (shdrs_start < shdr->sh_offset + shdr->sh_size + && shdr->sh_offset < shdrs_end)) + if ((scn->flags & ELF_F_MALLOCED) == 0) + return DWFL_E_BADELF; + + if (unlikely (shdrs_start < tshdr->sh_offset + tshdr->sh_size + && tshdr->sh_offset < shdrs_end)) + if ((tscn->flags & ELF_F_MALLOCED) == 0) + return DWFL_E_BADELF; + + GElf_Off phdrs_start = ehdr->e_phoff; + size_t phnums; + if (elf_getphdrnum (relocated, &phnums) < 0) + return DWFL_E_LIBELF; + if (phdrs_start != 0 && phnums != 0) + { + /* Overflows will have been checked by elf_getphdrnum/get|rawdata. */ + size_t phentsize = gelf_fsize (relocated, ELF_T_PHDR, 1, EV_CURRENT); + GElf_Off phdrs_end = phdrs_start + phnums * phentsize; + if (unlikely (phdrs_start < shdr->sh_offset + shdr->sh_size + && shdr->sh_offset < phdrs_end)) + if ((scn->flags & ELF_F_MALLOCED) == 0) + return DWFL_E_BADELF; + + if (unlikely (phdrs_start < tshdr->sh_offset + tshdr->sh_size + && tshdr->sh_offset < phdrs_end)) + if ((tscn->flags & ELF_F_MALLOCED) == 0) + return DWFL_E_BADELF; + } + } + + /* Fetch the relocation section and apply each reloc in it. */ + Elf_Data *reldata = elf_getdata (scn, NULL); + if (reldata == NULL) + return DWFL_E_LIBELF; + + Dwfl_Error result = DWFL_E_NOERROR; + bool first_badreltype = true; + + size_t sh_entsize + = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA, + 1, EV_CURRENT); + size_t nrels = shdr->sh_size / sh_entsize; + size_t complete = 0; + if (shdr->sh_type == SHT_REL) + for (size_t relidx = 0; !result && relidx < nrels; ++relidx) + { + GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem); + if (r == NULL) + return DWFL_E_LIBELF; + result = relocate (mod, relocated, reloc_symtab, tdata, ehdr, + r->r_offset, NULL, + GELF_R_TYPE (r->r_info), + GELF_R_SYM (r->r_info)); + check_badreltype (&first_badreltype, mod, &result); + if (partial) + switch (result) + { + case DWFL_E_NOERROR: + /* We applied the relocation. Elide it. */ + memset (&rel_mem, 0, sizeof rel_mem); + if (unlikely (gelf_update_rel (reldata, relidx, &rel_mem) == 0)) + return DWFL_E_LIBELF; + ++complete; + break; + case DWFL_E_BADRELTYPE: + case DWFL_E_RELUNDEF: + /* We couldn't handle this relocation. Skip it. */ + result = DWFL_E_NOERROR; + break; + default: + break; + } + } + else + for (size_t relidx = 0; !result && relidx < nrels; ++relidx) + { + GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx, + &rela_mem); + if (r == NULL) + return DWFL_E_LIBELF; + result = relocate (mod, relocated, reloc_symtab, tdata, ehdr, + r->r_offset, &r->r_addend, + GELF_R_TYPE (r->r_info), + GELF_R_SYM (r->r_info)); + check_badreltype (&first_badreltype, mod, &result); + if (partial) + switch (result) + { + case DWFL_E_NOERROR: + /* We applied the relocation. Elide it. */ + memset (&rela_mem, 0, sizeof rela_mem); + if (unlikely (gelf_update_rela (reldata, relidx, + &rela_mem) == 0)) + return DWFL_E_LIBELF; + ++complete; + break; + case DWFL_E_BADRELTYPE: + case DWFL_E_RELUNDEF: + /* We couldn't handle this relocation. Skip it. */ + result = DWFL_E_NOERROR; + break; + default: + break; + } + } + + if (likely (result == DWFL_E_NOERROR)) + { + if (!partial || complete == nrels) + /* Mark this relocation section as being empty now that we have + done its work. This affects unstrip -R, so e.g. it emits an + empty .rela.debug_info along with a .debug_info that has + already been fully relocated. */ + nrels = 0; + else if (complete != 0) + { + /* We handled some of the relocations but not all. + We've zeroed out the ones we processed. + Now remove them from the section. */ + + size_t next = 0; + if (shdr->sh_type == SHT_REL) + for (size_t relidx = 0; relidx < nrels; ++relidx) + { + GElf_Rel rel_mem; + GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem); + if (unlikely (r == NULL)) + return DWFL_E_LIBELF; + if (r->r_info != 0 || r->r_offset != 0) + { + if (next != relidx) + if (unlikely (gelf_update_rel (reldata, next, r) == 0)) + return DWFL_E_LIBELF; + ++next; + } + } + else + for (size_t relidx = 0; relidx < nrels; ++relidx) + { + GElf_Rela rela_mem; + GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem); + if (unlikely (r == NULL)) + return DWFL_E_LIBELF; + if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0) + { + if (next != relidx) + if (unlikely (gelf_update_rela (reldata, next, r) == 0)) + return DWFL_E_LIBELF; + ++next; + } + } + nrels = next; + } + + shdr->sh_size = reldata->d_size = nrels * sh_entsize; + if (unlikely (gelf_update_shdr (scn, shdr) == 0)) + return DWFL_E_LIBELF; + } + + return result; +} + +Dwfl_Error +internal_function +__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug) +{ + assert (mod->e_type == ET_REL); + + GElf_Ehdr ehdr_mem; + const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem); + if (ehdr == NULL) + return DWFL_E_LIBELF; + + size_t d_shstrndx; + if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0) + return DWFL_E_LIBELF; + + RELOC_SYMTAB_CACHE (reloc_symtab); + + /* Look at each section in the debuginfo file, and process the + relocation sections for debugging sections. */ + Dwfl_Error result = DWFL_E_NOERROR; + Elf_Scn *scn = NULL; + while (result == DWFL_E_NOERROR + && (scn = elf_nextscn (debugfile, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + return DWFL_E_LIBELF; + + if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) + && shdr->sh_size != 0) + { + /* It's a relocation section. */ + + Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info); + if (unlikely (tscn == NULL)) + result = DWFL_E_LIBELF; + else + result = relocate_section (mod, debugfile, ehdr, d_shstrndx, + &reloc_symtab, scn, shdr, tscn, + debug, true /* partial always OK. */); + } + } + + return result; +} + +Dwfl_Error +internal_function +__libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated, + Elf_Scn *relocscn, Elf_Scn *tscn, bool partial) +{ + GElf_Ehdr ehdr_mem; + GElf_Shdr shdr_mem; + + RELOC_SYMTAB_CACHE (reloc_symtab); + + size_t shstrndx; + if (elf_getshdrstrndx (relocated, &shstrndx) < 0) + return DWFL_E_LIBELF; + + Dwfl_Error result = __libdwfl_module_getebl (mod); + if (unlikely (result != DWFL_E_NOERROR)) + return result; + + GElf_Ehdr *ehdr = gelf_getehdr (relocated, &ehdr_mem); + if (unlikely (ehdr == NULL)) + return DWFL_E_LIBELF; + + GElf_Shdr *shdr = gelf_getshdr (relocscn, &shdr_mem); + if (unlikely (shdr == NULL)) + return DWFL_E_LIBELF; + + return relocate_section (mod, relocated, ehdr, shstrndx, &reloc_symtab, + relocscn, shdr, tscn, false, partial); +} diff --git a/libdwfl/segment.c b/libdwfl/segment.c new file mode 100644 index 00000000..f6a3e84e --- /dev/null +++ b/libdwfl/segment.c @@ -0,0 +1,330 @@ +/* Manage address space lookup table for libdwfl. + Copyright (C) 2008, 2009, 2010, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwflP.h" + +GElf_Addr +internal_function +__libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start) +{ + if (dwfl->segment_align > 1) + start &= -dwfl->segment_align; + return start; +} + +GElf_Addr +internal_function +__libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end) +{ + if (dwfl->segment_align > 1) + end = (end + dwfl->segment_align - 1) & -dwfl->segment_align; + return end; +} + +static bool +insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx) +{ + bool need_start = (i == 0 || dwfl->lookup_addr[i - 1] != start); + bool need_end = (i + 1 >= dwfl->lookup_elts + || dwfl->lookup_addr[i + 1] != end); + size_t need = need_start + need_end; + if (need == 0) + return false; + + if (dwfl->lookup_alloc - dwfl->lookup_elts < need) + { + size_t n = dwfl->lookup_alloc == 0 ? 16 : dwfl->lookup_alloc * 2; + GElf_Addr *naddr = realloc (dwfl->lookup_addr, sizeof naddr[0] * n); + if (unlikely (naddr == NULL)) + return true; + int *nsegndx = realloc (dwfl->lookup_segndx, sizeof nsegndx[0] * n); + if (unlikely (nsegndx == NULL)) + { + if (naddr != dwfl->lookup_addr) + free (naddr); + return true; + } + dwfl->lookup_alloc = n; + dwfl->lookup_addr = naddr; + dwfl->lookup_segndx = nsegndx; + + if (dwfl->lookup_module != NULL) + { + /* Make sure this array is big enough too. */ + Dwfl_Module **old = dwfl->lookup_module; + dwfl->lookup_module = realloc (dwfl->lookup_module, + sizeof dwfl->lookup_module[0] * n); + if (unlikely (dwfl->lookup_module == NULL)) + { + free (old); + return true; + } + } + } + + if (unlikely (i < dwfl->lookup_elts)) + { + const size_t move = dwfl->lookup_elts - i; + memmove (&dwfl->lookup_addr[i + need], &dwfl->lookup_addr[i], + move * sizeof dwfl->lookup_addr[0]); + memmove (&dwfl->lookup_segndx[i + need], &dwfl->lookup_segndx[i], + move * sizeof dwfl->lookup_segndx[0]); + if (dwfl->lookup_module != NULL) + memmove (&dwfl->lookup_module[i + need], &dwfl->lookup_module[i], + move * sizeof dwfl->lookup_module[0]); + } + + if (need_start) + { + dwfl->lookup_addr[i] = start; + dwfl->lookup_segndx[i] = segndx; + if (dwfl->lookup_module != NULL) + dwfl->lookup_module[i] = NULL; + ++i; + } + else + dwfl->lookup_segndx[i - 1] = segndx; + + if (need_end) + { + dwfl->lookup_addr[i] = end; + dwfl->lookup_segndx[i] = -1; + if (dwfl->lookup_module != NULL) + dwfl->lookup_module[i] = NULL; + } + + dwfl->lookup_elts += need; + + return false; +} + +static int +lookup (Dwfl *dwfl, GElf_Addr address, int hint) +{ + if (hint >= 0 + && address >= dwfl->lookup_addr[hint] + && ((size_t) hint + 1 == dwfl->lookup_elts + || address < dwfl->lookup_addr[hint + 1])) + return hint; + + /* Do binary search on the array indexed by module load address. */ + size_t l = 0, u = dwfl->lookup_elts; + while (l < u) + { + size_t idx = (l + u) / 2; + if (address < dwfl->lookup_addr[idx]) + u = idx; + else + { + l = idx + 1; + if (l == dwfl->lookup_elts || address < dwfl->lookup_addr[l]) + return idx; + } + } + + return -1; +} + +static bool +reify_segments (Dwfl *dwfl) +{ + int hint = -1; + int highest = -1; + bool fixup = false; + for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next) + if (! mod->gc) + { + const GElf_Addr start = __libdwfl_segment_start (dwfl, mod->low_addr); + const GElf_Addr end = __libdwfl_segment_end (dwfl, mod->high_addr); + bool resized = false; + + int idx = lookup (dwfl, start, hint); + if (unlikely (idx < 0)) + { + /* Module starts below any segment. Insert a low one. */ + if (unlikely (insert (dwfl, 0, start, end, -1))) + return true; + idx = 0; + resized = true; + } + else if (dwfl->lookup_addr[idx] > start) + { + /* The module starts in the middle of this segment. Split it. */ + if (unlikely (insert (dwfl, idx + 1, start, end, + dwfl->lookup_segndx[idx]))) + return true; + ++idx; + resized = true; + } + else if (dwfl->lookup_addr[idx] < start) + { + /* The module starts past the end of this segment. + Add a new one. */ + if (unlikely (insert (dwfl, idx + 1, start, end, -1))) + return true; + ++idx; + resized = true; + } + + if ((size_t) idx + 1 < dwfl->lookup_elts + && end < dwfl->lookup_addr[idx + 1]) + { + /* The module ends in the middle of this segment. Split it. */ + if (unlikely (insert (dwfl, idx + 1, + end, dwfl->lookup_addr[idx + 1], -1))) + return true; + resized = true; + } + + if (dwfl->lookup_module == NULL) + { + dwfl->lookup_module = calloc (dwfl->lookup_alloc, + sizeof dwfl->lookup_module[0]); + if (unlikely (dwfl->lookup_module == NULL)) + return true; + } + + /* Cache a backpointer in the module. */ + mod->segment = idx; + + /* Put MOD in the table for each segment that's inside it. */ + do + dwfl->lookup_module[idx++] = mod; + while ((size_t) idx < dwfl->lookup_elts + && dwfl->lookup_addr[idx] < end); + assert (dwfl->lookup_module[mod->segment] == mod); + + if (resized && idx - 1 >= highest) + /* Expanding the lookup tables invalidated backpointers + we've already stored. Reset those ones. */ + fixup = true; + + highest = idx - 1; + hint = (size_t) idx < dwfl->lookup_elts ? idx : -1; + } + + if (fixup) + /* Reset backpointer indices invalidated by table insertions. */ + for (size_t idx = 0; idx < dwfl->lookup_elts; ++idx) + if (dwfl->lookup_module[idx] != NULL) + dwfl->lookup_module[idx]->segment = idx; + + return false; +} + +int +dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod) +{ + if (unlikely (dwfl == NULL)) + return -1; + + if (unlikely (dwfl->lookup_module == NULL) + && mod != NULL + && unlikely (reify_segments (dwfl))) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + + int idx = lookup (dwfl, address, -1); + if (likely (mod != NULL)) + { + if (unlikely (idx < 0) || unlikely (dwfl->lookup_module == NULL)) + *mod = NULL; + else + { + *mod = dwfl->lookup_module[idx]; + + /* If this segment does not have a module, but the address is + the upper boundary of the previous segment's module, use that. */ + if (*mod == NULL && idx > 0 && dwfl->lookup_addr[idx] == address) + { + *mod = dwfl->lookup_module[idx - 1]; + if (*mod != NULL && (*mod)->high_addr != address) + *mod = NULL; + } + } + } + + if (likely (idx >= 0)) + /* Translate internal segment table index to user segment index. */ + idx = dwfl->lookup_segndx[idx]; + + return idx; +} +INTDEF (dwfl_addrsegment) + +int +dwfl_report_segment (Dwfl *dwfl, int ndx, const GElf_Phdr *phdr, GElf_Addr bias, + const void *ident) +{ + /* This was previously used for coalescing segments, but it was buggy since + day one. We don't use it anymore. */ + (void)ident; + + if (dwfl == NULL) + return -1; + + if (ndx < 0) + ndx = dwfl->next_segndx; + + if (phdr->p_align > 1 && (dwfl->segment_align <= 1 || + phdr->p_align < dwfl->segment_align)) + dwfl->segment_align = phdr->p_align; + + if (unlikely (dwfl->lookup_module != NULL)) + { + free (dwfl->lookup_module); + dwfl->lookup_module = NULL; + } + + GElf_Addr start = __libdwfl_segment_start (dwfl, bias + phdr->p_vaddr); + GElf_Addr end = __libdwfl_segment_end (dwfl, + bias + phdr->p_vaddr + phdr->p_memsz); + + /* Normally just appending keeps us sorted. */ + + size_t i = dwfl->lookup_elts; + while (i > 0 && unlikely (start < dwfl->lookup_addr[i - 1])) + --i; + + if (unlikely (insert (dwfl, i, start, end, ndx))) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + + dwfl->next_segndx = ndx + 1; + + return ndx; +} +INTDEF (dwfl_report_segment) diff --git a/libdwfl/zstd.c b/libdwfl/zstd.c new file mode 100644 index 00000000..dc4d5238 --- /dev/null +++ b/libdwfl/zstd.c @@ -0,0 +1,4 @@ +/* libzstd is pretty close to zlib and bzlib. */ + +#define ZSTD +#include "gzip.c" diff --git a/libebl/ChangeLog b/libebl/ChangeLog new file mode 100644 index 00000000..fff66b3e --- /dev/null +++ b/libebl/ChangeLog @@ -0,0 +1,1328 @@ +2021-04-19 Martin Liska + + * eblobjnotetypename.c (ebl_object_note_type_name): Use startswith. + * eblopenbackend.c (default_debugscn_p): Likewise. + +2020-12-16 Dmitry V. Levin + + * libeblP.h (_): Remove. + +2020-12-15 Dmitry V. Levin + + * eblbackendname.c (ebl_backend_name): Replace gettext(...) with _(...). + * eblcorenotetypename.c (ebl_core_note_type_name): Likewise. + * ebldynamictagname.c (ebl_dynamic_tag_name): Likewise. + * eblobjnote.c (ebl_object_note): Likewise. + * eblobjnotetypename.c (ebl_object_note_type_name): Likewise. + * eblosabiname.c (ebl_osabi_name): Likewise. + * eblsectionname.c (ebl_section_name): Likewise. + * eblsectiontypename.c (ebl_section_type_name): Likewise. + * eblsegmenttypename.c (ebl_segment_type_name): Likewise. + * eblsymbolbindingname.c (ebl_symbol_binding_name): Likewise. + * eblsymboltypename.c (ebl_symbol_type_name): Likewise. + +2020-10-19 Mark Wielaard + + * eblopenbackend.c (tilegx_init): Removed. + (machines): Set init to NULL for tilegx. + +2020-10-19 Mark Wielaard + + * Makefile.am (libebl_a_SOURCES): Remove ebl_syscall_abi.c. + * ebl-hooks.h (syscall_abi): Remove. + * ebl_syscall_abi.c: Delete. + * eblopenbackend.c (default_syscall_abi): Remove. + (fill_defaults): Remove syscall_abi assignment. + * libebl.h (ebl_syscall_abi): Remove. + +2020-09-03 Mark Wielaard + + * eblobjnote.c (ebl_object_note): For EM_AARCH64 handle BTI and PAC + in GNU_PROPERTY_AARCH64_FEATURE_1_AND. + +2020-07-19 Mark Wielaard + + * libebl.h: Only typedef Ebl if _LIBASM_H is undefined. + +2020-06-10 Mark Wielaard + + * eblopenbackend.c (i386_init, sh_init, x86_64_init, ia64_init, + alpha_init, arm_init, aarch64_init, sparc_init, ppc_init, + ppc64_init, s390_init, tilegx_init, m68k_init, bpf_init, + riscv_init, csky_init): Adjust signature. + (openbackend): Call init without sizeof(Ebl). + * libeblP.h (ebl_bhinit_t): Adjust signature. + +2020-06-04 Mark Wielaard + + * eblsegmenttypename.c (ebl_segment_type_name): Remove + PT_GNU_PROPERTY define. + +2020-04-17 Mark Wielaard + + * eblopenbackend.c (default_debugscn_p): Handle .gnu.debuglto_ + prefix. + +2020-02-08 Mark Wielaard + + * eblsegmenttypename.c (ebl_segment_type_name): Handle + PT_GNU_PROPERTY. + +2019-08-29 Mark Wielaard + + * Makefile.am (noinst_LIBRARIES): Add libebl.a. + (noinst_HEADERS): Add libebl.h. + +2019-07-05 Omar Sandoval + + * Makefile.am: Make libebl.a non-PIC by default. + Add libebl_pic.a. + Remove LIBEBL_SUBDIR definition. + (gen_SOURCES): Remove. + * eblopenbackend.c (machines): Replace dsoname with init callback. + (try_dlopen): Remove. + (openbackend): Use machine callback instead of try_dlopen(). + Don't assign result->dlhandle. + * eblclosebackend.c (ebl_closebackend): Remove dlclose() call. + +2019-04-29 Mao Han + + * eblopenbackend.c: Add C-SKY. + +2019-06-28 Mark Wielaard + + * eblopenbackend.c (try_dlopen): Remove result->name check. + (openbackend): Remove result->name assignment. + (struct ebl): Remove name. + +2019-05-30 Mark Wielaard + + * eblopenbackend.c (try_dlopen): New function extracted from + openbackend. + (openbackend): Replace ORIGINDIR define with BINORIGINDIR and + LIBORIGINDIR defines. Use tryopen to open backend in bin origin + path, lib origin path and without an explicit path. + +2019-04-28 Mark Wielaard + + * eblsymbolbindingname.c (ebl_symbol_binding_name): Check ebl is + not NULL for STB_GNU_UNIQUE. + * eblsymboltypename.c (ebl_symbol_type_name): Check ebl is not + NULL for STT_GNU_IFUNC. + +2019-01-29 Mark Wielaard + + * eblobjnote.c (ebl_object_note): Check pr_datasz padding doesn't + overflow descsz. + +2019-01-16 Mark Wielaard + + * libebl.h (ebl_core_note): Add desc as argument. + * eblcorenote.c (ebl_core_note): Take desc as an argument, check + it contains a zero terminated string if it is an NT_PLATFORM note. + +2019-01-16 Mark Wielaard + + * eblobjnte.c (ebl_object_note): Check pr_datasz isn't too large. + +2018-12-02 Mark Wielaard + + * eblobjnte.c (ebl_object_note): For GNU_PROPERTY_STACK_SIZE use + an Elf32_Addr or Elf64_Addr to read and print the size. + +2018-11-15 Mark Wielaard + + * eblobjnotetypename.c (ebl_object_note_type_name): Don't update + w, t and len unnecessarily. + +2018-11-12 Mark Wielaard + + * libebl.h (ebl_object_note): Add new argument namesz. + * eblobjnote.c (ebl_object_note): Likewise and handle GNU Build + Attribute notes. + * eblobjnotetypename.c (ebl_object_note_type_name): Handle GNU + Build Attribute notes. + +2018-11-11 Mark Wielaard + + * eblobjnote.c (ebl_object_note): Recognize NT_VERSION with zero + descriptor. Add explicit "GNU" name check. + * eblobjnotetypename.c (ebl_object_note_type_name): Add extra + argument descsz. Recognize NT_VERSION using descsz. With "GNU" + name it is NT_GNU_ABI_TAG. + * libebl.h (ebl_object_note_type_name): Add extra argument descsz. + +2018-10-18 Mark Wielaard + + * eblobjnote.c (ebl_object_note): Handle NT_GNU_PROPERTY_TYPE_0. + * eblobjnotetypename.c (ebl_object_note_type_name): Add + GNU_PROPERTY_TYPE_0. + +2018-10-02 Andreas Schwab + + * ebl-hooks.h (EBLHOOK(reloc_simple_type)): Add third parameter. + * libebl.h (ebl_reloc_simple_type): Likewise. + * eblopenbackend.c (default_reloc_simple_type): Likewise. + * eblrelocsimpletype.c (ebl_reloc_simple_type): Pass it down. + +2018-09-12 Mark Wielaard + + * eblsectionstripp.c (ebl_section_strip_p): Drop ehdr argument. + Use elf_getshdrstrndx. + * libebl.h (ebl_section_strip_p): Drop ehdr argument. + +2018-09-12 Mark Wielaard + + * ebl-hooks.h (check_special_symbol): Drop ehdr argument. + * ebl_check_special_symbol.c (ebl_check_special_symbol): Likewise. + * eblopenbackend.c (default_check_special_symbol): Likewise. + * libebl.h (ebl_check_special_symbol): Likewise. + +2018-07-04 Ross Burton + + * eblopenbackend.c: Remove error.h include. + +2018-04-25 Mark Wielaard + + * eblopenbackend.c (default_debugscn_p): Add new DWARF5 sections + .debug_addr, .debug_line_str, .debug_loclists, .debug_names, + .debug_rnglists and .debug_str_offsets. + +2018-04-19 Andreas Schwab + + * eblopenbackend.c (machines): Add entries for RISC-V. + +2018-03-16 Mark Wielaard + + * ebldynamictagname.c (ebl_dynamic_tag_name): Add SYMTAB_SHNDX to + stdtags. Add a eu_static_assert to make sure stdtags contains all + DT_NUM entries. + +2018-02-21 Mark Wielaard + + * eblcheckreloctargettype.c (ebl_check_reloc_target_type): Accept + SHT_NOTE. + +2018-02-09 Joshua Watt + + * eblobjnote.c (ebl_object_note): Use FALLTHROUGH macro instead of + comment. + +2017-04-27 Ulf Hermann + + * Makefile.am: Use fpic_CFLAGS. + +2017-07-19 Gustavo Romero + + * eblcorenotetypename.c: Add ppc64 HTM SPRs note as known type. + +2017-07-20 Mark Wielaard + + * Makefile.am (gen_SOURCES): Add ebl_data_marker_symbol.c. + * ebl-hooks.h (data_marker_symbol): New hook. + * ebl_data_marker_symbol.c: New file. + * eblopenbackend.c (default_data_marker_symbol): New function. + (fill_defaults): Add default_data_marker_symbol. + * libebl.h (ebl_data_marker_symbol): New function. + +2017-04-20 Ulf Hermann + + * libebl.h: Use __pure_attribute__. + +2017-02-15 Ulf Hermann + + * eblmachineflagname.c: Include system.h. + * eblopenbackend.c: Likewise. + +2016-07-08 Mark Wielaard + + * Makefile.am (gen_SOURCES): Remove eblstrtab.c. + * eblstrtab.c: Removed. + * libebl.h (Ebl_Strtab): Removed. + (Ebl_Strent): Removed. + (ebl_strtabinit): Removed. + (ebl_strtabfree): Removed. + (ebl_strtabadd): Removed. + (ebl_strtabfinalize): Removed. + (ebl_strtaboffset): Removed. + (ebl_string): Removed. + +2016-07-06 Mark Wielaard + + * Makefile.am (gen_SOURCES): Remove eblobjecttypename.c, + eblshflagscombine.c, eblwstrtab.c and eblgstrtab.c. + * ebl-hooks.h (object_type_name): Removed. + (sh_flags_combine): Likewise. + * eblgstrtab.c: Removed. + * eblobjecttypename.c: Removed. + * eblopenbackend.c (default_object_type_name): Removed. + (default_sh_flags_combine): Likewise. + (fill_defaults): Removed object_type_name and sh_flags_combine. + * eblshflagscombine.c: Removed. + * eblwstrtab.c: Removed. + * libebl.h (ebl_object_type_name): Removed. + (ebl_sh_flags_combine): Likewise. + (ebl_wstrtab*): Removed. + (ebl_gstrtab*): Likewise. + +2016-06-28 Richard Henderson + + * ebl-hooks.h (EBLHOOK(disasm)): Add ebl parameter. + * eblopenbackend.c (machines): Add EM_BPF entry. + +2016-05-20 Andreas Schwab + + * eblopenbackend.c (machines) [EM_68K]: Set class and data. + +2016-02-12 Mark Wielaard + + * eblobjnotetypename.c (ebl_object_note_type_name): Check name is + "Go" and use new goknowntypes then. Otherwise check name is not + "GNU" and return "unknown". + +2016-01-09 Mark Wielaard + + * eblobjnote.c (ebl_object_note): Add brackets around if statement + body. + +2015-12-18 Mark Wielaard + + * eblopenbackend.c (default_debugscn_p): Also match .zdebug sections. + +2015-12-08 Jose E. Marchesi + + * libebl.h: Prototype for ebl_ra_offset. + * eblabicfi.c (ebl_ra_offset): New function. + * libeblP.h (struct ebl): new field ra_offset; + +2015-09-24 Jose E. Marchesi + + * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid + relocation overflows in some platforms. + +2015-09-22 Mark Wielaard + + * *.c: Remove old-style function definitions. + +2015-09-09 Chih-Hung Hsieh + + * ebldwarftoregno.c (ebl_dwarf_to_regno): Remove redundant NULL tests + on parameters declared with __nonnull_attribute__. + * eblinitreg.c (ebl_frame_nregs): Likewise. + * eblnormalizepc.c (ebl_normalize_pc): Likewise. + * eblunwind.c (ebl_unwind): Likewise. + +2015-09-04 Chih-Hung Hsieh + + * eblopenbackend.c (ebl_openbackend_machine): Replace K&R function + definition with ansi-C definitions. + * eblstother.c (ebl_check_st_other_bits): Likewise. + +2015-06-12 Mark Wielaard + + * eblcheckreloctargettype.c (ebl_check_reloc_target_type): Allow + SHT_INIT_ARRAY, SHT_FINI_ARRAY and SHT_PREINIT_ARRAY. + +2015-05-17 Mark Wielaard + + * eblobjnote.c (ebl_object_note): If allocation buf is large, then + allocate it with malloc. + +2015-05-17 Mark Wielaard + + * eblopenbackend.c (MAX_PREFIX_LEN): New define (16). + (openbackend): Stack allocate symname array using MAX_PREFIX_LEN. + +2015-01-27 Mark Wielaard + + * libebl.h: Add comment from README that this is completely + UNSUPPORTED. + +2014-11-22 Mark Wielaard + + * ebl-hooks.h (bss_plt_p): Remove ehdr argument. + * eblbsspltp.c (ebl_bss_plt_p): Likewise. + * eblopenbackend.c (default_bss_plt_p): Likewise. + * libebl.h (ebl_bss_plt_p): Likewise. + +2014-11-17 Mark Wielaard + + * ebldebugscnp.c (ebl_debugscn_p): Check name is not NULL. + +2014-06-17 Mark Wielaard + + * eblinitreg.c (ebl_func_addr_mask): New function. + * libebl.h (ebl_func_addr_mask): Define. + * libeblP.h (struct ebl): Add func_addr_mask. + +2014-05-19 Mark Wielaard + + * Makefile.am (gen_SOURCES): Add eblcheckreloctargettype.c. + * eblcheckreloctargettype.c: New file. + * ebl-hooks.h (check_reloc_target_type): New hook. + * eblopenbackend.c (default_check_reloc_target_type): New function. + (fill_defaults): Assign default_check_reloc_target_type to + check_reloc_target_type. + * libebl.h (ebl_check_reloc_target_type): New function definition. + +2013-12-18 Mark Wielaard + + * Makefile.am (gen_SOURCES): Add eblresolvesym.c. + * ebl-hooks.h (resolve_sym_value): New entry. + * eblresolvesym.c: New file. + * libebl.h (ebl_resolve_sym_value): New definition. + * libeblP.h (fd_addr): New field. + (fd_data): Likewise. + +2013-12-18 Jan Kratochvil + + unwinder: s390 and s390x + * Makefile.am (gen_SOURCES): Add eblnormalizepc.c and eblunwind.c. + * ebl-hooks.h (normalize_pc, unwind): New. + * eblnormalizepc.c: New file. + * eblunwind.c: New file. + * libebl.h (Ebl_Register_Location): Add field pc_register. + (ebl_normalize_pc): New declaration. + (ebl_tid_registers_get_t, ebl_pid_memory_read_t): New definitions. + (ebl_unwind): New declaration. + +2013-12-15 Jan Kratochvil + + unwinder: ppc and ppc64 + * Makefile.am (gen_SOURCES): Add ebldwarftoregno.c. + * ebl-hooks.h (dwarf_to_regno): New. + * ebldwarftoregno.c: New file. + * libebl.h (Ebl_Core_Item): New field pc_register. + (ebl_tid_registers_t): Add FIRSTREG -1 to the comment. + (ebl_dwarf_to_regno): New. + +2013-11-25 Petr Machata + + * eblopenbackend.c (machines): Add entry for AArch64. + +2013-11-14 Jan Kratochvil + + Code cleanup: Remove const in prototype + * libebl.h (ebl_tid_registers_t): Remove const from firstreg. + +2013-11-07 Jan Kratochvil + Mark Wielaard + + * Makefile.am (gen_SOURCES): Add eblinitreg.c. + * ebl-hooks.h (set_initial_registers_tid): New entry. + * eblinitreg.c: New file. + * libebl.h (ebl_tid_registers_t): New definition. + (ebl_set_initial_registers_tid, ebl_frame_nregs): New declarations. + * libeblP.h (struct ebl): New entry frame_nregs. + +2013-10-06 Mark Wielaard + + * libebl.h (ebl_abi_cfi): Document restrictions using register + rules. + +2013-09-26 Petr Machata + + * eblcorenotetypename.c: Handle NT_ARM_TLS, NT_ARM_HW_BREAK, + NT_ARM_HW_WATCH, NT_SIGINFO, NT_FILE. + +2013-09-25 Mark Wielaard + + * eblsectionstripp.c (ebl_section_strip_p): Check shdr_l is not NULL. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2012-10-12 Jan Kratochvil + + * ebl-hooks.h (abi_cfi): Extend its comment for return value. + * eblopenbackend.c (default_abi_cfi): Return -1. + * libebl.h (ebl_abi_cfi): Extend its comment for return value. + +2012-08-30 Petr Machata + + * eblcorenotetypename.c: Handle PPC_VSX, X86_XSTATE, + S390_HIGH_GPRS, S390_TIMER, S390_TODCMP, S390_TODPREG, S390_CTRS, + S390_PREFIX, S390_LAST_BREAK, S390_SYSTEM_CALL, and ARM_VFP. + +2012-08-22 Jeff Kenton + + * eblopenbackend.c (machines): Add tilegx. + +2011-06-26 Mark Wielaard + + * eblopenbackend.c (default_debugscn_p): Add .debug_macro. + +2011-04-26 Mark Wielaard + + * libebl.h (ebl_object_note_type_name): Add const char *name arg. + * eblhooks.h (object_note_type_name): Likewise. + * eblopenbackend.c (default_object_note_type_name): Likewise. + * eblobjnotetypename.c (ebl_object_note_type_name): Likewise. + And print version if name is "stapsdt". + * eblobjnote.c (ebl_object_note): Add output for "stapsdt" notes. + +2011-03-21 Marek Polacek + + * ebldynamictagname.c: Fix typo in TLSDESC_GOT. + +2011-03-10 Mark Wielaard + + * Makefile.am (gen_SOURCES): Add eblstother.c. + * eblstother.c: New file. + * ebl-hooks.h: Add check_st_other_bits hook. + * eblopenbackend.c (default_check_st_other_bits): New function. + (fill_defaults): Hook default_check_st_other_bits. + * libebl.h (ebl_check_st_other_bits): New prototype. + +2010-07-07 Roland McGrath + + * eblopenbackend.c (default_debugscn_p): Match .gdb_index section. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2010-01-04 Roland McGrath + + * eblcorenote.c (ebl_core_note): Take GElf_Nhdr * and name data + pointer instead of only n_type and n_descsz. + * libebl.h: Update declaration. + * ebl-hooks.h: Update core_note hook signature. + * eblopenbackend.c (default_core_note): Likewise. + +2009-10-14 Roland McGrath + + * eblobjnote.c (ebl_object_note): Clean up NT_GNU_GOLD_VERSION printing. + +2009-10-05 Roland McGrath + + * eblopenbackend.c (default_debugscn_p): Match .debug_pubtypes and + .debug_types too. + +2009-09-02 Petr Machata + + * libebl/eblstrtab.c (morememory): Allocate memory in multiples of + pagesize. + +2009-08-06 Petr Machata + + * libebl/eblstrtab.c (ebl_strtabfinalize): Only call copystrings + if we have any strings to copy. + +2009-07-26 Mark Wielaard + + * eblobjnote.c (ebl_object_note): Handle NT_GNU_GOLD_VERSION. + + * eblobjnotetypename.c (ebl_object_note_type_name): Recognize + NT_GNU_GOLD_VERSION. + +2009-07-08 Roland McGrath + + * ebl-hooks.h: Add abi_cfi hook. + * eblopenbackend.c (default_abi_cfi): New function. + (fill_defaults): Add initializer. + * eblabicfi.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h: Declare ebl_abi_cfi. + +2009-07-08 Ulrich Drepper + + * eblsymbolbindingname.c (ebl_symbol_binding_name): Handle + STB_GNU_UNIQUE. + + * eblsymboltypename.c (ebl_symbol_type_name): Only handle STT_GNU_IFUNC + if the binary is marked as being for Linux. + +2009-04-01 Roland McGrath + + * eblsymboltypename.c (ebl_symbol_type_name): Add STT_GNU_IFUNC. + + * eblauxvinfo.c (AUXV_TYPES): Add RANDOM and BASE_PLATFORM. + +2009-02-01 Ulrich Drepper + + * eblreloctypename.c (ebl_reloc_type_name): Return "" + instead of "???" for invalid relocations. + +2008-08-01 Roland McGrath + + * eblcorenotetypename.c: Handle NT_386_IOPERM. + +2008-07-28 Roland McGrath + + * eblauxvinfo.c (AUXV_TYPES): Add EXECFN. + + * eblauxvinfo.c (ebl_auxv_info): Handle missing elements of standard + table. + +2008-07-04 Roland McGrath + + * libebl.h: Declare ebl_syscall_abi. + * ebl_syscall_abi.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * ebl-hooks.h: New hook syscall_abi. + * eblopenbackend.c (default_syscall_abi): New function. + (fill_defaults): Use it. + +2008-03-31 Roland McGrath + + * ebldynamictagname.c (ebl_dynamic_tag_name): Use hex for unknown tag. + + * ebl-hooks.h: Add check_special_section hook. + * eblopenbackend.c (fill_defaults): Set new hook to ... + (default_check_special_section): ... this, new function. + * ebl_check_special_section.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h: Declare it. + +2008-02-20 Roland McGrath + + * libebl.h: Declare ebl_check_object_attribute. + * eblcheckobjattr.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * ebl-hooks.h: Add check_object_attribute hook. + * eblopenbackend.c (default_check_object_attribute): New function. + (fill_defaults): Initialize pointer to it. + +2008-02-19 Roland McGrath + + * eblsectiontypename.c (ebl_section_type_name): + Handle SHT_GNU_ATTRIBUTES. + +2008-02-08 Roland McGrath + + * eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PPC_SPE. + +2008-01-30 Roland McGrath + + * eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_386_TLS. + +2007-10-18 Roland McGrath + + * eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PPC_VMX. + +2007-10-11 Roland McGrath + + * eblobjnote.c (ebl_object_note): Translate target format (byte-swap) + for NT_GNU_ABI_TAG contents. + +2007-08-22 Roland McGrath + + * libebl.h (Ebl_Core_Item): New member `group'. + +2007-08-19 Roland McGrath + + * ebl-hooks.h: Add new hook auxv_info. + * eblopenbackend.c (default_auxv_info): New function. + (fill_defaults): Initialize auxv_info hook. + * eblauxvinfo.c : New file. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h: Declare ebl_auxv_info. + + * eblcorenote.c: Rewritten with new signature. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h (Ebl_Register_Location, Ebl_Core_Item): New types. + (ebl_core_note_info): Completely revamp signature. + * ebl-hooks.h: Update decl. + * eblopenbackend.c (default_core_note): Update signature. + +2007-07-09 Roland McGrath + + * eblobjnotetypename.c (ebl_object_note_type_name): Handle + NT_GNU_HWCAP, NT_GNU_BUILD_ID. + + * eblobjnote.c (ebl_object_note): Handle NT_GNU_BUILD_ID. + +2007-04-22 Roland McGrath + + * eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PRXFPREG. + +2007-03-10 Roland McGrath + + * eblcorenote.c (ebl_core_note): For normally-zero types, + print in hex if not zero. + +2007-01-11 Roland McGrath + + * ebl-hooks.h (machine_section_flag_check): New hook. + * libebl.h: Declare ebl_machine_section_flag_check. + * eblmachinesectionflagcheck.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * eblopenbackend.c (default_machine_section_flag_check): New function. + (fill_defaults): Use it. + +2006-09-04 Roland McGrath + + * ebl-hooks.h: Replace register_name hook with register_info. + Also yield natural bit width and base type encoding. + * eblopenbackend.c (default_register_name): Renamed + default_register_info, new args added. + (fill_defaults): Update initialization. + * eblregname.c: File renamed ... + * eblreginfo.c: ... to this. + (ebl_register_name): Renamed to ebl_register_info, new args added. + * libebl.h: Update decl. + + * Makefile.am (gen_SOURCES): Update list. + +2006-07-06 Ulrich Drepper + + * ebldynamictagname.c: Add support for DT_GNU_HASH. + * ebldynamictagcheck.c: Likewise. + * eblsectiontypename.c: Add support for SHT_GNU_HASH. + +2006-07-05 Ulrich Drepper + + * Makefile.am (gen_SOURCES): Add eblsysvhashentrysize.c. + * libeblP.h (struct ebl): Add sysvhash_entrysize element. + * eblopenbackend.c (fill_defaults): Initialize sysvhash_entrysize. + + * eblopenbackend.c (openbackend): If possible, fill machine, class, + and data values in from the ELF file. + +2006-07-04 Ulrich Drepper + + * Makefile.am (gen_SOURCES): Add eblrelativerelocp.c. + * eblrelativerelocp.c: New file. + * ebl-hooks.c: Add relative_reloc_p. + * eblopenbackend.c (default_relative_reloc_p): New function. + (fill_defaults): Hook it up. + * libebl.h: Declare ebl_relative_reloc_p. + +2006-06-12 Ulrich Drepper + + * Makefile.am (gen_SOURCES): Add eblnonerelocp.c. + * eblnonerelocp.c: New file. + * ebl-hooks.c: Add none_reloc_p. + * eblopenbackend.c (default_none_reloc_p): New function. + (fill_defaults): Hook it up. + * libebl.h: Declare ebl_none_reloc_p. + +2006-05-27 Ulrich Drepper + + * libebl.h: Add extern "C". + +2005-11-25 Roland McGrath + + * eblregname.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * ebl-hooks.h: Declare register_name hook. + * libebl.h: Declare ebl_register_name. + * eblopenbackend.c (default_register_name): New function. + (fill_defaults): Use it. + +2005-11-16 Roland McGrath + + * libebl.h: Use "" for elf-knowledge.h, not <>. + +2005-11-15 Roland McGrath + + * Makefile.am: Removed everything for building libebl_*.so modules, + now in ../backends/Makefile.am instead. + * alpha_init.c: Moved to ../backends. + * alpha_reloc.def: Likewise. + * alpha_retval.c: Likewise. + * alpha_symbol.c: Likewise. + * arm_init.c: Likewise. + * arm_reloc.def: Likewise. + * arm_symbol.c: Likewise. + * common-reloc.c: Likewise. + * i386_corenote.c: Likewise. + * i386_init.c: Likewise. + * i386_reloc.def: Likewise. + * i386_retval.c: Likewise. + * i386_symbol.c: Likewise. + * ia64_init.c: Likewise. + * ia64_reloc.def: Likewise. + * ia64_symbol.c: Likewise. + * libebl_CPU.h: Likewise. + * ppc64_init.c: Likewise. + * ppc64_reloc.def: Likewise. + * ppc64_retval.c: Likewise. + * ppc64_symbol.c: Likewise. + * ppc_init.c: Likewise. + * ppc_reloc.def: Likewise. + * ppc_retval.c: Likewise. + * ppc_symbol.c: Likewise. + * s390_init.c: Likewise. + * s390_reloc.def: Likewise. + * s390_symbol.c: Likewise. + * sh_init.c: Likewise. + * sh_reloc.def: Likewise. + * sh_symbol.c: Likewise. + * sparc_init.c: Likewise. + * sparc_reloc.def: Likewise. + * sparc_symbol.c: Likewise. + * x86_64_corenote.c: Likewise. + * x86_64_init.c: Likewise. + * x86_64_reloc.def: Likewise. + * x86_64_retval.c: Likewise. + * x86_64_symbol.c: Likewise. + + * libebl.h: Comment fixes. + + * alpha_retval.c: New file. + * Makefile.am (alpha_SRCS): Add it. + * alpha_init.c (alpha_init): Initialize return_value_location hook. + + * ppc64_retval.c: New file. + * Makefile.am (ppc64_SRCS): Add it. + * ppc64_init.c (ppc64_init): Initialize return_value_location hook. + + * ppc_retval.c: New file. + * Makefile.am (ppc_SRCS): Add it. + * ppc_init.c (ppc_init): Initialize return_value_location hook. + +2005-11-14 Roland McGrath + + * ia64_init.c (ia64_init): Initialize EH->reloc_simple_type. + * sh_init.c (sh_init): Likewise. + * x86_64_init.c (x86_64_init): Likewise. + + * sparc_symbol.c (sparc_reloc_simple_type): New function. + * sparc_init.c (sparc_init): Use it. + + * arm_symbol.c (arm_reloc_simple_type): New function. + * arm_init.c (arm_init): Use it. + + * alpha_symbol.c (alpha_reloc_simple_type): New function. + * alpha_init.c (alpha_init): Use it. + + * ia64_reloc.def: Update bits per H. J. Lu . + + * arm_reloc.def: Update bits per Daniel Jacobowitz . + + * alpha_reloc.def: Update bits per Richard Henderson . + +2005-11-13 Roland McGrath + + * x86_64_retval.c: New file. + * Makefile.am (x86_64_SRCS): Add it. + * x86_64_init.c (x86_64_init): Use x86_64_return_value_location. + + * i386_retval.c: New file. + * Makefile.am (i386_SRCS): Add it. + (libdw): New variable. + (libebl_%.so): Use $(libdw) in link; use --as-needed. + * i386_init.c (i386_init): Use i386_return_value_location. + + * eblretval.c: New file. + * Makefile.am (gen_SOURCES): Add it. + (INCLUDES): Search in libdw. + * libebl.h: Include . Declare ebl_return_value_location. + * ebl-hooks.h: Declare return_value_location hook. + * eblopenbackend.c (default_return_value_location): New function. + (fill_defaults): Use it. + +2005-11-10 Roland McGrath + + * s390_init.c: New file. + * s390_reloc.def: New file. + * s390_symbol.c: New file. + * Makefile.am (modules, libebl_pic): Add s390. + (s390_SRCS, libebl_s390_pic_a_SOURCES): New variables. + (am_libebl_s390_pic_a_OBJECTS): New variable. + + * ppc64_init.c: Use common-reloc.c. + * ppc64_symbol.c (ppc64_backend_name): Removed. + (ppc64_reloc_type_check, ppc64_reloc_type_name): Likewise. + (ppc64_copy_reloc_p, ppc64_reloc_valid_use): Likewise. + + * ppc_init.c: Use common-reloc.c. + * ppc_symbol.c (ppc_backend_name): Removed. + (ppc_reloc_type_name, ppc_reloc_type_check): Likewise. + (ppc_reloc_valid_use, ppc_copy_reloc_p): Likewise. + + * sparc_init.c: Use common-reloc.c. + * sparc_symbol.c (sparc_backend_name): Removed. + (sparc_reloc_type_name, sparc_reloc_type_check): Likewise. + (sparc_copy_reloc_p): Likewise. + + * arm_init.c: Use common-reloc.c. + * arm_symbol.c (arm_backend_name): Removed. + (arm_reloc_type_name, arm_reloc_type_check, arm_copy_reloc_p): Removed. + + * alpha_init.c: Use common-reloc.c. + * alpha_symbol.c (alpha_backend_name): Removed. + (alpha_reloc_type_name, alpha_reloc_type_check): Likewise. + (alpha_copy_reloc_p): Likewise. + + * ia64_symbol.c (ia64_backend_name): Removed. + (ia64_reloc_type_name, ia64_reloc_type_check): Likewise. + (ia64_copy_reloc_p): Likewise. + + * x86_64_init.c: Use common-reloc.c. + * x86_64_symbol.c (x86_64_backend_name): Removed. + (x86_64_copy_reloc_p, x86_64_reloc_valid_use): Likewise. + (x86_64_reloc_type_check, x86_64_reloc_type_name): Likewise. + + * sh_init.c: Use common-reloc.c. + * sh_symbol.c: All functions removed. + (sh_reloc_simple_type): New function. + (sh_gotpc_reloc_check): New function. + + * common-reloc.c: New file. + * Makefile.am (noinst_HEADERS): Add it. + * i386_init.c: Include it. + + * sh_reloc.def: New file. + * i386_reloc.def: New file. + * alpha_reloc.def: New file. + * arm_reloc.def: New file. + * i386_reloc.def: New file. + * ia64_reloc.def: New file. + * ppc64_reloc.def: New file. + * ppc_reloc.def: New file. + * sh_reloc.def: New file. + * sparc_reloc.def: New file. + * x86_64_reloc.def: New file. + * Makefile.am (EXTRA_DIST): Add $(modules:=_reloc.def). + + * libebl_alpha.map: Removed. + * libebl_ia64.map: Removed. + * libebl_ppc.map: Removed. + * libebl_sparc.map: Removed. + * libebl_arm.map: Removed. + * libebl_i386.map: Removed. + * libebl_ppc64.map: Removed. + * libebl_sh.map: Removed. + * libebl_x86_64.map: Removed. + * Makefile.am (EXTRA_DIST): Remove them. + (libebl_%.map, libebl_%.so): New pattern rules. + + * libebl_alpha.h: Removed. + * libebl_ia64.h: Removed. + * libebl_ppc.h: Removed. + * libebl_sparc.h: Removed. + * libebl_arm.h: Removed. + * libebl_i386.h: Removed. + * libebl_ppc64.h: Removed. + * libebl_sh.h: Removed. + * libebl_x86_64.h: Removed. + * Makefile.am (noinst_HEADERS): Remove them. + + * x86_64_corenote.c: Use libebl_CPU.h instead. + * x86_64_symbol.c: Likewise. + * i386_corenote.c: Likewise. + +2005-11-09 Roland McGrath + + * ia64_symbol.c (ia64_reloc_simple_type): New function. + + * ebl-hooks.h (reloc_simple_type): Take the Ebl handle, not Elf handle. + * eblrelocsimpletype.c (ebl_reloc_simple_type): Update caller. + * eblopenbackend.c (default_reloc_simple_type): Update signature. + * i386_symbol.c (i386_reloc_simple_type): Likewise. + * ppc64_symbol.c (ppc64_reloc_simple_type): Likewise. + * ppc_symbol.c (ppc_reloc_simple_type): Likewise. + * x86_64_symbol.c (x86_64_reloc_simple_type): Likewise. + + * i386_symbol.c (i386_backend_name): Removed. + (i386_reloc_type_name, i386_reloc_type_check): Likewise. + (i386_reloc_valid_use): Removed. + (i386_copy_reloc_p): Removed. + + * alpha_destr.c: Removed. + * arm_destr.c: Removed. + * i386_destr.c: Removed. + * ia64_destr.c: Removed. + * ppc64_destr.c: Removed. + * ppc_destr.c: Removed. + * sh_destr.c: Removed. + * sparc_destr.c: Removed. + * x86_64_destr.c: Removed. + + * ebl-hooks.h: New file, broken out of ... + * libeblP.h (struct ebl): ... here. #include that for hook + declarations, after defining EBLHOOK macro. + * libebl_CPU.h: New file. + * Makefile.am (noinst_HEADERS): Add them. + + * libeblP.h (struct ebl): Use uint_fast16_t for machine, + and uint_fast8_t for class and data. + +2005-08-14 Roland McGrath + + * ia64_symbol.c (ia64_section_type_name): New function. + (ia64_dynamic_tag_check): New function. + (ia64_reloc_valid_use): New function. + * libebl_ia64.h: Declare them. + * ia64_init.c (ia64_init): Use them. + * Makefile.am (libebl_ia64.so): Link with libelf. + +2005-08-28 Ulrich Drepper + + * Makefile.am: Use $(LINK) not $(CC) when creating DSOs. + +2005-08-13 Roland McGrath + + * ia64_symbol.c (ia64_machine_flag_check): New function. + * libebl_ia64.h: Declare it. + * ia64_init.c (ia64_init): Use it. + +2005-08-13 Ulrich Drepper + + * libebl.h: Add ehdr parameter to ebl_bss_plt_p and + ebl_check_special_symbol. + * libeblP.h (struct ebl): Adjust callback functions. + * eblopenbackend.c: Adjust dummy functions. + * ebl_check_special_symbol.c: Add parameter and pass it on. + * eblbsspltp.c: Likewise. + * ppc_symbol.c (find_dyn_got): With ehdr passed, simplify search for + the dynamic section entry. + (ppc_check_special_symbol): Add ehdr parameter. + (ppc_bss_plt_p): Likewise. + * libebl_ppc.h: Adjust prototypes. + * ppc64_symbol.c (ppc_check_special_symbol): Add ehdr parameter. + (ppc_bss_plt_p): Likewise. + * libebl_ppc64.h: Adjust prototypes. + +2005-08-12 Roland McGrath + + * ppc_symbol.c (find_dyn_got): New function, broken out of ... + (ppc_bss_plt_p): ... here. Call that. + (ppc_check_special_symbol): Use find_dyn_got to fetch value to check + against _GLOBAL_OFFSET_TABLE_. + + * libeblP.h (struct ebl): Add bss_plt_p hook. + * eblopenbackend.c (default_bss_plt_p): New function. + (fill_defaults): Use it. + * eblbsspltp.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h: Declare ebl_bss_plt_p. + * ppc_symbol.c (ppc_bss_plt_p): New function. + * libebl_ppc.h: Declare it. + * ppc_init.c (ppc_init): Use it. + * ppc64_symbol.c (ppc64_bss_plt_p): New function. + * libebl_ppc64.h: Declare it. + * ppc64_init.c (ppc64_init): Use it. + + * ebl_check_special_symbol.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * libebl.h: Declare ebl_check_special_symbol. + * libeblP.h (struct ebl): Add check_special_symbol hook. + * eblopenbackend.c (default_check_special_symbol): New function. + (fill_defaults): Use it. + * ppc_symbol.c (ppc_check_special_symbol): New function. + * libebl_ppc.h: Add prototype. + * ppc_init.c (ppc_init): Use it. + * ppc64_symbol.c (ppc64_check_special_symbol): New function. + * libebl_ppc64.h: Add prototype. + * ppc64_init.c (ppc64_init): Use it. + +2005-08-07 Ulrich Drepper + + * ppc_init.c: Add support for new DT_PPC_* and R_PPC_* values. + * ppc_symbol.c: Likewise. + * libebl_ppc.h: Likewise. + * ppc64_init.c: There is now also a dynamic_tag_check functions + * ppc64_symbol.c: Add dynamic_tag_check. + * libebl_ppc64.h: Add prototype. + * alpha_init.c: Add support for new DT_ALPHA_* value. + * alpha_symbol.c: Likewise. + * libebl_alpha.h: Likewise. + +2005-08-03 Ulrich Drepper + + * libebl_alpha.map: Remove unnecessary exports. + * libebl_arm.map: Likewise. + * libebl_i386.map: Likewise. + * libebl_ia64.map: Likewise. + * libebl_ppc.map: Likewise. + * libebl_ppc64.map: Likewise. + * libebl_sh.map: Likewise. + * libebl_sparc.map: Likewise. + * libebl_x86_64.map: Likewise. + +2005-08-02 Ulrich Drepper + + * Makefile.am (libebl_a_SOURCES): Add eblelfclass.c, eblelfdata.c, + and eblelfmachine.c. + * elbopenbackend.c (machines): Add class and data fields. Initialize + them. + (ebl_openbackend): Initialize machine, class, data fields in result. + * libebl.h: Declare Add eblelfclass, eblelfdata, and eblelfmachine. + * libeblP.h (Ebl): Add machine, class, data fields. + +2005-07-23 Ulrich Drepper + + * eblsectionstripp.c: New file. + * Makefile.am (gen_SOURCES): Add eblsectionstripp.c. + * i386_init.c (i386_init): Install specific debugscn_p callback. + * i386_symbol.c (i386_debugscn_p): New function. + * libebl.h: Declare ebl_section_strip_p. + * libebl_i386.h: Declare i386_debugscn_p. + + * libebl.h: Move Ebl definition to... + * libeblP.h: ...here. + +2005-07-21 Roland McGrath + + * Makefile.am (install-ebl-modules): New target, commands from ... + (install): ... here. Make this depend on it. + (LIBEBL_SUBDIR): New variable, substituted by configure. + (install-ebl-modules): Install in $(libdir)/$(LIBEBL_SUBDIR). + * eblopenbackend.c (openbackend): Use LIBEBL_SUBDIR in module name. + +2005-07-21 Ulrich Drepper + + * eblcopyrelocp.c: New file. + * Makefile.am (gen_SOURCES): Add eblcopyrelocp.c. + * libebl.h: Declare ebl_copy_reloc_p. + * eblopenbackend.c (fill_defaults): Fill in copy_reloc_p. + (default_copy_reloc_p): New function. + * alpha_init.c: Define and use arch-specific copy_reloc_p function. + * alpha_symbol.c: Likewise. + * arm_init.c: Likewise. + * arm_symbol.c: Likewise. + * i386_init.c: Likewise. + * i386_symbol.c: Likewise. + * ia64_init.c: Likewise. + * ia64_symbol.c: Likewise. + * ppc64_init.c: Likewise. + * ppc64_symbol.c: Likewise. + * ppc_init.c: Likewise. + * ppc_symbol.c: Likewise. + * sh_init.c: Likewise. + * sh_symbol.c: Likewise. + * sparc_init.c: Likewise. + * sparc_symbol.c: Likewise. + * x86_64_init.c: Likewise. + * x86_64_symbol.c: Likewise. + * libebl_alpha.h: Declare the copy_reloc_p function. + * libebl_arm.h: Likewise. + * libebl_i386.h: Likewise. + * libebl_ia64.h: Likewise. + * libebl_ppc.h: Likewise. + * libebl_ppc64.h: Likewise. + * libebl_sh.h: Likewise. + * libebl_sparc.h: Likewise. + * libebl_x86_64.h: Likewise. + +2005-05-31 Roland McGrath + + * Makefile.am (libebl_*_so_SOURCES): Set to $(*_SRCS) so dependency + tracking works right. + +2005-05-21 Ulrich Drepper + + * libebl_x86_64.map: Add x86_64_core_note. + +2005-05-19 Roland McGrath + + * libebl_i386.map: Add i386_reloc_valid_use, i386_reloc_simple_type. + * libebl_ppc.map: Add ppc_reloc_simple_type. + * libebl_ppc64.map: Add ppc64_reloc_simple_type. + * libebl_x86_64.map: Add x86_64_reloc_simple_type. + +2005-05-11 Ulrich Drepper + + * eblcorenote.c: Handle new AT_* values and files with different + endianness. + * Makefile.am (x86_64_SRCS): Add x86_64_corenote.c. + * x86-64_corenote.c: New file. + * x86_64_init.c: Hook in x86_64_corenote. + * i386_corenote.c: Make file usable on 64-bit platforms. + + * eblopenbackend.c: If modules version comparison fails, reinitialize + hooks. + +2005-05-10 Ulrich Drepper + + * eblopenbackend.c: Require the init function to return a string. + Compare it with MODVERSION from config.h. + * alpha_init.c: Change return type. Return MODVERSION or NULL. + * arm_init.c: Likewise. + * eblopenbackend.c: Likewise. + * i386_init.c: Likewise. + * ia64_init.c: Likewise. + * ppc64_init.c: Likewise. + * ppc_init.c: Likewise. + * sh_init.c: Likewise. + * sparc_init.c: Likewise. + * x86_64_init.c: Likewise. + * libeblP.h: Adjust ebl_bhinit_t. + * libebl_alpha.h: Adjust init function prototype. + * libebl_arm.h: Likewise. + * libebl_i386.h: Likewise. + * libebl_ia64.h: Likewise. + * libebl_ppc.h: Likewise. + * libebl_ppc64.h: Likewise. + * libebl_sh.h: Likewise. + * libebl_sparc.h: Likewise. + * libebl_x86_64.h: Likewise. + + * mips_destr.c: Removed. + * mips_init.c: Removed. + * mips_symbol.c: Removed. + * libebl_mips.h: Removed. + * libebl_mips.map: Removed. + +2005-05-03 Roland McGrath + + * libebl.h (Ebl): Add `reloc_simple_type' member. + * eblopenbackend.c (default_reloc_simple_type): New function. + (openbackend): Use that as default reloc_simple_type callback. + * eblrelocsimpletype.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * i386_symbol.c (i386_reloc_simple_type): New function. + * libebl_i386.h: Declare it. + * i386_init.c (i386_init): Use it. + * x86_64_symbol.c (x86_64_reloc_simple_type): New function. + * libebl_x86_64.h: Declare it. + * x86_64_init.c (x86_64_init): Use it. + * ppc_symbol.c (ppc_reloc_simple_type): New function. + * libebl_ppc.h: Declare it. + * ppc_init.c (ppc_init): Use it. + * ppc64_symbol.c (ppc64_reloc_simple_type): New function. + * libebl_ppc64.h: Declare it. + * ppc64_init.c (ppc64_init): Use it. + +2005-03-17 Ulrich Drepper + + * eblcorenote.c (ebl_core_note): Add support for AT_SECURE. + +2005-02-15 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add -Wformat=2. + +2005-02-14 Ulrich Drepper + + * alpha_destr.c: Add __attribute__((unused)) where needed. + * alpha_init.c: Likewise. + * alpha_symbol.c: Likewise. + * arm_destr.c: Likewise. + * arm_init.c: Likewise. + * arm_symbol.c: Likewise. + * i386_corenote.c: Likewise. + * i386_destr.c: Likewise. + * i386_init.c: Likewise. + * i386_symbol.c: Likewise. + * ia64_destr.c: Likewise. + * ia64_init.c: Likewise. + * ia64_symbol.c: Likewise. + * mips_destr.c: Likewise. + * mips_init.c: Likewise. + * mips_symbol.c: Likewise. + * ppc64_destr.c: Likewise. + * ppc64_init.c: Likewise. + * ppc64_symbol.c: Likewise. + * ppc_destr.c: Likewise. + * ppc_init.c: Likewise. + * ppc_symbol.c: Likewise. + * sh_destr.c: Likewise. + * sh_init.c: Likewise. + * sh_symbol.c: Likewise. + * sparc_destr.c: Likewise. + * sparc_init.c: Likewise. + * sparc_symbol.c: Likewise. + * x86_64_destr.c: Likewise. + * x86_64_init.c: Likewise. + * x86_64_symbol.c: Likewise. + + * x86_64_symbol.c (reloc_map_table): Fix entries for R_X86_64_64 + and R_X86_64_32.. + +2005-02-06 Ulrich Drepper + + * eblstrtab.c: A few cleanups. + + * eblopenbackend.c: Mark unused parameters. + + * eblgstrtab.c: Cleanups a few printf format strings. + + * Makefile.am: Cleanup AM_CFLAGS handling. Add -Wunused -Wextra. + +2005-02-05 Ulrich Drepper + + * Makefile.am: Check for text relocations in constructed DSOs. + + * eblstrtab.c: Minor cleanups. + + * Makefile.am (AM_CFLAGS): Add -std=gnu99 and -fmudflap for MUDFLAP. + +2004-08-16 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add LIBSTR definition with base name of + the lib directory. + * eblopenbackend.c (openbackend): Use LIBSTR instead of hardcoded + lib in path to ebl modules. + +2004-04-01 Ulrich Drepper + + * Makefile.am: Add rules for ppc and ppc64 ebl module. + * ppc_init..c: New file. + * ppc_destr.c: New file. + * ppc_symbol.c: New file. + * libebl_ppc.h: New file. + * libebl_ppc.map: New file. + * ppc64_init..c: New file. + * ppc64_destr.c: New file. + * ppc64_symbol.c: New file. + * libebl_ppc64.h: New file. + * libebl_ppc64.map: New file. + +2004-01-20 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + +2004-01-18 Ulrich Drepper + + * libeblP.h (_): Use elfutils domain. + +2004-01-16 Ulrich Drepper + + * eblsectionname.c: Add support for SHN_BEFORE and SHN_AFTER. + +2004-01-13 Ulrich Drepper + + * eblsegmenttypename.c ((ebl_segment_type_name): Add support for + PT_GNU_RELRO. + +2004-01-08 Ulrich Drepper + + * libebl.h: Remove last traces of libtool. + +2004-01-05 Ulrich Drepper + + * elf-knowledge.h: Move to libelf subdir. + + * Makefile.am (EXTRA_DIST): Remove libebl.map. + * libebl.map: Removed. + +2003-12-08 Ulrich Drepper + + * eblsectiontypename.c (ebl_section_type_name): Add support for + SHT_SUNW_move, SHT_CHECKSUM, and SHT_GNU_LIBLIST. + +2003-11-19 Ulrich Drepper + + * ia64_symbol.c (ia64_dynamic_tag_name): New function. + * libebl_ia64.h (ia64_dynamic_tag_name): Declare. + * ia64_init.c (ia64_init): Register i164_dynamic_tag_name. + +2003-09-24 Ulrich Drepper + + * ia64_init.c (ia64_init): Initialize segment_type_name callback. + * ia64_symbol.c (ia64_segment_type_name): Define. + * libebl_ia64.h (ia64_segment_type_name): Declare. + +2003-09-22 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add -fpic. + +2003-08-14 Ulrich Drepper + + * Makefile.am (install): Remove dependency on libebl.so. + +2003-08-13 Ulrich Drepper + + * eblopenbackend.c: Adjust relative path to arch-specific DSOs + assuming the code ends up in the application. Add second dlopen() + try without any path, just the filename. + * Makefile.in: Remove rules to build and install libebl.so. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/libebl/Makefile.am b/libebl/Makefile.am new file mode 100644 index 00000000..d84e7ee2 --- /dev/null +++ b/libebl/Makefile.am @@ -0,0 +1,64 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 2000-2010, 2013, 2016, 2017 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +if BUILD_STATIC +AM_CFLAGS += $(fpic_CFLAGS) +endif +AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm +VERSION = 1 + +noinst_LIBRARIES = libebl.a libebl_pic.a + +libebl_a_SOURCES = eblopenbackend.c eblclosebackend.c eblreloctypename.c \ + eblsegmenttypename.c eblsectiontypename.c \ + eblmachineflagname.c eblsymboltypename.c \ + ebldynamictagname.c eblsectionname.c \ + eblsymbolbindingname.c eblbackendname.c eblosabiname.c \ + eblmachineflagcheck.c eblmachinesectionflagcheck.c \ + eblreloctypecheck.c eblrelocvaliduse.c \ + eblrelocsimpletype.c ebldynamictagcheck.c \ + eblcorenotetypename.c eblobjnotetypename.c eblcorenote.c \ + eblobjnote.c ebldebugscnp.c eblgotpcreloccheck.c \ + eblcopyrelocp.c eblsectionstripp.c eblelfclass.c \ + eblelfdata.c eblelfmachine.c ebl_check_special_symbol.c \ + eblbsspltp.c eblretval.c eblreginfo.c eblnonerelocp.c \ + eblrelativerelocp.c eblsysvhashentrysize.c eblauxvinfo.c \ + eblcheckobjattr.c ebl_check_special_section.c \ + eblabicfi.c eblstother.c eblinitreg.c \ + ebldwarftoregno.c eblnormalizepc.c eblunwind.c \ + eblresolvesym.c eblcheckreloctargettype.c \ + ebl_data_marker_symbol.c + +libebl_pic_a_SOURCES = +am_libebl_pic_a_OBJECTS = $(libebl_a_SOURCES:.c=.os) + +noinst_HEADERS = libebl.h libeblP.h ebl-hooks.h + +MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS) diff --git a/libebl/Makefile.in b/libebl/Makefile.in new file mode 100644 index 00000000..683804ce --- /dev/null +++ b/libebl/Makefile.in @@ -0,0 +1,920 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@BUILD_STATIC_TRUE@am__append_2 = $(fpic_CFLAGS) +subdir = libebl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libebl_a_AR = $(AR) $(ARFLAGS) +libebl_a_LIBADD = +am_libebl_a_OBJECTS = eblopenbackend.$(OBJEXT) \ + eblclosebackend.$(OBJEXT) eblreloctypename.$(OBJEXT) \ + eblsegmenttypename.$(OBJEXT) eblsectiontypename.$(OBJEXT) \ + eblmachineflagname.$(OBJEXT) eblsymboltypename.$(OBJEXT) \ + ebldynamictagname.$(OBJEXT) eblsectionname.$(OBJEXT) \ + eblsymbolbindingname.$(OBJEXT) eblbackendname.$(OBJEXT) \ + eblosabiname.$(OBJEXT) eblmachineflagcheck.$(OBJEXT) \ + eblmachinesectionflagcheck.$(OBJEXT) \ + eblreloctypecheck.$(OBJEXT) eblrelocvaliduse.$(OBJEXT) \ + eblrelocsimpletype.$(OBJEXT) ebldynamictagcheck.$(OBJEXT) \ + eblcorenotetypename.$(OBJEXT) eblobjnotetypename.$(OBJEXT) \ + eblcorenote.$(OBJEXT) eblobjnote.$(OBJEXT) \ + ebldebugscnp.$(OBJEXT) eblgotpcreloccheck.$(OBJEXT) \ + eblcopyrelocp.$(OBJEXT) eblsectionstripp.$(OBJEXT) \ + eblelfclass.$(OBJEXT) eblelfdata.$(OBJEXT) \ + eblelfmachine.$(OBJEXT) ebl_check_special_symbol.$(OBJEXT) \ + eblbsspltp.$(OBJEXT) eblretval.$(OBJEXT) eblreginfo.$(OBJEXT) \ + eblnonerelocp.$(OBJEXT) eblrelativerelocp.$(OBJEXT) \ + eblsysvhashentrysize.$(OBJEXT) eblauxvinfo.$(OBJEXT) \ + eblcheckobjattr.$(OBJEXT) ebl_check_special_section.$(OBJEXT) \ + eblabicfi.$(OBJEXT) eblstother.$(OBJEXT) eblinitreg.$(OBJEXT) \ + ebldwarftoregno.$(OBJEXT) eblnormalizepc.$(OBJEXT) \ + eblunwind.$(OBJEXT) eblresolvesym.$(OBJEXT) \ + eblcheckreloctargettype.$(OBJEXT) \ + ebl_data_marker_symbol.$(OBJEXT) +libebl_a_OBJECTS = $(am_libebl_a_OBJECTS) +libebl_pic_a_AR = $(AR) $(ARFLAGS) +libebl_pic_a_LIBADD = +libebl_pic_a_OBJECTS = $(am_libebl_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/ebl_check_special_section.Po \ + ./$(DEPDIR)/ebl_check_special_symbol.Po \ + ./$(DEPDIR)/ebl_data_marker_symbol.Po ./$(DEPDIR)/eblabicfi.Po \ + ./$(DEPDIR)/eblauxvinfo.Po ./$(DEPDIR)/eblbackendname.Po \ + ./$(DEPDIR)/eblbsspltp.Po ./$(DEPDIR)/eblcheckobjattr.Po \ + ./$(DEPDIR)/eblcheckreloctargettype.Po \ + ./$(DEPDIR)/eblclosebackend.Po ./$(DEPDIR)/eblcopyrelocp.Po \ + ./$(DEPDIR)/eblcorenote.Po ./$(DEPDIR)/eblcorenotetypename.Po \ + ./$(DEPDIR)/ebldebugscnp.Po ./$(DEPDIR)/ebldwarftoregno.Po \ + ./$(DEPDIR)/ebldynamictagcheck.Po \ + ./$(DEPDIR)/ebldynamictagname.Po ./$(DEPDIR)/eblelfclass.Po \ + ./$(DEPDIR)/eblelfdata.Po ./$(DEPDIR)/eblelfmachine.Po \ + ./$(DEPDIR)/eblgotpcreloccheck.Po ./$(DEPDIR)/eblinitreg.Po \ + ./$(DEPDIR)/eblmachineflagcheck.Po \ + ./$(DEPDIR)/eblmachineflagname.Po \ + ./$(DEPDIR)/eblmachinesectionflagcheck.Po \ + ./$(DEPDIR)/eblnonerelocp.Po ./$(DEPDIR)/eblnormalizepc.Po \ + ./$(DEPDIR)/eblobjnote.Po ./$(DEPDIR)/eblobjnotetypename.Po \ + ./$(DEPDIR)/eblopenbackend.Po ./$(DEPDIR)/eblosabiname.Po \ + ./$(DEPDIR)/eblreginfo.Po ./$(DEPDIR)/eblrelativerelocp.Po \ + ./$(DEPDIR)/eblrelocsimpletype.Po \ + ./$(DEPDIR)/eblreloctypecheck.Po \ + ./$(DEPDIR)/eblreloctypename.Po \ + ./$(DEPDIR)/eblrelocvaliduse.Po ./$(DEPDIR)/eblresolvesym.Po \ + ./$(DEPDIR)/eblretval.Po ./$(DEPDIR)/eblsectionname.Po \ + ./$(DEPDIR)/eblsectionstripp.Po \ + ./$(DEPDIR)/eblsectiontypename.Po \ + ./$(DEPDIR)/eblsegmenttypename.Po ./$(DEPDIR)/eblstother.Po \ + ./$(DEPDIR)/eblsymbolbindingname.Po \ + ./$(DEPDIR)/eblsymboltypename.Po \ + ./$(DEPDIR)/eblsysvhashentrysize.Po ./$(DEPDIR)/eblunwind.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libebl_a_SOURCES) $(libebl_pic_a_SOURCES) +DIST_SOURCES = $(libebl_a_SOURCES) $(libebl_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(srcdir)/../libelf -I$(srcdir)/../libdw \ + -I$(srcdir)/../libasm + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes \ + $(TRAMPOLINES_WARNING) $(LOGICAL_OP_WARNING) \ + $(DUPLICATED_COND_WARNING) $(NULL_DEREFERENCE_WARNING) \ + $(IMPLICIT_FALLTHROUGH_WARNING) $(if \ + $($(*F)_no_Werror),,-Werror) $(if \ + $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \ + $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) $(if \ + $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) $(am__append_2) +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +noinst_LIBRARIES = libebl.a libebl_pic.a +libebl_a_SOURCES = eblopenbackend.c eblclosebackend.c eblreloctypename.c \ + eblsegmenttypename.c eblsectiontypename.c \ + eblmachineflagname.c eblsymboltypename.c \ + ebldynamictagname.c eblsectionname.c \ + eblsymbolbindingname.c eblbackendname.c eblosabiname.c \ + eblmachineflagcheck.c eblmachinesectionflagcheck.c \ + eblreloctypecheck.c eblrelocvaliduse.c \ + eblrelocsimpletype.c ebldynamictagcheck.c \ + eblcorenotetypename.c eblobjnotetypename.c eblcorenote.c \ + eblobjnote.c ebldebugscnp.c eblgotpcreloccheck.c \ + eblcopyrelocp.c eblsectionstripp.c eblelfclass.c \ + eblelfdata.c eblelfmachine.c ebl_check_special_symbol.c \ + eblbsspltp.c eblretval.c eblreginfo.c eblnonerelocp.c \ + eblrelativerelocp.c eblsysvhashentrysize.c eblauxvinfo.c \ + eblcheckobjattr.c ebl_check_special_section.c \ + eblabicfi.c eblstother.c eblinitreg.c \ + ebldwarftoregno.c eblnormalizepc.c eblunwind.c \ + eblresolvesym.c eblcheckreloctargettype.c \ + ebl_data_marker_symbol.c + +libebl_pic_a_SOURCES = +am_libebl_pic_a_OBJECTS = $(libebl_a_SOURCES:.c=.os) +noinst_HEADERS = libebl.h libeblP.h ebl-hooks.h +MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libebl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libebl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libebl.a: $(libebl_a_OBJECTS) $(libebl_a_DEPENDENCIES) $(EXTRA_libebl_a_DEPENDENCIES) + $(AM_V_at)-rm -f libebl.a + $(AM_V_AR)$(libebl_a_AR) libebl.a $(libebl_a_OBJECTS) $(libebl_a_LIBADD) + $(AM_V_at)$(RANLIB) libebl.a + +libebl_pic.a: $(libebl_pic_a_OBJECTS) $(libebl_pic_a_DEPENDENCIES) $(EXTRA_libebl_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libebl_pic.a + $(AM_V_AR)$(libebl_pic_a_AR) libebl_pic.a $(libebl_pic_a_OBJECTS) $(libebl_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libebl_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebl_check_special_section.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebl_check_special_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebl_data_marker_symbol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblabicfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblauxvinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblbackendname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblbsspltp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcheckobjattr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcheckreloctargettype.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblclosebackend.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcopyrelocp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcorenote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblcorenotetypename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldebugscnp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldwarftoregno.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldynamictagcheck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ebldynamictagname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblelfclass.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblelfdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblelfmachine.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblgotpcreloccheck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblinitreg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblmachineflagcheck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblmachineflagname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblmachinesectionflagcheck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblnonerelocp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblnormalizepc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblobjnote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblobjnotetypename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblopenbackend.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblosabiname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblreginfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblrelativerelocp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblrelocsimpletype.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblreloctypecheck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblreloctypename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblrelocvaliduse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblresolvesym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblretval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsectionname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsectionstripp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsectiontypename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsegmenttypename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblstother.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsymbolbindingname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsymboltypename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblsysvhashentrysize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eblunwind.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/ebl_check_special_section.Po + -rm -f ./$(DEPDIR)/ebl_check_special_symbol.Po + -rm -f ./$(DEPDIR)/ebl_data_marker_symbol.Po + -rm -f ./$(DEPDIR)/eblabicfi.Po + -rm -f ./$(DEPDIR)/eblauxvinfo.Po + -rm -f ./$(DEPDIR)/eblbackendname.Po + -rm -f ./$(DEPDIR)/eblbsspltp.Po + -rm -f ./$(DEPDIR)/eblcheckobjattr.Po + -rm -f ./$(DEPDIR)/eblcheckreloctargettype.Po + -rm -f ./$(DEPDIR)/eblclosebackend.Po + -rm -f ./$(DEPDIR)/eblcopyrelocp.Po + -rm -f ./$(DEPDIR)/eblcorenote.Po + -rm -f ./$(DEPDIR)/eblcorenotetypename.Po + -rm -f ./$(DEPDIR)/ebldebugscnp.Po + -rm -f ./$(DEPDIR)/ebldwarftoregno.Po + -rm -f ./$(DEPDIR)/ebldynamictagcheck.Po + -rm -f ./$(DEPDIR)/ebldynamictagname.Po + -rm -f ./$(DEPDIR)/eblelfclass.Po + -rm -f ./$(DEPDIR)/eblelfdata.Po + -rm -f ./$(DEPDIR)/eblelfmachine.Po + -rm -f ./$(DEPDIR)/eblgotpcreloccheck.Po + -rm -f ./$(DEPDIR)/eblinitreg.Po + -rm -f ./$(DEPDIR)/eblmachineflagcheck.Po + -rm -f ./$(DEPDIR)/eblmachineflagname.Po + -rm -f ./$(DEPDIR)/eblmachinesectionflagcheck.Po + -rm -f ./$(DEPDIR)/eblnonerelocp.Po + -rm -f ./$(DEPDIR)/eblnormalizepc.Po + -rm -f ./$(DEPDIR)/eblobjnote.Po + -rm -f ./$(DEPDIR)/eblobjnotetypename.Po + -rm -f ./$(DEPDIR)/eblopenbackend.Po + -rm -f ./$(DEPDIR)/eblosabiname.Po + -rm -f ./$(DEPDIR)/eblreginfo.Po + -rm -f ./$(DEPDIR)/eblrelativerelocp.Po + -rm -f ./$(DEPDIR)/eblrelocsimpletype.Po + -rm -f ./$(DEPDIR)/eblreloctypecheck.Po + -rm -f ./$(DEPDIR)/eblreloctypename.Po + -rm -f ./$(DEPDIR)/eblrelocvaliduse.Po + -rm -f ./$(DEPDIR)/eblresolvesym.Po + -rm -f ./$(DEPDIR)/eblretval.Po + -rm -f ./$(DEPDIR)/eblsectionname.Po + -rm -f ./$(DEPDIR)/eblsectionstripp.Po + -rm -f ./$(DEPDIR)/eblsectiontypename.Po + -rm -f ./$(DEPDIR)/eblsegmenttypename.Po + -rm -f ./$(DEPDIR)/eblstother.Po + -rm -f ./$(DEPDIR)/eblsymbolbindingname.Po + -rm -f ./$(DEPDIR)/eblsymboltypename.Po + -rm -f ./$(DEPDIR)/eblsysvhashentrysize.Po + -rm -f ./$(DEPDIR)/eblunwind.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/ebl_check_special_section.Po + -rm -f ./$(DEPDIR)/ebl_check_special_symbol.Po + -rm -f ./$(DEPDIR)/ebl_data_marker_symbol.Po + -rm -f ./$(DEPDIR)/eblabicfi.Po + -rm -f ./$(DEPDIR)/eblauxvinfo.Po + -rm -f ./$(DEPDIR)/eblbackendname.Po + -rm -f ./$(DEPDIR)/eblbsspltp.Po + -rm -f ./$(DEPDIR)/eblcheckobjattr.Po + -rm -f ./$(DEPDIR)/eblcheckreloctargettype.Po + -rm -f ./$(DEPDIR)/eblclosebackend.Po + -rm -f ./$(DEPDIR)/eblcopyrelocp.Po + -rm -f ./$(DEPDIR)/eblcorenote.Po + -rm -f ./$(DEPDIR)/eblcorenotetypename.Po + -rm -f ./$(DEPDIR)/ebldebugscnp.Po + -rm -f ./$(DEPDIR)/ebldwarftoregno.Po + -rm -f ./$(DEPDIR)/ebldynamictagcheck.Po + -rm -f ./$(DEPDIR)/ebldynamictagname.Po + -rm -f ./$(DEPDIR)/eblelfclass.Po + -rm -f ./$(DEPDIR)/eblelfdata.Po + -rm -f ./$(DEPDIR)/eblelfmachine.Po + -rm -f ./$(DEPDIR)/eblgotpcreloccheck.Po + -rm -f ./$(DEPDIR)/eblinitreg.Po + -rm -f ./$(DEPDIR)/eblmachineflagcheck.Po + -rm -f ./$(DEPDIR)/eblmachineflagname.Po + -rm -f ./$(DEPDIR)/eblmachinesectionflagcheck.Po + -rm -f ./$(DEPDIR)/eblnonerelocp.Po + -rm -f ./$(DEPDIR)/eblnormalizepc.Po + -rm -f ./$(DEPDIR)/eblobjnote.Po + -rm -f ./$(DEPDIR)/eblobjnotetypename.Po + -rm -f ./$(DEPDIR)/eblopenbackend.Po + -rm -f ./$(DEPDIR)/eblosabiname.Po + -rm -f ./$(DEPDIR)/eblreginfo.Po + -rm -f ./$(DEPDIR)/eblrelativerelocp.Po + -rm -f ./$(DEPDIR)/eblrelocsimpletype.Po + -rm -f ./$(DEPDIR)/eblreloctypecheck.Po + -rm -f ./$(DEPDIR)/eblreloctypename.Po + -rm -f ./$(DEPDIR)/eblrelocvaliduse.Po + -rm -f ./$(DEPDIR)/eblresolvesym.Po + -rm -f ./$(DEPDIR)/eblretval.Po + -rm -f ./$(DEPDIR)/eblsectionname.Po + -rm -f ./$(DEPDIR)/eblsectionstripp.Po + -rm -f ./$(DEPDIR)/eblsectiontypename.Po + -rm -f ./$(DEPDIR)/eblsegmenttypename.Po + -rm -f ./$(DEPDIR)/eblstother.Po + -rm -f ./$(DEPDIR)/eblsymbolbindingname.Po + -rm -f ./$(DEPDIR)/eblsymboltypename.Po + -rm -f ./$(DEPDIR)/eblsysvhashentrysize.Po + -rm -f ./$(DEPDIR)/eblunwind.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h new file mode 100644 index 00000000..1214bb84 --- /dev/null +++ b/libebl/ebl-hooks.h @@ -0,0 +1,188 @@ +/* Backend hook signatures internal interface for libebl. + Copyright (C) 2000-2011, 2013, 2014, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* Return symbolic representation of relocation type. */ +const char *EBLHOOK(reloc_type_name) (int, char *, size_t); + +/* Check relocation type. */ +bool EBLHOOK(reloc_type_check) (int); + +/* Check if relocation type is for simple absolute relocations. */ +Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int, int *); + +/* Check relocation type use. */ +bool EBLHOOK(reloc_valid_use) (Elf *, int); + +/* Return true if the symbol type is that referencing the GOT. */ +bool EBLHOOK(gotpc_reloc_check) (Elf *, int); + +/* Return symbolic representation of segment type. */ +const char *EBLHOOK(segment_type_name) (int, char *, size_t); + +/* Return symbolic representation of section type. */ +const char *EBLHOOK(section_type_name) (int, char *, size_t); + +/* Return section name. */ +const char *EBLHOOK(section_name) (int, int, char *, size_t); + +/* Return next machine flag name. */ +const char *EBLHOOK(machine_flag_name) (GElf_Word *); + +/* Check whether machine flags are valid. */ +bool EBLHOOK(machine_flag_check) (GElf_Word); + +/* Check whether SHF_MASKPROC flag bits are valid. */ +bool EBLHOOK(machine_section_flag_check) (GElf_Xword); + +/* Check whether the section with the given index, header, and name + is a special machine section that is valid despite a combination + of flags or other details that are not generically valid. */ +bool EBLHOOK(check_special_section) (Ebl *, int, + const GElf_Shdr *, const char *); + +/* Return symbolic representation of symbol type. */ +const char *EBLHOOK(symbol_type_name) (int, char *, size_t); + +/* Return symbolic representation of symbol binding. */ +const char *EBLHOOK(symbol_binding_name) (int, char *, size_t); + +/* Return symbolic representation of dynamic tag. */ +const char *EBLHOOK(dynamic_tag_name) (int64_t, char *, size_t); + +/* Check dynamic tag. */ +bool EBLHOOK(dynamic_tag_check) (int64_t); + +/* Return symbolic representation of OS ABI. */ +const char *EBLHOOK(osabi_name) (int, char *, size_t); + +/* Name of a note entry type for core files. */ +const char *EBLHOOK(core_note_type_name) (uint32_t, char *, size_t); + +/* Name of a note entry type for object files. */ +const char *EBLHOOK(object_note_type_name) (const char *, uint32_t, + char *, size_t); + +/* Describe core note format. */ +int EBLHOOK(core_note) (const GElf_Nhdr *, const char *, + GElf_Word *, size_t *, const Ebl_Register_Location **, + size_t *, const Ebl_Core_Item **); + +/* Handle object file note. */ +bool EBLHOOK(object_note) (const char *, uint32_t, uint32_t, const char *); + +/* Check object attribute. */ +bool EBLHOOK(check_object_attribute) (Ebl *, const char *, int, uint64_t, + const char **, const char **); + +/* Check reloc target section type. */ +bool EBLHOOK(check_reloc_target_type) (Ebl *, Elf64_Word); + +/* Describe auxv element type. */ +int EBLHOOK(auxv_info) (GElf_Xword, const char **, const char **); + +/* Check section name for being that of a debug informatino section. */ +bool EBLHOOK(debugscn_p) (const char *); + +/* Check whether given relocation is a copy relocation. */ +bool EBLHOOK(copy_reloc_p) (int); + +/* Check whether given relocation is a no-op relocation. */ +bool EBLHOOK(none_reloc_p) (int); + +/* Check whether given relocation is a relative relocation. */ +bool EBLHOOK(relative_reloc_p) (int); + +/* Check whether given symbol's value is ok despite normal checks. */ +bool EBLHOOK(check_special_symbol) (Elf *, const GElf_Sym *, + const char *, const GElf_Shdr *); + +/* Check if this is a data marker symbol. e.g. '$d' symbols for ARM. */ +bool EBLHOOK(data_marker_symbol) (const GElf_Sym *sym, const char *sname); + +/* Check whether only valid bits are set on the st_other symbol flag. + Standard ST_VISIBILITY have already been masked off. */ +bool EBLHOOK(check_st_other_bits) (unsigned char st_other); + +/* Check if backend uses a bss PLT in this file. */ +bool EBLHOOK(bss_plt_p) (Elf *); + +/* Return location expression to find return value given the + DW_AT_type DIE of a DW_TAG_subprogram DIE. */ +int EBLHOOK(return_value_location) (Dwarf_Die *functypedie, + const Dwarf_Op **locp); + +/* Return register name information. */ +ssize_t EBLHOOK(register_info) (Ebl *ebl, + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type); + +/* Disassembler function. */ +int EBLHOOK(disasm) (Ebl *ebl, const uint8_t **startp, const uint8_t *end, + GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb, + DisasmGetSymCB_t symcb, void *outcbarg, void *symcbarg); + +/* Supply the machine-specific state of CFI before CIE initial programs. + Function returns 0 on success and -1 on error. */ +int EBLHOOK(abi_cfi) (Ebl *ebl, Dwarf_CIE *abi_info); + +/* Fetch process data from live TID and call SETFUNC one or more times. + Method should be present only when EBL_FRAME_NREGS > 0, otherwise the + backend doesn't support unwinding. */ +bool EBLHOOK(set_initial_registers_tid) (pid_t tid, + ebl_tid_registers_t *setfunc, + void *arg); + +/* Convert *REGNO as is in DWARF to a lower range suitable for + Dwarf_Frame->REGS indexing. */ +bool EBLHOOK(dwarf_to_regno) (Ebl *ebl, unsigned *regno); + +/* Optionally modify *PC as fetched from inferior data into valid PC + instruction pointer. */ +void EBLHOOK(normalize_pc) (Ebl *ebl, Dwarf_Addr *pc); + +/* Get previous frame state for an existing frame state. Method is called only + if unwinder could not find CFI for current PC. PC is for the + existing frame. SETFUNC sets register in the previous frame. GETFUNC gets + register from the existing frame. Note that GETFUNC vs. SETFUNC act on + a disjunct set of registers. READFUNC reads memory. ARG has to be passed + for SETFUNC, GETFUNC and READFUNC. *SIGNAL_FRAMEP is initialized to false, + it can be set to true if existing frame is a signal frame. SIGNAL_FRAMEP is + never NULL. */ +bool EBLHOOK(unwind) (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep); + +/* Returns true if the value can be resolved to an address in an + allocated section, which will be returned in *ADDR. + (e.g. function descriptor resolving) */ +bool EBLHOOK(resolve_sym_value) (Ebl *ebl, GElf_Addr *addr); + +/* Destructor for ELF backend handle. */ +void EBLHOOK(destr) (struct ebl *); diff --git a/libebl/ebl_check_special_section.c b/libebl/ebl_check_special_section.c new file mode 100644 index 00000000..903b69d5 --- /dev/null +++ b/libebl/ebl_check_special_section.c @@ -0,0 +1,41 @@ +/* Check for a special section allowed to violate generic constraints. + Copyright (C) 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_check_special_section (Ebl *ebl, int ndx, const GElf_Shdr *shdr, + const char *sname) +{ + return ebl != NULL && ebl->check_special_section (ebl, ndx, shdr, sname); +} diff --git a/libebl/ebl_check_special_symbol.c b/libebl/ebl_check_special_symbol.c new file mode 100644 index 00000000..1f60c3f0 --- /dev/null +++ b/libebl/ebl_check_special_symbol.c @@ -0,0 +1,45 @@ +/* Check special symbol's st_value. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +bool +ebl_check_special_symbol (Ebl *ebl, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) +{ + if (ebl == NULL) + return false; + + return ebl->check_special_symbol (ebl->elf, sym, name, destshdr); +} diff --git a/libebl/ebl_data_marker_symbol.c b/libebl/ebl_data_marker_symbol.c new file mode 100644 index 00000000..922d7203 --- /dev/null +++ b/libebl/ebl_data_marker_symbol.c @@ -0,0 +1,44 @@ +/* Check whether a symbol is a special data marker. + Copyright (C) 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +bool +ebl_data_marker_symbol (Ebl *ebl, const GElf_Sym *sym, const char *sname) +{ + if (ebl == NULL) + return false; + + return ebl->data_marker_symbol (sym, sname); +} diff --git a/libebl/eblabicfi.c b/libebl/eblabicfi.c new file mode 100644 index 00000000..8bf189f1 --- /dev/null +++ b/libebl/eblabicfi.c @@ -0,0 +1,46 @@ +/* Return ABI-specific DWARF CFI details. + Copyright (C) 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +ebl_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info) +{ + return ebl == NULL ? -1 : ebl->abi_cfi (ebl, abi_info); +} + +int +ebl_ra_offset (Ebl *ebl) +{ + return ebl->ra_offset; +} diff --git a/libebl/eblauxvinfo.c b/libebl/eblauxvinfo.c new file mode 100644 index 00000000..ce1141b8 --- /dev/null +++ b/libebl/eblauxvinfo.c @@ -0,0 +1,100 @@ +/* Describe known auxv types. + Copyright (C) 2007, 2008, 2009 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define AUXV_TYPES \ + TYPE (NULL, "") \ + TYPE (IGNORE, "") \ + TYPE (EXECFD, "d") \ + TYPE (EXECFN, "s") \ + TYPE (PHDR, "p") \ + TYPE (PHENT, "u") \ + TYPE (PHNUM, "u") \ + TYPE (PAGESZ, "u") \ + TYPE (BASE, "p") \ + TYPE (FLAGS, "x") \ + TYPE (ENTRY, "p") \ + TYPE (NOTELF, "") \ + TYPE (UID, "u") \ + TYPE (EUID, "u") \ + TYPE (GID, "u") \ + TYPE (EGID, "u") \ + TYPE (CLKTCK, "u") \ + TYPE (PLATFORM, "s") \ + TYPE (BASE_PLATFORM, "s") \ + TYPE (HWCAP, "x") \ + TYPE (FPUCW, "x") \ + TYPE (DCACHEBSIZE, "d") \ + TYPE (ICACHEBSIZE, "d") \ + TYPE (UCACHEBSIZE, "d") \ + TYPE (IGNOREPPC, "") \ + TYPE (SECURE, "u") \ + TYPE (SYSINFO, "p") \ + TYPE (SYSINFO_EHDR, "p") \ + TYPE (L1I_CACHESHAPE, "d") \ + TYPE (L1D_CACHESHAPE, "d") \ + TYPE (L2_CACHESHAPE, "d") \ + TYPE (L3_CACHESHAPE, "d") \ + TYPE (RANDOM, "p") + +static const struct +{ + const char *name, *format; +} auxv_types[] = + { +#define TYPE(name, fmt) [AT_##name] = { #name, fmt }, + AUXV_TYPES +#undef TYPE + }; +#define nauxv_types (sizeof auxv_types / sizeof auxv_types[0]) + +int +ebl_auxv_info (Ebl *ebl, GElf_Xword a_type, const char **name, + const char **format) +{ + int result = ebl->auxv_info (a_type, name, format); + if (result == 0 && a_type < nauxv_types && auxv_types[a_type].name != NULL) + { + /* The machine specific function did not know this type. */ + *name = auxv_types[a_type].name; + *format = auxv_types[a_type].format; + result = 1; + } + return result; +} diff --git a/libebl/eblbackendname.c b/libebl/eblbackendname.c new file mode 100644 index 00000000..e52b1e84 --- /dev/null +++ b/libebl/eblbackendname.c @@ -0,0 +1,42 @@ +/* Return backend name. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_backend_name (Ebl *ebl) +{ + return ebl != NULL ? ebl->emulation : _("No backend"); +} diff --git a/libebl/eblbsspltp.c b/libebl/eblbsspltp.c new file mode 100644 index 00000000..24c4a08b --- /dev/null +++ b/libebl/eblbsspltp.c @@ -0,0 +1,41 @@ +/* Check if backend uses a bss PLT. + Copyright (C) 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +bool +ebl_bss_plt_p (Ebl *ebl) +{ + return ebl == NULL ? false : ebl->bss_plt_p (ebl->elf); +} diff --git a/libebl/eblcheckobjattr.c b/libebl/eblcheckobjattr.c new file mode 100644 index 00000000..b590a039 --- /dev/null +++ b/libebl/eblcheckobjattr.c @@ -0,0 +1,56 @@ +/* Check object attributes. + Copyright (C) 2008 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +bool +ebl_check_object_attribute (Ebl *ebl, const char *vendor, int tag, + uint64_t value, const char **tag_name, + const char **value_name) +{ + if (ebl->check_object_attribute (ebl, vendor, tag, value, + tag_name, value_name)) + return true; + + if (strcmp (vendor, "gnu")) + return false; + + if (tag == 32) + { + *tag_name = "compatibility"; + return true; + } + + return false; +} diff --git a/libebl/eblcheckreloctargettype.c b/libebl/eblcheckreloctargettype.c new file mode 100644 index 00000000..068ad8f1 --- /dev/null +++ b/libebl/eblcheckreloctargettype.c @@ -0,0 +1,55 @@ +/* Check whether a section type is a valid target for relocation. + Copyright (C) 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type) +{ + if (ebl->check_reloc_target_type (ebl, sh_type)) + return true; + + switch (sh_type) + { + case SHT_PROGBITS: + case SHT_NOBITS: + case SHT_INIT_ARRAY: + case SHT_FINI_ARRAY: + case SHT_PREINIT_ARRAY: + case SHT_NOTE: + return true; + + default: + return false; + } +} diff --git a/libebl/eblclosebackend.c b/libebl/eblclosebackend.c new file mode 100644 index 00000000..501e5c7b --- /dev/null +++ b/libebl/eblclosebackend.c @@ -0,0 +1,50 @@ +/* Free ELF backend handle. + Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include + + +void +ebl_closebackend (Ebl *ebl) +{ + if (ebl != NULL) + { + /* Run the destructor. */ + ebl->destr (ebl); + + /* Free the resources. */ + free (ebl); + } +} diff --git a/libebl/eblcopyrelocp.c b/libebl/eblcopyrelocp.c new file mode 100644 index 00000000..0458c4f7 --- /dev/null +++ b/libebl/eblcopyrelocp.c @@ -0,0 +1,41 @@ +/* Check whether given relocation is a copy relocation. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_copy_reloc_p (Ebl *ebl, int reloc) +{ + return ebl->copy_reloc_p (reloc); +} diff --git a/libebl/eblcorenote.c b/libebl/eblcorenote.c new file mode 100644 index 00000000..7fab3974 --- /dev/null +++ b/libebl/eblcorenote.c @@ -0,0 +1,79 @@ +/* Describe known core note formats. + Copyright (C) 2007, 2010 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + + +int +ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name, + const char *desc, + GElf_Word *regs_offset, size_t *nregloc, + const Ebl_Register_Location **reglocs, size_t *nitems, + const Ebl_Core_Item **items) +{ + int result = ebl->core_note (nhdr, name, + regs_offset, nregloc, reglocs, nitems, items); + if (result == 0) + { + /* The machine specific function did not know this type. */ + + /* NT_PLATFORM is kind of special since it needs a zero terminated + string (other notes often have a fixed size string). */ + static const Ebl_Core_Item platform[] = + { + { + .name = "Platform", + .type = ELF_T_BYTE, .count = 0, .format = 's' + } + }; + + if (nhdr->n_type == NT_PLATFORM + && memchr (desc, '\0', nhdr->n_descsz) != NULL) + { + *regs_offset = 0; + *nregloc = 0; + *reglocs = NULL; + *items = platform; + *nitems = 1; + result = 1; + } + } + + return result; +} diff --git a/libebl/eblcorenotetypename.c b/libebl/eblcorenotetypename.c new file mode 100644 index 00000000..0e790d06 --- /dev/null +++ b/libebl/eblcorenotetypename.c @@ -0,0 +1,107 @@ +/* Return note type name. + Copyright (C) 2002, 2007, 2008, 2012, 2013 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +const char * +ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf, size_t len) +{ + const char *res = ebl->core_note_type_name (type, buf, len); + + if (res == NULL) + { + static const char *knowntypes[] = + { +#define KNOWNSTYPE(name) [NT_##name] = #name + KNOWNSTYPE (PRSTATUS), + KNOWNSTYPE (FPREGSET), + KNOWNSTYPE (PRPSINFO), + KNOWNSTYPE (TASKSTRUCT), + KNOWNSTYPE (PLATFORM), + KNOWNSTYPE (AUXV), + KNOWNSTYPE (GWINDOWS), + KNOWNSTYPE (ASRS), + KNOWNSTYPE (PSTATUS), + KNOWNSTYPE (PSINFO), + KNOWNSTYPE (PRCRED), + KNOWNSTYPE (UTSNAME), + KNOWNSTYPE (LWPSTATUS), + KNOWNSTYPE (LWPSINFO), + KNOWNSTYPE (PRFPXREG) +#undef KNOWNSTYPE + }; + + /* Handle standard names. */ + if (type < sizeof (knowntypes) / sizeof (knowntypes[0]) + && knowntypes[type] != NULL) + res = knowntypes[type]; + else + switch (type) + { +#define KNOWNSTYPE(name) case NT_##name: res = #name; break + KNOWNSTYPE (PRXFPREG); + KNOWNSTYPE (PPC_VMX); + KNOWNSTYPE (PPC_SPE); + KNOWNSTYPE (PPC_VSX); + KNOWNSTYPE (PPC_TM_SPR); + KNOWNSTYPE (386_TLS); + KNOWNSTYPE (386_IOPERM); + KNOWNSTYPE (X86_XSTATE); + KNOWNSTYPE (S390_HIGH_GPRS); + KNOWNSTYPE (S390_TIMER); + KNOWNSTYPE (S390_TODCMP); + KNOWNSTYPE (S390_TODPREG); + KNOWNSTYPE (S390_CTRS); + KNOWNSTYPE (S390_PREFIX); + KNOWNSTYPE (S390_LAST_BREAK); + KNOWNSTYPE (S390_SYSTEM_CALL); + KNOWNSTYPE (ARM_VFP); + KNOWNSTYPE (ARM_TLS); + KNOWNSTYPE (ARM_HW_BREAK); + KNOWNSTYPE (ARM_HW_WATCH); + KNOWNSTYPE (ARM_SYSTEM_CALL); + KNOWNSTYPE (SIGINFO); + KNOWNSTYPE (FILE); +#undef KNOWNSTYPE + + default: + snprintf (buf, len, "%s: %" PRIu32, _(""), type); + + res = buf; + } + } + + return res; +} diff --git a/libebl/ebldebugscnp.c b/libebl/ebldebugscnp.c new file mode 100644 index 00000000..2964fdb6 --- /dev/null +++ b/libebl/ebldebugscnp.c @@ -0,0 +1,42 @@ +/* Check section name for being that of a debug informatino section. + Copyright (C) 2002, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +bool +ebl_debugscn_p (Ebl *ebl, const char *name) +{ + return name != NULL && ebl->debugscn_p (name); +} diff --git a/libebl/ebldwarftoregno.c b/libebl/ebldwarftoregno.c new file mode 100644 index 00000000..c6644969 --- /dev/null +++ b/libebl/ebldwarftoregno.c @@ -0,0 +1,40 @@ +/* Convert *REGNO as is in DWARF to a lower range. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +bool +ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno) +{ + /* ebl is declared NN */ + return ebl->dwarf_to_regno == NULL ? true : ebl->dwarf_to_regno (ebl, regno); +} diff --git a/libebl/ebldynamictagcheck.c b/libebl/ebldynamictagcheck.c new file mode 100644 index 00000000..c2311ccd --- /dev/null +++ b/libebl/ebldynamictagcheck.c @@ -0,0 +1,54 @@ +/* Check dynamic tag. + Copyright (C) 2001, 2002, 2006 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +bool +ebl_dynamic_tag_check (Ebl *ebl, int64_t tag) +{ + bool res = ebl != NULL ? ebl->dynamic_tag_check (tag) : false; + + if (!res + && ((tag >= 0 && tag < DT_NUM) + || (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT) + || (tag >= DT_GNU_HASH && tag <= DT_SYMINFO) + || tag == DT_VERSYM + || (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM) + || tag == DT_AUXILIARY + || tag == DT_FILTER)) + res = true; + + return res; +} diff --git a/libebl/ebldynamictagname.c b/libebl/ebldynamictagname.c new file mode 100644 index 00000000..3f8d8ee4 --- /dev/null +++ b/libebl/ebldynamictagname.c @@ -0,0 +1,111 @@ +/* Return dynamic tag name. + Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include "system.h" + + +const char * +ebl_dynamic_tag_name (Ebl *ebl, int64_t tag, char *buf, size_t len) +{ + const char *res = ebl != NULL ? ebl->dynamic_tag_name (tag, buf, len) : NULL; + + if (res == NULL) + { + if (tag >= 0 && tag < DT_NUM) + { + static const char *stdtags[] = + { + "NULL", "NEEDED", "PLTRELSZ", "PLTGOT", "HASH", "STRTAB", + "SYMTAB", "RELA", "RELASZ", "RELAENT", "STRSZ", "SYMENT", + "INIT", "FINI", "SONAME", "RPATH", "SYMBOLIC", "REL", "RELSZ", + "RELENT", "PLTREL", "DEBUG", "TEXTREL", "JMPREL", "BIND_NOW", + "INIT_ARRAY", "FINI_ARRAY", "INIT_ARRAYSZ", "FINI_ARRAYSZ", + "RUNPATH", "FLAGS", "ENCODING", "PREINIT_ARRAY", + "PREINIT_ARRAYSZ", "SYMTAB_SHNDX" + }; + eu_static_assert (sizeof (stdtags) / sizeof (const char *) == DT_NUM); + + res = stdtags[tag]; + } + else if (tag == DT_VERSYM) + res = "VERSYM"; + else if (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT) + { + static const char *valrntags[] = + { + "GNU_PRELINKED", "GNU_CONFLICTSZ", "GNU_LIBLISTSZ", + "CHECKSUM", "PLTPADSZ", "MOVEENT", "MOVESZ", "FEATURE_1", + "POSFLAG_1", "SYMINSZ", "SYMINENT" + }; + + res = valrntags[tag - DT_GNU_PRELINKED]; + } + else if (tag >= DT_GNU_HASH && tag <= DT_SYMINFO) + { + static const char *addrrntags[] = + { + "GNU_HASH", "TLSDESC_PLT", "TLSDESC_GOT", + "GNU_CONFLICT", "GNU_LIBLIST", "CONFIG", "DEPAUDIT", "AUDIT", + "PLTPAD", "MOVETAB", "SYMINFO" + }; + + res = addrrntags[tag - DT_GNU_HASH]; + } + else if (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM) + { + static const char *suntags[] = + { + "RELACOUNT", "RELCOUNT", "FLAGS_1", "VERDEF", "VERDEFNUM", + "VERNEED", "VERNEEDNUM" + }; + + res = suntags[tag - DT_RELACOUNT]; + } + else if (tag == DT_AUXILIARY) + res = "AUXILIARY"; + else if (tag == DT_FILTER) + res = "FILTER"; + else + { + snprintf (buf, len, _(": %#" PRIx64), tag); + + res = buf; + + } + } + + return res; +} diff --git a/libebl/eblelfclass.c b/libebl/eblelfclass.c new file mode 100644 index 00000000..2ffef304 --- /dev/null +++ b/libebl/eblelfclass.c @@ -0,0 +1,41 @@ +/* Return ELF class. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +ebl_get_elfclass (Ebl *ebl) +{ + return ebl->class; +} diff --git a/libebl/eblelfdata.c b/libebl/eblelfdata.c new file mode 100644 index 00000000..072924b6 --- /dev/null +++ b/libebl/eblelfdata.c @@ -0,0 +1,41 @@ +/* Return ELF data encoding. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +ebl_get_elfdata (Ebl *ebl) +{ + return ebl->data; +} diff --git a/libebl/eblelfmachine.c b/libebl/eblelfmachine.c new file mode 100644 index 00000000..c2c86275 --- /dev/null +++ b/libebl/eblelfmachine.c @@ -0,0 +1,41 @@ +/* Return ELF machine. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +ebl_get_elfmachine (Ebl *ebl) +{ + return ebl->machine; +} diff --git a/libebl/eblgotpcreloccheck.c b/libebl/eblgotpcreloccheck.c new file mode 100644 index 00000000..7c9c079c --- /dev/null +++ b/libebl/eblgotpcreloccheck.c @@ -0,0 +1,42 @@ +/* Return true if the symbol type is that referencing the GOT. E.g., + R_386_GOTPC. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_gotpc_reloc_check (Ebl *ebl, int reloc) +{ + return ebl != NULL ? ebl->gotpc_reloc_check (ebl->elf, reloc) : false; +} diff --git a/libebl/eblinitreg.c b/libebl/eblinitreg.c new file mode 100644 index 00000000..8a3fb18a --- /dev/null +++ b/libebl/eblinitreg.c @@ -0,0 +1,59 @@ +/* Fetch live process Dwfl_Frame from PID. + Copyright (C) 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +bool +ebl_set_initial_registers_tid (Ebl *ebl, pid_t tid, + ebl_tid_registers_t *setfunc, + void *arg) +{ + /* Otherwise caller could not allocate THREAD frame of proper size. + If set_initial_registers_tid is unsupported then FRAME_NREGS is zero. */ + assert (ebl->set_initial_registers_tid != NULL); + return ebl->set_initial_registers_tid (tid, setfunc, arg); +} + +size_t +ebl_frame_nregs (Ebl *ebl) +{ + /* ebl is declared NN */ + return ebl->frame_nregs; +} + +GElf_Addr +ebl_func_addr_mask (Ebl *ebl) +{ + return ((ebl == NULL || ebl->func_addr_mask == 0) + ? ~(GElf_Addr)0 : ebl->func_addr_mask); +} diff --git a/libebl/eblmachineflagcheck.c b/libebl/eblmachineflagcheck.c new file mode 100644 index 00000000..e98b600e --- /dev/null +++ b/libebl/eblmachineflagcheck.c @@ -0,0 +1,41 @@ +/* Check machine flag. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_machine_flag_check (Ebl *ebl, Elf64_Word flags) +{ + return ebl != NULL ? ebl->machine_flag_check (flags) : (flags == 0); +} diff --git a/libebl/eblmachineflagname.c b/libebl/eblmachineflagname.c new file mode 100644 index 00000000..5f440776 --- /dev/null +++ b/libebl/eblmachineflagname.c @@ -0,0 +1,88 @@ +/* Return machine flag names. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + + +const char * +ebl_machine_flag_name (Ebl *ebl, Elf64_Word flags, char *buf, size_t len) +{ + const char *res; + + if (flags == 0) + res = ""; + else + { + char *cp = buf; + int first = 1; + const char *machstr; + size_t machstrlen; + + do + { + if (! first) + { + if (cp + 1 >= buf + len) + break; + *cp++ = ','; + } + + machstr = ebl != NULL ? ebl->machine_flag_name (&flags) : NULL; + if (machstr == NULL) + { + /* No more known flag. */ + snprintf (cp, buf + len - cp, "%#x", flags); + break; + } + + machstrlen = strlen (machstr) + 1; + if ((size_t) (buf + len - cp) < machstrlen) + { + *((char *) mempcpy (cp, machstr, buf + len - cp - 1)) = '\0'; + break; + } + + cp = mempcpy (cp, machstr, machstrlen); + + first = 0; + } + while (flags != 0); + + res = buf; + } + + return res; +} diff --git a/libebl/eblmachinesectionflagcheck.c b/libebl/eblmachinesectionflagcheck.c new file mode 100644 index 00000000..a73b230d --- /dev/null +++ b/libebl/eblmachinesectionflagcheck.c @@ -0,0 +1,40 @@ +/* Check SHF_MASKPROC flags. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_machine_section_flag_check (Ebl *ebl, GElf_Xword flags) +{ + return ebl != NULL ? ebl->machine_section_flag_check (flags) : (flags == 0); +} diff --git a/libebl/eblnonerelocp.c b/libebl/eblnonerelocp.c new file mode 100644 index 00000000..e51a3b00 --- /dev/null +++ b/libebl/eblnonerelocp.c @@ -0,0 +1,41 @@ +/* Check whether given relocation is a no-op relocation. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2006. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_none_reloc_p (Ebl *ebl, int reloc) +{ + return ebl->none_reloc_p (reloc); +} diff --git a/libebl/eblnormalizepc.c b/libebl/eblnormalizepc.c new file mode 100644 index 00000000..1629353d --- /dev/null +++ b/libebl/eblnormalizepc.c @@ -0,0 +1,41 @@ +/* Modify PC as fetched from inferior data into valid PC. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +void +ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc) +{ + /* ebl is declared NN */ + if (ebl->normalize_pc != NULL) + ebl->normalize_pc (ebl, pc); +} diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c new file mode 100644 index 00000000..36efe275 --- /dev/null +++ b/libebl/eblobjnote.c @@ -0,0 +1,658 @@ +/* Print contents of object file note. + Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "common.h" +#include "libelfP.h" +#include "libdwP.h" +#include "memory-access.h" + + +void +ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, + uint32_t descsz, const char *desc) +{ + if (! ebl->object_note (name, type, descsz, desc)) + { + /* The machine specific function did not know this type. */ + + if (strcmp ("stapsdt", name) == 0) + { + if (type != 3) + { + printf (_("unknown SDT version %u\n"), type); + return; + } + + /* Descriptor starts with three addresses, pc, base ref and + semaphore. Then three zero terminated strings provider, + name and arguments. */ + + union + { + Elf64_Addr a64[3]; + Elf32_Addr a32[3]; + } addrs; + + size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT); + if (descsz < addrs_size + 3) + { + invalid_sdt: + printf (_("invalid SDT probe descriptor\n")); + return; + } + + Elf_Data src = + { + .d_type = ELF_T_ADDR, .d_version = EV_CURRENT, + .d_buf = (void *) desc, .d_size = addrs_size + }; + + Elf_Data dst = + { + .d_type = ELF_T_ADDR, .d_version = EV_CURRENT, + .d_buf = &addrs, .d_size = addrs_size + }; + + if (gelf_xlatetom (ebl->elf, &dst, &src, + elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL) + { + printf ("%s\n", elf_errmsg (-1)); + return; + } + + const char *provider = desc + addrs_size; + const char *pname = memchr (provider, '\0', desc + descsz - provider); + if (pname == NULL) + goto invalid_sdt; + + ++pname; + const char *args = memchr (pname, '\0', desc + descsz - pname); + if (args == NULL || + memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1) + goto invalid_sdt; + + GElf_Addr pc; + GElf_Addr base; + GElf_Addr sem; + if (gelf_getclass (ebl->elf) == ELFCLASS32) + { + pc = addrs.a32[0]; + base = addrs.a32[1]; + sem = addrs.a32[2]; + } + else + { + pc = addrs.a64[0]; + base = addrs.a64[1]; + sem = addrs.a64[2]; + } + + printf (_(" PC: ")); + printf ("%#" PRIx64 ",", pc); + printf (_(" Base: ")); + printf ("%#" PRIx64 ",", base); + printf (_(" Semaphore: ")); + printf ("%#" PRIx64 "\n", sem); + printf (_(" Provider: ")); + printf ("%s,", provider); + printf (_(" Name: ")); + printf ("%s,", pname); + printf (_(" Args: ")); + printf ("'%s'\n", args); + return; + } + + if (strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX, + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0 + && (type == NT_GNU_BUILD_ATTRIBUTE_OPEN + || type == NT_GNU_BUILD_ATTRIBUTE_FUNC)) + { + /* There might or might not be a pair of addresses in the desc. */ + if (descsz > 0) + { + printf (" Address Range: "); + + union + { + Elf64_Addr a64[2]; + Elf32_Addr a32[2]; + } addrs; + + size_t addr_size = gelf_fsize (ebl->elf, ELF_T_ADDR, + 2, EV_CURRENT); + if (descsz != addr_size) + printf ("\n"); + else + { + Elf_Data src = + { + .d_type = ELF_T_ADDR, .d_version = EV_CURRENT, + .d_buf = (void *) desc, .d_size = descsz + }; + + Elf_Data dst = + { + .d_type = ELF_T_ADDR, .d_version = EV_CURRENT, + .d_buf = &addrs, .d_size = descsz + }; + + if (gelf_xlatetom (ebl->elf, &dst, &src, + elf_getident (ebl->elf, + NULL)[EI_DATA]) == NULL) + printf ("%s\n", elf_errmsg (-1)); + else + { + if (addr_size == 4) + printf ("%#" PRIx32 " - %#" PRIx32 "\n", + addrs.a32[0], addrs.a32[1]); + else + printf ("%#" PRIx64 " - %#" PRIx64 "\n", + addrs.a64[0], addrs.a64[1]); + } + } + } + + /* Most data actually is inside the name. + https://fedoraproject.org/wiki/Toolchain/Watermark */ + + /* We need at least 2 chars of data to describe the + attribute and value encodings. */ + const char *data = (name + + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)); + if (namesz < 2) + { + printf ("\n"); + return; + } + + printf (" "); + + /* In most cases the value comes right after the encoding bytes. */ + const char *value = &data[2]; + switch (data[1]) + { + case GNU_BUILD_ATTRIBUTE_VERSION: + printf ("VERSION: "); + break; + case GNU_BUILD_ATTRIBUTE_STACK_PROT: + printf ("STACK_PROT: "); + break; + case GNU_BUILD_ATTRIBUTE_RELRO: + printf ("RELRO: "); + break; + case GNU_BUILD_ATTRIBUTE_STACK_SIZE: + printf ("STACK_SIZE: "); + break; + case GNU_BUILD_ATTRIBUTE_TOOL: + printf ("TOOL: "); + break; + case GNU_BUILD_ATTRIBUTE_ABI: + printf ("ABI: "); + break; + case GNU_BUILD_ATTRIBUTE_PIC: + printf ("PIC: "); + break; + case GNU_BUILD_ATTRIBUTE_SHORT_ENUM: + printf ("SHORT_ENUM: "); + break; + case 32 ... 126: + printf ("\"%s\": ", &data[1]); + value += strlen (&data[1]) + 1; + break; + default: + printf (": "); + break; + } + + switch (data[0]) + { + case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC: + { + /* Any numbers are always in (unsigned) little endian. */ + static const Dwarf dbg + = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB }; + size_t bytes = namesz - (value - name); + uint64_t val; + if (bytes == 1) + val = *(unsigned char *) value; + else if (bytes == 2) + val = read_2ubyte_unaligned (&dbg, value); + else if (bytes == 4) + val = read_4ubyte_unaligned (&dbg, value); + else if (bytes == 8) + val = read_8ubyte_unaligned (&dbg, value); + else + goto unknown; + printf ("%" PRIx64, val); + } + break; + case GNU_BUILD_ATTRIBUTE_TYPE_STRING: + printf ("\"%s\"", value); + break; + case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE: + printf ("TRUE"); + break; + case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE: + printf ("FALSE"); + break; + default: + { + unknown: + printf (""); + } + break; + } + + printf ("\n"); + + return; + } + + /* NT_VERSION doesn't have any info. All data is in the name. */ + if (descsz == 0 && type == NT_VERSION) + return; + + /* Everything else should have the "GNU" owner name. */ + if (strcmp ("GNU", name) != 0) + return; + + switch (type) + { + case NT_GNU_BUILD_ID: + if (strcmp (name, "GNU") == 0 && descsz > 0) + { + printf (_(" Build ID: ")); + uint_fast32_t i; + for (i = 0; i < descsz - 1; ++i) + printf ("%02" PRIx8, (uint8_t) desc[i]); + printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); + } + break; + + case NT_GNU_GOLD_VERSION: + if (strcmp (name, "GNU") == 0 && descsz > 0) + /* A non-null terminated version string. */ + printf (_(" Linker version: %.*s\n"), + (int) descsz, desc); + break; + + case NT_GNU_PROPERTY_TYPE_0: + if (strcmp (name, "GNU") == 0 && descsz > 0) + { + /* There are at least 2 words. type and datasz. */ + while (descsz >= 8) + { + struct pr_prop + { + GElf_Word pr_type; + GElf_Word pr_datasz; + } prop; + + Elf_Data in = + { + .d_version = EV_CURRENT, + .d_type = ELF_T_WORD, + .d_size = 8, + .d_buf = (void *) desc + }; + Elf_Data out = + { + .d_version = EV_CURRENT, + .d_type = ELF_T_WORD, + .d_size = descsz, + .d_buf = (void *) &prop + }; + + if (gelf_xlatetom (ebl->elf, &out, &in, + elf_getident (ebl->elf, + NULL)[EI_DATA]) == NULL) + { + printf ("%s\n", elf_errmsg (-1)); + return; + } + + desc += 8; + descsz -= 8; + + if (prop.pr_datasz > descsz) + { + printf ("BAD property datasz: %" PRId32 "\n", + prop.pr_datasz); + return; + } + + int elfclass = gelf_getclass (ebl->elf); + char *elfident = elf_getident (ebl->elf, NULL); + GElf_Ehdr ehdr; + gelf_getehdr (ebl->elf, &ehdr); + + /* Prefix. */ + printf (" "); + if (prop.pr_type == GNU_PROPERTY_STACK_SIZE) + { + printf ("STACK_SIZE "); + union + { + Elf64_Addr a64; + Elf32_Addr a32; + } addr; + if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4) + || (elfclass == ELFCLASS64 && prop.pr_datasz == 8)) + { + in.d_type = ELF_T_ADDR; + out.d_type = ELF_T_ADDR; + in.d_size = prop.pr_datasz; + out.d_size = prop.pr_datasz; + in.d_buf = (void *) desc; + out.d_buf = (elfclass == ELFCLASS32 + ? (void *) &addr.a32 + : (void *) &addr.a64); + + if (gelf_xlatetom (ebl->elf, &out, &in, + elfident[EI_DATA]) == NULL) + { + printf ("%s\n", elf_errmsg (-1)); + return; + } + if (elfclass == ELFCLASS32) + printf ("%#" PRIx32 "\n", addr.a32); + else + printf ("%#" PRIx64 "\n", addr.a64); + } + else + printf (" (garbage datasz: %" PRIx32 ")\n", + prop.pr_datasz); + } + else if (prop.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED) + { + printf ("NO_COPY_ON_PROTECTION"); + if (prop.pr_datasz == 0) + printf ("\n"); + else + printf (" (garbage datasz: %" PRIx32 ")\n", + prop.pr_datasz); + } + else if (prop.pr_type >= GNU_PROPERTY_LOPROC + && prop.pr_type <= GNU_PROPERTY_HIPROC + && (ehdr.e_machine == EM_386 + || ehdr.e_machine == EM_X86_64)) + { + printf ("X86 "); + if (prop.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND) + { + printf ("FEATURE_1_AND: "); + + if (prop.pr_datasz == 4) + { + GElf_Word data; + in.d_type = ELF_T_WORD; + out.d_type = ELF_T_WORD; + in.d_size = 4; + out.d_size = 4; + in.d_buf = (void *) desc; + out.d_buf = (void *) &data; + + if (gelf_xlatetom (ebl->elf, &out, &in, + elfident[EI_DATA]) == NULL) + { + printf ("%s\n", elf_errmsg (-1)); + return; + } + printf ("%08" PRIx32 " ", data); + + if ((data & GNU_PROPERTY_X86_FEATURE_1_IBT) + != 0) + { + printf ("IBT"); + data &= ~GNU_PROPERTY_X86_FEATURE_1_IBT; + if (data != 0) + printf (" "); + } + + if ((data & GNU_PROPERTY_X86_FEATURE_1_SHSTK) + != 0) + { + printf ("SHSTK"); + data &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK; + if (data != 0) + printf (" "); + } + + if (data != 0) + printf ("UNKNOWN"); + } + else + printf ("", + prop.pr_datasz); + + printf ("\n"); + } + else + { + printf ("%#" PRIx32, prop.pr_type); + if (prop.pr_datasz > 0) + { + printf (" data: "); + size_t i; + for (i = 0; i < prop.pr_datasz - 1; i++) + printf ("%02" PRIx8 " ", (uint8_t) desc[i]); + printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); + } + } + } + else if (prop.pr_type >= GNU_PROPERTY_LOPROC + && prop.pr_type <= GNU_PROPERTY_HIPROC + && ehdr.e_machine == EM_AARCH64) + { + printf ("AARCH64 "); + if (prop.pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) + { + printf ("FEATURE_1_AND: "); + + if (prop.pr_datasz == 4) + { + GElf_Word data; + in.d_type = ELF_T_WORD; + out.d_type = ELF_T_WORD; + in.d_size = 4; + out.d_size = 4; + in.d_buf = (void *) desc; + out.d_buf = (void *) &data; + + if (gelf_xlatetom (ebl->elf, &out, &in, + elfident[EI_DATA]) == NULL) + { + printf ("%s\n", elf_errmsg (-1)); + return; + } + printf ("%08" PRIx32 " ", data); + + if ((data & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) + != 0) + { + printf ("BTI"); + data &= ~GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + if (data != 0) + printf (" "); + } + + if ((data & GNU_PROPERTY_AARCH64_FEATURE_1_PAC) + != 0) + { + printf ("PAC"); + data &= ~GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + if (data != 0) + printf (" "); + } + + if (data != 0) + printf ("UNKNOWN"); + } + else + printf ("", + prop.pr_datasz); + + printf ("\n"); + } + else + { + printf ("%#" PRIx32, prop.pr_type); + if (prop.pr_datasz > 0) + { + printf (" data: "); + size_t i; + for (i = 0; i < prop.pr_datasz - 1; i++) + printf ("%02" PRIx8 " ", (uint8_t) desc[i]); + printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); + } + } + } + else + { + if (prop.pr_type >= GNU_PROPERTY_LOPROC + && prop.pr_type <= GNU_PROPERTY_HIPROC) + printf ("proc_type %#" PRIx32, prop.pr_type); + else if (prop.pr_type >= GNU_PROPERTY_LOUSER + && prop.pr_type <= GNU_PROPERTY_HIUSER) + printf ("app_type %#" PRIx32, prop.pr_type); + else + printf ("unknown_type %#" PRIx32, prop.pr_type); + + if (prop.pr_datasz > 0) + { + printf (" data: "); + size_t i; + for (i = 0; i < prop.pr_datasz - 1; i++) + printf ("%02" PRIx8 " ", (uint8_t) desc[i]); + printf ("%02" PRIx8 "\n", (uint8_t) desc[i]); + } + } + + if (elfclass == ELFCLASS32) + prop.pr_datasz = NOTE_ALIGN4 (prop.pr_datasz); + else + prop.pr_datasz = NOTE_ALIGN8 (prop.pr_datasz); + + desc += prop.pr_datasz; + if (descsz > prop.pr_datasz) + descsz -= prop.pr_datasz; + else + descsz = 0; + } + } + break; + + case NT_GNU_ABI_TAG: + if (descsz >= 8 && descsz % 4 == 0) + { + Elf_Data in = + { + .d_version = EV_CURRENT, + .d_type = ELF_T_WORD, + .d_size = descsz, + .d_buf = (void *) desc + }; + /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes). If it + is much (4*) larger dynamically allocate memory to convert. */ +#define FIXED_TAG_BYTES 16 + uint32_t sbuf[FIXED_TAG_BYTES]; + uint32_t *buf; + if (unlikely (descsz / 4 > FIXED_TAG_BYTES)) + { + buf = malloc (descsz); + if (unlikely (buf == NULL)) + return; + } + else + buf = sbuf; + Elf_Data out = + { + .d_version = EV_CURRENT, + .d_type = ELF_T_WORD, + .d_size = descsz, + .d_buf = buf + }; + + if (elf32_xlatetom (&out, &in, ebl->data) != NULL) + { + const char *os; + switch (buf[0]) + { + case ELF_NOTE_OS_LINUX: + os = "Linux"; + break; + + case ELF_NOTE_OS_GNU: + os = "GNU"; + break; + + case ELF_NOTE_OS_SOLARIS2: + os = "Solaris"; + break; + + case ELF_NOTE_OS_FREEBSD: + os = "FreeBSD"; + break; + + default: + os = "???"; + break; + } + + printf (_(" OS: %s, ABI: "), os); + for (size_t cnt = 1; cnt < descsz / 4; ++cnt) + { + if (cnt > 1) + putchar_unlocked ('.'); + printf ("%" PRIu32, buf[cnt]); + } + putchar_unlocked ('\n'); + } + if (descsz / 4 > FIXED_TAG_BYTES) + free (buf); + break; + } + FALLTHROUGH; + + default: + /* Unknown type. */ + break; + } + } +} diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c new file mode 100644 index 00000000..4662906d --- /dev/null +++ b/libebl/eblobjnotetypename.c @@ -0,0 +1,138 @@ +/* Return note type name. + Copyright (C) 2002, 2007, 2009, 2011, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include + + +const char * +ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type, + GElf_Word descsz, + char *buf, size_t len) +{ + const char *res = ebl->object_note_type_name (name, type, buf, len); + + if (res == NULL) + { + if (strcmp (name, "stapsdt") == 0) + { + snprintf (buf, len, "Version: %" PRIu32, type); + return buf; + } + +#define ELF_NOTE_GOPKGLIST 1 +#define ELF_NOTE_GOABIHASH 2 +#define ELF_NOTE_GODEPS 3 +#define ELF_NOTE_GOBUILDID 4 + + static const char *goknowntypes[] = + { +#define KNOWNSTYPE(name) [ELF_NOTE_GO##name] = #name + KNOWNSTYPE (PKGLIST), + KNOWNSTYPE (ABIHASH), + KNOWNSTYPE (DEPS), + KNOWNSTYPE (BUILDID), +#undef KNOWNSTYPE + }; + + if (strcmp (name, "Go") == 0) + { + if (type < sizeof (goknowntypes) / sizeof (goknowntypes[0]) + && goknowntypes[type] != NULL) + return goknowntypes[type]; + else + { + snprintf (buf, len, "%s: %" PRIu32, _(""), type); + return buf; + } + } + + if (startswith (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) + { + /* GNU Build Attribute notes (ab)use the owner name to store + most of their data. Don't decode everything here. Just + the type.*/ + char *t = buf; + const char *gba = "GNU Build Attribute"; + int w = snprintf (t, len, "%s ", gba); + t += w; + len -= w; + if (type == NT_GNU_BUILD_ATTRIBUTE_OPEN) + snprintf (t, len, "OPEN"); + else if (type == NT_GNU_BUILD_ATTRIBUTE_FUNC) + snprintf (t, len, "FUNC"); + else + snprintf (t, len, "%x", type); + + return buf; + } + + if (strcmp (name, "GNU") != 0) + { + /* NT_VERSION is special, all data is in the name. */ + if (descsz == 0 && type == NT_VERSION) + return "VERSION"; + + snprintf (buf, len, "%s: %" PRIu32, _(""), type); + return buf; + } + + /* And finally all the "GNU" note types. */ + static const char *knowntypes[] = + { +#define KNOWNSTYPE(name) [NT_##name] = #name + KNOWNSTYPE (GNU_ABI_TAG), + KNOWNSTYPE (GNU_HWCAP), + KNOWNSTYPE (GNU_BUILD_ID), + KNOWNSTYPE (GNU_GOLD_VERSION), + KNOWNSTYPE (GNU_PROPERTY_TYPE_0), + }; + + /* Handle standard names. */ + if (type < sizeof (knowntypes) / sizeof (knowntypes[0]) + && knowntypes[type] != NULL) + res = knowntypes[type]; + else + { + snprintf (buf, len, "%s: %" PRIu32, _(""), type); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c new file mode 100644 index 00000000..71fafed7 --- /dev/null +++ b/libebl/eblopenbackend.c @@ -0,0 +1,713 @@ +/* Generate ELF backend handle. + Copyright (C) 2000-2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +Ebl *i386_init (Elf *, GElf_Half, Ebl *); +Ebl *sh_init (Elf *, GElf_Half, Ebl *); +Ebl *x86_64_init (Elf *, GElf_Half, Ebl *); +Ebl *ia64_init (Elf *, GElf_Half, Ebl *); +Ebl *alpha_init (Elf *, GElf_Half, Ebl *); +Ebl *arm_init (Elf *, GElf_Half, Ebl *); +Ebl *aarch64_init (Elf *, GElf_Half, Ebl *); +Ebl *sparc_init (Elf *, GElf_Half, Ebl *); +Ebl *ppc_init (Elf *, GElf_Half, Ebl *); +Ebl *ppc64_init (Elf *, GElf_Half, Ebl *); +Ebl *s390_init (Elf *, GElf_Half, Ebl *); +Ebl *m68k_init (Elf *, GElf_Half, Ebl *); +Ebl *bpf_init (Elf *, GElf_Half, Ebl *); +Ebl *riscv_init (Elf *, GElf_Half, Ebl *); +Ebl *csky_init (Elf *, GElf_Half, Ebl *); + +/* This table should contain the complete list of architectures as far + as the ELF specification is concerned. */ +/* XXX When things are stable replace the string pointers with char + arrays to avoid relocations. */ +static const struct +{ + ebl_bhinit_t init; + const char *emulation; + const char *prefix; + int prefix_len; + int em; + int class; + int data; +} machines[] = +{ + { i386_init, "elf_i386", "i386", 4, EM_386, ELFCLASS32, ELFDATA2LSB }, + { ia64_init, "elf_ia64", "ia64", 4, EM_IA_64, ELFCLASS64, ELFDATA2LSB }, + { alpha_init, "elf_alpha", "alpha", 5, EM_ALPHA, ELFCLASS64, ELFDATA2LSB }, + { x86_64_init, "elf_x86_64", "x86_64", 6, EM_X86_64, ELFCLASS64, ELFDATA2LSB }, + { ppc_init, "elf_ppc", "ppc", 3, EM_PPC, ELFCLASS32, ELFDATA2MSB }, + { ppc64_init, "elf_ppc64", "ppc64", 5, EM_PPC64, ELFCLASS64, ELFDATA2MSB }, + // XXX class and machine fields need to be filled in for all archs. + { sh_init, "elf_sh", "sh", 2, EM_SH, 0, 0 }, + { arm_init, "ebl_arm", "arm", 3, EM_ARM, 0, 0 }, + { sparc_init, "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 }, + { sparc_init, "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 }, + { sparc_init, "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 }, + { s390_init, "ebl_s390", "s390", 4, EM_S390, 0, 0 }, + + { NULL, "elf_tilegx", "tilegx", 6, EM_TILEGX, ELFCLASS64, ELFDATA2LSB }, + { NULL, "elf_m32", "m32", 3, EM_M32, 0, 0 }, + { m68k_init, "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB }, + { NULL, "elf_m88k", "m88k", 4, EM_88K, 0, 0 }, + { NULL, "elf_i860", "i860", 4, EM_860, 0, 0 }, + { NULL, "ebl_s370", "s370", 4, EM_S370, 0, 0 }, + { NULL, "elf_parisc", "parisc", 6, EM_PARISC, 0, 0 }, + { NULL, "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 }, + { sparc_init, "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 }, + { NULL, "elf_i960", "i960", 4, EM_960, 0, 0 }, + { NULL, "ebl_v800", "v800", 4, EM_V800, 0, 0 }, + { NULL, "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 }, + { NULL, "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 }, + { NULL, "ebl_rce", "rce", 3, EM_RCE, 0, 0 }, + { NULL, "elf_tricore", "tricore", 7, EM_TRICORE, 0, 0 }, + { NULL, "elf_arc", "arc", 3, EM_ARC, 0, 0 }, + { NULL, "elf_h8_300", "h8_300", 6, EM_H8_300, 0, 0 }, + { NULL, "elf_h8_300h", "h8_300h", 6, EM_H8_300H, 0, 0 }, + { NULL, "elf_h8s", "h8s", 6, EM_H8S, 0, 0 }, + { NULL, "elf_h8_500", "h8_500", 6, EM_H8_500, 0, 0 }, + { NULL, "elf_coldfire", "coldfire", 8, EM_COLDFIRE, 0, 0 }, + { m68k_init, "elf_68hc12", "68hc12", 6, EM_68HC12, 0, 0 }, + { NULL, "elf_mma", "mma", 3, EM_MMA, 0, 0 }, + { NULL, "elf_pcp", "pcp", 3, EM_PCP, 0, 0 }, + { NULL, "elf_ncpu", "ncpu", 4, EM_NCPU, 0, 0 }, + { NULL, "elf_ndr1", "ndr1", 4, EM_NDR1, 0, 0 }, + { NULL, "elf_starcore", "starcore", 8, EM_STARCORE, 0, 0 }, + { NULL, "elf_me16", "em16", 4, EM_ME16, 0, 0 }, + { NULL, "elf_st100", "st100", 5, EM_ST100, 0, 0 }, + { NULL, "elf_tinyj", "tinyj", 5, EM_TINYJ, 0, 0 }, + { NULL, "elf_pdsp", "pdsp", 4, EM_PDSP, 0, 0 }, + { NULL, "elf_fx66", "fx66", 4, EM_FX66, 0, 0 }, + { NULL, "elf_st9plus", "st9plus", 7, EM_ST9PLUS, 0, 0 }, + { NULL, "elf_st7", "st7", 3, EM_ST7, 0, 0 }, + { m68k_init, "elf_68hc16", "68hc16", 6, EM_68HC16, 0, 0 }, + { m68k_init, "elf_68hc11", "68hc11", 6, EM_68HC11, 0, 0 }, + { m68k_init, "elf_68hc08", "68hc08", 6, EM_68HC08, 0, 0 }, + { m68k_init, "elf_68hc05", "68hc05", 6, EM_68HC05, 0, 0 }, + { NULL, "elf_svx", "svx", 3, EM_SVX, 0, 0 }, + { NULL, "elf_st19", "st19", 4, EM_ST19, 0, 0 }, + { NULL, "elf_vax", "vax", 3, EM_VAX, 0, 0 }, + { NULL, "elf_cris", "cris", 4, EM_CRIS, 0, 0 }, + { NULL, "elf_javelin", "javelin", 7, EM_JAVELIN, 0, 0 }, + { NULL, "elf_firepath", "firepath", 8, EM_FIREPATH, 0, 0 }, + { NULL, "elf_zsp", "zsp", 3, EM_ZSP, 0, 0 }, + { NULL, "elf_mmix", "mmix", 4, EM_MMIX, 0, 0 }, + { NULL, "elf_huany", "huany", 5, EM_HUANY, 0, 0 }, + { NULL, "elf_prism", "prism", 5, EM_PRISM, 0, 0 }, + { NULL, "elf_avr", "avr", 3, EM_AVR, 0, 0 }, + { NULL, "elf_fr30", "fr30", 4, EM_FR30, 0, 0 }, + { NULL, "elf_dv10", "dv10", 4, EM_D10V, 0, 0 }, + { NULL, "elf_dv30", "dv30", 4, EM_D30V, 0, 0 }, + { NULL, "elf_v850", "v850", 4, EM_V850, 0, 0 }, + { NULL, "elf_m32r", "m32r", 4, EM_M32R, 0, 0 }, + { NULL, "elf_mn10300", "mn10300", 7, EM_MN10300, 0, 0 }, + { NULL, "elf_mn10200", "mn10200", 7, EM_MN10200, 0, 0 }, + { NULL, "elf_pj", "pj", 2, EM_PJ, 0, 0 }, + { NULL, "elf_openrisc", "openrisc", 8, EM_OPENRISC, 0, 0 }, + { NULL, "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 }, + { NULL, "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 }, + { aarch64_init, "elf_aarch64", "aarch64", 7, EM_AARCH64, ELFCLASS64, 0 }, + { bpf_init, "elf_bpf", "bpf", 3, EM_BPF, 0, 0 }, + { riscv_init, "elf_riscv", "riscv", 5, EM_RISCV, ELFCLASS64, ELFDATA2LSB }, + { riscv_init, "elf_riscv", "riscv", 5, EM_RISCV, ELFCLASS32, ELFDATA2LSB }, + { csky_init, "elf_csky", "csky", 4, EM_CSKY, ELFCLASS32, ELFDATA2LSB }, +}; +#define nmachines (sizeof (machines) / sizeof (machines[0])) + +/* No machine prefix should be larger than this. */ +#define MAX_PREFIX_LEN 16 + +/* Default callbacks. Mostly they just return the error value. */ +static const char *default_reloc_type_name (int ignore, char *buf, size_t len); +static bool default_reloc_type_check (int ignore); +static bool default_reloc_valid_use (Elf *elf, int ignore); +static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore, int *addsub); +static bool default_gotpc_reloc_check (Elf *elf, int ignore); +static const char *default_segment_type_name (int ignore, char *buf, + size_t len); +static const char *default_section_type_name (int ignore, char *buf, + size_t len); +static const char *default_section_name (int ignore, int ignore2, char *buf, + size_t len); +static const char *default_machine_flag_name (Elf64_Word *ignore); +static bool default_machine_flag_check (Elf64_Word flags); +static bool default_machine_section_flag_check (GElf_Xword flags); +static const char *default_symbol_type_name (int ignore, char *buf, + size_t len); +static const char *default_symbol_binding_name (int ignore, char *buf, + size_t len); +static const char *default_dynamic_tag_name (int64_t ignore, char *buf, + size_t len); +static bool default_dynamic_tag_check (int64_t ignore); +static const char *default_osabi_name (int ignore, char *buf, size_t len); +static void default_destr (struct ebl *ignore); +static const char *default_core_note_type_name (uint32_t, char *buf, + size_t len); +static const char *default_object_note_type_name (const char *name, uint32_t, + char *buf, size_t len); +static int default_core_note (const GElf_Nhdr *nhdr, const char *name, + GElf_Word *regs_offset, size_t *nregloc, + const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **); +static int default_auxv_info (GElf_Xword a_type, + const char **name, const char **format); +static bool default_object_note (const char *name, uint32_t type, + uint32_t descsz, const char *desc); +static bool default_debugscn_p (const char *name); +static bool default_copy_reloc_p (int reloc); +static bool default_none_reloc_p (int reloc); +static bool default_relative_reloc_p (int reloc); +static bool default_check_special_symbol (Elf *elf, + const GElf_Sym *sym, + const char *name, + const GElf_Shdr *destshdr); +static bool default_data_marker_symbol (const GElf_Sym *sym, const char *sname); +static bool default_check_st_other_bits (unsigned char st_other); +static bool default_check_special_section (Ebl *, int, + const GElf_Shdr *, const char *); +static bool default_bss_plt_p (Elf *elf); +static int default_return_value_location (Dwarf_Die *functypedie, + const Dwarf_Op **locops); +static ssize_t default_register_info (Ebl *ebl, + int regno, char *name, size_t namelen, + const char **prefix, + const char **setname, + int *bits, int *type); +static bool default_check_object_attribute (Ebl *ebl, const char *vendor, + int tag, uint64_t value, + const char **tag_name, + const char **value_name); +static bool default_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type); +static int default_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info); + + +static void +fill_defaults (Ebl *result) +{ + result->reloc_type_name = default_reloc_type_name; + result->reloc_type_check = default_reloc_type_check; + result->reloc_valid_use = default_reloc_valid_use; + result->reloc_simple_type = default_reloc_simple_type; + result->gotpc_reloc_check = default_gotpc_reloc_check; + result->segment_type_name = default_segment_type_name; + result->section_type_name = default_section_type_name; + result->section_name = default_section_name; + result->machine_flag_name = default_machine_flag_name; + result->machine_flag_check = default_machine_flag_check; + result->machine_section_flag_check = default_machine_section_flag_check; + result->check_special_section = default_check_special_section; + result->symbol_type_name = default_symbol_type_name; + result->symbol_binding_name = default_symbol_binding_name; + result->dynamic_tag_name = default_dynamic_tag_name; + result->dynamic_tag_check = default_dynamic_tag_check; + result->osabi_name = default_osabi_name; + result->core_note_type_name = default_core_note_type_name; + result->object_note_type_name = default_object_note_type_name; + result->core_note = default_core_note; + result->auxv_info = default_auxv_info; + result->object_note = default_object_note; + result->debugscn_p = default_debugscn_p; + result->copy_reloc_p = default_copy_reloc_p; + result->none_reloc_p = default_none_reloc_p; + result->relative_reloc_p = default_relative_reloc_p; + result->check_special_symbol = default_check_special_symbol; + result->data_marker_symbol = default_data_marker_symbol; + result->check_st_other_bits = default_check_st_other_bits; + result->bss_plt_p = default_bss_plt_p; + result->return_value_location = default_return_value_location; + result->register_info = default_register_info; + result->check_object_attribute = default_check_object_attribute; + result->check_reloc_target_type = default_check_reloc_target_type; + result->disasm = NULL; + result->abi_cfi = default_abi_cfi; + result->destr = default_destr; + result->sysvhash_entrysize = sizeof (Elf32_Word); +} + +/* Find an appropriate backend for the file associated with ELF. */ +static Ebl * +openbackend (Elf *elf, const char *emulation, GElf_Half machine) +{ + Ebl *result; + size_t cnt; + + /* First allocate the data structure for the result. We do this + here since this assures that the structure is always large + enough. */ + result = (Ebl *) calloc (1, sizeof (Ebl)); + if (result == NULL) + { + // XXX uncomment + // __libebl_seterror (ELF_E_NOMEM); + return NULL; + } + + /* Fill in the default callbacks. The initializer for the machine + specific module can overwrite the values. */ + fill_defaults (result); + + /* XXX Currently all we do is to look at 'e_machine' value in the + ELF header. With an internal mapping table from EM_* value to + DSO name we try to load the appropriate module to handle this + binary type. + + Multiple modules for the same machine type are possible and they + will be tried in sequence. The lookup process will only stop + when a module which can handle the machine type is found or all + available matching modules are tried. */ + for (cnt = 0; cnt < nmachines; ++cnt) + if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0) + || (emulation == NULL && machines[cnt].em == machine)) + { + /* Well, we know the emulation name now. */ + result->emulation = machines[cnt].emulation; + + /* We access some data structures directly. Make sure the 32 and + 64 bit variants are laid out the same. */ + assert (offsetof (Elf32_Ehdr, e_machine) + == offsetof (Elf64_Ehdr, e_machine)); + assert (sizeof (((Elf32_Ehdr *) 0)->e_machine) + == sizeof (((Elf64_Ehdr *) 0)->e_machine)); + assert (offsetof (Elf, state.elf32.ehdr) + == offsetof (Elf, state.elf64.ehdr)); + + /* Prefer taking the information from the ELF file. */ + if (elf == NULL) + { + result->machine = machines[cnt].em; + result->class = machines[cnt].class; + result->data = machines[cnt].data; + } + else + { + result->machine = elf->state.elf32.ehdr->e_machine; + result->class = elf->state.elf32.ehdr->e_ident[EI_CLASS]; + result->data = elf->state.elf32.ehdr->e_ident[EI_DATA]; + } + + if (machines[cnt].init && + machines[cnt].init (elf, machine, result)) + { + result->elf = elf; + /* A few entries are mandatory. */ + assert (result->destr != NULL); + return result; + } + + /* We don't have a backend but the emulation/machine ID matches. + Return that information. */ + result->elf = elf; + fill_defaults (result); + + return result; + } + + /* Nothing matched. We use only the default callbacks. */ + result->elf = elf; + result->emulation = ""; + fill_defaults (result); + + return result; +} + + +/* Find an appropriate backend for the file associated with ELF. */ +Ebl * +ebl_openbackend (Elf *elf) +{ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + + /* Get the ELF header of the object. */ + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + // XXX uncomment + // __libebl_seterror (elf_errno ()); + return NULL; + } + + return openbackend (elf, NULL, ehdr->e_machine); +} + + +/* Find backend without underlying ELF file. */ +Ebl * +ebl_openbackend_machine (GElf_Half machine) +{ + return openbackend (NULL, NULL, machine); +} + + +/* Find backend with given emulation name. */ +Ebl * +ebl_openbackend_emulation (const char *emulation) +{ + return openbackend (NULL, emulation, EM_NONE); +} + + +/* Default callbacks. Mostly they just return the error value. */ +static const char * +default_reloc_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_reloc_type_check (int ignore __attribute__ ((unused))) +{ + return false; +} + +static bool +default_reloc_valid_use (Elf *elf __attribute__ ((unused)), + int ignore __attribute__ ((unused))) +{ + return false; +} + +static Elf_Type +default_reloc_simple_type (Ebl *eh __attribute__ ((unused)), + int ignore __attribute__ ((unused)), + int *addsub __attribute__ ((unused))) +{ + return ELF_T_NUM; +} + +static bool +default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), + int ignore __attribute__ ((unused))) +{ + return false; +} + +static const char * +default_segment_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_section_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_section_name (int ignore __attribute__ ((unused)), + int ignore2 __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_machine_flag_name (Elf64_Word *ignore __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_machine_flag_check (Elf64_Word flags __attribute__ ((unused))) +{ + return flags == 0; +} + +static bool +default_machine_section_flag_check (GElf_Xword flags) +{ + return flags == 0; +} + +static bool +default_check_special_section (Ebl *ebl __attribute__ ((unused)), + int ndx __attribute__ ((unused)), + const GElf_Shdr *shdr __attribute__ ((unused)), + const char *sname __attribute__ ((unused))) +{ + return false; +} + +static const char * +default_symbol_type_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_symbol_binding_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_dynamic_tag_check (int64_t ignore __attribute__ ((unused))) +{ + return false; +} + +static void +default_destr (struct ebl *ignore __attribute__ ((unused))) +{ +} + +static const char * +default_osabi_name (int ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static const char * +default_core_note_type_name (uint32_t ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static int +default_auxv_info (GElf_Xword a_type __attribute__ ((unused)), + const char **name __attribute__ ((unused)), + const char **format __attribute__ ((unused))) +{ + return 0; +} + +static int +default_core_note (const GElf_Nhdr *nhdr __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + GElf_Word *ro __attribute__ ((unused)), + size_t *nregloc __attribute__ ((unused)), + const Ebl_Register_Location **reglocs + __attribute__ ((unused)), + size_t *nitems __attribute__ ((unused)), + const Ebl_Core_Item **items __attribute__ ((unused))) +{ + return 0; +} + +static const char * +default_object_note_type_name (const char *name __attribute__ ((unused)), + uint32_t ignore __attribute__ ((unused)), + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_object_note (const char *name __attribute__ ((unused)), + uint32_t type __attribute__ ((unused)), + uint32_t descsz __attribute__ ((unused)), + const char *desc __attribute__ ((unused))) +{ + return NULL; +} + +static bool +default_debugscn_p (const char *name) +{ + /* We know by default only about the DWARF debug sections which have + fixed names. */ + static const char *dwarf_scn_names[] = + { + /* DWARF 1 */ + ".debug", + ".line", + /* GNU DWARF 1 extensions */ + ".debug_srcinfo", + ".debug_sfnames", + /* DWARF 1.1 and DWARF 2 */ + ".debug_aranges", + ".debug_pubnames", + /* DWARF 2 */ + ".debug_info", + ".debug_abbrev", + ".debug_line", + ".debug_frame", + ".debug_str", + ".debug_loc", + ".debug_macinfo", + /* DWARF 3 */ + ".debug_ranges", + ".debug_pubtypes", + /* DWARF 4 */ + ".debug_types", + /* GDB DWARF 4 extension */ + ".gdb_index", + /* GNU/DWARF 5 extension/proposal */ + ".debug_macro", + /* DWARF 5 */ + ".debug_addr", + ".debug_line_str", + ".debug_loclists", + ".debug_names", + ".debug_rnglists", + ".debug_str_offsets", + /* SGI/MIPS DWARF 2 extensions */ + ".debug_weaknames", + ".debug_funcnames", + ".debug_typenames", + ".debug_varnames" + }; + const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names) + / sizeof (dwarf_scn_names[0])); + for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt) + if (strcmp (name, dwarf_scn_names[cnt]) == 0 + || (startswith (name, ".zdebug") + && strcmp (&name[2], &dwarf_scn_names[cnt][1]) == 0) + || (startswith (name, ".gnu.debuglto_") + && strcmp (&name[14], dwarf_scn_names[cnt]) == 0)) + return true; + + return false; +} + +static bool +default_copy_reloc_p (int reloc __attribute__ ((unused))) +{ + return false; +} +strong_alias (default_copy_reloc_p, default_none_reloc_p) +strong_alias (default_copy_reloc_p, default_relative_reloc_p) + +static bool +default_check_special_symbol (Elf *elf __attribute__ ((unused)), + const GElf_Sym *sym __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + const GElf_Shdr *destshdr __attribute__ ((unused))) +{ + return false; +} + +static bool +default_data_marker_symbol (const GElf_Sym *sym __attribute__ ((unused)), + const char *sname __attribute__ ((unused))) +{ + return false; +} + +static bool +default_check_st_other_bits (unsigned char st_other __attribute__ ((unused))) +{ + return false; +} + + +static bool +default_bss_plt_p (Elf *elf __attribute__ ((unused))) +{ + return false; +} + +static int +default_return_value_location (Dwarf_Die *functypedie __attribute__ ((unused)), + const Dwarf_Op **locops __attribute__ ((unused))) +{ + return -2; +} + +static ssize_t +default_register_info (Ebl *ebl __attribute__ ((unused)), + int regno, char *name, size_t namelen, + const char **prefix, + const char **setname, + int *bits, int *type) +{ + if (name == NULL) + return 0; + + *setname = "???"; + *prefix = ""; + *bits = -1; + *type = DW_ATE_void; + return snprintf (name, namelen, "reg%d", regno); +} + +static bool +default_check_object_attribute (Ebl *ebl __attribute__ ((unused)), + const char *vendor __attribute__ ((unused)), + int tag __attribute__ ((unused)), + uint64_t value __attribute__ ((unused)), + const char **tag_name, const char **value_name) +{ + *tag_name = NULL; + *value_name = NULL; + return false; +} + +static bool +default_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), + Elf64_Word sh_type __attribute__ ((unused))) +{ + return false; +} + +static int +default_abi_cfi (Ebl *ebl __attribute__ ((unused)), + Dwarf_CIE *abi_info __attribute__ ((unused))) +{ + return -1; +} diff --git a/libebl/eblosabiname.c b/libebl/eblosabiname.c new file mode 100644 index 00000000..48b3c051 --- /dev/null +++ b/libebl/eblosabiname.c @@ -0,0 +1,80 @@ +/* Return OS ABI name + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len) +{ + const char *res = ebl != NULL ? ebl->osabi_name (osabi, buf, len) : NULL; + + if (res == NULL) + { + if (osabi == ELFOSABI_NONE) + res = "UNIX - System V"; + else if (osabi == ELFOSABI_HPUX) + res = "HP/UX"; + else if (osabi == ELFOSABI_NETBSD) + res = "NetBSD"; + else if (osabi == ELFOSABI_LINUX) + res = "Linux"; + else if (osabi == ELFOSABI_SOLARIS) + res = "Solaris"; + else if (osabi == ELFOSABI_AIX) + res = "AIX"; + else if (osabi == ELFOSABI_IRIX) + res = "Irix"; + else if (osabi == ELFOSABI_FREEBSD) + res = "FreeBSD"; + else if (osabi == ELFOSABI_TRU64) + res = "TRU64"; + else if (osabi == ELFOSABI_MODESTO) + res = "Modesto"; + else if (osabi == ELFOSABI_OPENBSD) + res = "OpenBSD"; + else if (osabi == ELFOSABI_ARM) + res = "Arm"; + else if (osabi == ELFOSABI_STANDALONE) + res = _("Stand alone"); + else + { + snprintf (buf, len, "%s: %d", _(""), osabi); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblreginfo.c b/libebl/eblreginfo.c new file mode 100644 index 00000000..acc48495 --- /dev/null +++ b/libebl/eblreginfo.c @@ -0,0 +1,44 @@ +/* Return register name information. + Copyright (C) 2005, 2006 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +ssize_t +ebl_register_info (Ebl *ebl, int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type) +{ + return ebl == NULL ? -1 : ebl->register_info (ebl, regno, name, namelen, + prefix, setname, bits, type); +} diff --git a/libebl/eblrelativerelocp.c b/libebl/eblrelativerelocp.c new file mode 100644 index 00000000..51f5dce2 --- /dev/null +++ b/libebl/eblrelativerelocp.c @@ -0,0 +1,41 @@ +/* Check whether given relocation is a relative relocation. + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2006. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_relative_reloc_p (Ebl *ebl, int reloc) +{ + return ebl->relative_reloc_p (reloc); +} diff --git a/libebl/eblrelocsimpletype.c b/libebl/eblrelocsimpletype.c new file mode 100644 index 00000000..12292804 --- /dev/null +++ b/libebl/eblrelocsimpletype.c @@ -0,0 +1,40 @@ +/* Check relocation type for simple types. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +Elf_Type +ebl_reloc_simple_type (Ebl *ebl, int reloc, int *addsub) +{ + return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc, addsub) : ELF_T_NUM; +} diff --git a/libebl/eblreloctypecheck.c b/libebl/eblreloctypecheck.c new file mode 100644 index 00000000..80e67ef7 --- /dev/null +++ b/libebl/eblreloctypecheck.c @@ -0,0 +1,41 @@ +/* Check relocation type. + Copyright (C) 2001, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_reloc_type_check (Ebl *ebl, int reloc) +{ + return ebl != NULL ? ebl->reloc_type_check (reloc) : false; +} diff --git a/libebl/eblreloctypename.c b/libebl/eblreloctypename.c new file mode 100644 index 00000000..e53ec0c0 --- /dev/null +++ b/libebl/eblreloctypename.c @@ -0,0 +1,49 @@ +/* Return relocation type name. + Copyright (C) 2001, 2002, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_reloc_type_name (Ebl *ebl, int reloc, char *buf, size_t len) +{ + const char *res; + + res = ebl != NULL ? ebl->reloc_type_name (reloc, buf, len) : NULL; + if (res == NULL) + /* There are no generic relocation type names. */ + res = ""; + + return res; +} diff --git a/libebl/eblrelocvaliduse.c b/libebl/eblrelocvaliduse.c new file mode 100644 index 00000000..f0bed345 --- /dev/null +++ b/libebl/eblrelocvaliduse.c @@ -0,0 +1,41 @@ +/* Check relocation type use. + Copyright (C) 2003 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_reloc_valid_use (Ebl *ebl, int reloc) +{ + return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, reloc) : false; +} diff --git a/libebl/eblresolvesym.c b/libebl/eblresolvesym.c new file mode 100644 index 00000000..470f6f06 --- /dev/null +++ b/libebl/eblresolvesym.c @@ -0,0 +1,43 @@ +/* Resolve a symbol value to an allocated section of the Elf file. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +bool +ebl_resolve_sym_value (Ebl *ebl, GElf_Addr *addr) +{ + if (ebl == NULL || ebl->resolve_sym_value == NULL) + return false; + + return ebl->resolve_sym_value (ebl, addr); +} diff --git a/libebl/eblretval.c b/libebl/eblretval.c new file mode 100644 index 00000000..7c039824 --- /dev/null +++ b/libebl/eblretval.c @@ -0,0 +1,42 @@ +/* Return location expression to find return value given a function type DIE. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +int +ebl_return_value_location (Ebl *ebl, Dwarf_Die *functypedie, + const Dwarf_Op **locops) +{ + return ebl == NULL ? -1 : ebl->return_value_location (functypedie, locops); +} diff --git a/libebl/eblsectionname.c b/libebl/eblsectionname.c new file mode 100644 index 00000000..825ad2f8 --- /dev/null +++ b/libebl/eblsectionname.c @@ -0,0 +1,90 @@ +/* Return section name. + Copyright (C) 2001, 2002, 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_section_name (Ebl *ebl, int section, int xsection, char *buf, size_t len, + const char *scnnames[], size_t shnum) +{ + const char *res = ebl != NULL ? ebl->section_name (section, xsection, + buf, len) : NULL; + + if (res == NULL) + { + if (section == SHN_UNDEF) + res = "UNDEF"; + else if (section == SHN_ABS) + res = "ABS"; + else if (section == SHN_COMMON) + res = "COMMON"; + else if (section == SHN_BEFORE) + res = "BEFORE"; + else if (section == SHN_AFTER) + res = "AFTER"; + else if ((section < SHN_LORESERVE || section == SHN_XINDEX) + && (size_t) section < shnum) + { + int idx = section != SHN_XINDEX ? section : xsection; + + if (scnnames != NULL) + res = scnnames[idx]; + else + { + snprintf (buf, len, "%d", idx); + res = buf; + } + } + else + { + /* Handle OS-specific section names. */ + if (section == SHN_XINDEX) + snprintf (buf, len, "%s: %d", "XINDEX", xsection); + else if (section >= SHN_LOOS && section <= SHN_HIOS) + snprintf (buf, len, "LOOS+%x", section - SHN_LOOS); + /* Handle processor-specific section names. */ + else if (section >= SHN_LOPROC && section <= SHN_HIPROC) + snprintf (buf, len, "LOPROC+%x", section - SHN_LOPROC); + else if (section >= SHN_LORESERVE && section <= SHN_HIRESERVE) + snprintf (buf, len, "LORESERVE+%x", section - SHN_LORESERVE); + else + snprintf (buf, len, "%s: %d", _(""), section); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblsectionstripp.c b/libebl/eblsectionstripp.c new file mode 100644 index 00000000..a5624ffe --- /dev/null +++ b/libebl/eblsectionstripp.c @@ -0,0 +1,70 @@ +/* Check whether section can be stripped. + Copyright (C) 2005, 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libeblP.h" + + +bool +ebl_section_strip_p (Ebl *ebl, const GElf_Shdr *shdr, + const char *name, bool remove_comment, + bool only_remove_debug) +{ + /* If only debug information should be removed check the name. There + is unfortunately no other way. */ + if (unlikely (only_remove_debug)) + { + if (ebl_debugscn_p (ebl, name)) + return true; + + if (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) + { + Elf_Scn *scn_l = elf_getscn (ebl->elf, (shdr)->sh_info); + GElf_Shdr shdr_mem_l; + GElf_Shdr *shdr_l = gelf_getshdr (scn_l, &shdr_mem_l); + if (shdr_l != NULL) + { + size_t shstrndx; + if (elf_getshdrstrndx (ebl->elf, &shstrndx) != 0) + return false; + const char *s_l = elf_strptr (ebl->elf, shstrndx, + shdr_l->sh_name); + if (s_l != NULL && ebl_debugscn_p (ebl, s_l)) + return true; + } + } + + return false; + } + + return SECTION_STRIP_P (shdr, name, remove_comment); +} diff --git a/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c new file mode 100644 index 00000000..2008b95a --- /dev/null +++ b/libebl/eblsectiontypename.c @@ -0,0 +1,123 @@ +/* Return section type name. + Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_section_type_name (Ebl *ebl, int section, char *buf, size_t len) +{ + const char *res = ebl->section_type_name (section, buf, len); + + if (res == NULL) + { + static const char *knowntypes[] = + { +#define KNOWNSTYPE(name) [SHT_##name] = #name + KNOWNSTYPE (NULL), + KNOWNSTYPE (PROGBITS), + KNOWNSTYPE (SYMTAB), + KNOWNSTYPE (STRTAB), + KNOWNSTYPE (RELA), + KNOWNSTYPE (HASH), + KNOWNSTYPE (DYNAMIC), + KNOWNSTYPE (NOTE), + KNOWNSTYPE (NOBITS), + KNOWNSTYPE (REL), + KNOWNSTYPE (SHLIB), + KNOWNSTYPE (DYNSYM), + KNOWNSTYPE (INIT_ARRAY), + KNOWNSTYPE (FINI_ARRAY), + KNOWNSTYPE (PREINIT_ARRAY), + KNOWNSTYPE (GROUP), + KNOWNSTYPE (SYMTAB_SHNDX) + }; + + /* Handle standard names. */ + if ((size_t) section < sizeof (knowntypes) / sizeof (knowntypes[0]) + && knowntypes[section] != NULL) + res = knowntypes[section]; + /* The symbol versioning/Sun extensions. */ + else if (section >= SHT_LOSUNW && section <= SHT_HISUNW) + { + static const char *sunwtypes[] = + { +#undef KNOWNSTYPE +#define KNOWNSTYPE(name) [SHT_##name - SHT_LOSUNW] = #name + KNOWNSTYPE (SUNW_move), + KNOWNSTYPE (SUNW_COMDAT), + KNOWNSTYPE (SUNW_syminfo), + KNOWNSTYPE (GNU_verdef), + KNOWNSTYPE (GNU_verneed), + KNOWNSTYPE (GNU_versym) + }; + res = sunwtypes[section - SHT_LOSUNW]; + } + else + /* A few GNU additions. */ + switch (section) + { + case SHT_CHECKSUM: + res = "CHECKSUM"; + break; + case SHT_GNU_LIBLIST: + res = "GNU_LIBLIST"; + break; + case SHT_GNU_HASH: + res = "GNU_HASH"; + break; + case SHT_GNU_ATTRIBUTES: + res = "GNU_ATTRIBUTES"; + break; + + default: + /* Handle OS-specific section names. */ + if (section >= SHT_LOOS && section <= SHT_HIOS) + snprintf (buf, len, "SHT_LOOS+%x", section - SHT_LOOS); + /* Handle processor-specific section names. */ + else if (section >= SHT_LOPROC && section <= SHT_HIPROC) + snprintf (buf, len, "SHT_LOPROC+%x", section - SHT_LOPROC); + else if ((unsigned int) section >= SHT_LOUSER + && (unsigned int) section <= SHT_HIUSER) + snprintf (buf, len, "SHT_LOUSER+%x", section - SHT_LOUSER); + else + snprintf (buf, len, "%s: %d", _(""), section); + + res = buf; + break; + } + } + + return res; +} diff --git a/libebl/eblsegmenttypename.c b/libebl/eblsegmenttypename.c new file mode 100644 index 00000000..99779214 --- /dev/null +++ b/libebl/eblsegmenttypename.c @@ -0,0 +1,88 @@ +/* Return segment type name. + Copyright (C) 2001, 2002, 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_segment_type_name (Ebl *ebl, int segment, char *buf, size_t len) +{ + const char *res; + + res = ebl != NULL ? ebl->segment_type_name (segment, buf, len) : NULL; + if (res == NULL) + { + static const char *ptypes[PT_NUM] = + { +#define PTYPE(name) [PT_##name] = #name + PTYPE (NULL), + PTYPE (LOAD), + PTYPE (DYNAMIC), + PTYPE (INTERP), + PTYPE (NOTE), + PTYPE (SHLIB), + PTYPE (PHDR), + PTYPE (TLS) + }; + + /* Is it one of the standard segment types? */ + if (segment >= PT_NULL && segment < PT_NUM) + res = ptypes[segment]; + else if (segment == PT_GNU_EH_FRAME) + res = "GNU_EH_FRAME"; + else if (segment == PT_GNU_STACK) + res = "GNU_STACK"; + else if (segment == PT_GNU_RELRO) + res = "GNU_RELRO"; + else if (segment == PT_GNU_PROPERTY) + res = "GNU_PROPERTY"; + else if (segment == PT_SUNWBSS) + res = "SUNWBSS"; + else if (segment == PT_SUNWSTACK) + res = "SUNWSTACK"; + else + { + if (segment >= PT_LOOS && segment <= PT_HIOS) + snprintf (buf, len, "LOOS+%d", segment - PT_LOOS); + else if (segment >= PT_LOPROC && segment <= PT_HIPROC) + snprintf (buf, len, "LOPROC+%d", segment - PT_LOPROC); + else + snprintf (buf, len, "%s: %d", _(""), segment); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblstother.c b/libebl/eblstother.c new file mode 100644 index 00000000..273f6fc1 --- /dev/null +++ b/libebl/eblstother.c @@ -0,0 +1,41 @@ +/* Check st_other flag. + Copyright (C) 2011 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_check_st_other_bits (Ebl *ebl, unsigned char st_other) +{ + return ((st_other ^ GELF_ST_VISIBILITY (st_other)) == 0 + || ebl->check_st_other_bits (st_other ^ GELF_ST_VISIBILITY (st_other))); +} diff --git a/libebl/eblsymbolbindingname.c b/libebl/eblsymbolbindingname.c new file mode 100644 index 00000000..ebd8c2e3 --- /dev/null +++ b/libebl/eblsymbolbindingname.c @@ -0,0 +1,75 @@ +/* Return symbol binding name. + Copyright (C) 2001, 2002, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_symbol_binding_name (Ebl *ebl, int binding, char *buf, size_t len) +{ + const char *res; + + res = ebl != NULL ? ebl->symbol_type_name (binding, buf, len) : NULL; + if (res == NULL) + { + static const char *stb_names[STB_NUM] = + { + "LOCAL", "GLOBAL", "WEAK" + }; + + /* Standard binding? */ + if (binding < STB_NUM) + res = stb_names[binding]; + else + { + char *ident; + + if (binding >= STB_LOPROC && binding <= STB_HIPROC) + snprintf (buf, len, "LOPROC+%d", binding - STB_LOPROC); + else if (binding == STB_GNU_UNIQUE + && ebl != NULL + && (ident = elf_getident (ebl->elf, NULL)) != NULL + && ident[EI_OSABI] == ELFOSABI_LINUX) + return "GNU_UNIQUE"; + else if (binding >= STB_LOOS && binding <= STB_HIOS) + snprintf (buf, len, "LOOS+%d", binding - STB_LOOS); + else + snprintf (buf, len, _(": %d"), binding); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblsymboltypename.c b/libebl/eblsymboltypename.c new file mode 100644 index 00000000..0ff1722a --- /dev/null +++ b/libebl/eblsymboltypename.c @@ -0,0 +1,81 @@ +/* Return symbol type name. + Copyright (C) 2001, 2002, 2009 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + + +const char * +ebl_symbol_type_name (Ebl *ebl, int symbol, char *buf, size_t len) +{ + const char *res; + + res = ebl != NULL ? ebl->symbol_type_name (symbol, buf, len) : NULL; + if (res == NULL) + { + static const char *stt_names[STT_NUM] = + { + [STT_NOTYPE] = "NOTYPE", + [STT_OBJECT] = "OBJECT", + [STT_FUNC] = "FUNC", + [STT_SECTION] = "SECTION", + [STT_FILE] = "FILE", + [STT_COMMON] = "COMMON", + [STT_TLS] = "TLS" + }; + + /* Standard type? */ + if (symbol < STT_NUM) + res = stt_names[symbol]; + else + { + char *ident; + + if (symbol >= STT_LOPROC && symbol <= STT_HIPROC) + snprintf (buf, len, "LOPROC+%d", symbol - STT_LOPROC); + else if (symbol == STT_GNU_IFUNC + && ebl != NULL + && (ident = elf_getident (ebl->elf, NULL)) != NULL + && ident[EI_OSABI] == ELFOSABI_LINUX) + return "GNU_IFUNC"; + else if (symbol >= STT_LOOS && symbol <= STT_HIOS) + snprintf (buf, len, "LOOS+%d", symbol - STT_LOOS); + else + snprintf (buf, len, _(": %d"), symbol); + + res = buf; + } + } + + return res; +} diff --git a/libebl/eblsysvhashentrysize.c b/libebl/eblsysvhashentrysize.c new file mode 100644 index 00000000..20494313 --- /dev/null +++ b/libebl/eblsysvhashentrysize.c @@ -0,0 +1,41 @@ +/* Return OS ABI name + Copyright (C) 2006 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2006. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +int +ebl_sysvhash_entrysize (Ebl *ebl) +{ + return ebl->sysvhash_entrysize; +} diff --git a/libebl/eblunwind.c b/libebl/eblunwind.c new file mode 100644 index 00000000..2970d03e --- /dev/null +++ b/libebl/eblunwind.c @@ -0,0 +1,44 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +bool +ebl_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, ebl_pid_memory_read_t *readfunc, + void *arg, bool *signal_framep) +{ + /* ebl is declared NN */ + if (ebl->unwind == NULL) + return false; + return ebl->unwind (ebl, pc, setfunc, getfunc, readfunc, arg, signal_framep); +} diff --git a/libebl/libebl.h b/libebl/libebl.h new file mode 100644 index 00000000..731001d3 --- /dev/null +++ b/libebl/libebl.h @@ -0,0 +1,403 @@ +/* Interface for libebl. + Copyright (C) 2000-2010, 2013, 2014, 2015, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +/* This is the interface for the Elfutils Backend Library. + It is a completely UNSUPPORTED interface. Don't use any libebl + function directly. These are only for internal elfutils backends + and tools. There is NO source or binary compatible guarantee. */ + + +#ifndef _LIBEBL_H +#define _LIBEBL_H 1 + +#include +#include "libdw.h" +#include +#include +#include + +#include "elf-knowledge.h" + + +/* Opaque type for the handle. libasm.h defined the same thing. */ +#ifndef _LIBASM_H +typedef struct ebl Ebl; +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Get backend handle for object associated with ELF handle. */ +extern Ebl *ebl_openbackend (Elf *elf); +/* Similar but without underlying ELF file. */ +extern Ebl *ebl_openbackend_machine (GElf_Half machine); +/* Similar but with emulation name given. */ +extern Ebl *ebl_openbackend_emulation (const char *emulation); + +/* Free resources allocated for backend handle. */ +extern void ebl_closebackend (Ebl *bh); + + +/* Information about the descriptor. */ + +/* Get ELF machine. */ +extern int ebl_get_elfmachine (Ebl *ebl) __pure_attribute__; + +/* Get ELF class. */ +extern int ebl_get_elfclass (Ebl *ebl) __pure_attribute__; + +/* Get ELF data encoding. */ +extern int ebl_get_elfdata (Ebl *ebl) __pure_attribute__; + + +/* Function to call the callback functions including default ELF + handling. */ + +/* Return backend name. */ +extern const char *ebl_backend_name (Ebl *ebl); + +/* Return relocation type name. */ +extern const char *ebl_reloc_type_name (Ebl *ebl, int reloc, + char *buf, size_t len); + +/* Check relocation type. */ +extern bool ebl_reloc_type_check (Ebl *ebl, int reloc); + +/* Check relocation type use. */ +extern bool ebl_reloc_valid_use (Ebl *ebl, int reloc); + +/* Check if relocation type is for simple absolute relocations. + Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM. + If the relocation type is an ADD or SUB relocation, set *ADDSUB to 1 or -1, + resp. */ +extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc, int *addsub); + +/* Return true if the symbol type is that referencing the GOT. E.g., + R_386_GOTPC. */ +extern bool ebl_gotpc_reloc_check (Ebl *ebl, int reloc); + +/* Return segment type name. */ +extern const char *ebl_segment_type_name (Ebl *ebl, int segment, + char *buf, size_t len); + +/* Return section type name. */ +extern const char *ebl_section_type_name (Ebl *ebl, int section, + char *buf, size_t len); + +/* Return section name. */ +extern const char *ebl_section_name (Ebl *ebl, int section, int xsection, + char *buf, size_t len, + const char *scnnames[], size_t shnum); + +/* Return machine flag names. */ +extern const char *ebl_machine_flag_name (Ebl *ebl, GElf_Word flags, + char *buf, size_t len); + +/* Check whether machine flag is valid. */ +extern bool ebl_machine_flag_check (Ebl *ebl, GElf_Word flags); + +/* Check whether SHF_MASKPROC flags are valid. */ +extern bool ebl_machine_section_flag_check (Ebl *ebl, GElf_Xword flags); + +/* Check whether the section with the given index, header, and name + is a special machine section that is valid despite a combination + of flags or other details that are not generically valid. */ +extern bool ebl_check_special_section (Ebl *ebl, int ndx, + const GElf_Shdr *shdr, const char *name); + +/* Return symbol type name. */ +extern const char *ebl_symbol_type_name (Ebl *ebl, int symbol, + char *buf, size_t len); + +/* Return symbol binding name. */ +extern const char *ebl_symbol_binding_name (Ebl *ebl, int binding, + char *buf, size_t len); + +/* Return dynamic tag name. */ +extern const char *ebl_dynamic_tag_name (Ebl *ebl, int64_t tag, + char *buf, size_t len); + +/* Check dynamic tag. */ +extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag); + +/* Check whether given symbol's st_value and st_size are OK despite failing + normal checks. */ +extern bool ebl_check_special_symbol (Ebl *ebl, + const GElf_Sym *sym, const char *name, + const GElf_Shdr *destshdr); + +/* Check if this is a data marker symbol. e.g. '$d' symbols for ARM. */ +extern bool ebl_data_marker_symbol (Ebl *ebl, const GElf_Sym *sym, + const char *sname); + +/* Check whether only valid bits are set on the st_other symbol flag. */ +extern bool ebl_check_st_other_bits (Ebl *ebl, unsigned char st_other); + +/* Return symbolic representation of OS ABI. */ +extern const char *ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len); + + +/* Return name of the note section type for a core file. */ +extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf, + size_t len); + +/* Return name of the note section type for an object file. */ +extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name, + uint32_t type, GElf_Word descsz, + char *buf, size_t len); + +/* Print information about object note if available. */ +extern void ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, + uint32_t type, uint32_t descsz, const char *desc); + +/* Check whether an attribute in a .gnu_attributes section is recognized. + Fills in *TAG_NAME with the name for this tag. + If VALUE is a known value for that tag, also fills in *VALUE_NAME. */ +extern bool ebl_check_object_attribute (Ebl *ebl, const char *vendor, + int tag, uint64_t value, + const char **tag_name, + const char **value_name); + +/* Check whether a section type is a valid reloc target. */ +extern bool ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type); + + +/* Check section name for being that of a debug informatino section. */ +extern bool ebl_debugscn_p (Ebl *ebl, const char *name); + +/* Check whether given relocation is a copy relocation. */ +extern bool ebl_copy_reloc_p (Ebl *ebl, int reloc); + +/* Check whether given relocation is a no-op relocation. */ +extern bool ebl_none_reloc_p (Ebl *ebl, int reloc); + +/* Check whether given relocation is a relative relocation. */ +extern bool ebl_relative_reloc_p (Ebl *ebl, int reloc); + +/* Check whether section should be stripped. */ +extern bool ebl_section_strip_p (Ebl *ebl, + const GElf_Shdr *shdr, const char *name, + bool remove_comment, bool only_remove_debug); + +/* Check if backend uses a bss PLT in this file. */ +extern bool ebl_bss_plt_p (Ebl *ebl); + +/* Return size of entry in SysV-style hash table. */ +extern int ebl_sysvhash_entrysize (Ebl *ebl); + +/* Return location expression to find return value given a + DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing + function itself (whose DW_AT_type attribute describes its return type). + Returns -1 for a libdw error (see dwarf_errno). + Returns -2 for an unrecognized type formation. + Returns zero if the function has no return value (e.g. "void" in C). + Otherwise, *LOCOPS gets a location expression to find the return value, + and returns the number of operations in the expression. The pointer is + permanently allocated at least as long as the Ebl handle is open. */ +extern int ebl_return_value_location (Ebl *ebl, + Dwarf_Die *functypedie, + const Dwarf_Op **locops); + +/* Fill in register information given DWARF register numbers. + If NAME is null, return the maximum REGNO + 1 that has a name. + Otherwise, store in NAME the name for DWARF register number REGNO + and return the number of bytes written (including '\0' terminator). + Return -1 if NAMELEN is too short or REGNO is negative or too large. + Return 0 if REGNO is unused (a gap in the DWARF number assignment). + On success, set *SETNAME to a description like "integer" or "FPU" + fit for "%s registers" title display, and *PREFIX to the string + that precedes NAME in canonical assembler syntax (e.g. "%" or "$"). + The NAME string contains identifier characters only (maybe just digits). */ +extern ssize_t ebl_register_info (Ebl *ebl, + int regno, char *name, size_t namelen, + const char **prefix, const char **setname, + int *bits, int *type); + +/* Supply the ABI-specified state of DWARF CFI before CIE initial programs. + + The DWARF 3.0 spec says that the default initial states of all registers + are "undefined", unless otherwise specified by the machine/compiler ABI. + + This default is wrong for every machine with the CFI generated by GCC. + The EH unwinder does not really distinguish "same_value" and "undefined", + since it doesn't matter for unwinding (in either case there is no change + to make for that register). GCC generates CFI that says nothing at all + about registers it hasn't spilled somewhere. For our unwinder to give + the true story, the backend must supply an initial state that uses + "same_value" rules for all the callee-saves registers. + + This can fill in the initial_instructions, initial_instructions_end + members of *ABI_INFO to point at a CFI instruction stream to process + before each CIE's initial instructions. It should set the + data_alignment_factor member if it affects the initial instructions. + + The callback should not use the register rules DW_CFA_expression or + DW_CFA_val_expression. Defining the CFA using DW_CFA_def_cfa_expression + is allowed. This is an implementation detail since register rules + store expressions as offsets from the .eh_frame or .debug_frame data. + + As a shorthand for some common cases, for this instruction stream + we overload some CFI instructions that cannot be used in a CIE: + + DW_CFA_restore -- Change default rule for all unmentioned + registers from undefined to same_value. + + This function can also fill in ABI_INFO->return_address_register with the + DWARF register number that identifies the actual PC in machine state. + If there is no canonical DWARF register number with that meaning, it's + left unchanged (callers usually initialize with (Dwarf_Word) -1). + This value is not used by CFI per se. + + Function returns 0 on success and -1 for error or unsupported by the + backend. */ +extern int ebl_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info) + __nonnull_attribute__ (2); + +/* Register map info. */ +typedef struct +{ + Dwarf_Half offset; /* Byte offset in register data block. */ + Dwarf_Half regno; /* DWARF register number. */ + uint8_t bits; /* Bits of data for one register. */ + uint8_t pad; /* Bytes of padding after register's data. */ + Dwarf_Half count; /* Consecutive register numbers here. */ + bool pc_register; +} Ebl_Register_Location; + +/* Non-register data items in core notes. */ +typedef struct +{ + const char *name; /* Printable identifier. */ + const char *group; /* Identifier for category of related items. */ + Dwarf_Half offset; /* Byte offset in note data. */ + Dwarf_Half count; + Elf_Type type; + char format; + bool thread_identifier; + bool pc_register; +} Ebl_Core_Item; + +/* Describe the format of a core file note with the given header and NAME. + NAME is not guaranteed terminated, it's NHDR->n_namesz raw bytes. */ +extern int ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, + const char *name, const char *desc, + GElf_Word *regs_offset, size_t *nregloc, + const Ebl_Register_Location **reglocs, + size_t *nitems, const Ebl_Core_Item **items) + __nonnull_attribute__ (1, 2, 3, 4, 5, 6, 7, 8); + +/* Describe the auxv type number. */ +extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type, + const char **name, const char **format) + __nonnull_attribute__ (1, 3, 4); + +/* Callback type for ebl_set_initial_registers_tid. + Register -1 is mapped to PC (if arch PC has no DWARF number). + If FIRSTREG is -1 then NREGS has to be 1. */ +typedef bool (ebl_tid_registers_t) (int firstreg, unsigned nregs, + const Dwarf_Word *regs, void *arg) + __nonnull_attribute__ (3); + +/* Callback to fetch process data from live TID. + EBL architecture has to have EBL_FRAME_NREGS > 0, otherwise the + backend doesn't support unwinding and this function call may crash. */ +extern bool ebl_set_initial_registers_tid (Ebl *ebl, + pid_t tid, + ebl_tid_registers_t *setfunc, + void *arg) + __nonnull_attribute__ (1, 3); + +/* Number of registers to allocate for ebl_set_initial_registers_tid. + EBL architecture can unwind iff EBL_FRAME_NREGS > 0. */ +extern size_t ebl_frame_nregs (Ebl *ebl) + __nonnull_attribute__ (1); + +/* Offset to apply to the value of the return_address_register, as + fetched from a Dwarf CFI. This is used by some backends, where the + return_address_register actually contains the call address. */ +extern int ebl_ra_offset (Ebl *ebl) + __nonnull_attribute__ (1); + +/* Mask to use for function symbol or unwind return addresses in case + the architecture adds some extra non-address bits to it. This is + different from ebl_resolve_sym_value which only works for actual + symbol addresses (in non-ET_REL files) that might resolve to an + address in a different section. ebl_func_addr_mask is called to + turn a given function value into the a real address or offset (the + original value might not be a real address). This works for all + cases where an actual function address (or offset in ET_REL symbol + tables) is needed. */ +extern GElf_Addr ebl_func_addr_mask (Ebl *ebl); + +/* Convert *REGNO as is in DWARF to a lower range suitable for + Dwarf_Frame->REGS indexing. */ +extern bool ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno) + __nonnull_attribute__ (1, 2); + +/* Modify PC as fetched from inferior data into valid PC. */ +extern void ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc) + __nonnull_attribute__ (1, 2); + +/* Callback type for ebl_unwind's parameter getfunc. */ +typedef bool (ebl_tid_registers_get_t) (int firstreg, unsigned nregs, + Dwarf_Word *regs, void *arg) + __nonnull_attribute__ (3); + +/* Callback type for ebl_unwind's parameter readfunc. */ +typedef bool (ebl_pid_memory_read_t) (Dwarf_Addr addr, Dwarf_Word *data, + void *arg) + __nonnull_attribute__ (3); + +/* Get previous frame state for an existing frame state. Method is called only + if unwinder could not find CFI for current PC. PC is for the + existing frame. SETFUNC sets register in the previous frame. GETFUNC gets + register from the existing frame. Note that GETFUNC vs. SETFUNC act on + a disjunct set of registers. READFUNC reads memory. ARG has to be passed + for SETFUNC, GETFUNC and READFUNC. *SIGNAL_FRAMEP is initialized to false, + it can be set to true if existing frame is a signal frame. SIGNAL_FRAMEP is + never NULL. */ +extern bool ebl_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep) + __nonnull_attribute__ (1, 3, 4, 5, 7); + +/* Returns true if the value can be resolved to an address in an + allocated section, which will be returned in *ADDR + (e.g. function descriptor resolving) */ +extern bool ebl_resolve_sym_value (Ebl *ebl, GElf_Addr *addr) + __nonnull_attribute__ (2); + +#ifdef __cplusplus +} +#endif + +#endif /* libebl.h */ diff --git a/libebl/libeblP.h b/libebl/libeblP.h new file mode 100644 index 00000000..fa1c2c9f --- /dev/null +++ b/libebl/libeblP.h @@ -0,0 +1,94 @@ +/* Internal definitions for interface for libebl. + Copyright (C) 2000-2009, 2013, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBEBLP_H +#define _LIBEBLP_H 1 + +#include +#include +#include +#include + + +/* Backend handle. */ +struct ebl +{ + /* Emulation name. */ + const char *emulation; + + /* ELF machine, class, and data encoding. */ + uint_fast16_t machine; + uint_fast8_t class; + uint_fast8_t data; + + /* The libelf handle (if known). */ + Elf *elf; + + /* See ebl-hooks.h for the declarations of the hook functions. */ +# define EBLHOOK(name) (*name) +# include "ebl-hooks.h" +# undef EBLHOOK + + /* Size of entry in Sysv-style hash table. */ + int sysvhash_entrysize; + + /* Number of registers to allocate for ebl_set_initial_registers_tid. + Ebl architecture can unwind iff FRAME_NREGS > 0. */ + size_t frame_nregs; + + /* Offset to apply to the value of the return_address_register, as + fetched from a Dwarf CFI. This is used by some backends, where + the return_address_register actually contains the call + address. */ + int ra_offset; + + /* Mask to use to turn a function value into a real function address + in case the architecture adds some extra non-address bits to it. + If not initialized (0) then ebl_func_addr_mask will return ~0, + otherwise it should be the actual mask to use. */ + GElf_Addr func_addr_mask; + + /* Function descriptor load address and table as used by + ebl_resolve_sym_value if available for this arch. */ + GElf_Addr fd_addr; + Elf_Data *fd_data; +}; + + +/* Type of the initialization functions in the backend modules. + The init function returns the given Ebl * or NULL if it couldn't + initialize for the given Elf or machine. */ +typedef Ebl *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *); + + +/* LEB128 constant helper macros. */ +#define ULEB128_7(x) (BUILD_BUG_ON_ZERO ((x) >= (1U << 7)) + (x)) + +#define BUILD_BUG_ON_ZERO(x) (sizeof (char [(x) ? -1 : 1]) - 1) + +#endif /* libeblP.h */ diff --git a/libelf/ChangeLog b/libelf/ChangeLog new file mode 100644 index 00000000..a1fd414c --- /dev/null +++ b/libelf/ChangeLog @@ -0,0 +1,1880 @@ +2020-12-12 Mark Wielaard + + * elf.h: Update from glibc. + +2020-12-16 Dmitry V. Levin + + * libelfP.h (_): Remove. + +2020-12-15 Mark Wielaard + + * elf_begin.c (get_shnum): Make sure the full Ehdr is available. + +2020-12-12 Dmitry V. Levin + + * common.h: Fix spelling typo in comment. + * gelf.h: Likewise. + * libelf.h: Likewise. + * libelfP.h: Likewise. + * elf32_checksum.c (elfw2): Likewise. + * elf_begin.c (dup_elf, write_file): Likewise. + * elf_compress.c (__libelf_compress): Likewise. + * elf_compress_gnu.c (elf_compress_gnu): Likewise. + +2020-12-11 Dmitry V. Levin + + * Makefile.am (GCC_INCLUDE): Remove. + +2020-12-09 Dmitry V. Levin + + * Makefile.am (noinst_PROGRAMS): Rename to noinst_DATA. + (libelf_so_SOURCES): Remove. + (CLEANFILES): Add libelf.so. + +2020-11-30 Dmitry V. Levin + + * Makefile.am (libelf.so$(EXEEXT)): Drop $(EXEEXT) suffix. + +2020-11-06 Mark Wielaard + + * elf-knowledge.h (SH_ENTSIZE_HASH): Update comment. + +2020-11-01 Mark Wielaard + + * elf_strptr.c (elf_strptr): Check shdr is not NULL. + +2020-11-01 Mark Wielaard + + * elf_getphdrnum.c (__elf_getphdrnum_rdlock): Set *dst to zero on + error. + +2020-11-01 Mark Wielaard + + * libelfP.h (__libelf_data_type): Take an GElf_Ehdr instead of an + Elf handle. + * elf_getdata.c (__libelf_data_type): Likewise. And check ehdr + directly instead of fetching a new one. + (__libelf_set_rawdata_wrlock): Fetch Ehdr, report an error when that + fails, otherwise call __libelf_data_type. + +2020-10-28 Mark Wielaard + + * elf.h: Update from glibc. + +2020-08-28 Mark Wielaard + + * elf.h: Update from glibc. + +2020-08-19 Mark Wielaard + + * elf32_updatenull.c (updatenull_wrlock): Fixup the sh_addralign + of an SHF_COMPRESSED section if necessary. + +2020-06-04 Mark Wielaard + + * elf.h: Update from glibc. + +2020-05-08 Mark Wielaard + + * elf_strptr.c (elf_strptr): Check shdr is not NULL. + +2020-05-08 Mark Wielaard + + * elf_getdata.c (__libelf_set_rawdata_wrlock): Check + __gelf_getehdr_rdlock return value. + +2020-04-25 Mark Wielaard + + * elf_compress.c (__libelf_compress): Remove free (out_buf). + +2020-03-18 Omar Sandoval + + * elf_getphdrnum.c (__elf_getphdrnum_rdlock): Call + __elf{32,64}_getshdr_rdlock if the shdr is not cached. + +2019-03-20 Matthias Maennich + + * elf_compress.c (__libelf_compress): Always call deflate_cleanup + in failure path. Call deflateEnd only once. + (__libelf_decompress): Call inflateEnd only once. + +2019-06-18 Mark Wielaard + + * common.h (allocate_elf): Use int64_t instead of off_t for offset. + * elf32_newphdr.c (newphdr): Document why Elf32/64_Word is correct. + * elf32_updatefile.c (fill): Use int64_t instead of off_t for pos. + (updatefile): Define last_offset, shdr_offset and scn_start as + int64_t instead of off_t. + * elf32_updatenull.c: Define Elf32_SizeWord and Elf64_SizeWord. + (updatenull_wrlock): Return int64_t instead of off_t. Define size, + sh_entsize, sh_align and sh_size as SizeWords. Define offset as + int64_t. Cast data->d_off to SizeWord instead of GElf_Word. Drop + size GElf_Word cast. Cast offset to SizeWord instead of GElf_Word + when comparing with sh_size. + * elf_begin.c (get_shnum): Define offset as int64_t instead of + off_t. Document why use GElf_Word is correct. + (file_read_elf): Define offset as int64_t instead of off_t. + (__libelf_read_mmaped_file): Likewise. + (read_unmmaped_file): Likewise. + (read_file): Likewise. + * elf_getaroff.c (elf_getaroff): Return int64_t. + * elf_getbase.c (elf_getbase): Likewise. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Define offset as + int64_t instead of off_t. + * elf_update.c (write_file): Return int64_t instead of off_t, + define size as int64_t instead of off_t. + (elf_update): Likewise. + * libelfP.h (struct Elf): Define start_offset, sizestr_offset and + offset as int64_t. + (__libelf_read_mmaped_file): Define offset as int64_t. + (__elf32_updatenull_wrlock): Return int64_t. + (__elf64_updatenull_wrlock): Return int64_t. + +2019-05-12 Mark Wielaard + + * elf32_updatenull.c (updatenull_wrlock): Mark shdr_flags dirty if + either offset or size changed. + +2019-05-01 Mark Wielaard + + * gelf_getnote.c (gelf_getnote): Check n_namesz doesn't overflow + offset. + +2019-04-30 Mark Wielaard + + * note_xlate.h (elf_cvt_note): Indicate we only translated the note + header if we ran out of data by updating len, src and dest. + +2019-04-01 Mao Han + + * elf.h: Update from glibc. + +2019-03-07 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Use posix_memalign instead of + aligned_alloc. + +2019-03-06 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Free scns before returning + allocation failure. + +2019-02-24 Mark Wielaard + + * gelf_xlate.c (__elf_xfctstof): Remove alias. + * libelfP.h (__elf_xfctstof): Remove definition. + +2019-02-24 Mark Wielaard + + * elf32_fsize.c (local_strong_alias): Remove definition. + (msize): Remove alias. + * libelfP.h (__elf32_msize): Remove definition. + (__elf64_msize): Likewise. + +2019-02-21 Mark Wielaard + + * common.h (determine_kind): Only accept EV_CURRENT. + * elf32_fsize.c (fsize): Just check version is EV_CURRENT. + Use __libelf_type_size without version dimension. + * elf32_updatefile.c (updatemmap): Define fctp from __elf_xfctstom + without version dimension. + (updatefile): Likewise. + * elf32_updatenull.c (default_ehdr): Check e_version is EV_CURRENT. + (updatenull_wrlock): Check d_version is EV_CURRENT. + (elf32_xlatetof): Likewise. And get recsize without version + dimension from __elf_xfctstom. + (elf32_xlatetom): Likewise. + * elf_begin.c (elf_begin): Check __libelf_version is EV_CURRENT. + * elf_compress.c (__libelf_reset_rawdata): Set d_version to + EV_CURRENT. + * elf_getdata.c (shtype_map): Remove version dimension. + (__libelf_type_aligns): Likewise. + (__libelf_data_type): Use shtype_map without version dimension. + (convert_data): Remove unused version argument. Get fp from + __elf_xfctstom without version dimensions. + (__libelf_set_data_list_rdlock): Call convert_data without version. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Call __elfcfctstom + conversion function without version dimensions. Set d_version to + EV_CURRENT. + * elf_newdata.c (elf_newdata): Set d_version to EV_CURRENT. + * elf_version.c (__libelf_version_initialized): Removed. + (__libelf_version): Initialized to EV_NONE. + (elf_version): Always return EV_CURRENT for EV_NONE version. + Only accept (and return) EV_CURRENT as version. + * gelf_fsize.c (__libelf_type_sizes): Remove version dimension. + (gelf_fsize): Only accept EV_CURRENT as version. + Use __libelf_type_sizes without version dimension. + * gelf_xlate.c (__elf_xftstom): Remove version dimensions. + * libelfP.h (__elf_xfctstom): Defined without version dimensions. + (__elf_xfctstof): Likewise. + (__libelf_type_sizes): Define without version dimension. + (elf_typesize): Define using __libelf_type_sizes without version + dimension. + (__libelf_version_initialized): Remove definition. + (__libelf_version): Add definition. + (LIBELF_EV_IDX): Removed define. + (__libelf_type_aligns): Remove version dimension. + * nlist.c (nlist): Call elf_version unconditionally. + +2019-02-19 Mark Wielaard + + * elf_compress.c (do_deflate_cleanup): Remove ei_data argument, + check cdatap is not NULL before calling free. + (deflate_cleanup): Add cdata as argument. + (__libelf_compress): Also check whether the d_size is not zero + before converting data. Call deflate_cleanup with an extra + argument depending on whether there is converted data to free. + Always allocate allocate at least one byte for buf_out. + +2019-02-14 Mark Wielaard + + * elf_begin.c (read_long_names): Make sure ar_size is properly + terminated. Sanity check len early if we can. + +2019-01-18 Mark Wielaard + + * Makefile.am (INSTALL_ELFH): Add elf.h to include_HEADERS when + defined, otherwise (the default) add elf.h to noinst_HEADERS. + +2019-01-16 Mark Wielaard + + * note_xlate.h (elf_cvt_note): Check n_namesz and n_descsz don't + overflow note_len into note header. + +2018-11-17 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Make sure to call convert + function on a properly aligned destination. + +2018-11-16 Mark Wielaard + + * libebl.h (__elf32_msize): Mark with const attribute. + (__elf64_msize): Likewise. + +2018-11-13 Mark Wielaard + + * elf_getdata.c (__libelf_set_rawdata_wrlock): Explicitly set the + alignment of SHF_COMPRESSED data to the alignment of ELF_T_CHDR. + * elf_compress.c (elf_compress): After compression set sh_addralign + to the alignment of ELF_T_CHDR. + +2018-11-09 Mark Wielaard + + * elf_compress_gnu.c (elf_compress_gnu): Use elf_getdata. + +2018-11-12 Mark Wielaard + + * elf-knowledge.c (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX): New define. + (NT_GNU_BUILD_ATTRIBUTE_{OPEN,FUNC}): Likewise. + (GNU_BUILD_ATTRIBUTE_TYPE_{NUMERIC,STRING,BOOL_TRUE,BOOL_FALSE}): + Likewise. + (GNU_BUILD_ATTRIBUTE_{VERSION,STACK_PROT,RELRO,STACK_SIZE,TOOL,ABI, + PIC,SHORT_ENUM}): Likewise. + +2018-11-09 Mark Wielaard + + * elf_compress.c (__libelf_reset_rawdata): Make rawdata change + explicit by calling __libelf_set_data_list. + * elf_getdata.c (convert_data): Don't convert if type is ELF_T_BYTE + even if endianness is different. + +2018-10-18 Mark Wielaard + + * libelf.h (Elf_Type): Add ELF_T_NHDR8. + * libelfP.h (__libelf_data_type): Add align argument. + (NOTE_ALIGN): Split into... + (NOTE_ALIGN4): ... and ... + (NOTE_ALIGN8): this. + * elf32_xlatetom.c (xlatetom): Recognize both ELF_T_NHDR and + ELF_T_NHDR8. + * elf_compress.c (elf_compress): Pass zdata_align to + __libelf_data_type. + * elf_compress_gnu.c (elf_compress_gnu): Pass sh_addralign to + __libelf_data_type. + * elf_getdata.c (shtype_map): Add ELF_T_NHDR8. + (__libelf_data_type): Take align as extra argument, use it to + determine Elf_Type. + (__libelf_set_rawdata_wrlock): Recognize ELF_T_NHDR8. Pass align to + __libelf_data_type. + * gelf_fsize.c (__libelf_type_sizes): Add ELF_T_NHDR8. + * gelf_getnote.c (gelf_getnote): Use Elf_Type of Elf_Data to calculate + padding. + * gelf_xlate.c (__elf_xfctstom): Set ELF_T_NHDR to elf_cvt_note4, + add ELF_T_NHDR8. + * note_xlate.h (elf_cvt_note): Take nhdr8 argument and use it to + determine padding. + (elf_cvt_note4): New function. + (elf_cvt_note8): Likewise. + +2018-09-13 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Use shnum, not ehdr->e_shnum. + * elf_getscn.c (elf_getscn): Create section zero if it is requested, + but doesn't exist yet. + +2018-09-12 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Use memmove, not memcpy. + * elf_update.c (write_file): Try to mremap if file needs to be + extended. + +2018-08-18 Mark Wielaard + + * libelf.h (elf_compress_gnu): Add documentation about + interaction between SHF_COMPRESED and elf_compress_gnu. + * elf_compress_gnu.c (elf_compress_gnu): Return error if section + sh_flags has SHF_COMPRESSED set. + +2018-07-27 Mark Wielaard + + * libelf.h (elf_getshdrstrndx): Fix documentation. + (elf_getshstrndx): Likewise. + +2018-06-19 Mark Wielaard + + * libelfP.h (__libelf_type_align): Remove !ALLOW_UNALIGNED guard. + * elf_getdata.c (__libelf_type_aligns): Likewise. + (convert_data): Remove ALLOW_UNALIGNED check. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Likewise. + +2018-06-21 Mark Wielaard + + * elf.h: Update from glibc. + +2018-04-19 Andreas Schwab + + * elf.h: Update from glibc. + +2018-02-16 Mark Wielaard + + * elf.h: Update from glibc. + +2018-02-09 Joshua Watt + + * elf32_updatenull.c (updatenull_wrlock): Use FALLTHROUGH macro + instead of comment. + * elf_begin.c (read_unmmaped_file): Likewise. + (elf_begin): Likewise. + * elf_cntl.c (elf_cntl): Likewise. + +2017-10-04 Mark Wielaard + + * elf_begin.c (file_read_elf): Skip sanity checking e_shoff if scncnt + is zero, we won't use it then. + +2017-10-04 Mark Wielaard + + * libelfP.h: Add ELF_E_INVALID_ELF to error values enum. + * elf_error.c (ELF_E_INVALID_ELF_IDX): New define. Use it as value + for ELF_E_INVALID_ELF in msgidx. + * elf_getshdrstrndx.c (elf_getshdrstrndx): Distinquish between pread + failing and not having enough data. + * elf_begin.c (get_shnum): Likewise. Explicitly set libelf errno on + too large value. + (file_read_elf): Make sure to always set libelf errno when returning + NULL. Distinquish between i/o file and elf data errors. + +2017-08-18 Ulf Hermann + + * gelf_xlate.c: Use attribute_packed. + +2017-04-27 Ulf Hermann + + * libelfP.h: Use attribute_hidden. + +2017-04-27 Ulf Hermann + + * Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS. + +2017-08-15 Mark Wielaard + + * elf.h: Update from glibc. Add new powerpc note descriptors. + +2017-07-19 Gustavo Romero + + * elf.h: Add known type in notes segment descriptor for HTM SPRs. + +2017-02-17 Ulf hermann + + * Makefile.am: Add libelf_so_DEPS, which include libeu.a, + libelf_so_LIBS. + (libelf_so_LDLIBS): Add $(libelf_so_DEPS). + (libelf.so$(EXEEXT): Use $(libelf_so_LIBS), require libelf.map + from the right directory. + +2017-04-20 Ulf Hermann + + * libelfP.h: Don't include config.h. + +2017-04-20 Ulf Hermann + + * elf_begin.c: Use F_GETFD rather than F_GETFL. + +2017-04-20 Ulf Hermann + + * libelf.h: Define macros for various function attributes and use + them. + +2017-04-20 Ulf Hermann + + * elf_update.c: Set ELF_F_MMAPPED flag if we mmap from elf_update. + +2017-04-19 Mark Wielaard + + * elf_getarsym.c (elf_getarsym): Initialize n to zero. + +2017-03-27 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Always update last_positition. + (updatefile): Likewise. + +2017-03-24 Mark Wielaard + + * elf_compress.c (__libelf_decompress): Check insane compression + ratios before trying to allocate output buffer. + +2016-10-11 Akihiko Odaki + Mark Wielaard + + * gelf.h (gelf_newehdr): Change return type to void *. + (gelf_newphdr): Likewise. + * gelf_newehdr.c (gelf_newehdr): Likewise. + * gelf_newphdr.c (gelf_newphdr): Likewise. + +2016-10-21 Mark Wielaard + + * elf_getdata.c (__libelf_set_rawdata_wrlock): Sanity check + offset and size before trying to malloc and read data. + +2016-10-26 Mark Wielaard + + * elf_begin.c (read_file): Always set maxsize when parent == NULL. + +2016-10-11 Akihiko Odaki + + * elf_getarsym.c (elf_getarsym): Open code rawmemchr when not + available. + * elf_strptr.c: Include stdbool.h. + (validate_str): New function. + (elf_strptr): Use validate_str instead of memrchr. + +2016-10-11 Akihiko Odaki + + * elf32_updatefile.c: Remove sys/param.h include. + * elf32_updatenull.c: Likewise. Add system.h include. + * elf_begin.c: Remove sys/param.h. + * elf_compress: Likewise. Add system.h include. + (MAX): Remove definition. + +2016-08-07 Mark Wielaard + + * elf_compress.c (__libelf_reset_rawdata): Check scn->flags and + free rawdata_base when malloced. Set ELF_F_MALLOCED for scn->flags. + * elf_end.c (elf_end): Check scn->flags and free rawdata_base if + malloced. + * libelfP.h (struct Elf_Scn): Document flags ELF_F_MALLOCED usage. + +2016-07-06 Mark Wielaard + + * elf-knowledge.h (SH_FLAGS_COMBINE): Removed. + (SH_FLAGS_IMPORTANT): Likewise. + +2016-07-06 Mark Wielaard + + * elf32_updatenull.c (updatenull_wrlock): Ignore e_type when + updating phdrs. + * elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): Only do sanity + checking if phdrs haven't been read in yet. + +2016-06-24 John Ogness + + * elf32_updatenull.c (updatenull_wrlock): Find first section. + * elf_nextscn.c (elf_nextscn): When scn is NULL start from 0th + section. + +2016-06-28 Richard Henderson + + * elf.h: Update from glibc. Add lots of new EM_* definitions. + +2016-04-14 Mark Wielaard + + * elf_compress.c (__libelf_compress): Free out_buf if deflateInit + fails. + +2016-02-13 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Free scns when out of memory. + +2016-01-28 Mark Wielaard + + * elf.h: Update from glibc. Add new i386 and x86_64 relocations. + +2016-02-12 Mark Wielaard + + * elf.h: Update from glibc. Add NT_ARM_SYSTEM_CALL. + +2016-02-04 Mark Wielaard + + * elf_getdata.c (__libelf_set_rawdata_wrlock): Don't adjust align + for SHT_NOBITS sections. + +2016-01-22 Chih-Hung Hsieh + + * elf_compress.c (__libelf_compress): Move nested function + 'do_deflate_cleanup' to file scope to compile with clang. + * elf_strptr.c (elf_strptr): Move nested function 'get_zdata' + to file scope to compile with clang. + +2016-01-13 Mark Wielaard + + * libelf.h: Check SHF_COMPRESSED is defined. If not define it and the + associated ELF compression types/defines. + +2015-11-26 Mark Wielaard + + * elf_compress.c (__libelf_decompress_elf): New function, extracted + from... + (elf_compress): here. Check zdata_base use __libelf_decompress_elf. + * elf_strptr.c (elf_strptr): If SHF_COMPRESSED check, uncompress and + use zdata. + * libelfP.h (struct Elf_Scn): Add zdata_size and zdata_align. + (__libelf_decompress_elf): New internal function definition. + +2015-10-21 Mark Wielaard + + * Makefile.am (libelf_a_SOURCES): Add elf_compress.c and + elf_compress_gnu.c. + * elf_compress.c: New file. + * elf_compress_gnu.c: Likewise. + * elf_begin.c (file_read_elf): Make a writable copy of the shdrs + for ELF_C_READ_MMAP. + * elf_end.c (elf_end): Free zdata_base. + * elf_error.c: Add ELF_E_ALREADY_COMPRESSED, + ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and + ELF_E_DECOMPRESS_ERROR. + * elf_data.c (__libelf_data_type): New internal function extracted + from convert_data. + (convert_data): Handle SHF_COMPRESSED. + * elf32_updatenull.c (updatenull_wrlock): Check sh_entsize against + uncompressed section data size if SHF_COMPRESSED. + * elf32_getshdr.c (load_shdr_wrlock): Adjust assert to account for + ELF_C_READ_MMAP. + * libelf.h: Define elf_compress and elf_compress_gnu. + * libelf.map (ELFUTILS_1.7): Add elf_compress and elf_compress_gnu. + * libelfP.h: Add ELF_E_ALREADY_COMPRESSED, + ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and + ELF_E_DECOMPRESS_ERROR. Define __libelf_data_type. + (__libelf_compress): New internal function definition. + (__libelf_decompress): Likewise. + (__libelf_reset_rawdata): Likewise. + (__libelf_data_type): Likewise. + (struct Elf_Scn): Add zdata_base. + +2015-11-19 Mark Wielaard + + * Makefile.am (libelf_a_SOURCES): Add elf32_getchdr.c, + elf64_getchdr.c and gelf_getchdr.c. + (noinst_HEADERS): Add chdr_xlate.h. + * abstract.h: Define Chdr32 and Chdr64. + * chdr_xlate.h: New file. + * elf32_getchdr.c: New file. + * elf64_getchdr.c: New file. + * elf_error.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE + and ELF_E_INVALID_SECTION_FLAGS. + * elf_getdata.c (__libelf_set_rawdata_wrlock): Set d_type to + ELF_T_CHDR for SHF_COMPRESSED sections. + * exttypes.h: Add Chdr32 and Chdr64. + * gelf.h (GElf_Chdr): New typedef. + (gelf_getchdr): New function definition. + * gelf_fsize.c (__libelf_type_sizes): Add ELF_T_CHDR. + * gelf_getchdr.c: New file. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_CHDR cvt_chdr. + * gelf_xlate.h: Add Chdr. + * libelf.h (Elf_Type): Add ELF_T_CHDR. + (elf32_getchdr): New function definition. + (elf64_getchdr): Likewise. + * libelf.map (ELFUTILS_1.7): New sections add elf32_getchdr, + elf64_getchdr and gelf_getchdr. + * libelfP.h: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE + and ELF_E_INVALID_SECTION_FLAGS. + +2015-10-16 Mark Wielaard + + * Makefile.am (libelf_so_LDLIBS): Add -lz. + +2015-10-14 Mark Wielaard + + * elf.h: Update from glibc. Add section compression constants and + structures. + +2015-10-20 Jose E. Marchesi + + * elf_begin.c (get_shnum): Elf64_Shdr.sh_size is an Elf64_Xword. + Fix the size argument to pread_retry. + +2015-10-13 Chih-Hung Hsieh + + * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Move nested + function 'fill_mmap' to file scope. + * elf_begin.c (elf_begin): Move nested function 'lock_dup_elf' + to file scope. + +2015-10-09 Josh Stone + + * libelf.h: Replace loff_t with int64_t throughout. + +2015-10-05 Mark Wielaard + + * elf_update.c (write_file): Only use posix_fallocate when using + mmap. Only report failure when errno is ENOSPC. + +2015-10-09 Josh Stone + + * libelfP.h (struct Elf): Replace off64_t with off_t. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Likewise. + +2015-10-05 Chih-Hung Hsieh + + * elf_getarsym.c (elf_getarsym): Do not use + union of variable length arrays. + +2015-10-05 Josh Stone + + * Makefile.am (libelf.so): Add AM_V_CCLD and AM_V_at silencers. + +2015-09-24 Jose E. Marchesi + + * Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid + relocation overflows in some platforms. + +2015-09-29 Mark Wielaard + + * elf32_updatenull.c (default_ehdr): Set e_version when EV_NONE. + (updatenull_wrlock): Always set e_shentsize. + +2015-09-23 Mark Wielaard + + * elf32_getehdr.c (getehdr_wrlock): Mark as internal_function. + * elf32_getshdr.c (getshdr_rdlock): Likewise. + (getshdr_wrlock): Likewise. + * elf_error.c (__libelf_seterrno): Likewise. + * elf_getphdrnum.c (__elf_getphdrnum_rdlock): Likewise. + (__elf_getphdrnum_chk_rdlock): Likewise. + * elf_getshdrnum.c (__elf_getphdrnum_rdlock): Likewise. + (__elf_getphdrnum_chk_rdlock): Likewise. + * elf_getshdrnum.c (__elf_getshdrnum_rdlock): Likewise. + * elf_readall.c (__libelf_readall): Likewise. + * gelf_getehdr.c (__gelf_getehdr_rdlock): Likewise. + +2015-09-22 Mark Wielaard + + * *.c: Remove old-style function definitions. + +2015-06-22 Mark Wielaard + + * dl-hash.h: Update from glibc. + +2015-06-18 Mark Wielaard + + * elf32_updatefile.c (updatefile): Always free shdr_data and scns + when allocated on failure paths. + +2015-06-18 Mark Wielaard + + * nlist.c (nlist): Check symscn shdr exists before use. + +2015-06-16 Mark Wielaard + + * elf_update.c (write_file): Always also use ftruncate before + posix_fallocate to make sure file has the right size. + +2015-06-04 Mark Wielaard + + * elf_getdata.c (__libelf_type_aligns): Add entries for ELF_T_EHDR, + ELF_T_OFF, ELF_T_PHDR, ELF_T_SHDR, ELF_T_SWORD, ELF_T_XWORD, + ELF_T_SXWORD, ELF_T_GNUHASH, ELF_T_AUXV. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Check alignment + of rawdata against requested type. + +2015-06-02 Mark Wielaard + + * elf_getdata.c (convert_data): Make sure source data is properly + aligned for type before calling actual conversion function. + +2015-06-04 Mark Wielaard + + * elf_begin.c (get_shnum): Check alignment of Shdr, not Ehdr before + direct access. + +2015-06-02 Mark Wielaard + + * elf_begin.c (file_read_elf): Split checks for ehdr and shdr + alignment, drop phdr alignment check. + +2015-05-31 Mark Wielaard + + * elf32_getshdr.c (load_shdr_wrlock): Allocate shdrs with malloc, + not alloca and free after conversion when a copy needs to be made. + +2015-05-31 Mark Wielaard + + * elf32_getphdr.c (getphdr_wrlock): Allocate phdrs with malloc, not + alloca and free after conversion when a copy needs to be made. + +2015-05-31 Mark Wielaard + + * elf_getarsym.c (elf_getarsym): Allocate temporary file_date with + malloc, not alloca also in !ALLOW_UNALIGNED case. + +2015-05-30 Mark Wielaard + + * gelf_xlate.c (elf_cvt_Byte): Only call memmove with non-zero size. + +2015-05-30 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Only call mempcpy and update + last_position when d_size is non-zero. + +2015-05-17 Mark Wielaard + + * elf32_updatefile.c (updatefile): Allocate shdr_data and scns + with malloc, not alloca. Free after writing section headers. + +2015-05-16 Mark Wielaard + + * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage + with malloc, not alloca. Free after writing section header. + +2015-05-16 Mark Wielaard + + * elf_getarsym.c (elf_getarsym): Allocate temporary file_date with + malloc, not alloca. Call free after out. + +2015-05-14 Mark Wielaard + + * elf_update.c (write_file): Use posix_fallocate instead of + ftruncate to extend file if necessary. + +2015-05-13 Mark Wielaard + + * elf32_updatenull.c (default_ehdr): If e_phnum is zero then set + e_phoff also to zero. + +2015-05-12 Mark Wielaard + + * elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign + is a powerof2. + * elf_getdata.c (__libelf_set_rawdata_wrlock): Clamp large d_aligns + to the elf image offset. + +2015-05-12 Mark Wielaard + + * elf32_newphdr.c (newphdr): Call __libelf_seterrno with + ELF_E_INVALID_INDEX before failing. Check whether section zero shdr + actually exists if we need to put extended phnum in section zero. + +2015-05-08 Mark Wielaard + + * nlist.c (nlist): Call gelf_fsize with EV_CURRENT. + +2015-01-03 Mark Wielaard + + * version_xlate.h (elf_cvt_Verdef): Use memmove to copy src to dest. + (elf_cvt_Verneed): Likewise. + +2015-03-28 Mark Wielaard + + * elf.h: Update from glibc. + +2015-03-23 Mark Wielaard + + * elf32_updatenull.c (updatenull_wrlock): Don't extend size with + SHT_NOBITS sh_offset. + +2015-02-18 Mark Wielaard + + * libelfP.h (__libelf_set_data_list_rdlock): Make internal_function. + +2015-02-07 Jan Kratochvil + + * elf32_updatenull.c (__elfw2(LIBELFBITS,updatenull_wrlock)): Consider + sh_addralign 0 as 1. + +2015-01-22 Mark Wielaard + + * elf_strptr (elf_strptr): Make sure returned string is NUL + terminated. + +2015-01-21 Mark Wielaard + + * elf_strptr.c (elf_strptr): Check data_list_rear == NULL instead + of rawdata_base != NULL before using rawdata directly. + +2015-01-20 Mark Wielaard + + * libelfP.h (__elf_strptr_internal): New function declaration. + * elf_getdata.c (__libelf_set_data_list_rdlock): New internal + function extracted from... + (__elf_getdata_rdlock): ... here. + * elf_newdata.c (elf_newdata): Check scn->rawdata_base and update + datalist if necessary. + +2015-01-20 Mark Wielaard + + * elf_strptr.c (elf_strptr): Call __elf[32|64]_getshdr_rdlock if + necessary. + +2014-12-30 Mark Wielaard + + * elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): New function. + (elf_getphdrnum): Call __elf_getphdrnum_chk_rdlock. + * gelf_getphdr (gelf_getphdr): Call __elf_getphdrnum_chk_rdlock + and always check ndx against phnum. + * libelfP.h (__elf_getphdrnum_chk_rdlock): New internal function. + +2014-12-25 Mark Wielaard + + * elf_begin.c (__libelf_next_arhdr_wrlock): ar_size cannot be + negative. Include start_offset in maxsize. + +2014-12-28 Alexander Cherepanov + + * elf_begin.c (read_long_names): Don't miss '/' right after + another '/'. Fixes a dir traversal vuln in ar extraction. + +2014-12-18 Ulrich Drepper + + * Makefile.am: Suppress output of textrel_check command. + +2014-12-16 Mark Wielaard + + * elf_begin.c (read_long_names): Make sure long_names len fits + in mapped ELF file. + +2014-12-15 Mark Wielaard + + * elf_getarsym.c (elf_getarsym): Check index_size doesn't overflow. + +2014-12-15 Mark Wielaard + + * elf_begin.c (read_long_names): Clear any garbage left in the + name table. + +2014-12-11 Mark Wielaard + + * elf_begin.c (file_read_elf): Correct ELF64 section offset check. + +2014-12-11 Mark Wielaard + + * elf_begin.c (read_long_names): Check for offset overflow. + (__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size. + Don't allow it to go beyond end of file. + +2014-12-09 Mark Wielaard + + * elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow. + +2014-11-27 Mark Wielaard + + * Makefile.am (libelf.so): Use textrel_check. + +2014-11-23 Mark Wielaard + + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Change signed + overflow check to unsigned. + +2014-11-23 Mark Wielaard + + * note_xlate.h (elf_cvt_note): Copy over any leftover data if + src != dest. The data is probably part of truncated name/desc. + +2014-11-22 Mark Wielaard + + * elf_getphdrnum.c (elf_getphdrnum): Sanity check the + __elf_getphdrnum_rdlock result. + +2014-11-18 Mark Wielaard + + * version_xlate.h (elf_cvt_Verdef): Check for overflow. + (elf_cvt_Verneed): Likewise. + +2014-11-17 Mark Wielaard + + * elf-knowledge.h (SECTION_STRIP_P): Check name is not NULL. + +2014-11-16 Mark Wielaard + + * elf_getshdrstrndx.c: Check there are section headers before + handling SHN_XINDEX. + +2014-11-16 Mark Wielaard + + * elf32_getphdr.c (getphdr_wrlock): Check e_phoff isn't zero. + Check for too many pheaders. + * elf_getphdrnum.c (__elf_getphdrnum_rdlock): Check section zero + actually exists before handling PN_XNUM. + +2014-11-16 Mark Wielaard + + * gelf_getnote.c (gelf_getnote): Check padding overflow. + +2014-11-16 Mark Wielaard + + * elf_getdata.c (__libelf_set_rawdata_wrlock): Declare offset, size + and align as Elf64_Off and Elf64_Xword not size_t. + +2014-11-14 Mark Wielaard + + * gelf_getnote.c (gelf_getnote): Check offset overflow. + +2014-11-13 Mark Wielaard + + * elf_getdata.c (__libelf_set_rawdata_wrlock): Fix unsigned overflow + check. + +2014-11-08 Mark Wielaard + + * elf_begin.c (__libelf_next_arhdr_wrlock): Use mempcpy not __mempcpy. + +2014-11-07 Mark Wielaard + + * elf_begin.c (file_read_elf): Correct sh_size check. + * elf_getdata.c (__libelf_set_rawdata_wrlock): Check for unsigned + overflow. + +2014-09-10 Petr Machata + + * elf_begin (read_unmmaped_file): Call __libelf_seterrno if the + file is unreadable. + +2014-07-07 Mark Wielaard + + * elf.h: Update from glibc. + +2014-04-13 Mark Wielaard + + * Makefile.am: Remove !MUDFLAP conditions. + * elf_begin.c (read_file): Don't clear use_mmap when _MUDFLAP is + defined. + * elf_update.c (write_file): Remove _MUDFLAP condition. + +2014-01-17 Jakub Jelinek + Roland McGrath + + * libelfP.h (INVALID_NDX): Define. + * gelf_getdyn.c (gelf_getdyn): Use it. Remove ndx < 0 test if any. + * gelf_getlib.c (gelf_getlib): Likewise. + * gelf_getmove.c (gelf_getmove): Likewise. + * gelf_getrel.c (gelf_getrel): Likewise. + * gelf_getrela.c (gelf_getrela): Likewise. + * gelf_getsym.c (gelf_getsym): Likewise. + * gelf_getsyminfo.c (gelf_getsyminfo): Likewise. + * gelf_getsymshndx.c (gelf_getsymshndx): Likewise. + * gelf_getversym.c (gelf_getversym): Likewise. + * gelf_update_dyn.c (gelf_update_dyn): Likewise. + * gelf_update_lib.c (gelf_update_lib): Likewise. + * gelf_update_move.c (gelf_update_move): Likewise. + * gelf_update_rel.c (gelf_update_rel): Likewise. + * gelf_update_rela.c (gelf_update_rela): Likewise. + * gelf_update_sym.c (gelf_update_sym): Likewise. + * gelf_update_syminfo.c (gelf_update_syminfo): Likewise. + * gelf_update_symshndx.c (gelf_update_symshndx): Likewise. + * gelf_update_versym.c (gelf_update_versym): Likewise. + +2014-01-17 Jakub Jelinek + + * elf32_getphdr.c (elfw2(LIBELFBITS,getphdr)): Check if program header + table fits into object's bounds. + * elf_getshdrstrndx.c (elf_getshstrndx): Add elf->start_offset to + elf->map_address. Check if first section header fits into object's + bounds. + * elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)): + Check if section header table fits into object's bounds. + * elf_begin.c (get_shnum): Ensure section headers fits into + object's bounds. + (file_read_elf): Make sure scncnt is small enough to allocate both + ElfXX_Shdr and Elf_Scn array. Make sure section and program header + tables fit into object's bounds. Avoid memory leak on failure. + * elf_newscn.c (elf_newscn): Check for overflow. + * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Likewise. + (__elfw2(LIBELFBITS,updatefile)): Likewise. + * elf32_newphdr.c (elfw2(LIBELFBITS,newphdr)): Likewise. + * elf_getarsym.c (elf_getarsym): Likewise. + +2013-11-08 Mark Wielaard + + * elf32_updatefile.c (elfXX_updatemmap): Only memcpy ehdr when not + already directly mmapped. + +2013-11-05 Mark Wielaard + + * elf32_updatefile.c (elfXX_updatefile): Copy all section headers + if elf->flags dirty. + +2013-11-01 Michael Forney + + * Makefile.am: Use READELF. + +2013-10-01 Petr Machata + + * elf.h: Update from glibc. + +2013-06-17 Petr Machata + + * elf.h: Update from glibc. + +2013-08-28 Namhyung Kim + + * gelf.h (gelf_fsize): Fix typo in comment. + +2013-08-28 Mark Wielaard + + * gelf_getauxv.c (gelf_getauxv): Add missing whitespace. + +2013-08-27 Mark Wielaard + + * gelf_getauxv.c (gelf_getauxv): Remove unnecessary casts to char *. + +2013-08-25 Kurt Roeckx + + * gelf_getauxv.c (gelf_getauxv): Use memcpy instead of pointer + dereference to avoid alignment problems. + +2013-01-07 Roland McGrath + + * elf_getarsym.c (elf_getarsym): Copy FILE_DATA into stack space if it + would be unaligned and !ALLOW_UNALIGNED. + + * elf_getarsym.c (read_number_entries): Use memcpy instead of pointer + dereference so as not to assume the field is naturally aligned. + +2012-09-17 Petr Machata + + * elf.h: Update from glibc. + +2012-08-16 Roland McGrath + + * elf.h: Update from glibc. + +2012-08-14 Mark Wielaard + + * elf32_checksum.c (ebl_debugscn_p): Removed unused define and + confusing outdated comment. + +2012-08-01 Petr Machata + + * elf_getarsym (read_number_entries): New function. + (elf_getarsym): Handle 64-bit symbol table, stored in special + entry named "/SYM64/". + * elf_begin.c (__libelf_next_arhdr_wrlock): Don't reject archive + because it contains 64-bit symbol table. + +2012-07-19 Mark Wielaard + + * elf32_getshdr.c (load_shdr_wrlock): Add elf->flags & ELF_F_MALLOCED + to asserts. + +2012-07-17 Petr Machata + + * elf32_xlatetom.c (elfw2(LIBELFBITS, xlatetom)): Do not check for + integer number of records in case of ELF_T_NHDR. + +2012-04-02 Mark Wielaard + + * elf32_offscn.c: Do not match SHT_NOBITS sections at OFFSET unless + there are no nonempty sections at that offset. + +2012-03-21 Roland McGrath + + * elf-knowledge.h (SECTION_STRIP_P): Remove < SHT_NUM check. + +2011-02-26 Mark Wielaard + + * elf_end.c (elf_end): Call rwlock_unlock before rwlock_fini. + +2011-01-05 Jan Kratochvil + + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Fix off64_t overflow + when MAXIMUM_SIZE == ~0. + +2010-08-18 Roland McGrath + + * gelf_fsize.c (__libelf_type_sizes): Add entries for ELF_T_LIB + and ELF_T_GNUHASH. + Reported by Mark Hatle . + + * exttypes.h: Add cases for ElfNN_Lib. + Reported by Mark Hatle . + +2010-06-14 Ulrich Drepper + + * gelf_update_shdr.c: Implicitly set ELF_F_DIRTY bit. + * gelf_update_phdr.c: Likewise. + * gelf_update_ehdr.c: Likewise. + +2010-04-14 Roland McGrath + + * elf32_getphdr.c: Check for e_phoff/size outside the file bounds. + * elf_begin.c (file_read_elf): Don't set .phdr here. + +2010-04-13 Roland McGrath + + * elf.h: Update from glibc. + +2010-04-06 Roland McGrath + + * elf_error.c (ELF_E_FD_MISMATCH_IDX): Avoid nonobvious abbreviation + in error message. + +2010-04-01 Petr Machata + + * elf_getdata.c (__elf_getdata_rdlock): Initialize data.s for data + that do not need a conversion. + +2010-03-11 Roland McGrath + + * elf.h: Update from glibc. + +2010-03-04 Ulrich Drepper + + * elf.h: Update from glibc. + +2010-02-17 Roland McGrath + + * elf_begin.c (file_read_elf): Leave section rawdata_base and + data_base pointers null when [sh_offset,sh_size) points outside + the mapped file. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + +2010-01-07 Roland McGrath + + * elf32_getphdr.c: Use __elf_getphdrnum_rdlock. + * gelf_getphdr.c: Likewise. + * gelf_update_phdr.c: Likewise. + * elf32_updatefile.c (__elf32_updatemmap, __elf32_updatefile): Likewise. + * elf32_updatenull.c (__elf32_updatenull_wrlock): Likewise. + * elf32_newphdr.c: Clear section 0's sh_info when resetting e_phnum. + If COUNT is too large, use store PN_XNUM instead and set sh_info. + * elf_begin.c (file_read_elf): Always allocate space we can use later + for section 0 if doing RDWR. + + * elf_getphdrnum.c: New file. + * Makefile.am (libelf_a_SOURCES): Add it. + * libelf.h: Declare elf_getphdrnum. + * libelfP.h: Declare __elf_getphdrnum_rdlock. + * libelf.map (ELFUTILS_1.6): New set, add elf_getphdrnum. + + * elf.h: Update from glibc. + +2009-10-23 Lubomir Rintel + + * elf32_updatefile.c (fill_mmap): When starting past shdr_end, start + filling from section start, not shdr_end. + +2009-11-10 Roland McGrath + + * elf_readall.c (__libelf_readall): Fetch file size if not yet known. + +2009-11-06 Mark Wielaard + + * elf_next.c (elf_next): Mark the archive header as unusable when + there is no next ar element. + +2009-08-12 Mark Wielaard + + * Makefile.am (libelf.so): Use -Wl,-z,defs not -defs. + +2009-07-26 Ulrich Drepper + + * elf.h: Update from glibc. + +2009-07-21 Ulrich Drepper + + * elf32_updatefile.c (__elfXX_updatemmap): Fix handling of gaps between + sections. Patch by Lubomir Rintel . + +2009-07-08 Roland McGrath + + * libelfP.h (struct Elf): Remove unused ar.has_index field. + Reorder various members for optimal packing. + +2009-07-08 Ulrich Drepper + + * elf.h: Update from glibc. + +2009-06-13 Ulrich Drepper + + * Makefile.am (libelf_a_SOURCES): Replace elf_getshnum.c and + elf_getshstrndx.c with elf_getshdrnum.c and elf_getshdrstrndx.c. + * elf_getshnum.c: Renamed to... + * elf_getshdrnum.c: ...this. Rename function and add old name as + alias. Likewise for internal functions with derived names. + * elf_getshstrndx.c: Renamed to... + * elf_getshdrstrndx.c: ...this. Rename function and add old name as + alias. Likewise for internal functions with derived names. + * libelf.h: Add prototypes for new names. Make old names as + deprecated. + * libelfP.h: Rename internal function prototypes. + * libelf.map: Export for names. + * elf32_checksum.c: Don't use deprecated functions. + * elf32_getshdr.c: Likewise. + +2009-06-01 Ulrich Drepper + + * elf.h: Update from glibc. + +2009-04-14 Roland McGrath + + * elf.h: Update from glibc. + +2009-04-01 Roland McGrath + + * elf.h: Update from glibc. + +2009-02-10 Ulrich Drepper + + * elf32_updatefile.c (updatefile): For the zeroth section we still + have to copy the section header. + +2009-02-01 Ulrich Drepper + + * elf_strptr.c: Add comment re possible problem. + +2009-01-26 Ulrich Drepper + + * elf32_updatenull.c (updatenull_wrlock): Fix comment of + ELF_F_LAYOUT behaviour re section header table. + +2009-01-22 Ulrich Drepper + + * elf32_updatefile.c (__elfXX_updatemmap): Fill the gap between + sections even if only the section at the start of the gap has been + changed. + (__elfXX_updatefile): Likewise. + +2009-01-21 Ulrich Drepper + + * elf32_updatefile.c (__elfXX_updatemmap): Skip most of the loop to + handle sections for NOBITS sections. + (elfXX_updatefile): Likewise. + + * elf32_updatefile.c (__elfXX_updatemmap): When skipping non-NOBITS + sections we haven't loaded, update last_position based on scn_start, + not based on old value. Don't run the loop for the dummy section 0. + (elfXX_updatefile): Don't run the loop for the dummy section 0. + +2009-01-10 Ulrich Drepper + + * libelfP.h (_): We only have one translation domain, elfutils. + + * Makefile.am: Use USE_LOCKS instead of USE_TLS. + * elf_error.c: Always use __thread. Remove all !USE_TLS code. + +2009-01-04 Roland McGrath + + * note_xlate.h (elf_cvt_note): Don't examine a size too small to + container a note header. + +2008-12-11 Roland McGrath + + * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle + placement offset going backwards, for out-of-order or overlapping + (bogus) sh_offset layouts. It's a dumb use, but should not crash. + (__elfw2(LIBELFBITS,updatefile)): Likewise. + Fixes RHBZ#476136. + + * libelf.h (Elf_Data): Whitespace fix. + +2008-12-10 Roland McGrath + + * elf_getarhdr.c (elf_getarhdr): Fix missing rename in last change. + +2008-10-22 Petr Machata + + * elf_rawfile.c (elf_rawfile): Lock around elf-> references. + +2008-10-21 Petr Machata + + * libelfP.h: Rename getehdr_rdlock to getehdr_wrlock. + * elf32_getehdr.c (getehdr_rdlock): Move the code to new function + getehdr_impl and make it a wrapper. Rename to getehdr_wrlock. + (getehdr_impl): Guard elf->class init with wrlock. + (getehdr): Also make it a wrapper of getehdr_impl. + * elf32_updatenull.c (updatenull_wrlock): Call getehdr_wrlock. + +2008-10-20 Petr Machata + + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Lock around the + code that reads mutable elf state. Relock to write lock to chain + the new chunk on the elf rawchunks list. + +2008-10-20 Petr Machata + + * elf32_checksum.c (checksum): Place a lock around the code that + processes data. Make it wrlock if the code needs to xlate the + data before processing. + +2008-10-16 Petr Machata + + * elf_begin.c + (__libelf_next_arhdr): Rename to __libelf_next_arhdr_wrlock. + (dup_elf): Adjust the call. + (elf_begin): New local function lock_dup_elf. Relocks the elf if + necessary before calling dup. Call this instead of dup_elf. + * elf_getarhdr.c + (elf_getarhdr): Lock before calling __libelf_next_arhdr_wrlock. + * elf_next.c (elf_next): Likewise. + * elf_rand.c (elf_rand): Likewise. + +2008-10-14 Petr Machata + + * elf_getdata.c (__elf_getdata_rdlock): Lock before converting. + +2008-11-26 Roland McGrath + + * elf.h: Update from glibc. + +2008-10-06 Roland McGrath + + * elf_getarhdr.c (elf_getarhdr): Return NULL when passed NULL. + +2008-08-27 Roland McGrath + + * elf_begin.c (get_shnum): Avoid misaligned reads for matching endian. + + * libelfP.h [!ALLOW_UNALIGNED] (__libelf_type_align): Fix CLASS index. + +2008-08-25 Roland McGrath + + * Makefile.am (libelf_so_LDLIBS): New variable. + (libelf.so): Use it in the link. + +2008-08-21 Petr Machata + + * elf_getdata.c, libelfP.h + (__elf_getdata_internal): Rename to __elf_getdata_rdlock. + (__libelf_set_rawdata_wrlock): New function. + (__libelf_set_rawdata): Make it a wrapper that calls *_wrlock. + * elf32_updatenull.c, libelfP.h + (__elfNN_updatenull): Rename to __elfNN_updatenull_wrlock. + +2008-08-21 Petr Machata + + * elf32_getphdr.c, libelfP.h + (__elfNN_getphdr_internal): Drop. Move __elfNN_getphdr_internal + code to __elfNN_getphdr_wrlock. + (__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): New functions. + (__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): Make these + wrappers of getphdr_impl. + +2008-08-21 Petr Machata + + * elf32_getehdr.c, libelfP.h + (__elfNN_getehdr_internal): Rename to __elfNN_getehdr_rdlock. + * gelf_getehdr, libelfP.h: + (__gelf_getehdr_internal): Rename to __gelf_getehdr_rdlock. + +2008-08-21 Petr Machata + + * elf32_getshdr.c + (__elfNN_getshdr_internal): Drop. + (load_shdr_wrlock, scn_valid): New functions, contain bits of + behaviour from __elfNN_getshdr_internal. + (__elfNN_getshdr_rdlock, __elfNN_getshdr_wrlock): Replacements for + dropped _internal functions above. + * elf_getshnum.c + (__elf_getshnum_internal): Rename to __elf_getshnum_rdlock. + +2008-08-04 Petr Machata + + * libelfP.h (RWLOCK_RDLOCK, RWLOCK_WRLOCK, RWLOCK_UNLOCK): New macros. + +2008-07-28 Roland McGrath + + * elf.h: Update from glibc. + +2008-03-31 Roland McGrath + + * elf32_offscn.c: Make sure shdrs have been read in. + +2008-02-19 Roland McGrath + + * elf.h: Update from glibc. + +2008-02-08 Roland McGrath + + * elf.h: Update from glibc. + +2008-01-31 Ulrich Drepper + + * elf_strptr.c (elf_strptr): Don't fail if the ELF file is currently + under construction and no raw data can be read from disk. + +2008-01-30 Roland McGrath + + * elf.h: Update from glibc. + +2008-01-26 Roland McGrath + + * elf_begin.c (__libelf_next_arhdr): Rewrite conversions using a macro. + Fixes various pastos in wrong type in sizeof, wrong string parsed. + +2008-01-20 Roland McGrath + + * elf_getaroff.c: Calculate from start_offset, instead of using + parent's state.ar.offset field. + +2008-01-08 Roland McGrath + + * Makefile.am (euinclude): Variable removed. + (pkginclude_HEADERS): Set this instead of euinclude_HEADERS. + +2008-01-03 Roland McGrath + + * common.h: Add __attribute__ ((unused)) to static functions. + +2007-12-20 Ulrich Drepper + + * Makefile.am (libelf_a_SOURCES): Add elf_scnshndx. + * libelfP.h (struct Elf_Scn): Add shndx_index field. + Declare __elf_scnshndx_internal. + * elf32_getshdr.c: Record location of extended section header. + * elf_begin.c (file_read_elf): Likewise. + * elf_scnshndx.c: New file. + * libelf.h: Declare elf_scnshndx. + * libelf.map: Add elf_scnshndx to version ELFUTILS_1.4. + +2007-11-12 Roland McGrath + + * libelf.h: Replace off64_t with loff_t throughout. + Only that type name is unconditionally defined by + +2007-11-03 Roland McGrath + + * libelf.h (Elf_Data): Comment fix. + +2007-10-18 Roland McGrath + + * elf.h: Update from glibc. + +2007-10-07 Roland McGrath + + * elf_begin.c (__libelf_next_arhdr): Fix fencepost error and wrong + member access in terminating name with no trailing /. Trim trailing + spaces when there is no /. + +2007-10-04 Roland McGrath + + * elf_end.c (elf_end): Don't free ELF->state.ar.ar_sym when it's -1l. + +2007-10-03 Roland McGrath + + * libelf.h (Elf_Data): Use off64_t for d_off. + (Elf_Arhdr): Use off64_t for ar_size. + (elf_update, elf_getbase, elf_getaroff): Return off64_t. + + * gelf_rawchunk.c: File removed. + * gelf_freechunk.c: File removed. + * Makefile.am (libelf_a_SOURCES): Remove them. + * libelf.map (ELFUTILS_1.0): Remove exports. + * gelf.h: Remove decls. + + * elf_getdata_rawchunk.c: New file. + * Makefile.am (libelf_a_SOURCES): Add it. + * libelf.map (ELFUTILS_1.3): Add elf_getdata_rawchunk. + * libelf.h: Declare it. + * libelfP.h (Elf_Data_Chunk): New type. + (struct Elf.elf): New member `rawchunks'. + * elf_end.c (elf_end): Free recorded rawchunk buffers. + +2007-08-24 Roland McGrath + + * gelf_getnote.c: New file. + * Makefile.am (libelf_a_SOURCES): Add it. + * gelf.h: Declare gelf_getnote. + * libelf.map (ELFUTILS_1.3): Add gelf_getnote. + + * libelfP.h (NOTE_ALIGN): New macro. + * note_xlate.h: New file. + * Makefile.am (noinst_HEADERS): Add it. + * gelf_xlate.c: Include it. + (__elf_xfctstom): Use elf_cvt_note. + * elf_getdata.c (shtype_map, __libelf_type_align): Handle SHT_NOTE. + (__libelf_set_rawdata): Likewise. + +2007-08-19 Roland McGrath + + * gelf_update_auxv.c: New file. + * gelf_getauxv.c: New file. + * Makefile.am (libelf_a_SOURCES): Add them. + * gelf.h: Declare gelf_getauxv, gelf_update_auxv. + * libelf.map (ELFUTILS_1.3): New set, inherits fom ELFUTILS_1.2. + Export gelf_getauxv, gelf_update_auxv. + + * libelf.h (Elf_Type): Add ELF_T_AUXV. + * abstract.h: Add auxv_t entries. + * exttypes.h: Likewise. + * gelf_xlate.h: Likewise. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_AUXV entries. + * gelf_fsize.c (__libelf_type_sizes): Likewise. + +2007-08-12 Roland McGrath + + * elf32_updatefile.c (compare_sections): Sort secondarily on sh_size, + and only tertiarily on index. + +2007-07-09 Roland McGrath + + * elf.h: Update from glibc. + +2007-04-22 Roland McGrath + + * elf.h: Update from glibc. + +2007-03-18 Roland McGrath + + * elf_begin.c (get_shnum): Fix test for e_shoff being out of bounds. + Return zero when the section headers do not fit within MAXSIZE. + +2007-03-09 Roland McGrath + + * libelfP.h (LIBELF_EV_IDX): New macro. + (__libelf_type_align): New macro. + [! ALLOW_UNALIGNED]: Declare __libc_type_aligns array. + * elf_getdata.c (shtype_map): Convert to just Elf_Type[][]. + (convert_data, __libelf_set_rawdata): Use that, __libelf_type_align, + and __libelf_type_sizes, in place of old table. + (__libc_type_aligns): New const variable. + +2007-02-04 Ulrich Drepper + + * Makefile (libelf.so): Build with -z relro. + + * elf_begin.c (read_file): When using ELF_C_READ_MMAP use MAP_PRIVATE. + +2007-01-30 Ulrich Drepper + + * nlist.c: Close file descriptor before returning. + +2007-01-20 Roland McGrath + + * gnuhash_xlate.h (elf_cvt_gnuhash): Fix fence-post error so we + convert the final word. + + * elf32_getshdr.c: Don't byteswap shdr fields when EI_DATA matches + MY_ELFDATA on !ALLOW_UNALIGNED machines. + +2007-01-18 Roland McGrath + + * gelf_rawchunk.c (gelf_rawchunk): Clear RESULT pointer after freeing + it on read error. + +2006-10-13 Roland McGrath + + * elf32_updatenull.c: Look for and accept phdr also for ET_CORE. + * elf_error.c (msgstr): Change ELF_E_INVALID_PHDR string. + +2006-08-29 Roland McGrath + + * elf32_getphdr.c: Don't byteswap phdr fields when EI_DATA matches + MY_ELFDATA on !ALLOW_UNALIGNED machines. + Reported by Christian Aichinger . + + * Makefile.am (CLEANFILES): Add libelf.so.$(VERSION). + +2006-08-08 Ulrich Drepper + + * elf.h (DT_VALNUM): Update. + (DT_ADDRNUM): Likewise. + +2006-07-12 Ulrich Drepper + + * elf32_updatefile.c: Adjust for internal_function_def removal. + * elf32_updatenull.c: Likewise. + * elf_begin.c: Likewise. + * elf_getdata.c: Likewise. + +2006-07-11 Ulrich Drepper + + * libelf.h: Define ELF_T_GNUHASH. + * elf_getdata.c (TYPEIDX): Handle SHT_GNU_HASH. + (shtype_map): Add SHT_GNU_HASH entries. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_GNUHASH entries. + * gnuhash_xlate.h: New file. + * Makefile.am (noinst_HEADERS): Add gnuhash_xlate.h. + +2006-07-06 Ulrich Drepper + + * elf_gnu_hash.c: New file. + * libelf.h: Declare elf_gnu_hash. + * Makefile.am (libelf_a_SOURCES): Add elf_gnu_hash. + * libelf.map: Add elf_gnu_map for version ELFUTILS_1.2. + +2006-06-15 Roland McGrath + + * libelf.h (elf_getarsym): Fix comment typo. + Rename second parameter to be more explanatory. + (elf_getident, elf_rawhide): Likewise. + +2006-05-28 Ulrich Drepper + + * elf32_updatefile.c (updatemmap): Preserve section content if + copying would overwrite them. + Fix msync paramters. + +2006-04-04 Roland McGrath + + * elf32_updatefile.c (updatemmap): Handle other-endian case. + +2006-04-04 Ulrich Drepper + + * elf32_updatefile.c (updatemmap): Cleanups. Remove shdr_dest + variable. Before writing sections, make a copy of the section + header data if necessary. Don't write section header while + writing the section constent, it might overwrite some sections. + Restore the pointer afterwards. + * elf32_updatenull.c (updatenull): If the offset of a section in a + file changed make sure we read the section so that it'll be written + out. + + * elf_update.c: Remove debug message. + +2005-12-07 Roland McGrath + + * gelf_xlate.c [! ALLOW_UNALIGNED] (union unaligned): New type. + (FETCH, STORE): New macros. + (INLINE3): Use those to do alignment-friendly conversion. + + * elf32_getshdr.c: Include map_address and start_offset in alignment + calculations. + * elf32_getphdr.c: Likewise. + +2005-11-19 Roland McGrath + + * elf.h: Update from glibc. + +2005-11-17 Roland McGrath + + * elf.h: Update from glibc. + +2005-11-10 Roland McGrath + + * elf.h: Update from glibc. + +2005-09-09 Roland McGrath + + * elf_update.c (write_file): Stat the file and fchmod it after update + if its mode had S_ISUID or S_ISGID bits set. + +2005-08-28 Ulrich Drepper + + * elf32_getphdr.c: Include . Use pread_retry instead of + pread. And branch prediction where useful. + * elf_begin.c: Likewise. + * elf_getdata.c: Likewise. + * elf_getshstrndx.c: Likewise. + * elf_readall.c: Likewise. + * gelf_rawchunk.c: Likewise. + * elf32_updatefile.c: Include . Use pread_retry instead of + pread. And branch prediction where useful. + * elf_getarsym.c: Don't define pread_retry here. + + * Makefile.am: Use $(LINK) not $(CC) when creating DSO. + (%.os): Use COMPILE.os. + (COMPILE.os): Filter out gconv options. + +2005-08-27 Ulrich Drepper + + * elf_begin.c (file_read_elf): Avoid reading ELF header from file + again. Instead accept additional parameter which points to it if we + don't use mmap. + (get_shnum): Use passed in e_ident value as source of ELF header. + +2005-08-15 Ulrich Drepper + + * elf_begin.c (__libelf_next_arhdr): Use TEMP_FAILURE_RETRY. + + * Makefile (libelf_a_SOURCES): Add elf_getaroff.c. + * libelf.map: Export elf_getaroff. + * libelf.h: Declare elf_getaroff. + * elf_getaroff.c: New file. + +2005-08-13 Ulrich Drepper + + * elf_begin.c (get_shnum): Optimize memory handling. Always read from + mapped file if available. Fix access to 64-bit sh_size. Recognize + overflow. + (file_read_elf): Likewise. + +2005-08-12 Roland McGrath + + * elf32_offscn.c: Do not match empty sections at OFFSET unless + there are no nonempty sections at that offset. + +2005-08-07 Ulrich Drepper + + * elf.h: Update from glibc. + +2005-08-06 Ulrich Drepper + + * Makefile.am (AM_CFLAGS): Add -fpic when BUILD_STATIC. + +2005-08-03 Ulrich Drepper + + * libelf.map: Move elf32_offscn, elf64_offscn, and gelf_offscn in + new version ELFUTILS_1.1.1. + +2005-08-02 Ulrich Drepper + + * elf_error.c: Add handling of ELF_E_INVALID_OFFSET. + * elf32_offscn.c: New file. + * elf64_offscn.c: New file. + * gelf_offscn.c: New file. + * Makefile.am (libelf_a_SOURCES): Add elf32_offscn.c, elf64_offscn.c, + and gelf_offscn.c. + * libelf.sym: Export new symbols. + +2005-07-23 Ulrich Drepper + + * elf-knowledge.h (SECTION_STRIP_P): Don't handle removal of debug + sections here anymore. + * elf32_checksum.c: Adjust for change in SECTION_STRIP_P interface. + + * elf_update.c (elf_update): Get write lock, not read lock. + + * elf32_updatenull.c (updatenull): Get section headers if necessary + and possible. + +2005-07-22 Ulrich Drepper + + * elf32_updatenull.c (updatenull): If program header hasn't been loaded + yet, try to do it now. + Don't unnecessarily update overflow of section count in zeroth section + sh_size field. + If section content hasn't been read yet, do it before looking for the + block size. If no section data present, infer size of section header. + +2005-05-11 Ulrich Drepper + + * elf.h: Update again. + +2005-05-09 Ulrich Drepper + + * elf.h: Update from glibc. + +2005-05-08 Roland McGrath + + * elf_begin.c (read_file) [_MUDFLAP]: Don't use mmap for now. + * elf_update.c (write_file) [_MUDFLAP]: Likewise. + +2005-03-29 Ulrich Drepper + + * elf32_checksum.c: Use INTUSE and INTDEF to avoid PLTs. + * elf_end.c: Likewise. + * elf_getdata.c: Likewise. + * gelf_getehdr.c: Likewise. + * nlist.c: Likewise. + * libelfP.h: Add declarations of internal functions. + +2005-02-15 Ulrich Drepper + + * common.h (CONVERT): Make sure all values are unsigned. + (CONVERT_TO): Likewise. + + * Makefile.am (AM_CFLAGS): Add -Wformat=2. + Fix rule to build libelf.so. + +2005-02-06 Ulrich Drepper + + * Makefile.am: Cleanup AM_CFLAGS handling. Add -Wunused -Wextra. + Remove lint handling. + * elf32_getphdr.c: Minor cleanups. + * elf32_getshdr.c: Likewise. + * elf32_updatefile.c: Likewise. + * elf32_updatenull.c: Likewise. + * elf_begin.c: Likewise. + * elf_error.c: Likewise. + * elf_getarsym.c: Likewise. + * elf_getdata.c: Likewise. + * elf_update.c: Likewise. + * gelf_xlate.c: Likewise. + +2005-02-05 Ulrich Drepper + + * Makefile.am: Check for text relocations in constructed DSO. + + * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -Werror -fpic -fmudflap. + +2005-02-04 Ulrich Drepper + + * gelf_getehdr.c (gelf_getehdr): Slight optimization. + + * elf32_checksum.c (checksum): Do not look at NOBITS sections. + + * gelf.h: Add gelf_checksum prototype. + +2004-09-25 Ulrich Drepper + + * elf32_checksum.c: Make compile with gcc 4.0. + * elf32_updatefile.c: Likewise. + * elf32_updatenull.c: Likewise. + * elf_begin.c: Likewise. + * elf_error.c: Likewise. + * elf_getdata.c: Likewise. + * elf_getident.c: Likewise. + +2004-04-01 Ulrich Drepper + + * elf.h: Update from glibc. + +2004-01-23 Ulrich Drepper + + * elf_update.c: Fix locking. + * elf_clone.c: Likewise. + + * libelf.h: Define ELF_T_LIB. + * gelf_getlib.c: New file. + * gelf_update_lib.c: New file. + * gelf.h: Declare the new functions. Define GElf_Lib. + * abstract.h: Define Lib, Lib32, Lib64. + * gelf_xlate.c (__elf_xfctstom): Add ELF_T_LIB entry. + * gelf_xlate.h: Add entry for ElfXX_Lib. + * elf_getdata.c: Recognize SHT_GNU_LIBLIST as a known section type. + * libelf.map: Add new symbols to ELFUTILS_1.1. + * Makefile.am (libelf_a_SOURCES): Add gelf_getlib.c and + gelf_update_lib.c. + +2004-01-17 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + + * gelf_xlate.c (INLINE3): Avoid using cast as lvalue. + * dl-hash.h (_dl_elf_hash): Likewise. + +2004-01-05 Ulrich Drepper + + * elf-knowledge.h: New file. From libelf subdir. + * Makefile.am (euincludedir): Define. + (euinclude_HEADERS): Add elf-knowledge.h. + +2003-09-24 Ulrich Drepper + + * elf.h: Define some PT_IA_64_HP_* constants. + +2003-09-23 Jakub Jelinek + + * libelfP.h (struct Elf): Move state.elf64.sizestr_offset after + state.elf64.scnincr to match state.elf{,32}. + +2003-08-12 Ulrich Drepper + + * elf32_updatefile.c (__updatemmap): When writing back file where + some sections have not been read in, count their sizes based on + the section header. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/libelf/Makefile.am b/libelf/Makefile.am new file mode 100644 index 00000000..560ed45f --- /dev/null +++ b/libelf/Makefile.am @@ -0,0 +1,137 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 1996-2010, 2015 Red Hat, Inc. +## This file is part of elfutils. +## +## This file is free software; you can redistribute it and/or modify +## it under the terms of either +## +## * the GNU Lesser General Public License as published by the Free +## Software Foundation; either version 3 of the License, or (at +## your option) any later version +## +## or +## +## * 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 +## +## or both in parallel, as here. +## +## elfutils 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 copies of the GNU General Public License and +## the GNU Lesser General Public License along with this program. If +## not, see . +## +include $(top_srcdir)/config/eu.am +if BUILD_STATIC +AM_CFLAGS += $(fpic_CFLAGS) +endif + +VERSION = 1 + +lib_LIBRARIES = libelf.a +noinst_LIBRARIES = libelf_pic.a +noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so) +include_HEADERS = libelf.h gelf.h nlist.h + +noinst_HEADERS = abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \ + version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h \ + chdr_xlate.h + +if INSTALL_ELFH +include_HEADERS += elf.h +else +noinst_HEADERS += elf.h +endif + +pkginclude_HEADERS = elf-knowledge.h + +libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \ + elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \ + gelf_getclass.c elf_getbase.c elf_getident.c \ + elf32_fsize.c elf64_fsize.c gelf_fsize.c \ + elf32_xlatetof.c elf32_xlatetom.c elf64_xlatetof.c \ + elf64_xlatetom.c gelf_xlate.c \ + elf32_getehdr.c elf64_getehdr.c gelf_getehdr.c \ + elf32_newehdr.c elf64_newehdr.c gelf_newehdr.c \ + gelf_update_ehdr.c \ + elf32_getphdr.c elf64_getphdr.c gelf_getphdr.c \ + elf32_newphdr.c elf64_newphdr.c gelf_newphdr.c \ + gelf_update_phdr.c \ + elf_getarhdr.c elf_getarsym.c \ + elf_rawfile.c elf_readall.c elf_cntl.c \ + elf_getscn.c elf_nextscn.c elf_ndxscn.c elf_newscn.c \ + elf32_getshdr.c elf64_getshdr.c gelf_getshdr.c \ + gelf_update_shdr.c \ + elf_strptr.c elf_rawdata.c elf_getdata.c elf_newdata.c \ + elf_getdata_rawchunk.c \ + elf_flagelf.c elf_flagehdr.c elf_flagphdr.c elf_flagscn.c \ + elf_flagshdr.c elf_flagdata.c elf_memory.c \ + elf_update.c elf32_updatenull.c elf64_updatenull.c \ + elf32_updatefile.c elf64_updatefile.c \ + gelf_getsym.c gelf_update_sym.c \ + gelf_getversym.c gelf_getverneed.c gelf_getvernaux.c \ + gelf_getverdef.c gelf_getverdaux.c \ + gelf_getrel.c gelf_getrela.c \ + gelf_update_rel.c gelf_update_rela.c \ + gelf_getdyn.c gelf_update_dyn.c \ + gelf_getmove.c gelf_update_move.c \ + gelf_getsyminfo.c gelf_update_syminfo.c \ + gelf_getauxv.c gelf_update_auxv.c \ + gelf_getnote.c \ + gelf_xlatetof.c gelf_xlatetom.c \ + nlist.c \ + gelf_getsymshndx.c gelf_update_symshndx.c \ + gelf_update_versym.c gelf_update_verneed.c \ + gelf_update_vernaux.c gelf_update_verdef.c \ + gelf_update_verdaux.c \ + elf_getphdrnum.c elf_getshdrnum.c elf_getshdrstrndx.c \ + gelf_checksum.c elf32_checksum.c elf64_checksum.c \ + libelf_crc32.c libelf_next_prime.c \ + elf_clone.c \ + gelf_getlib.c gelf_update_lib.c \ + elf32_offscn.c elf64_offscn.c gelf_offscn.c \ + elf_getaroff.c \ + elf_gnu_hash.c \ + elf_scnshndx.c \ + elf32_getchdr.c elf64_getchdr.c gelf_getchdr.c \ + elf_compress.c elf_compress_gnu.c + +libelf_pic_a_SOURCES = +am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os) + +libelf_so_DEPS = ../lib/libeu.a +libelf_so_LDLIBS = $(libelf_so_DEPS) -lz +if USE_LOCKS +libelf_so_LDLIBS += -lpthread +endif + +libelf_so_LIBS = libelf_pic.a +libelf.so: $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$@.$(VERSION) \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libelf_so_LIBS) -Wl,--no-whole-archive \ + $(libelf_so_LDLIBS) + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + +install: install-am libelf.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so + ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION) + ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libelf.so + +EXTRA_DIST = libelf.map + +CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so libelf.so.$(VERSION) diff --git a/libelf/Makefile.in b/libelf/Makefile.in new file mode 100644 index 00000000..91d980be --- /dev/null +++ b/libelf/Makefile.in @@ -0,0 +1,1364 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@BUILD_STATIC_TRUE@am__append_2 = $(fpic_CFLAGS) +@INSTALL_ELFH_TRUE@am__append_3 = elf.h +@INSTALL_ELFH_FALSE@am__append_4 = elf.h +@USE_LOCKS_TRUE@am__append_5 = -lpthread +subdir = libelf +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__include_HEADERS_DIST) \ + $(am__noinst_HEADERS_DIST) $(pkginclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(pkgincludedir)" +LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libelf_a_AR = $(AR) $(ARFLAGS) +libelf_a_LIBADD = +am_libelf_a_OBJECTS = elf_version.$(OBJEXT) elf_hash.$(OBJEXT) \ + elf_error.$(OBJEXT) elf_fill.$(OBJEXT) elf_begin.$(OBJEXT) \ + elf_next.$(OBJEXT) elf_rand.$(OBJEXT) elf_end.$(OBJEXT) \ + elf_kind.$(OBJEXT) gelf_getclass.$(OBJEXT) \ + elf_getbase.$(OBJEXT) elf_getident.$(OBJEXT) \ + elf32_fsize.$(OBJEXT) elf64_fsize.$(OBJEXT) \ + gelf_fsize.$(OBJEXT) elf32_xlatetof.$(OBJEXT) \ + elf32_xlatetom.$(OBJEXT) elf64_xlatetof.$(OBJEXT) \ + elf64_xlatetom.$(OBJEXT) gelf_xlate.$(OBJEXT) \ + elf32_getehdr.$(OBJEXT) elf64_getehdr.$(OBJEXT) \ + gelf_getehdr.$(OBJEXT) elf32_newehdr.$(OBJEXT) \ + elf64_newehdr.$(OBJEXT) gelf_newehdr.$(OBJEXT) \ + gelf_update_ehdr.$(OBJEXT) elf32_getphdr.$(OBJEXT) \ + elf64_getphdr.$(OBJEXT) gelf_getphdr.$(OBJEXT) \ + elf32_newphdr.$(OBJEXT) elf64_newphdr.$(OBJEXT) \ + gelf_newphdr.$(OBJEXT) gelf_update_phdr.$(OBJEXT) \ + elf_getarhdr.$(OBJEXT) elf_getarsym.$(OBJEXT) \ + elf_rawfile.$(OBJEXT) elf_readall.$(OBJEXT) elf_cntl.$(OBJEXT) \ + elf_getscn.$(OBJEXT) elf_nextscn.$(OBJEXT) \ + elf_ndxscn.$(OBJEXT) elf_newscn.$(OBJEXT) \ + elf32_getshdr.$(OBJEXT) elf64_getshdr.$(OBJEXT) \ + gelf_getshdr.$(OBJEXT) gelf_update_shdr.$(OBJEXT) \ + elf_strptr.$(OBJEXT) elf_rawdata.$(OBJEXT) \ + elf_getdata.$(OBJEXT) elf_newdata.$(OBJEXT) \ + elf_getdata_rawchunk.$(OBJEXT) elf_flagelf.$(OBJEXT) \ + elf_flagehdr.$(OBJEXT) elf_flagphdr.$(OBJEXT) \ + elf_flagscn.$(OBJEXT) elf_flagshdr.$(OBJEXT) \ + elf_flagdata.$(OBJEXT) elf_memory.$(OBJEXT) \ + elf_update.$(OBJEXT) elf32_updatenull.$(OBJEXT) \ + elf64_updatenull.$(OBJEXT) elf32_updatefile.$(OBJEXT) \ + elf64_updatefile.$(OBJEXT) gelf_getsym.$(OBJEXT) \ + gelf_update_sym.$(OBJEXT) gelf_getversym.$(OBJEXT) \ + gelf_getverneed.$(OBJEXT) gelf_getvernaux.$(OBJEXT) \ + gelf_getverdef.$(OBJEXT) gelf_getverdaux.$(OBJEXT) \ + gelf_getrel.$(OBJEXT) gelf_getrela.$(OBJEXT) \ + gelf_update_rel.$(OBJEXT) gelf_update_rela.$(OBJEXT) \ + gelf_getdyn.$(OBJEXT) gelf_update_dyn.$(OBJEXT) \ + gelf_getmove.$(OBJEXT) gelf_update_move.$(OBJEXT) \ + gelf_getsyminfo.$(OBJEXT) gelf_update_syminfo.$(OBJEXT) \ + gelf_getauxv.$(OBJEXT) gelf_update_auxv.$(OBJEXT) \ + gelf_getnote.$(OBJEXT) gelf_xlatetof.$(OBJEXT) \ + gelf_xlatetom.$(OBJEXT) nlist.$(OBJEXT) \ + gelf_getsymshndx.$(OBJEXT) gelf_update_symshndx.$(OBJEXT) \ + gelf_update_versym.$(OBJEXT) gelf_update_verneed.$(OBJEXT) \ + gelf_update_vernaux.$(OBJEXT) gelf_update_verdef.$(OBJEXT) \ + gelf_update_verdaux.$(OBJEXT) elf_getphdrnum.$(OBJEXT) \ + elf_getshdrnum.$(OBJEXT) elf_getshdrstrndx.$(OBJEXT) \ + gelf_checksum.$(OBJEXT) elf32_checksum.$(OBJEXT) \ + elf64_checksum.$(OBJEXT) libelf_crc32.$(OBJEXT) \ + libelf_next_prime.$(OBJEXT) elf_clone.$(OBJEXT) \ + gelf_getlib.$(OBJEXT) gelf_update_lib.$(OBJEXT) \ + elf32_offscn.$(OBJEXT) elf64_offscn.$(OBJEXT) \ + gelf_offscn.$(OBJEXT) elf_getaroff.$(OBJEXT) \ + elf_gnu_hash.$(OBJEXT) elf_scnshndx.$(OBJEXT) \ + elf32_getchdr.$(OBJEXT) elf64_getchdr.$(OBJEXT) \ + gelf_getchdr.$(OBJEXT) elf_compress.$(OBJEXT) \ + elf_compress_gnu.$(OBJEXT) +libelf_a_OBJECTS = $(am_libelf_a_OBJECTS) +libelf_pic_a_AR = $(AR) $(ARFLAGS) +libelf_pic_a_LIBADD = +libelf_pic_a_OBJECTS = $(am_libelf_pic_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/elf32_checksum.Po \ + ./$(DEPDIR)/elf32_fsize.Po ./$(DEPDIR)/elf32_getchdr.Po \ + ./$(DEPDIR)/elf32_getehdr.Po ./$(DEPDIR)/elf32_getphdr.Po \ + ./$(DEPDIR)/elf32_getshdr.Po ./$(DEPDIR)/elf32_newehdr.Po \ + ./$(DEPDIR)/elf32_newphdr.Po ./$(DEPDIR)/elf32_offscn.Po \ + ./$(DEPDIR)/elf32_updatefile.Po \ + ./$(DEPDIR)/elf32_updatenull.Po ./$(DEPDIR)/elf32_xlatetof.Po \ + ./$(DEPDIR)/elf32_xlatetom.Po ./$(DEPDIR)/elf64_checksum.Po \ + ./$(DEPDIR)/elf64_fsize.Po ./$(DEPDIR)/elf64_getchdr.Po \ + ./$(DEPDIR)/elf64_getehdr.Po ./$(DEPDIR)/elf64_getphdr.Po \ + ./$(DEPDIR)/elf64_getshdr.Po ./$(DEPDIR)/elf64_newehdr.Po \ + ./$(DEPDIR)/elf64_newphdr.Po ./$(DEPDIR)/elf64_offscn.Po \ + ./$(DEPDIR)/elf64_updatefile.Po \ + ./$(DEPDIR)/elf64_updatenull.Po ./$(DEPDIR)/elf64_xlatetof.Po \ + ./$(DEPDIR)/elf64_xlatetom.Po ./$(DEPDIR)/elf_begin.Po \ + ./$(DEPDIR)/elf_clone.Po ./$(DEPDIR)/elf_cntl.Po \ + ./$(DEPDIR)/elf_compress.Po ./$(DEPDIR)/elf_compress_gnu.Po \ + ./$(DEPDIR)/elf_end.Po ./$(DEPDIR)/elf_error.Po \ + ./$(DEPDIR)/elf_fill.Po ./$(DEPDIR)/elf_flagdata.Po \ + ./$(DEPDIR)/elf_flagehdr.Po ./$(DEPDIR)/elf_flagelf.Po \ + ./$(DEPDIR)/elf_flagphdr.Po ./$(DEPDIR)/elf_flagscn.Po \ + ./$(DEPDIR)/elf_flagshdr.Po ./$(DEPDIR)/elf_getarhdr.Po \ + ./$(DEPDIR)/elf_getaroff.Po ./$(DEPDIR)/elf_getarsym.Po \ + ./$(DEPDIR)/elf_getbase.Po ./$(DEPDIR)/elf_getdata.Po \ + ./$(DEPDIR)/elf_getdata_rawchunk.Po \ + ./$(DEPDIR)/elf_getident.Po ./$(DEPDIR)/elf_getphdrnum.Po \ + ./$(DEPDIR)/elf_getscn.Po ./$(DEPDIR)/elf_getshdrnum.Po \ + ./$(DEPDIR)/elf_getshdrstrndx.Po ./$(DEPDIR)/elf_gnu_hash.Po \ + ./$(DEPDIR)/elf_hash.Po ./$(DEPDIR)/elf_kind.Po \ + ./$(DEPDIR)/elf_memory.Po ./$(DEPDIR)/elf_ndxscn.Po \ + ./$(DEPDIR)/elf_newdata.Po ./$(DEPDIR)/elf_newscn.Po \ + ./$(DEPDIR)/elf_next.Po ./$(DEPDIR)/elf_nextscn.Po \ + ./$(DEPDIR)/elf_rand.Po ./$(DEPDIR)/elf_rawdata.Po \ + ./$(DEPDIR)/elf_rawfile.Po ./$(DEPDIR)/elf_readall.Po \ + ./$(DEPDIR)/elf_scnshndx.Po ./$(DEPDIR)/elf_strptr.Po \ + ./$(DEPDIR)/elf_update.Po ./$(DEPDIR)/elf_version.Po \ + ./$(DEPDIR)/gelf_checksum.Po ./$(DEPDIR)/gelf_fsize.Po \ + ./$(DEPDIR)/gelf_getauxv.Po ./$(DEPDIR)/gelf_getchdr.Po \ + ./$(DEPDIR)/gelf_getclass.Po ./$(DEPDIR)/gelf_getdyn.Po \ + ./$(DEPDIR)/gelf_getehdr.Po ./$(DEPDIR)/gelf_getlib.Po \ + ./$(DEPDIR)/gelf_getmove.Po ./$(DEPDIR)/gelf_getnote.Po \ + ./$(DEPDIR)/gelf_getphdr.Po ./$(DEPDIR)/gelf_getrel.Po \ + ./$(DEPDIR)/gelf_getrela.Po ./$(DEPDIR)/gelf_getshdr.Po \ + ./$(DEPDIR)/gelf_getsym.Po ./$(DEPDIR)/gelf_getsyminfo.Po \ + ./$(DEPDIR)/gelf_getsymshndx.Po ./$(DEPDIR)/gelf_getverdaux.Po \ + ./$(DEPDIR)/gelf_getverdef.Po ./$(DEPDIR)/gelf_getvernaux.Po \ + ./$(DEPDIR)/gelf_getverneed.Po ./$(DEPDIR)/gelf_getversym.Po \ + ./$(DEPDIR)/gelf_newehdr.Po ./$(DEPDIR)/gelf_newphdr.Po \ + ./$(DEPDIR)/gelf_offscn.Po ./$(DEPDIR)/gelf_update_auxv.Po \ + ./$(DEPDIR)/gelf_update_dyn.Po ./$(DEPDIR)/gelf_update_ehdr.Po \ + ./$(DEPDIR)/gelf_update_lib.Po ./$(DEPDIR)/gelf_update_move.Po \ + ./$(DEPDIR)/gelf_update_phdr.Po ./$(DEPDIR)/gelf_update_rel.Po \ + ./$(DEPDIR)/gelf_update_rela.Po \ + ./$(DEPDIR)/gelf_update_shdr.Po ./$(DEPDIR)/gelf_update_sym.Po \ + ./$(DEPDIR)/gelf_update_syminfo.Po \ + ./$(DEPDIR)/gelf_update_symshndx.Po \ + ./$(DEPDIR)/gelf_update_verdaux.Po \ + ./$(DEPDIR)/gelf_update_verdef.Po \ + ./$(DEPDIR)/gelf_update_vernaux.Po \ + ./$(DEPDIR)/gelf_update_verneed.Po \ + ./$(DEPDIR)/gelf_update_versym.Po ./$(DEPDIR)/gelf_xlate.Po \ + ./$(DEPDIR)/gelf_xlatetof.Po ./$(DEPDIR)/gelf_xlatetom.Po \ + ./$(DEPDIR)/libelf_crc32.Po ./$(DEPDIR)/libelf_next_prime.Po \ + ./$(DEPDIR)/nlist.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libelf_a_SOURCES) $(libelf_pic_a_SOURCES) +DIST_SOURCES = $(libelf_a_SOURCES) $(libelf_pic_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(noinst_DATA) +am__include_HEADERS_DIST = libelf.h gelf.h nlist.h elf.h +am__noinst_HEADERS_DIST = abstract.h common.h exttypes.h gelf_xlate.h \ + libelfP.h version_xlate.h gnuhash_xlate.h note_xlate.h \ + dl-hash.h chdr_xlate.h elf.h +HEADERS = $(include_HEADERS) $(noinst_HEADERS) $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes \ + $(TRAMPOLINES_WARNING) $(LOGICAL_OP_WARNING) \ + $(DUPLICATED_COND_WARNING) $(NULL_DEREFERENCE_WARNING) \ + $(IMPLICIT_FALLTHROUGH_WARNING) $(if \ + $($(*F)_no_Werror),,-Werror) $(if \ + $($(*F)_no_Wunused),,-Wunused -Wextra) $(if \ + $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) $(if \ + $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) $(am__append_2) +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda $(am_libelf_pic_a_OBJECTS) libelf.so \ + libelf.so.$(VERSION) +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +lib_LIBRARIES = libelf.a +noinst_LIBRARIES = libelf_pic.a +noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so) +include_HEADERS = libelf.h gelf.h nlist.h $(am__append_3) +noinst_HEADERS = abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \ + version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h \ + chdr_xlate.h $(am__append_4) +pkginclude_HEADERS = elf-knowledge.h +libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \ + elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \ + gelf_getclass.c elf_getbase.c elf_getident.c \ + elf32_fsize.c elf64_fsize.c gelf_fsize.c \ + elf32_xlatetof.c elf32_xlatetom.c elf64_xlatetof.c \ + elf64_xlatetom.c gelf_xlate.c \ + elf32_getehdr.c elf64_getehdr.c gelf_getehdr.c \ + elf32_newehdr.c elf64_newehdr.c gelf_newehdr.c \ + gelf_update_ehdr.c \ + elf32_getphdr.c elf64_getphdr.c gelf_getphdr.c \ + elf32_newphdr.c elf64_newphdr.c gelf_newphdr.c \ + gelf_update_phdr.c \ + elf_getarhdr.c elf_getarsym.c \ + elf_rawfile.c elf_readall.c elf_cntl.c \ + elf_getscn.c elf_nextscn.c elf_ndxscn.c elf_newscn.c \ + elf32_getshdr.c elf64_getshdr.c gelf_getshdr.c \ + gelf_update_shdr.c \ + elf_strptr.c elf_rawdata.c elf_getdata.c elf_newdata.c \ + elf_getdata_rawchunk.c \ + elf_flagelf.c elf_flagehdr.c elf_flagphdr.c elf_flagscn.c \ + elf_flagshdr.c elf_flagdata.c elf_memory.c \ + elf_update.c elf32_updatenull.c elf64_updatenull.c \ + elf32_updatefile.c elf64_updatefile.c \ + gelf_getsym.c gelf_update_sym.c \ + gelf_getversym.c gelf_getverneed.c gelf_getvernaux.c \ + gelf_getverdef.c gelf_getverdaux.c \ + gelf_getrel.c gelf_getrela.c \ + gelf_update_rel.c gelf_update_rela.c \ + gelf_getdyn.c gelf_update_dyn.c \ + gelf_getmove.c gelf_update_move.c \ + gelf_getsyminfo.c gelf_update_syminfo.c \ + gelf_getauxv.c gelf_update_auxv.c \ + gelf_getnote.c \ + gelf_xlatetof.c gelf_xlatetom.c \ + nlist.c \ + gelf_getsymshndx.c gelf_update_symshndx.c \ + gelf_update_versym.c gelf_update_verneed.c \ + gelf_update_vernaux.c gelf_update_verdef.c \ + gelf_update_verdaux.c \ + elf_getphdrnum.c elf_getshdrnum.c elf_getshdrstrndx.c \ + gelf_checksum.c elf32_checksum.c elf64_checksum.c \ + libelf_crc32.c libelf_next_prime.c \ + elf_clone.c \ + gelf_getlib.c gelf_update_lib.c \ + elf32_offscn.c elf64_offscn.c gelf_offscn.c \ + elf_getaroff.c \ + elf_gnu_hash.c \ + elf_scnshndx.c \ + elf32_getchdr.c elf64_getchdr.c gelf_getchdr.c \ + elf_compress.c elf_compress_gnu.c + +libelf_pic_a_SOURCES = +am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os) +libelf_so_DEPS = ../lib/libeu.a +libelf_so_LDLIBS = $(libelf_so_DEPS) -lz $(am__append_5) +libelf_so_LIBS = libelf_pic.a +EXTRA_DIST = libelf.map +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libelf/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits libelf/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libelf.a: $(libelf_a_OBJECTS) $(libelf_a_DEPENDENCIES) $(EXTRA_libelf_a_DEPENDENCIES) + $(AM_V_at)-rm -f libelf.a + $(AM_V_AR)$(libelf_a_AR) libelf.a $(libelf_a_OBJECTS) $(libelf_a_LIBADD) + $(AM_V_at)$(RANLIB) libelf.a + +libelf_pic.a: $(libelf_pic_a_OBJECTS) $(libelf_pic_a_DEPENDENCIES) $(EXTRA_libelf_pic_a_DEPENDENCIES) + $(AM_V_at)-rm -f libelf_pic.a + $(AM_V_AR)$(libelf_pic_a_AR) libelf_pic.a $(libelf_pic_a_OBJECTS) $(libelf_pic_a_LIBADD) + $(AM_V_at)$(RANLIB) libelf_pic.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_checksum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_fsize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getchdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_getshdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_newehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_newphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_offscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_updatefile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_updatenull.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_xlatetof.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32_xlatetom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_checksum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_fsize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getchdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_getshdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_newehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_newphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_offscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_updatefile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_updatenull.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_xlatetof.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64_xlatetom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_begin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_clone.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_cntl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_compress.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_compress_gnu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_end.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_error.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_fill.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagelf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_flagshdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getarhdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getaroff.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getarsym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getbase.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getdata_rawchunk.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getident.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getphdrnum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getshdrnum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_getshdrstrndx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_gnu_hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_kind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_memory.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_ndxscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_newdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_newscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_next.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_nextscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_rand.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_rawdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_rawfile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_readall.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_scnshndx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_strptr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_update.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf_version.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_checksum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_fsize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getauxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getchdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getclass.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getdyn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getlib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getmove.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getnote.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getrel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getrela.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getshdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getsym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getsyminfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getsymshndx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getverdaux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getverdef.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getvernaux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getverneed.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_getversym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_newehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_newphdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_offscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_auxv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_dyn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_ehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_lib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_move.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_phdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_rel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_rela.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_shdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_sym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_syminfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_symshndx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_verdaux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_verdef.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_vernaux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_verneed.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_update_versym.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_xlate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_xlatetof.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gelf_xlatetom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libelf_crc32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libelf_next_prime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlist.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install-exec: install-exec-am +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/elf32_checksum.Po + -rm -f ./$(DEPDIR)/elf32_fsize.Po + -rm -f ./$(DEPDIR)/elf32_getchdr.Po + -rm -f ./$(DEPDIR)/elf32_getehdr.Po + -rm -f ./$(DEPDIR)/elf32_getphdr.Po + -rm -f ./$(DEPDIR)/elf32_getshdr.Po + -rm -f ./$(DEPDIR)/elf32_newehdr.Po + -rm -f ./$(DEPDIR)/elf32_newphdr.Po + -rm -f ./$(DEPDIR)/elf32_offscn.Po + -rm -f ./$(DEPDIR)/elf32_updatefile.Po + -rm -f ./$(DEPDIR)/elf32_updatenull.Po + -rm -f ./$(DEPDIR)/elf32_xlatetof.Po + -rm -f ./$(DEPDIR)/elf32_xlatetom.Po + -rm -f ./$(DEPDIR)/elf64_checksum.Po + -rm -f ./$(DEPDIR)/elf64_fsize.Po + -rm -f ./$(DEPDIR)/elf64_getchdr.Po + -rm -f ./$(DEPDIR)/elf64_getehdr.Po + -rm -f ./$(DEPDIR)/elf64_getphdr.Po + -rm -f ./$(DEPDIR)/elf64_getshdr.Po + -rm -f ./$(DEPDIR)/elf64_newehdr.Po + -rm -f ./$(DEPDIR)/elf64_newphdr.Po + -rm -f ./$(DEPDIR)/elf64_offscn.Po + -rm -f ./$(DEPDIR)/elf64_updatefile.Po + -rm -f ./$(DEPDIR)/elf64_updatenull.Po + -rm -f ./$(DEPDIR)/elf64_xlatetof.Po + -rm -f ./$(DEPDIR)/elf64_xlatetom.Po + -rm -f ./$(DEPDIR)/elf_begin.Po + -rm -f ./$(DEPDIR)/elf_clone.Po + -rm -f ./$(DEPDIR)/elf_cntl.Po + -rm -f ./$(DEPDIR)/elf_compress.Po + -rm -f ./$(DEPDIR)/elf_compress_gnu.Po + -rm -f ./$(DEPDIR)/elf_end.Po + -rm -f ./$(DEPDIR)/elf_error.Po + -rm -f ./$(DEPDIR)/elf_fill.Po + -rm -f ./$(DEPDIR)/elf_flagdata.Po + -rm -f ./$(DEPDIR)/elf_flagehdr.Po + -rm -f ./$(DEPDIR)/elf_flagelf.Po + -rm -f ./$(DEPDIR)/elf_flagphdr.Po + -rm -f ./$(DEPDIR)/elf_flagscn.Po + -rm -f ./$(DEPDIR)/elf_flagshdr.Po + -rm -f ./$(DEPDIR)/elf_getarhdr.Po + -rm -f ./$(DEPDIR)/elf_getaroff.Po + -rm -f ./$(DEPDIR)/elf_getarsym.Po + -rm -f ./$(DEPDIR)/elf_getbase.Po + -rm -f ./$(DEPDIR)/elf_getdata.Po + -rm -f ./$(DEPDIR)/elf_getdata_rawchunk.Po + -rm -f ./$(DEPDIR)/elf_getident.Po + -rm -f ./$(DEPDIR)/elf_getphdrnum.Po + -rm -f ./$(DEPDIR)/elf_getscn.Po + -rm -f ./$(DEPDIR)/elf_getshdrnum.Po + -rm -f ./$(DEPDIR)/elf_getshdrstrndx.Po + -rm -f ./$(DEPDIR)/elf_gnu_hash.Po + -rm -f ./$(DEPDIR)/elf_hash.Po + -rm -f ./$(DEPDIR)/elf_kind.Po + -rm -f ./$(DEPDIR)/elf_memory.Po + -rm -f ./$(DEPDIR)/elf_ndxscn.Po + -rm -f ./$(DEPDIR)/elf_newdata.Po + -rm -f ./$(DEPDIR)/elf_newscn.Po + -rm -f ./$(DEPDIR)/elf_next.Po + -rm -f ./$(DEPDIR)/elf_nextscn.Po + -rm -f ./$(DEPDIR)/elf_rand.Po + -rm -f ./$(DEPDIR)/elf_rawdata.Po + -rm -f ./$(DEPDIR)/elf_rawfile.Po + -rm -f ./$(DEPDIR)/elf_readall.Po + -rm -f ./$(DEPDIR)/elf_scnshndx.Po + -rm -f ./$(DEPDIR)/elf_strptr.Po + -rm -f ./$(DEPDIR)/elf_update.Po + -rm -f ./$(DEPDIR)/elf_version.Po + -rm -f ./$(DEPDIR)/gelf_checksum.Po + -rm -f ./$(DEPDIR)/gelf_fsize.Po + -rm -f ./$(DEPDIR)/gelf_getauxv.Po + -rm -f ./$(DEPDIR)/gelf_getchdr.Po + -rm -f ./$(DEPDIR)/gelf_getclass.Po + -rm -f ./$(DEPDIR)/gelf_getdyn.Po + -rm -f ./$(DEPDIR)/gelf_getehdr.Po + -rm -f ./$(DEPDIR)/gelf_getlib.Po + -rm -f ./$(DEPDIR)/gelf_getmove.Po + -rm -f ./$(DEPDIR)/gelf_getnote.Po + -rm -f ./$(DEPDIR)/gelf_getphdr.Po + -rm -f ./$(DEPDIR)/gelf_getrel.Po + -rm -f ./$(DEPDIR)/gelf_getrela.Po + -rm -f ./$(DEPDIR)/gelf_getshdr.Po + -rm -f ./$(DEPDIR)/gelf_getsym.Po + -rm -f ./$(DEPDIR)/gelf_getsyminfo.Po + -rm -f ./$(DEPDIR)/gelf_getsymshndx.Po + -rm -f ./$(DEPDIR)/gelf_getverdaux.Po + -rm -f ./$(DEPDIR)/gelf_getverdef.Po + -rm -f ./$(DEPDIR)/gelf_getvernaux.Po + -rm -f ./$(DEPDIR)/gelf_getverneed.Po + -rm -f ./$(DEPDIR)/gelf_getversym.Po + -rm -f ./$(DEPDIR)/gelf_newehdr.Po + -rm -f ./$(DEPDIR)/gelf_newphdr.Po + -rm -f ./$(DEPDIR)/gelf_offscn.Po + -rm -f ./$(DEPDIR)/gelf_update_auxv.Po + -rm -f ./$(DEPDIR)/gelf_update_dyn.Po + -rm -f ./$(DEPDIR)/gelf_update_ehdr.Po + -rm -f ./$(DEPDIR)/gelf_update_lib.Po + -rm -f ./$(DEPDIR)/gelf_update_move.Po + -rm -f ./$(DEPDIR)/gelf_update_phdr.Po + -rm -f ./$(DEPDIR)/gelf_update_rel.Po + -rm -f ./$(DEPDIR)/gelf_update_rela.Po + -rm -f ./$(DEPDIR)/gelf_update_shdr.Po + -rm -f ./$(DEPDIR)/gelf_update_sym.Po + -rm -f ./$(DEPDIR)/gelf_update_syminfo.Po + -rm -f ./$(DEPDIR)/gelf_update_symshndx.Po + -rm -f ./$(DEPDIR)/gelf_update_verdaux.Po + -rm -f ./$(DEPDIR)/gelf_update_verdef.Po + -rm -f ./$(DEPDIR)/gelf_update_vernaux.Po + -rm -f ./$(DEPDIR)/gelf_update_verneed.Po + -rm -f ./$(DEPDIR)/gelf_update_versym.Po + -rm -f ./$(DEPDIR)/gelf_xlate.Po + -rm -f ./$(DEPDIR)/gelf_xlatetof.Po + -rm -f ./$(DEPDIR)/gelf_xlatetom.Po + -rm -f ./$(DEPDIR)/libelf_crc32.Po + -rm -f ./$(DEPDIR)/libelf_next_prime.Po + -rm -f ./$(DEPDIR)/nlist.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/elf32_checksum.Po + -rm -f ./$(DEPDIR)/elf32_fsize.Po + -rm -f ./$(DEPDIR)/elf32_getchdr.Po + -rm -f ./$(DEPDIR)/elf32_getehdr.Po + -rm -f ./$(DEPDIR)/elf32_getphdr.Po + -rm -f ./$(DEPDIR)/elf32_getshdr.Po + -rm -f ./$(DEPDIR)/elf32_newehdr.Po + -rm -f ./$(DEPDIR)/elf32_newphdr.Po + -rm -f ./$(DEPDIR)/elf32_offscn.Po + -rm -f ./$(DEPDIR)/elf32_updatefile.Po + -rm -f ./$(DEPDIR)/elf32_updatenull.Po + -rm -f ./$(DEPDIR)/elf32_xlatetof.Po + -rm -f ./$(DEPDIR)/elf32_xlatetom.Po + -rm -f ./$(DEPDIR)/elf64_checksum.Po + -rm -f ./$(DEPDIR)/elf64_fsize.Po + -rm -f ./$(DEPDIR)/elf64_getchdr.Po + -rm -f ./$(DEPDIR)/elf64_getehdr.Po + -rm -f ./$(DEPDIR)/elf64_getphdr.Po + -rm -f ./$(DEPDIR)/elf64_getshdr.Po + -rm -f ./$(DEPDIR)/elf64_newehdr.Po + -rm -f ./$(DEPDIR)/elf64_newphdr.Po + -rm -f ./$(DEPDIR)/elf64_offscn.Po + -rm -f ./$(DEPDIR)/elf64_updatefile.Po + -rm -f ./$(DEPDIR)/elf64_updatenull.Po + -rm -f ./$(DEPDIR)/elf64_xlatetof.Po + -rm -f ./$(DEPDIR)/elf64_xlatetom.Po + -rm -f ./$(DEPDIR)/elf_begin.Po + -rm -f ./$(DEPDIR)/elf_clone.Po + -rm -f ./$(DEPDIR)/elf_cntl.Po + -rm -f ./$(DEPDIR)/elf_compress.Po + -rm -f ./$(DEPDIR)/elf_compress_gnu.Po + -rm -f ./$(DEPDIR)/elf_end.Po + -rm -f ./$(DEPDIR)/elf_error.Po + -rm -f ./$(DEPDIR)/elf_fill.Po + -rm -f ./$(DEPDIR)/elf_flagdata.Po + -rm -f ./$(DEPDIR)/elf_flagehdr.Po + -rm -f ./$(DEPDIR)/elf_flagelf.Po + -rm -f ./$(DEPDIR)/elf_flagphdr.Po + -rm -f ./$(DEPDIR)/elf_flagscn.Po + -rm -f ./$(DEPDIR)/elf_flagshdr.Po + -rm -f ./$(DEPDIR)/elf_getarhdr.Po + -rm -f ./$(DEPDIR)/elf_getaroff.Po + -rm -f ./$(DEPDIR)/elf_getarsym.Po + -rm -f ./$(DEPDIR)/elf_getbase.Po + -rm -f ./$(DEPDIR)/elf_getdata.Po + -rm -f ./$(DEPDIR)/elf_getdata_rawchunk.Po + -rm -f ./$(DEPDIR)/elf_getident.Po + -rm -f ./$(DEPDIR)/elf_getphdrnum.Po + -rm -f ./$(DEPDIR)/elf_getscn.Po + -rm -f ./$(DEPDIR)/elf_getshdrnum.Po + -rm -f ./$(DEPDIR)/elf_getshdrstrndx.Po + -rm -f ./$(DEPDIR)/elf_gnu_hash.Po + -rm -f ./$(DEPDIR)/elf_hash.Po + -rm -f ./$(DEPDIR)/elf_kind.Po + -rm -f ./$(DEPDIR)/elf_memory.Po + -rm -f ./$(DEPDIR)/elf_ndxscn.Po + -rm -f ./$(DEPDIR)/elf_newdata.Po + -rm -f ./$(DEPDIR)/elf_newscn.Po + -rm -f ./$(DEPDIR)/elf_next.Po + -rm -f ./$(DEPDIR)/elf_nextscn.Po + -rm -f ./$(DEPDIR)/elf_rand.Po + -rm -f ./$(DEPDIR)/elf_rawdata.Po + -rm -f ./$(DEPDIR)/elf_rawfile.Po + -rm -f ./$(DEPDIR)/elf_readall.Po + -rm -f ./$(DEPDIR)/elf_scnshndx.Po + -rm -f ./$(DEPDIR)/elf_strptr.Po + -rm -f ./$(DEPDIR)/elf_update.Po + -rm -f ./$(DEPDIR)/elf_version.Po + -rm -f ./$(DEPDIR)/gelf_checksum.Po + -rm -f ./$(DEPDIR)/gelf_fsize.Po + -rm -f ./$(DEPDIR)/gelf_getauxv.Po + -rm -f ./$(DEPDIR)/gelf_getchdr.Po + -rm -f ./$(DEPDIR)/gelf_getclass.Po + -rm -f ./$(DEPDIR)/gelf_getdyn.Po + -rm -f ./$(DEPDIR)/gelf_getehdr.Po + -rm -f ./$(DEPDIR)/gelf_getlib.Po + -rm -f ./$(DEPDIR)/gelf_getmove.Po + -rm -f ./$(DEPDIR)/gelf_getnote.Po + -rm -f ./$(DEPDIR)/gelf_getphdr.Po + -rm -f ./$(DEPDIR)/gelf_getrel.Po + -rm -f ./$(DEPDIR)/gelf_getrela.Po + -rm -f ./$(DEPDIR)/gelf_getshdr.Po + -rm -f ./$(DEPDIR)/gelf_getsym.Po + -rm -f ./$(DEPDIR)/gelf_getsyminfo.Po + -rm -f ./$(DEPDIR)/gelf_getsymshndx.Po + -rm -f ./$(DEPDIR)/gelf_getverdaux.Po + -rm -f ./$(DEPDIR)/gelf_getverdef.Po + -rm -f ./$(DEPDIR)/gelf_getvernaux.Po + -rm -f ./$(DEPDIR)/gelf_getverneed.Po + -rm -f ./$(DEPDIR)/gelf_getversym.Po + -rm -f ./$(DEPDIR)/gelf_newehdr.Po + -rm -f ./$(DEPDIR)/gelf_newphdr.Po + -rm -f ./$(DEPDIR)/gelf_offscn.Po + -rm -f ./$(DEPDIR)/gelf_update_auxv.Po + -rm -f ./$(DEPDIR)/gelf_update_dyn.Po + -rm -f ./$(DEPDIR)/gelf_update_ehdr.Po + -rm -f ./$(DEPDIR)/gelf_update_lib.Po + -rm -f ./$(DEPDIR)/gelf_update_move.Po + -rm -f ./$(DEPDIR)/gelf_update_phdr.Po + -rm -f ./$(DEPDIR)/gelf_update_rel.Po + -rm -f ./$(DEPDIR)/gelf_update_rela.Po + -rm -f ./$(DEPDIR)/gelf_update_shdr.Po + -rm -f ./$(DEPDIR)/gelf_update_sym.Po + -rm -f ./$(DEPDIR)/gelf_update_syminfo.Po + -rm -f ./$(DEPDIR)/gelf_update_symshndx.Po + -rm -f ./$(DEPDIR)/gelf_update_verdaux.Po + -rm -f ./$(DEPDIR)/gelf_update_verdef.Po + -rm -f ./$(DEPDIR)/gelf_update_vernaux.Po + -rm -f ./$(DEPDIR)/gelf_update_verneed.Po + -rm -f ./$(DEPDIR)/gelf_update_versym.Po + -rm -f ./$(DEPDIR)/gelf_xlate.Po + -rm -f ./$(DEPDIR)/gelf_xlatetof.Po + -rm -f ./$(DEPDIR)/gelf_xlatetom.Po + -rm -f ./$(DEPDIR)/libelf_crc32.Po + -rm -f ./$(DEPDIR)/libelf_next_prime.Po + -rm -f ./$(DEPDIR)/nlist.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLIBRARIES \ + uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-libLIBRARIES install-man install-pdf install-pdf-am \ + install-pkgincludeHEADERS install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLIBRARIES uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) +libelf.so: $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS) + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \ + -Wl,--soname,$@.$(VERSION) \ + -Wl,--version-script,$<,--no-undefined \ + -Wl,--whole-archive $(libelf_so_LIBS) -Wl,--no-whole-archive \ + $(libelf_so_LDLIBS) + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + +install: install-am libelf.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so + ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION) + ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libelf.so + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libelf/abstract.h b/libelf/abstract.h new file mode 100644 index 00000000..d4515f27 --- /dev/null +++ b/libelf/abstract.h @@ -0,0 +1,330 @@ +/* Abstract description of component ELF types. + Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +/* ELF header. */ +#define Ehdr(Bits, Ext) \ +START (Bits, Ehdr, Ext##Ehdr) \ + TYPE_EXTRA (unsigned char e_ident[EI_NIDENT];) \ + TYPE_XLATE (memmove (tdest->e_ident, tsrc->e_ident, EI_NIDENT);) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_type) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_machine) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), e_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Addr), e_entry) \ + TYPE_NAME (ElfW2(Bits, Ext##Off), e_phoff) \ + TYPE_NAME (ElfW2(Bits, Ext##Off), e_shoff) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), e_flags) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_ehsize) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_phentsize) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_phnum) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_shentsize) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_shnum) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), e_shstrndx) \ +END (Bits, Ext##Ehdr) + +#define Ehdr32(Ext) \ + Ehdr(32, Ext) +#define Ehdr64(Ext) \ + Ehdr(64, Ext) + + +/* Program header. */ +#define Phdr32(Ext) \ +START (32, Phdr, Ext##Phdr) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_type) \ + TYPE_NAME (ElfW2(32, Ext##Off), p_offset) \ + TYPE_NAME (ElfW2(32, Ext##Addr), p_vaddr) \ + TYPE_NAME (ElfW2(32, Ext##Addr), p_paddr) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_filesz) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_memsz) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_flags) \ + TYPE_NAME (ElfW2(32, Ext##Word), p_align) \ +END (32, Ext##Phdr) +#define Phdr64(Ext) \ +START (64, Phdr, Ext##Phdr) \ + TYPE_NAME (ElfW2(64, Ext##Word), p_type) \ + TYPE_NAME (ElfW2(64, Ext##Word), p_flags) \ + TYPE_NAME (ElfW2(64, Ext##Off), p_offset) \ + TYPE_NAME (ElfW2(64, Ext##Addr), p_vaddr) \ + TYPE_NAME (ElfW2(64, Ext##Addr), p_paddr) \ + TYPE_NAME (ElfW2(64, Ext##Xword), p_filesz) \ + TYPE_NAME (ElfW2(64, Ext##Xword), p_memsz) \ + TYPE_NAME (ElfW2(64, Ext##Xword), p_align) \ +END (64, Ext##Phdr) + + +/* Section header. */ +#define Shdr32(Ext) \ +START (32, Shdr, Ext##Shdr) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_name) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_type) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_flags) \ + TYPE_NAME (ElfW2(32, Ext##Addr), sh_addr) \ + TYPE_NAME (ElfW2(32, Ext##Off), sh_offset) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_size) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_link) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_info) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_addralign) \ + TYPE_NAME (ElfW2(32, Ext##Word), sh_entsize) \ +END (32, Ext##Shdr) +#define Shdr64(Ext) \ +START (64, Shdr, Ext##Shdr) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_name) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_type) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_flags) \ + TYPE_NAME (ElfW2(64, Ext##Addr), sh_addr) \ + TYPE_NAME (ElfW2(64, Ext##Off), sh_offset) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_size) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_link) \ + TYPE_NAME (ElfW2(64, Ext##Word), sh_info) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_addralign) \ + TYPE_NAME (ElfW2(64, Ext##Xword), sh_entsize) \ +END (64, Ext##Shdr) + + +/* Symbol table. */ +#define Sym32(Ext) \ +START (32, Sym, Ext##Sym) \ + TYPE_NAME (ElfW2(32, Ext##Word), st_name) \ + TYPE_NAME (ElfW2(32, Ext##Addr), st_value) \ + TYPE_NAME (ElfW2(32, Ext##Word), st_size) \ + TYPE_EXTRA (unsigned char st_info;) \ + TYPE_XLATE (tdest->st_info = tsrc->st_info;) \ + TYPE_EXTRA (unsigned char st_other;) \ + TYPE_XLATE (tdest->st_other = tsrc->st_other;) \ + TYPE_NAME (ElfW2(32, Ext##Half), st_shndx) \ +END (32, Ext##Sym) +#define Sym64(Ext) \ +START (64, Sym, Ext##Sym) \ + TYPE_NAME (ElfW2(64, Ext##Word), st_name) \ + TYPE_EXTRA (unsigned char st_info;) \ + TYPE_XLATE (tdest->st_info = tsrc->st_info;) \ + TYPE_EXTRA (unsigned char st_other;) \ + TYPE_XLATE (tdest->st_other = tsrc->st_other;) \ + TYPE_NAME (ElfW2(64, Ext##Half), st_shndx) \ + TYPE_NAME (ElfW2(64, Ext##Addr), st_value) \ + TYPE_NAME (ElfW2(64, Ext##Xword), st_size) \ +END (64, Ext##Sym) + + +/* Relocation. */ +#define Rel32(Ext) \ +START (32, Rel, Ext##Rel) \ + TYPE_NAME (ElfW2(32, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(32, Ext##Word), r_info) \ +END (32, Ext##Rel) +#define Rel64(Ext) \ +START (64, Rel, Ext##Rel) \ + TYPE_NAME (ElfW2(64, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(64, Ext##Xword), r_info) \ +END (64, Ext##Rel) + +#define Rela32(Ext) \ +START (32, Rela, Ext##Rela) \ + TYPE_NAME (ElfW2(32, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(32, Ext##Word), r_info) \ + TYPE_NAME (ElfW2(32, Ext##Sword), r_addend) \ +END (32, Ext##Rela) +#define Rela64(Ext) \ +START (64, Rela, Ext##Rela) \ + TYPE_NAME (ElfW2(64, Ext##Addr), r_offset) \ + TYPE_NAME (ElfW2(64, Ext##Xword), r_info) \ + TYPE_NAME (ElfW2(64, Ext##Sxword), r_addend) \ +END (64, Ext##Rela) + + +/* Note entry header. */ +#define Note(Bits, Ext) \ +START (Bits, Nhdr, Ext##Nhdr) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), n_namesz) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), n_descsz) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), n_type) \ +END (Bits, Ext##Nhdr) + +#define Note32(Ext) \ + Note (32, Ext) +#define Note64(Ext) \ + Note (64, Ext) + + +/* Dynamic section data. */ +#define Dyn32(Ext) \ +START (32, Dyn, Ext##Dyn) \ + TYPE_NAME (ElfW2(32, Ext##Sword), d_tag) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(32, Ext##Word) d_val;) \ + TYPE_EXTRA (ElfW2(32, Ext##Addr) d_ptr;) \ + TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);) \ + TYPE_EXTRA (ElfW2(32, Ext##Off) d_off;) \ + TYPE_EXTRA (} d_un;) \ +END (32, Ext##Dyn) +#define Dyn64(Ext) \ +START (64, Dyn, Ext##Dyn) \ + TYPE_NAME (ElfW2(64, Ext##Xword), d_tag) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(64, Ext##Xword) d_val;) \ + TYPE_EXTRA (ElfW2(64, Ext##Addr) d_ptr;) \ + TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);) \ + TYPE_EXTRA (} d_un;) \ +END (64, Ext##Dyn) + + +#ifndef GENERATE_CONVERSION +/* Version definitions. */ +# define Verdef(Bits, Ext) \ +START (Bits, Verdef, Ext##Verdef) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_flags) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_ndx) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vd_cnt) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vd_hash) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vd_aux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vd_next) \ +END (Bits, Ext##Verdef) + +# define Verdef32(Ext) \ + Verdef (32, Ext) +# define Verdef64(Ext) \ + Verdef (64, Ext) + +# define Verdaux(Bits, Ext) \ +START (Bits, Verdaux, Ext##Verdaux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vda_name) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vda_next) \ +END (Bits, Ext##Verdaux) + +# define Verdaux32(Ext) \ + Verdaux (32, Ext) +# define Verdaux64(Ext) \ + Verdaux (64, Ext) + +/* Required versions. */ +# define Verneed(Bits, Ext) \ +START (Bits, Verneed, Ext##Verneed) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vn_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vn_cnt) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vn_file) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vn_aux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vn_next) \ +END (Bits, Ext##Verneed) + +# define Verneed32(Ext) \ + Verneed (32, Ext) +# define Verneed64(Ext) \ + Verneed (64, Ext) + +# define Vernaux(Bits, Ext) \ +START (Bits, Vernaux, Ext##Vernaux) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vna_hash) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vna_flags) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), vna_other) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vna_name) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), vna_next) \ +END (Bits, Ext##Vernaux) + +# define Vernaux32(Ext) \ + Vernaux (32, Ext) +# define Vernaux64(Ext) \ + Vernaux (64, Ext) +#endif + +/* Symbol information. */ +#define Syminfo(Bits, Ext) \ +START (Bits, Syminfo, Ext##Syminfo) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), si_boundto) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), si_flags) \ +END (Bits, Ext##Syminfo) + +#define Syminfo32(Ext) \ + Syminfo (32, Ext) +#define Syminfo64(Ext) \ + Syminfo (64, Ext) + +/* Move information. */ +#define Move(Bits, Ext) \ +START (Bits, Move, Ext##Move) \ + TYPE_NAME (ElfW2(Bits, Ext##Xword), m_value) \ + TYPE_NAME (ElfW2(Bits, Ext##Xword), m_info) \ + TYPE_NAME (ElfW2(Bits, Ext##Xword), m_poffset) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), m_repeat) \ + TYPE_NAME (ElfW2(Bits, Ext##Half), m_stride) \ +END (Bits, Ext##Move) + +#define Move32(Ext) \ + Move (32, Ext) +#define Move64(Ext) \ + Move (64, Ext) + +#define Lib(Bits, Ext) \ +START (Bits, Lib, Ext##Lib) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_name) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_time_stamp) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_checksum) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_version) \ + TYPE_NAME (ElfW2(Bits, Ext##Word), l_flags) \ +END (Bits, Ext##Lib) + +#define Lib32(Ext) \ + Lib (32, Ext) +#define Lib64(Ext) \ + Lib (64, Ext) + +#define auxv_t32(Ext) \ +START (32, auxv_t, Ext##auxv_t) \ + TYPE_NAME (ElfW2(32, Ext##Word), a_type) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(32, Ext##Word) a_val;) \ + TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);) \ + TYPE_EXTRA (} a_un;) \ +END (32, Ext##auxv_t) +#define auxv_t64(Ext) \ +START (64, auxv_t, Ext##auxv_t) \ + TYPE_NAME (ElfW2(64, Ext##Xword), a_type) \ + TYPE_EXTRA (union {) \ + TYPE_EXTRA (ElfW2(64, Ext##Xword) a_val;) \ + TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);) \ + TYPE_EXTRA (} a_un;) \ +END (64, Ext##auxv_t) + +/* Note that there is actual compression data right after the Chdr. + So we also have a separate conversion function for the whole + section. */ +#define Chdr32(Ext) \ +START (32, Chdr, Ext##Chdr) \ + TYPE_NAME (ElfW2(32, Ext##Word), ch_type) \ + TYPE_NAME (ElfW2(32, Ext##Word), ch_size) \ + TYPE_NAME (ElfW2(32, Ext##Word), ch_addralign) \ +END (32, Ext##Chdr) + +#define Chdr64(Ext) \ +START (64, Chdr, Ext##Chdr) \ + TYPE_NAME (ElfW2(64, Ext##Word), ch_type) \ + TYPE_NAME (ElfW2(64, Ext##Word), ch_reserved) \ + TYPE_NAME (ElfW2(64, Ext##Xword), ch_size) \ + TYPE_NAME (ElfW2(64, Ext##Xword), ch_addralign) \ +END (64, Ext##Chdr) diff --git a/libelf/chdr_xlate.h b/libelf/chdr_xlate.h new file mode 100644 index 00000000..70782b43 --- /dev/null +++ b/libelf/chdr_xlate.h @@ -0,0 +1,33 @@ +#include "common.h" + +/* These functions convert a while section, one Chdr plus compression data. */ + +static void +Elf32_cvt_chdr (void *dest, const void *src, size_t len, int encode) +{ + if (len == 0) + return; + + /* Move everything over, if necessary, we only need to xlate the + header, not the compressed data following it. */ + if (dest != src) + memmove (dest, src, len); + + if (len >= sizeof (Elf32_Chdr)) + Elf32_cvt_Chdr (dest, src, sizeof (Elf32_Chdr), encode); +} + +static void +Elf64_cvt_chdr (void *dest, const void *src, size_t len, int encode) +{ + if (len == 0) + return; + + /* Move everything over, if necessary, we only need to xlate the + header, not the compressed data following it. */ + if (dest != src) + memmove (dest, src, len); + + if (len >= sizeof (Elf64_Chdr)) + Elf64_cvt_Chdr (dest, src, sizeof (Elf64_Chdr), encode); +} diff --git a/libelf/common.h b/libelf/common.h new file mode 100644 index 00000000..e41c717d --- /dev/null +++ b/libelf/common.h @@ -0,0 +1,163 @@ +/* Common definitions for handling files in memory or only on disk. + Copyright (C) 1998, 1999, 2000, 2002, 2005, 2008 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _COMMON_H +#define _COMMON_H 1 + +#include +#include +#include +#include +#include + +#include "libelfP.h" + +static inline Elf_Kind +__attribute__ ((unused)) +determine_kind (void *buf, size_t len) +{ + /* First test for an archive. */ + if (len >= SARMAG && memcmp (buf, ARMAG, SARMAG) == 0) + return ELF_K_AR; + + /* Next try ELF files. */ + if (len >= EI_NIDENT && memcmp (buf, ELFMAG, SELFMAG) == 0) + { + /* Could be an ELF file. */ + int eclass = (int) ((unsigned char *) buf)[EI_CLASS]; + int data = (int) ((unsigned char *) buf)[EI_DATA]; + int version = (int) ((unsigned char *) buf)[EI_VERSION]; + + if (eclass > ELFCLASSNONE && eclass < ELFCLASSNUM + && data > ELFDATANONE && data < ELFDATANUM + && version == EV_CURRENT) + return ELF_K_ELF; + } + + /* We do not know this file type. */ + return ELF_K_NONE; +} + + +/* Allocate an Elf descriptor and fill in the generic information. */ +static inline Elf * +__attribute__ ((unused)) +allocate_elf (int fildes, void *map_address, int64_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra) +{ + Elf *result = (Elf *) calloc (1, sizeof (Elf) + extra); + if (result == NULL) + __libelf_seterrno (ELF_E_NOMEM); + else + { + result->kind = kind; + result->ref_count = 1; + result->cmd = cmd; + result->fildes = fildes; + result->start_offset = offset; + result->maximum_size = maxsize; + result->map_address = map_address; + result->parent = parent; + + rwlock_init (result->lock); + } + + return result; +} + + +/* Acquire lock for the descriptor and all children. */ +static void +__attribute__ ((unused)) +libelf_acquire_all (Elf *elf) +{ + rwlock_wrlock (elf->lock); + + if (elf->kind == ELF_K_AR) + { + Elf *child = elf->state.ar.children; + + while (child != NULL) + { + if (child->ref_count != 0) + libelf_acquire_all (child); + child = child->next; + } + } +} + +/* Release own lock and those of the children. */ +static void +__attribute__ ((unused)) +libelf_release_all (Elf *elf) +{ + if (elf->kind == ELF_K_AR) + { + Elf *child = elf->state.ar.children; + + while (child != NULL) + { + if (child->ref_count != 0) + libelf_release_all (child); + child = child->next; + } + } + + rwlock_unlock (elf->lock); +} + + +/* Macro to convert endianness in place. It determines the function it + has to use itself. */ +#define CONVERT(Var) \ + (Var) = (sizeof (Var) == 1 \ + ? (unsigned char) (Var) \ + : (sizeof (Var) == 2 \ + ? bswap_16 (Var) \ + : (sizeof (Var) == 4 \ + ? bswap_32 (Var) \ + : bswap_64 (Var)))) + +#define CONVERT_TO(Dst, Var) \ + (Dst) = (sizeof (Var) == 1 \ + ? (unsigned char) (Var) \ + : (sizeof (Var) == 2 \ + ? bswap_16 (Var) \ + : (sizeof (Var) == 4 \ + ? bswap_32 (Var) \ + : bswap_64 (Var)))) + + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define MY_ELFDATA ELFDATA2LSB +#else +# define MY_ELFDATA ELFDATA2MSB +#endif + +#endif /* common.h */ diff --git a/libelf/dl-hash.h b/libelf/dl-hash.h new file mode 100644 index 00000000..6ee5d1a6 --- /dev/null +++ b/libelf/dl-hash.h @@ -0,0 +1,75 @@ +/* Compute hash value for given string according to ELF standard. + Copyright (C) 1995-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _DL_HASH_H +#define _DL_HASH_H 1 + + +/* This is the hashing function specified by the ELF ABI. In the + first five operations no overflow is possible so we optimized it a + bit. */ +static unsigned int +__attribute__ ((unused)) +_dl_elf_hash (const char *name_arg) +{ + const unsigned char *name = (const unsigned char *) name_arg; + unsigned long int hash = *name; + if (hash != 0 && name[1] != '\0') + { + hash = (hash << 4) + name[1]; + if (name[2] != '\0') + { + hash = (hash << 4) + name[2]; + if (name[3] != '\0') + { + hash = (hash << 4) + name[3]; + if (name[4] != '\0') + { + hash = (hash << 4) + name[4]; + name += 5; + while (*name != '\0') + { + unsigned long int hi; + hash = (hash << 4) + *name++; + hi = hash & 0xf0000000; + + /* The algorithm specified in the ELF ABI is as + follows: + + if (hi != 0) + hash ^= hi >> 24; + + hash &= ~hi; + + But the following is equivalent and a lot + faster, especially on modern processors. */ + + hash ^= hi >> 24; + } + + /* Second part of the modified formula. This + operation can be lifted outside the loop. */ + hash &= 0x0fffffff; + } + } + } + } + return hash; +} + +#endif /* dl-hash.h */ diff --git a/libelf/elf-knowledge.h b/libelf/elf-knowledge.h new file mode 100644 index 00000000..6e005fa5 --- /dev/null +++ b/libelf/elf-knowledge.h @@ -0,0 +1,101 @@ +/* Accumulation of various pieces of knowledge about ELF. + Copyright (C) 2000-2012, 2014, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _ELF_KNOWLEDGE_H +#define _ELF_KNOWLEDGE_H 1 + +#include + + +/* Test whether a section can be stripped or not. */ +#define SECTION_STRIP_P(shdr, name, remove_comment) \ + /* Sections which are allocated are not removed. */ \ + (((shdr)->sh_flags & SHF_ALLOC) == 0 \ + /* We never remove .note sections. */ \ + && (shdr)->sh_type != SHT_NOTE \ + && (((shdr)->sh_type) != SHT_PROGBITS \ + /* Never remove .gnu.warning.* sections. */ \ + || (name != NULL \ + && strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) != 0\ + /* We remove .comment sections only if explicitly told to do so. */\ + && (remove_comment \ + || strcmp (name, ".comment") != 0)))) + + +/* Test whether `sh_info' field in section header contains a section + index. There are two kinds of sections doing this: + + - the sections containing relocation information reference in this + field the section to which the relocations apply; + + - section with the SHF_INFO_LINK flag set to signal that `sh_info' + references a section. This allows correct handling of unknown + sections. */ +#define SH_INFO_LINK_P(Shdr) \ + ((Shdr)->sh_type == SHT_REL || (Shdr)->sh_type == SHT_RELA \ + || ((Shdr)->sh_flags & SHF_INFO_LINK) != 0) + + +/* Size of an entry in the hash table. The ELF specification says all + entries are regardless of platform 32-bits in size. Early 64-bit + ports (namely Alpha for Linux) got this wrong. The wording was not + clear. + + Several years later the ABI for the 64-bit S390s was developed. + Many things were copied from the IA-64 ABI (which uses the correct + 32-bit entry size) but it does get the SHT_HASH entry size wrong by + using a 64-bit entry size. So now we need this macro to special + case both the alpha and s390x ABIs. */ +#define SH_ENTSIZE_HASH(Ehdr) \ + ((Ehdr)->e_machine == EM_ALPHA \ + || ((Ehdr)->e_machine == EM_S390 \ + && (Ehdr)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4) + +/* GNU Annobin notes are not fully standardized and abuses the owner name. */ + +#define ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX "GA" + +#define NT_GNU_BUILD_ATTRIBUTE_OPEN 0x100 +#define NT_GNU_BUILD_ATTRIBUTE_FUNC 0x101 + +#define GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC '*' +#define GNU_BUILD_ATTRIBUTE_TYPE_STRING '$' +#define GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE '+' +#define GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE '!' + +#define GNU_BUILD_ATTRIBUTE_VERSION 1 +#define GNU_BUILD_ATTRIBUTE_STACK_PROT 2 +#define GNU_BUILD_ATTRIBUTE_RELRO 3 +#define GNU_BUILD_ATTRIBUTE_STACK_SIZE 4 +#define GNU_BUILD_ATTRIBUTE_TOOL 5 +#define GNU_BUILD_ATTRIBUTE_ABI 6 +#define GNU_BUILD_ATTRIBUTE_PIC 7 +#define GNU_BUILD_ATTRIBUTE_SHORT_ENUM 8 + +#endif /* elf-knowledge.h */ diff --git a/libelf/elf.h b/libelf/elf.h new file mode 100644 index 00000000..8e3e618f --- /dev/null +++ b/libelf/elf.h @@ -0,0 +1,4105 @@ +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ELF_H +#define _ELF_H 1 + +/* Standard ELF types. */ + +#include + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; + +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ +#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_IAMCU 6 /* Intel MCU */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + /* reserved 11-14 */ +#define EM_PARISC 15 /* HPPA */ + /* reserved 16 */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ +#define EM_SPU 23 /* IBM SPU/SPC */ + /* reserved 24-35 */ +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam */ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ +#define EM_PDP10 64 /* Digital PDP-10 */ +#define EM_PDP11 65 /* Digital PDP-11 */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit emb.proc */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit emb.proc */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_COMPACT 93 /* ARC International ARCompact */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore */ +#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */ +#define EM_NS32K 97 /* National Semi. 32000 */ +#define EM_TPC 98 /* Tenor Network TPC */ +#define EM_SNP1K 99 /* Trebia SNP 1000 */ +#define EM_ST200 100 /* STMicroelectronics ST200 */ +#define EM_IP2K 101 /* Ubicom IP2xxx */ +#define EM_MAX 102 /* MAX processor */ +#define EM_CR 103 /* National Semi. CompactRISC */ +#define EM_F2MC16 104 /* Fujitsu F2MC16 */ +#define EM_MSP430 105 /* Texas Instruments msp430 */ +#define EM_BLACKFIN 106 /* Analog Devices Blackfin DSP */ +#define EM_SE_C33 107 /* Seiko Epson S1C33 family */ +#define EM_SEP 108 /* Sharp embedded microprocessor */ +#define EM_ARCA 109 /* Arca RISC */ +#define EM_UNICORE 110 /* PKU-Unity & MPRC Peking Uni. mc series */ +#define EM_EXCESS 111 /* eXcess configurable cpu */ +#define EM_DXP 112 /* Icera Semi. Deep Execution Processor */ +#define EM_ALTERA_NIOS2 113 /* Altera Nios II */ +#define EM_CRX 114 /* National Semi. CompactRISC CRX */ +#define EM_XGATE 115 /* Motorola XGATE */ +#define EM_C166 116 /* Infineon C16x/XC16x */ +#define EM_M16C 117 /* Renesas M16C */ +#define EM_DSPIC30F 118 /* Microchip Technology dsPIC30F */ +#define EM_CE 119 /* Freescale Communication Engine RISC */ +#define EM_M32C 120 /* Renesas M32C */ + /* reserved 121-130 */ +#define EM_TSK3000 131 /* Altium TSK3000 */ +#define EM_RS08 132 /* Freescale RS08 */ +#define EM_SHARC 133 /* Analog Devices SHARC family */ +#define EM_ECOG2 134 /* Cyan Technology eCOG2 */ +#define EM_SCORE7 135 /* Sunplus S+core7 RISC */ +#define EM_DSP24 136 /* New Japan Radio (NJR) 24-bit DSP */ +#define EM_VIDEOCORE3 137 /* Broadcom VideoCore III */ +#define EM_LATTICEMICO32 138 /* RISC for Lattice FPGA */ +#define EM_SE_C17 139 /* Seiko Epson C17 */ +#define EM_TI_C6000 140 /* Texas Instruments TMS320C6000 DSP */ +#define EM_TI_C2000 141 /* Texas Instruments TMS320C2000 DSP */ +#define EM_TI_C5500 142 /* Texas Instruments TMS320C55x DSP */ +#define EM_TI_ARP32 143 /* Texas Instruments App. Specific RISC */ +#define EM_TI_PRU 144 /* Texas Instruments Prog. Realtime Unit */ + /* reserved 145-159 */ +#define EM_MMDSP_PLUS 160 /* STMicroelectronics 64bit VLIW DSP */ +#define EM_CYPRESS_M8C 161 /* Cypress M8C */ +#define EM_R32C 162 /* Renesas R32C */ +#define EM_TRIMEDIA 163 /* NXP Semi. TriMedia */ +#define EM_QDSP6 164 /* QUALCOMM DSP6 */ +#define EM_8051 165 /* Intel 8051 and variants */ +#define EM_STXP7X 166 /* STMicroelectronics STxP7x */ +#define EM_NDS32 167 /* Andes Tech. compact code emb. RISC */ +#define EM_ECOG1X 168 /* Cyan Technology eCOG1X */ +#define EM_MAXQ30 169 /* Dallas Semi. MAXQ30 mc */ +#define EM_XIMO16 170 /* New Japan Radio (NJR) 16-bit DSP */ +#define EM_MANIK 171 /* M2000 Reconfigurable RISC */ +#define EM_CRAYNV2 172 /* Cray NV2 vector architecture */ +#define EM_RX 173 /* Renesas RX */ +#define EM_METAG 174 /* Imagination Tech. META */ +#define EM_MCST_ELBRUS 175 /* MCST Elbrus */ +#define EM_ECOG16 176 /* Cyan Technology eCOG16 */ +#define EM_CR16 177 /* National Semi. CompactRISC CR16 */ +#define EM_ETPU 178 /* Freescale Extended Time Processing Unit */ +#define EM_SLE9X 179 /* Infineon Tech. SLE9X */ +#define EM_L10M 180 /* Intel L10M */ +#define EM_K10M 181 /* Intel K10M */ + /* reserved 182 */ +#define EM_AARCH64 183 /* ARM AARCH64 */ + /* reserved 184 */ +#define EM_AVR32 185 /* Amtel 32-bit microprocessor */ +#define EM_STM8 186 /* STMicroelectronics STM8 */ +#define EM_TILE64 187 /* Tilera TILE64 */ +#define EM_TILEPRO 188 /* Tilera TILEPro */ +#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ +#define EM_CUDA 190 /* NVIDIA CUDA */ +#define EM_TILEGX 191 /* Tilera TILE-Gx */ +#define EM_CLOUDSHIELD 192 /* CloudShield */ +#define EM_COREA_1ST 193 /* KIPO-KAIST Core-A 1st gen. */ +#define EM_COREA_2ND 194 /* KIPO-KAIST Core-A 2nd gen. */ +#define EM_ARCV2 195 /* Synopsys ARCv2 ISA. */ +#define EM_OPEN8 196 /* Open8 RISC */ +#define EM_RL78 197 /* Renesas RL78 */ +#define EM_VIDEOCORE5 198 /* Broadcom VideoCore V */ +#define EM_78KOR 199 /* Renesas 78KOR */ +#define EM_56800EX 200 /* Freescale 56800EX DSC */ +#define EM_BA1 201 /* Beyond BA1 */ +#define EM_BA2 202 /* Beyond BA2 */ +#define EM_XCORE 203 /* XMOS xCORE */ +#define EM_MCHP_PIC 204 /* Microchip 8-bit PIC(r) */ + /* reserved 205-209 */ +#define EM_KM32 210 /* KM211 KM32 */ +#define EM_KMX32 211 /* KM211 KMX32 */ +#define EM_EMX16 212 /* KM211 KMX16 */ +#define EM_EMX8 213 /* KM211 KMX8 */ +#define EM_KVARC 214 /* KM211 KVARC */ +#define EM_CDP 215 /* Paneve CDP */ +#define EM_COGE 216 /* Cognitive Smart Memory Processor */ +#define EM_COOL 217 /* Bluechip CoolEngine */ +#define EM_NORC 218 /* Nanoradio Optimized RISC */ +#define EM_CSR_KALIMBA 219 /* CSR Kalimba */ +#define EM_Z80 220 /* Zilog Z80 */ +#define EM_VISIUM 221 /* Controls and Data Services VISIUMcore */ +#define EM_FT32 222 /* FTDI Chip FT32 */ +#define EM_MOXIE 223 /* Moxie processor */ +#define EM_AMDGPU 224 /* AMD GPU */ + /* reserved 225-242 */ +#define EM_RISCV 243 /* RISC-V */ + +#define EM_BPF 247 /* Linux BPF -- in-kernel virtual machine */ +#define EM_CSKY 252 /* C-SKY */ + +#define EM_NUM 253 + +/* Old spellings/synonyms. */ + +#define EM_ARC_A5 EM_ARC_COMPACT + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_BEFORE 0xff00 /* Order section before all others + (Solaris). */ +#define SHN_AFTER 0xff01 /* Order section after all others + (Solaris). */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_GNU_RETAIN (1 << 21) /* Not to be GCed by linker. */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ + +/* Section compression header. Used when SHF_COMPRESSED is set. */ + +typedef struct +{ + Elf32_Word ch_type; /* Compression format. */ + Elf32_Word ch_size; /* Uncompressed data size. */ + Elf32_Word ch_addralign; /* Uncompressed data alignment. */ +} Elf32_Chdr; + +typedef struct +{ + Elf64_Word ch_type; /* Compression format. */ + Elf64_Word ch_reserved; + Elf64_Xword ch_size; /* Uncompressed data size. */ + Elf64_Xword ch_addralign; /* Uncompressed data alignment. */ +} Elf64_Chdr; + +/* Legal values for ch_type (compression algorithm). */ +#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */ +#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */ +#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */ +#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */ +#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_GNU_UNIQUE 10 /* Unique symbol. */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + + +/* How to extract and insert information held in the st_other field. */ + +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) + +/* For ELF64 the definitions are the same. */ +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) + +/* Symbol visibility specification encoded in the st_other field. */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Special value for e_phnum. This indicates that the real number of + program headers is too large to fit into e_phnum. Instead the real + value is in the field sh_info of section 0. */ + +#define PN_XNUM 0xffff + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_GNU_PROPERTY 0x6474e553 /* GNU property */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_PRFPREG 2 /* Contains copy of fpregset + struct. */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ +#define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t, + size might increase */ +#define NT_FILE 0x46494c45 /* Contains information about mapped + files */ +#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ +#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ +#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ +#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_PPC_TAR 0x103 /* Target Address Register */ +#define NT_PPC_PPR 0x104 /* Program Priority Register */ +#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */ +#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */ +#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */ +#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */ +#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */ +#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */ +#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */ +#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */ +#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address + Register */ +#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority + Register */ +#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control + Register */ +#define NT_PPC_PKEY 0x110 /* Memory Protection Keys + registers. */ +#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ +#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ +#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ +#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ +#define NT_S390_TIMER 0x301 /* s390 timer register */ +#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ +#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ +#define NT_S390_CTRS 0x304 /* s390 control registers */ +#define NT_S390_PREFIX 0x305 /* s390 prefix register */ +#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ +#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ +#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ +#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 + upper half. */ +#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */ +#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */ +#define NT_S390_GS_BC 0x30c /* s390 guarded storage + broadcast control block. */ +#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */ +#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ +#define NT_ARM_TLS 0x401 /* ARM TLS register */ +#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ +#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ +#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ +#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension + registers */ +#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication + code masks. */ +#define NT_ARM_PACA_KEYS 0x407 /* ARM pointer authentication + address keys. */ +#define NT_ARM_PACG_KEYS 0x408 /* ARM pointer authentication + generic key. */ +#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */ +#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */ +#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */ +#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ +#define DT_NUM 35 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +#define DT_TLSDESC_PLT 0x6ffffef6 +#define DT_TLSDESC_GOT 0x6ffffef7 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 11 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ +#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */ +#define DF_1_IGNMULDEF 0x00040000 +#define DF_1_NOKSYMS 0x00080000 +#define DF_1_NOHDR 0x00100000 +#define DF_1_EDITED 0x00200000 /* Object is modified after built. */ +#define DF_1_NORELOC 0x00400000 +#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ +#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */ +#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ +#define DF_1_STUB 0x04000000 +#define DF_1_PIE 0x08000000 +#define DF_1_KMOD 0x10000000 +#define DF_1_WEAKFILTER 0x20000000 +#define DF_1_NOCOMMON 0x40000000 + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ + +/* Auxiliary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + uint32_t a_type; /* Entry type */ + union + { + uint32_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + uint64_t a_type; /* Entry type */ + union + { + uint64_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ +#define AT_CLKTCK 17 /* Frequency of times() */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine-dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored. */ + +#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ + +#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ + +#define AT_RANDOM 25 /* Address of 16 random bytes. */ + +#define AT_HWCAP2 26 /* More machine-dependent hints about + processor capabilities. */ + +#define AT_EXECFN 31 /* Filename of executable. */ + +/* Pointer to the global system page used for system calls and other + nice things. */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains + log2 of line size; mask those to get cache size. */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 + +/* Shapes of the caches, with more room to describe them. + *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits + and the cache associativity in the next 16 bits. */ +#define AT_L1I_CACHESIZE 40 +#define AT_L1I_CACHEGEOMETRY 41 +#define AT_L1D_CACHESIZE 42 +#define AT_L1D_CACHEGEOMETRY 43 +#define AT_L2_CACHESIZE 44 +#define AT_L2_CACHEGEOMETRY 45 +#define AT_L3_CACHESIZE 46 +#define AT_L3_CACHEGEOMETRY 47 + +#define AT_MINSIGSTKSZ 51 /* Stack needed for signal delivery + (AArch64). */ + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define NT_GNU_ABI_TAG 1 +#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ + +/* Known OSes. These values can appear in word 0 of an + NT_GNU_ABI_TAG note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 +#define ELF_NOTE_OS_FREEBSD 3 + +/* Synthetic hwcap information. The descriptor begins with two words: + word 0: number of entries + word 1: bitmask of enabled entries + Then follow variable-length entries, one byte followed by a + '\0'-terminated hwcap name string. The byte gives the bit + number to test if enabled, (1U << bit) & bitmask. */ +#define NT_GNU_HWCAP 2 + +/* Build ID bits as generated by ld --build-id. + The descriptor consists of any nonzero number of bytes. */ +#define NT_GNU_BUILD_ID 3 + +/* Version note generated by GNU gold containing a version string. */ +#define NT_GNU_GOLD_VERSION 4 + +/* Program property. */ +#define NT_GNU_PROPERTY_TYPE_0 5 + +/* Note section name of program property. */ +#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property" + +/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */ + +/* Stack size. */ +#define GNU_PROPERTY_STACK_SIZE 1 +/* No copy relocation on protected data symbol. */ +#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 + +/* Processor-specific semantics, lo */ +#define GNU_PROPERTY_LOPROC 0xc0000000 +/* Processor-specific semantics, hi */ +#define GNU_PROPERTY_HIPROC 0xdfffffff +/* Application-specific semantics, lo */ +#define GNU_PROPERTY_LOUSER 0xe0000000 +/* Application-specific semantics, hi */ +#define GNU_PROPERTY_HIUSER 0xffffffff + +/* AArch64 specific GNU properties. */ +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 + +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) + +/* The x86 instruction sets indicated by the corresponding bits are + used in program. Their support in the hardware is optional. */ +#define GNU_PROPERTY_X86_ISA_1_USED 0xc0000000 +/* The x86 instruction sets indicated by the corresponding bits are + used in program and they must be supported by the hardware. */ +#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0000001 +/* X86 processor-specific features used in program. */ +#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 + +#define GNU_PROPERTY_X86_ISA_1_486 (1U << 0) +#define GNU_PROPERTY_X86_ISA_1_586 (1U << 1) +#define GNU_PROPERTY_X86_ISA_1_686 (1U << 2) +#define GNU_PROPERTY_X86_ISA_1_SSE (1U << 3) +#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4) +#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5) +#define GNU_PROPERTY_X86_ISA_1_SSSE3 (1U << 6) +#define GNU_PROPERTY_X86_ISA_1_SSE4_1 (1U << 7) +#define GNU_PROPERTY_X86_ISA_1_SSE4_2 (1U << 8) +#define GNU_PROPERTY_X86_ISA_1_AVX (1U << 9) +#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10) +#define GNU_PROPERTY_X86_ISA_1_AVX512F (1U << 11) +#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12) +#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13) +#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14) +#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15) +#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16) +#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17) + +/* This indicates that all executable sections are compatible with + IBT. */ +#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0) +/* This indicates that all executable sections are compatible with + SHSTK. */ +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1) + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) + + +/* Motorola 68k specific definitions. */ + +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ +#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ +#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ +#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ +#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ +#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ +#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ +#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ +#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ +#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ +#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ +#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ +#define R_68K_TLS_LE32 37 /* 32 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE16 38 /* 16 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE8 39 /* 8 bit offset relative to + static TLS block */ +#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ +#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ +#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ +/* Keep this the last entry. */ +#define R_68K_NUM 43 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +#define R_386_SIZE32 38 /* 32-bit symbol size */ +#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ +#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS + descriptor for + relaxation. */ +#define R_386_TLS_DESC 41 /* TLS descriptor containing + pointer to code and to + argument, returning the TLS + offset for the symbol. */ +#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ +#define R_386_GOT32X 43 /* Load from 32 bit GOT entry, + relaxable. */ +/* Keep this the last entry. */ +#define R_386_NUM 44 + +/* SUN SPARC specific definitions. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +#define R_SPARC_GOTDATA_HIX22 80 +#define R_SPARC_GOTDATA_LOX10 81 +#define R_SPARC_GOTDATA_OP_HIX22 82 +#define R_SPARC_GOTDATA_OP_LOX10 83 +#define R_SPARC_GOTDATA_OP 84 +#define R_SPARC_H34 85 +#define R_SPARC_SIZE32 86 +#define R_SPARC_SIZE64 87 +#define R_SPARC_WDISP10 88 +#define R_SPARC_JMP_IREL 248 +#define R_SPARC_IRELATIVE 249 +#define R_SPARC_GNU_VTINHERIT 250 +#define R_SPARC_GNU_VTENTRY 251 +#define R_SPARC_REV32 252 +/* Keep this the last entry. */ +#define R_SPARC_NUM 253 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used. */ +#define EF_MIPS_PIC 2 /* Contains PIC code. */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */ +#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ +#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */ +#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */ + +/* The following are unofficial names and should not be used. */ + +#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1 +#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2 +#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3 +#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4 +#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5 +#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32 +#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64 + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols. */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols. */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link. */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols. */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes. */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging info. */ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information. */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 +#define SHT_MIPS_XHASH 0x7000002b + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be in global data area. */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_PLT 0x8 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation. */ + Elf32_Word gt_unused; /* Not used. */ + } gt_header; /* First entry in section. */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G. */ + Elf32_Word gt_bytes; /* This many bytes would be used. */ + } gt_entry; /* Subsequent entries in section. */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used. */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used. */ + Elf32_Sword ri_gp_value; /* $gp register value. */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ +#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ +#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ +#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ +#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ +#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ +#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ +#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ +#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ +#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ +#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ +#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ +#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ +#define R_MIPS_GLOB_DAT 51 +#define R_MIPS_COPY 126 +#define R_MIPS_JUMP_SLOT 127 +/* Keep this the last entry. */ +#define R_MIPS_NUM 128 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information. */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 +#define PT_MIPS_ABIFLAGS 0x70000003 /* FP mode requirement. */ + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +/* The address of .got.plt in an executable using the new non-PIC ABI. */ +#define DT_MIPS_PLTGOT 0x70000032 +/* The base of the PLT in an executable using the new non-PIC ABI if that + PLT is writable. For a non-writable PLT, this is omitted or has a zero + value. */ +#define DT_MIPS_RWPLT 0x70000034 +/* An alternative description of the classic MIPS RLD_MAP that is usable + in a PIE as it stores a relative offset from the address of the tag + rather than an absolute address. */ +#define DT_MIPS_RLD_MAP_REL 0x70000035 +/* GNU-style hash table with xlat. */ +#define DT_MIPS_XHASH 0x70000036 +#define DT_MIPS_NUM 0x37 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + +typedef struct +{ + /* Version of flags structure. */ + Elf32_Half version; + /* The level of the ISA: 1-5, 32, 64. */ + unsigned char isa_level; + /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise. */ + unsigned char isa_rev; + /* The size of general purpose registers. */ + unsigned char gpr_size; + /* The size of co-processor 1 registers. */ + unsigned char cpr1_size; + /* The size of co-processor 2 registers. */ + unsigned char cpr2_size; + /* The floating-point ABI. */ + unsigned char fp_abi; + /* Processor-specific extension. */ + Elf32_Word isa_ext; + /* Mask of ASEs used. */ + Elf32_Word ases; + /* Mask of general flags. */ + Elf32_Word flags1; + Elf32_Word flags2; +} Elf_MIPS_ABIFlags_v0; + +/* Values for the register size bytes of an abi flags structure. */ + +#define MIPS_AFL_REG_NONE 0x00 /* No registers. */ +#define MIPS_AFL_REG_32 0x01 /* 32-bit registers. */ +#define MIPS_AFL_REG_64 0x02 /* 64-bit registers. */ +#define MIPS_AFL_REG_128 0x03 /* 128-bit registers. */ + +/* Masks for the ases word of an ABI flags structure. */ + +#define MIPS_AFL_ASE_DSP 0x00000001 /* DSP ASE. */ +#define MIPS_AFL_ASE_DSPR2 0x00000002 /* DSP R2 ASE. */ +#define MIPS_AFL_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */ +#define MIPS_AFL_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */ +#define MIPS_AFL_ASE_MDMX 0x00000010 /* MDMX ASE. */ +#define MIPS_AFL_ASE_MIPS3D 0x00000020 /* MIPS-3D ASE. */ +#define MIPS_AFL_ASE_MT 0x00000040 /* MT ASE. */ +#define MIPS_AFL_ASE_SMARTMIPS 0x00000080 /* SmartMIPS ASE. */ +#define MIPS_AFL_ASE_VIRT 0x00000100 /* VZ ASE. */ +#define MIPS_AFL_ASE_MSA 0x00000200 /* MSA ASE. */ +#define MIPS_AFL_ASE_MIPS16 0x00000400 /* MIPS16 ASE. */ +#define MIPS_AFL_ASE_MICROMIPS 0x00000800 /* MICROMIPS ASE. */ +#define MIPS_AFL_ASE_XPA 0x00001000 /* XPA ASE. */ +#define MIPS_AFL_ASE_MASK 0x00001fff /* All ASEs. */ + +/* Values for the isa_ext word of an ABI flags structure. */ + +#define MIPS_AFL_EXT_XLR 1 /* RMI Xlr instruction. */ +#define MIPS_AFL_EXT_OCTEON2 2 /* Cavium Networks Octeon2. */ +#define MIPS_AFL_EXT_OCTEONP 3 /* Cavium Networks OcteonP. */ +#define MIPS_AFL_EXT_LOONGSON_3A 4 /* Loongson 3A. */ +#define MIPS_AFL_EXT_OCTEON 5 /* Cavium Networks Octeon. */ +#define MIPS_AFL_EXT_5900 6 /* MIPS R5900 instruction. */ +#define MIPS_AFL_EXT_4650 7 /* MIPS R4650 instruction. */ +#define MIPS_AFL_EXT_4010 8 /* LSI R4010 instruction. */ +#define MIPS_AFL_EXT_4100 9 /* NEC VR4100 instruction. */ +#define MIPS_AFL_EXT_3900 10 /* Toshiba R3900 instruction. */ +#define MIPS_AFL_EXT_10000 11 /* MIPS R10000 instruction. */ +#define MIPS_AFL_EXT_SB1 12 /* Broadcom SB-1 instruction. */ +#define MIPS_AFL_EXT_4111 13 /* NEC VR4111/VR4181 instruction. */ +#define MIPS_AFL_EXT_4120 14 /* NEC VR4120 instruction. */ +#define MIPS_AFL_EXT_5400 15 /* NEC VR5400 instruction. */ +#define MIPS_AFL_EXT_5500 16 /* NEC VR5500 instruction. */ +#define MIPS_AFL_EXT_LOONGSON_2E 17 /* ST Microelectronics Loongson 2E. */ +#define MIPS_AFL_EXT_LOONGSON_2F 18 /* ST Microelectronics Loongson 2F. */ + +/* Masks for the flags1 word of an ABI flags structure. */ +#define MIPS_AFL_FLAGS1_ODDSPREG 1 /* Uses odd single-precision registers. */ + +/* Object attribute values. */ +enum +{ + /* Not tagged or not using any ABIs affected by the differences. */ + Val_GNU_MIPS_ABI_FP_ANY = 0, + /* Using hard-float -mdouble-float. */ + Val_GNU_MIPS_ABI_FP_DOUBLE = 1, + /* Using hard-float -msingle-float. */ + Val_GNU_MIPS_ABI_FP_SINGLE = 2, + /* Using soft-float. */ + Val_GNU_MIPS_ABI_FP_SOFT = 3, + /* Using -mips32r2 -mfp64. */ + Val_GNU_MIPS_ABI_FP_OLD_64 = 4, + /* Using -mfpxx. */ + Val_GNU_MIPS_ABI_FP_XX = 5, + /* Using -mips32r2 -mfp64. */ + Val_GNU_MIPS_ABI_FP_64 = 6, + /* Using -mips32r2 -mfp64 -mno-odd-spreg. */ + Val_GNU_MIPS_ABI_FP_64A = 7, + /* Maximum allocated FP ABI value. */ + Val_GNU_MIPS_ABI_FP_MAX = 7 +}; + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indices. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tentatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ +#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_GNU_VTENTRY 232 +#define R_PARISC_GNU_VTINHERIT 233 +#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ +#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ +#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ +#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ +#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ +#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ +#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ +#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ +#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ +#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ +#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L +#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R +#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L +#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R +#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 +#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 +/* Keep this the last entry. */ +#define R_ALPHA_NUM 46 + +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + +/* Legal values for d_tag of Elf64_Dyn. */ +#define DT_ALPHA_PLTRO (DT_LOPROC + 0) +#define DT_ALPHA_NUM 1 + +/* PowerPC specific declarations */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* PowerPC relocations defined for the TLS access ABI. */ +#define R_PPC_TLS 67 /* none (sym+add)@tls */ +#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ +#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ +#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ +#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ +#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ +#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ +#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ +#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ +#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ +#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */ +#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */ + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* GNU extension to support local ifunc. */ +#define R_PPC_IRELATIVE 248 + +/* GNU relocs used in PIC code sequences. */ +#define R_PPC_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +/* PowerPC specific values for the Dyn d_tag field. */ +#define DT_PPC_GOT (DT_LOPROC + 0) +#define DT_PPC_OPT (DT_LOPROC + 1) +#define DT_PPC_NUM 2 + +/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */ +#define PPC_OPT_TLS 1 + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ + +/* PowerPC64 relocations defined for the TLS access ABI. */ +#define R_PPC64_TLS 67 /* none (sym+add)@tls */ +#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ +#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ +#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ +#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ +#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ +#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ +#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ +#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ +#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ +#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ +#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ +#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ +#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ +#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ +#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ +#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ +#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ +#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */ +#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */ +#define R_PPC64_TOCSAVE 109 /* none */ + +/* Added when HA and HI relocs were changed to report overflows. */ +#define R_PPC64_ADDR16_HIGH 110 +#define R_PPC64_ADDR16_HIGHA 111 +#define R_PPC64_TPREL16_HIGH 112 +#define R_PPC64_TPREL16_HIGHA 113 +#define R_PPC64_DTPREL16_HIGH 114 +#define R_PPC64_DTPREL16_HIGHA 115 + +/* GNU extension to support local ifunc. */ +#define R_PPC64_JMP_IREL 247 +#define R_PPC64_IRELATIVE 248 +#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ + +/* e_flags bits specifying ABI. + 1 for original function descriptor using ABI, + 2 for revised ABI without function descriptors, + 0 for unspecified or not using any features affected by the differences. */ +#define EF_PPC64_ABI 3 + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_OPD (DT_LOPROC + 1) +#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +#define DT_PPC64_OPT (DT_LOPROC + 3) +#define DT_PPC64_NUM 4 + +/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry. */ +#define PPC64_OPT_TLS 1 +#define PPC64_OPT_MULTI_TOC 2 +#define PPC64_OPT_LOCALENTRY 4 + +/* PowerPC64 specific values for the Elf64_Sym st_other field. */ +#define STO_PPC64_LOCAL_BIT 5 +#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) +#define PPC64_LOCAL_ENTRY_OFFSET(other) \ + (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2) + + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 +#define EF_ARM_SOFT_FLOAT 0x200 +#define EF_ARM_VFP_FLOAT 0x400 +#define EF_ARM_MAVERICK_FLOAT 0x800 + +#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */ +#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */ + + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +/* Constants defined in AAELF. */ +#define EF_ARM_BE8 0x00800000 +#define EF_ARM_LE8 0x00400000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 +#define EF_ARM_EABI_VER3 0x03000000 +#define EF_ARM_EABI_VER4 0x04000000 +#define EF_ARM_EABI_VER5 0x05000000 + +/* Additional symbol types for Thumb. */ +#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ +#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step. */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base. */ +#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ +#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ +#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ +#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ + + +/* AArch64 relocs. */ + +#define R_AARCH64_NONE 0 /* No relocation. */ + +/* ILP32 AArch64 relocs. */ +#define R_AARCH64_P32_ABS32 1 /* Direct 32 bit. */ +#define R_AARCH64_P32_COPY 180 /* Copy symbol at runtime. */ +#define R_AARCH64_P32_GLOB_DAT 181 /* Create GOT entry. */ +#define R_AARCH64_P32_JUMP_SLOT 182 /* Create PLT entry. */ +#define R_AARCH64_P32_RELATIVE 183 /* Adjust by program base. */ +#define R_AARCH64_P32_TLS_DTPMOD 184 /* Module number, 32 bit. */ +#define R_AARCH64_P32_TLS_DTPREL 185 /* Module-relative offset, 32 bit. */ +#define R_AARCH64_P32_TLS_TPREL 186 /* TP-relative offset, 32 bit. */ +#define R_AARCH64_P32_TLSDESC 187 /* TLS Descriptor. */ +#define R_AARCH64_P32_IRELATIVE 188 /* STT_GNU_IFUNC relocation. */ + +/* LP64 AArch64 relocs. */ +#define R_AARCH64_ABS64 257 /* Direct 64 bit. */ +#define R_AARCH64_ABS32 258 /* Direct 32 bit. */ +#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ +#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ +#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ +#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ +#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ +#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ +#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ +#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ +#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ +#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ +#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ +#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ +#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ +#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ +#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ +#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ +#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ +#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ +#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ +#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ +#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ +#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ +#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ +#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ +#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ +#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ +#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ +#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ +#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ +#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ +#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ +#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ +#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ +#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ +#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ +#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ +#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ +#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ +#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ +#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ +#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ +#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ +#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ +#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ +#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ +#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ +#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ +#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ +#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ +#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ +#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ +#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ +#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ +#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ +#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ +#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ +#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ +#define R_AARCH64_TLS_DTPMOD 1028 /* Module number, 64 bit. */ +#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset, 64 bit. */ +#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset, 64 bit. */ +#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ +#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ + +/* AArch64 specific values for the Dyn d_tag field. */ +#define DT_AARCH64_BTI_PLT (DT_LOPROC + 1) +#define DT_AARCH64_PAC_PLT (DT_LOPROC + 3) +#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5) +#define DT_AARCH64_NUM 6 + +/* AArch64 specific values for the st_other field. */ +#define STO_AARCH64_VARIANT_PCS 0x80 + +/* ARM relocs. */ + +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* Deprecated PC relative 26 + bit branch. */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 /* Direct & 0x7C (LDR, STR). */ +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 /* PC relative 24 bit (Thumb32 BL). */ +#define R_ARM_THM_PC8 11 /* PC relative & 0x3FC + (Thumb16 LDR, ADD, ADR). */ +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 /* Obsolete static relocation. */ +#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ +#define R_ARM_THM_SWI8 14 /* Reserved. */ +#define R_ARM_XPC25 15 /* Reserved. */ +#define R_ARM_THM_XPC22 16 /* Reserved. */ +#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* Deprecated, 32 bit PLT address. */ +#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */ +#define R_ARM_JUMP24 29 /* PC relative 24 bit + (B, BL). */ +#define R_ARM_THM_JUMP24 30 /* PC relative 24 bit (Thumb32 B.W). */ +#define R_ARM_BASE_ABS 31 /* Adjust by program base. */ +#define R_ARM_ALU_PCREL_7_0 32 /* Obsolete. */ +#define R_ARM_ALU_PCREL_15_8 33 /* Obsolete. */ +#define R_ARM_ALU_PCREL_23_15 34 /* Obsolete. */ +#define R_ARM_LDR_SBREL_11_0 35 /* Deprecated, prog. base relative. */ +#define R_ARM_ALU_SBREL_19_12 36 /* Deprecated, prog. base relative. */ +#define R_ARM_ALU_SBREL_27_20 37 /* Deprecated, prog. base relative. */ +#define R_ARM_TARGET1 38 +#define R_ARM_SBREL31 39 /* Program base relative. */ +#define R_ARM_V4BX 40 +#define R_ARM_TARGET2 41 +#define R_ARM_PREL31 42 /* 32 bit PC relative. */ +#define R_ARM_MOVW_ABS_NC 43 /* Direct 16-bit (MOVW). */ +#define R_ARM_MOVT_ABS 44 /* Direct high 16-bit (MOVT). */ +#define R_ARM_MOVW_PREL_NC 45 /* PC relative 16-bit (MOVW). */ +#define R_ARM_MOVT_PREL 46 /* PC relative (MOVT). */ +#define R_ARM_THM_MOVW_ABS_NC 47 /* Direct 16 bit (Thumb32 MOVW). */ +#define R_ARM_THM_MOVT_ABS 48 /* Direct high 16 bit + (Thumb32 MOVT). */ +#define R_ARM_THM_MOVW_PREL_NC 49 /* PC relative 16 bit + (Thumb32 MOVW). */ +#define R_ARM_THM_MOVT_PREL 50 /* PC relative high 16 bit + (Thumb32 MOVT). */ +#define R_ARM_THM_JUMP19 51 /* PC relative 20 bit + (Thumb32 B.W). */ +#define R_ARM_THM_JUMP6 52 /* PC relative X & 0x7E + (Thumb16 CBZ, CBNZ). */ +#define R_ARM_THM_ALU_PREL_11_0 53 /* PC relative 12 bit + (Thumb32 ADR.W). */ +#define R_ARM_THM_PC12 54 /* PC relative 12 bit + (Thumb32 LDR{D,SB,H,SH}). */ +#define R_ARM_ABS32_NOI 55 /* Direct 32-bit. */ +#define R_ARM_REL32_NOI 56 /* PC relative 32-bit. */ +#define R_ARM_ALU_PC_G0_NC 57 /* PC relative (ADD, SUB). */ +#define R_ARM_ALU_PC_G0 58 /* PC relative (ADD, SUB). */ +#define R_ARM_ALU_PC_G1_NC 59 /* PC relative (ADD, SUB). */ +#define R_ARM_ALU_PC_G1 60 /* PC relative (ADD, SUB). */ +#define R_ARM_ALU_PC_G2 61 /* PC relative (ADD, SUB). */ +#define R_ARM_LDR_PC_G1 62 /* PC relative (LDR,STR,LDRB,STRB). */ +#define R_ARM_LDR_PC_G2 63 /* PC relative (LDR,STR,LDRB,STRB). */ +#define R_ARM_LDRS_PC_G0 64 /* PC relative (STR{D,H}, + LDR{D,SB,H,SH}). */ +#define R_ARM_LDRS_PC_G1 65 /* PC relative (STR{D,H}, + LDR{D,SB,H,SH}). */ +#define R_ARM_LDRS_PC_G2 66 /* PC relative (STR{D,H}, + LDR{D,SB,H,SH}). */ +#define R_ARM_LDC_PC_G0 67 /* PC relative (LDC, STC). */ +#define R_ARM_LDC_PC_G1 68 /* PC relative (LDC, STC). */ +#define R_ARM_LDC_PC_G2 69 /* PC relative (LDC, STC). */ +#define R_ARM_ALU_SB_G0_NC 70 /* Program base relative (ADD,SUB). */ +#define R_ARM_ALU_SB_G0 71 /* Program base relative (ADD,SUB). */ +#define R_ARM_ALU_SB_G1_NC 72 /* Program base relative (ADD,SUB). */ +#define R_ARM_ALU_SB_G1 73 /* Program base relative (ADD,SUB). */ +#define R_ARM_ALU_SB_G2 74 /* Program base relative (ADD,SUB). */ +#define R_ARM_LDR_SB_G0 75 /* Program base relative (LDR, + STR, LDRB, STRB). */ +#define R_ARM_LDR_SB_G1 76 /* Program base relative + (LDR, STR, LDRB, STRB). */ +#define R_ARM_LDR_SB_G2 77 /* Program base relative + (LDR, STR, LDRB, STRB). */ +#define R_ARM_LDRS_SB_G0 78 /* Program base relative + (LDR, STR, LDRB, STRB). */ +#define R_ARM_LDRS_SB_G1 79 /* Program base relative + (LDR, STR, LDRB, STRB). */ +#define R_ARM_LDRS_SB_G2 80 /* Program base relative + (LDR, STR, LDRB, STRB). */ +#define R_ARM_LDC_SB_G0 81 /* Program base relative (LDC,STC). */ +#define R_ARM_LDC_SB_G1 82 /* Program base relative (LDC,STC). */ +#define R_ARM_LDC_SB_G2 83 /* Program base relative (LDC,STC). */ +#define R_ARM_MOVW_BREL_NC 84 /* Program base relative 16 + bit (MOVW). */ +#define R_ARM_MOVT_BREL 85 /* Program base relative high + 16 bit (MOVT). */ +#define R_ARM_MOVW_BREL 86 /* Program base relative 16 + bit (MOVW). */ +#define R_ARM_THM_MOVW_BREL_NC 87 /* Program base relative 16 + bit (Thumb32 MOVW). */ +#define R_ARM_THM_MOVT_BREL 88 /* Program base relative high + 16 bit (Thumb32 MOVT). */ +#define R_ARM_THM_MOVW_BREL 89 /* Program base relative 16 + bit (Thumb32 MOVW). */ +#define R_ARM_TLS_GOTDESC 90 +#define R_ARM_TLS_CALL 91 +#define R_ARM_TLS_DESCSEQ 92 /* TLS relaxation. */ +#define R_ARM_THM_TLS_CALL 93 +#define R_ARM_PLT32_ABS 94 +#define R_ARM_GOT_ABS 95 /* GOT entry. */ +#define R_ARM_GOT_PREL 96 /* PC relative GOT entry. */ +#define R_ARM_GOT_BREL12 97 /* GOT entry relative to GOT + origin (LDR). */ +#define R_ARM_GOTOFF12 98 /* 12 bit, GOT entry relative + to GOT origin (LDR, STR). */ +#define R_ARM_GOTRELAX 99 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* PC relative & 0xFFE (Thumb16 B). */ +#define R_ARM_THM_PC9 103 /* PC relative & 0x1FE + (Thumb16 B/B). */ +#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ +#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic + thread local data */ +#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS + block */ +#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of + static TLS block offset */ +#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +#define R_ARM_TLS_LDO12 109 /* 12 bit relative to TLS + block (LDR, STR). */ +#define R_ARM_TLS_LE12 110 /* 12 bit relative to static + TLS block (LDR, STR). */ +#define R_ARM_TLS_IE12GP 111 /* 12 bit GOT entry relative + to GOT origin (LDR). */ +#define R_ARM_ME_TOO 128 /* Obsolete. */ +#define R_ARM_THM_TLS_DESCSEQ 129 +#define R_ARM_THM_TLS_DESCSEQ16 129 +#define R_ARM_THM_TLS_DESCSEQ32 130 +#define R_ARM_THM_GOT_BREL12 131 /* GOT entry relative to GOT + origin, 12 bit (Thumb32 LDR). */ +#define R_ARM_IRELATIVE 160 +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +/* C-SKY */ +#define R_CKCORE_NONE 0 /* no reloc */ +#define R_CKCORE_ADDR32 1 /* direct 32 bit (S + A) */ +#define R_CKCORE_PCRELIMM8BY4 2 /* disp ((S + A - P) >> 2) & 0xff */ +#define R_CKCORE_PCRELIMM11BY2 3 /* disp ((S + A - P) >> 1) & 0x7ff */ +#define R_CKCORE_PCREL32 5 /* 32-bit rel (S + A - P) */ +#define R_CKCORE_PCRELJSR_IMM11BY2 6 /* disp ((S + A - P) >>1) & 0x7ff */ +#define R_CKCORE_RELATIVE 9 /* 32 bit adjust program base(B + A)*/ +#define R_CKCORE_COPY 10 /* 32 bit adjust by program base */ +#define R_CKCORE_GLOB_DAT 11 /* off between got and sym (S) */ +#define R_CKCORE_JUMP_SLOT 12 /* PLT entry (S) */ +#define R_CKCORE_GOTOFF 13 /* offset to GOT (S + A - GOT) */ +#define R_CKCORE_GOTPC 14 /* PC offset to GOT (GOT + A - P) */ +#define R_CKCORE_GOT32 15 /* 32 bit GOT entry (G) */ +#define R_CKCORE_PLT32 16 /* 32 bit PLT entry (G) */ +#define R_CKCORE_ADDRGOT 17 /* GOT entry in GLOB_DAT (GOT + G) */ +#define R_CKCORE_ADDRPLT 18 /* PLT entry in GLOB_DAT (GOT + G) */ +#define R_CKCORE_PCREL_IMM26BY2 19 /* ((S + A - P) >> 1) & 0x3ffffff */ +#define R_CKCORE_PCREL_IMM16BY2 20 /* disp ((S + A - P) >> 1) & 0xffff */ +#define R_CKCORE_PCREL_IMM16BY4 21 /* disp ((S + A - P) >> 2) & 0xffff */ +#define R_CKCORE_PCREL_IMM10BY2 22 /* disp ((S + A - P) >> 1) & 0x3ff */ +#define R_CKCORE_PCREL_IMM10BY4 23 /* disp ((S + A - P) >> 2) & 0x3ff */ +#define R_CKCORE_ADDR_HI16 24 /* high & low 16 bit ADDR */ + /* ((S + A) >> 16) & 0xffff */ +#define R_CKCORE_ADDR_LO16 25 /* (S + A) & 0xffff */ +#define R_CKCORE_GOTPC_HI16 26 /* high & low 16 bit GOTPC */ + /* ((GOT + A - P) >> 16) & 0xffff */ +#define R_CKCORE_GOTPC_LO16 27 /* (GOT + A - P) & 0xffff */ +#define R_CKCORE_GOTOFF_HI16 28 /* high & low 16 bit GOTOFF */ + /* ((S + A - GOT) >> 16) & 0xffff */ +#define R_CKCORE_GOTOFF_LO16 29 /* (S + A - GOT) & 0xffff */ +#define R_CKCORE_GOT12 30 /* 12 bit disp GOT entry (G) */ +#define R_CKCORE_GOT_HI16 31 /* high & low 16 bit GOT */ + /* (G >> 16) & 0xffff */ +#define R_CKCORE_GOT_LO16 32 /* (G & 0xffff) */ +#define R_CKCORE_PLT12 33 /* 12 bit disp PLT entry (G) */ +#define R_CKCORE_PLT_HI16 34 /* high & low 16 bit PLT */ + /* (G >> 16) & 0xffff */ +#define R_CKCORE_PLT_LO16 35 /* G & 0xffff */ +#define R_CKCORE_ADDRGOT_HI16 36 /* high & low 16 bit ADDRGOT */ + /* (GOT + G * 4) & 0xffff */ +#define R_CKCORE_ADDRGOT_LO16 37 /* (GOT + G * 4) & 0xffff */ +#define R_CKCORE_ADDRPLT_HI16 38 /* high & low 16 bit ADDRPLT */ + /* ((GOT + G * 4) >> 16) & 0xFFFF */ +#define R_CKCORE_ADDRPLT_LO16 39 /* (GOT+G*4) & 0xffff */ +#define R_CKCORE_PCREL_JSR_IMM26BY2 40 /* disp ((S+A-P) >>1) & x3ffffff */ +#define R_CKCORE_TOFFSET_LO16 41 /* (S+A-BTEXT) & 0xffff */ +#define R_CKCORE_DOFFSET_LO16 42 /* (S+A-BTEXT) & 0xffff */ +#define R_CKCORE_PCREL_IMM18BY2 43 /* disp ((S+A-P) >>1) & 0x3ffff */ +#define R_CKCORE_DOFFSET_IMM18 44 /* disp (S+A-BDATA) & 0x3ffff */ +#define R_CKCORE_DOFFSET_IMM18BY2 45 /* disp ((S+A-BDATA)>>1) & 0x3ffff */ +#define R_CKCORE_DOFFSET_IMM18BY4 46 /* disp ((S+A-BDATA)>>2) & 0x3ffff */ +#define R_CKCORE_GOT_IMM18BY4 48 /* disp (G >> 2) */ +#define R_CKCORE_PLT_IMM18BY4 49 /* disp (G >> 2) */ +#define R_CKCORE_PCREL_IMM7BY4 50 /* disp ((S+A-P) >>2) & 0x7f */ +#define R_CKCORE_TLS_LE32 51 /* 32 bit offset to TLS block */ +#define R_CKCORE_TLS_IE32 52 +#define R_CKCORE_TLS_GD32 53 +#define R_CKCORE_TLS_LDM32 54 +#define R_CKCORE_TLS_LDO32 55 +#define R_CKCORE_TLS_DTPMOD32 56 +#define R_CKCORE_TLS_DTPOFF32 57 +#define R_CKCORE_TLS_TPOFF32 58 + +/* C-SKY elf header definition. */ +#define EF_CSKY_ABIMASK 0XF0000000 +#define EF_CSKY_OTHER 0X0FFF0000 +#define EF_CSKY_PROCESSOR 0X0000FFFF + +#define EF_CSKY_ABIV1 0X10000000 +#define EF_CSKY_ABIV2 0X20000000 + +/* C-SKY attributes section. */ +#define SHT_CSKY_ATTRIBUTES (SHT_LOPROC + 1) + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_SH_MACH_MASK 0x1f +#define EF_SH_UNKNOWN 0x0 +#define EF_SH1 0x1 +#define EF_SH2 0x2 +#define EF_SH3 0x3 +#define EF_SH_DSP 0x4 +#define EF_SH3_DSP 0x5 +#define EF_SH4AL_DSP 0x6 +#define EF_SH3E 0x8 +#define EF_SH4 0x9 +#define EF_SH2E 0xb +#define EF_SH4A 0xc +#define EF_SH2A 0xd +#define EF_SH4_NOFPU 0x10 +#define EF_SH4A_NOFPU 0x11 +#define EF_SH4_NOMMU_NOFPU 0x12 +#define EF_SH2A_NOFPU 0x13 +#define EF_SH3_NOMMU 0x14 +#define EF_SH2A_SH4_NOFPU 0x15 +#define EF_SH2A_SH3_NOFPU 0x16 +#define EF_SH2A_SH4 0x17 +#define EF_SH2A_SH3E 0x18 + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* S/390 specific definitions. */ + +/* Valid values for the e_flags field. */ + +#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +#define R_390_TLS_GDCALL 38 /* Tag for function call in general + dynamic TLS code. */ +#define R_390_TLS_LDCALL 39 /* Tag for function call in local + dynamic TLS code. */ +#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic + thread local data. */ +#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic + thread local data. */ +#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS + block. */ +#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS + block. */ +#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS + block. */ +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ +#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ +/* Keep this the last entry. */ +#define R_390_NUM 62 + + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 + + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ +#define R_X86_64_PC64 24 /* PC relative 64 bit */ +#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ +#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative + offset to GOT */ +#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ +#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset + to GOT entry */ +#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ +#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ +#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset + to PLT entry */ +#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ +#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS + descriptor. */ +#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ +#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ +#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ + /* 39 Reserved was R_X86_64_PC32_BND */ + /* 40 Reserved was R_X86_64_PLT32_BND */ +#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative + offset to GOT entry without REX + prefix, relaxable. */ +#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative + offset to GOT entry with REX prefix, + relaxable. */ +#define R_X86_64_NUM 43 + +/* x86-64 sh_type values. */ +#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */ + + +/* AM33 relocations. */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ +#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */ +#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */ +#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */ +#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block + offset. */ +#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block + offset. */ +#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS + block. */ +#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */ +#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */ +#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */ +#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed + by linker relaxation. */ +#define R_MN10300_ALIGN 34 /* Alignment requirement for linker + relaxation. */ +#define R_MN10300_NUM 35 + + +/* M32R relocs. */ +#define R_M32R_NONE 0 /* No reloc. */ +#define R_M32R_16 1 /* Direct 16 bit. */ +#define R_M32R_32 2 /* Direct 32 bit. */ +#define R_M32R_24 3 /* Direct 24 bit. */ +#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +#define R_M32R_LO16 9 /* Low 16 bit. */ +#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +#define R_M32R_GNU_VTINHERIT 11 +#define R_M32R_GNU_VTENTRY 12 +/* M32R relocs use SHT_RELA. */ +#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +#define R_M32R_RELA_GNU_VTINHERIT 43 +#define R_M32R_RELA_GNU_VTENTRY 44 +#define R_M32R_REL32 45 /* PC relative 32 bit. */ + +#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +#define R_M32R_COPY 50 /* Copy symbol at runtime */ +#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +#define R_M32R_RELATIVE 53 /* Adjust by program base */ +#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned + low */ +#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed + low */ +#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to + GOT with unsigned low */ +#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to + GOT with signed low */ +#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to + GOT */ +#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT + with unsigned low */ +#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT + with signed low */ +#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +#define R_M32R_NUM 256 /* Keep this the last entry. */ + +/* MicroBlaze relocations */ +#define R_MICROBLAZE_NONE 0 /* No reloc. */ +#define R_MICROBLAZE_32 1 /* Direct 32 bit. */ +#define R_MICROBLAZE_32_PCREL 2 /* PC relative 32 bit. */ +#define R_MICROBLAZE_64_PCREL 3 /* PC relative 64 bit. */ +#define R_MICROBLAZE_32_PCREL_LO 4 /* Low 16 bits of PCREL32. */ +#define R_MICROBLAZE_64 5 /* Direct 64 bit. */ +#define R_MICROBLAZE_32_LO 6 /* Low 16 bit. */ +#define R_MICROBLAZE_SRO32 7 /* Read-only small data area. */ +#define R_MICROBLAZE_SRW32 8 /* Read-write small data area. */ +#define R_MICROBLAZE_64_NONE 9 /* No reloc. */ +#define R_MICROBLAZE_32_SYM_OP_SYM 10 /* Symbol Op Symbol relocation. */ +#define R_MICROBLAZE_GNU_VTINHERIT 11 /* GNU C++ vtable hierarchy. */ +#define R_MICROBLAZE_GNU_VTENTRY 12 /* GNU C++ vtable member usage. */ +#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset. */ +#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset. */ +#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative). */ +#define R_MICROBLAZE_REL 16 /* Adjust by program base. */ +#define R_MICROBLAZE_JUMP_SLOT 17 /* Create PLT entry. */ +#define R_MICROBLAZE_GLOB_DAT 18 /* Create GOT entry. */ +#define R_MICROBLAZE_GOTOFF_64 19 /* 64 bit offset to GOT. */ +#define R_MICROBLAZE_GOTOFF_32 20 /* 32 bit offset to GOT. */ +#define R_MICROBLAZE_COPY 21 /* Runtime copy. */ +#define R_MICROBLAZE_TLS 22 /* TLS Reloc. */ +#define R_MICROBLAZE_TLSGD 23 /* TLS General Dynamic. */ +#define R_MICROBLAZE_TLSLD 24 /* TLS Local Dynamic. */ +#define R_MICROBLAZE_TLSDTPMOD32 25 /* TLS Module ID. */ +#define R_MICROBLAZE_TLSDTPREL32 26 /* TLS Offset Within TLS Block. */ +#define R_MICROBLAZE_TLSDTPREL64 27 /* TLS Offset Within TLS Block. */ +#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */ +#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */ + +/* Legal values for d_tag (dynamic entry type). */ +#define DT_NIOS2_GP 0x70000002 /* Address of _gp. */ + +/* Nios II relocations. */ +#define R_NIOS2_NONE 0 /* No reloc. */ +#define R_NIOS2_S16 1 /* Direct signed 16 bit. */ +#define R_NIOS2_U16 2 /* Direct unsigned 16 bit. */ +#define R_NIOS2_PCREL16 3 /* PC relative 16 bit. */ +#define R_NIOS2_CALL26 4 /* Direct call. */ +#define R_NIOS2_IMM5 5 /* 5 bit constant expression. */ +#define R_NIOS2_CACHE_OPX 6 /* 5 bit expression, shift 22. */ +#define R_NIOS2_IMM6 7 /* 6 bit constant expression. */ +#define R_NIOS2_IMM8 8 /* 8 bit constant expression. */ +#define R_NIOS2_HI16 9 /* High 16 bit. */ +#define R_NIOS2_LO16 10 /* Low 16 bit. */ +#define R_NIOS2_HIADJ16 11 /* High 16 bit, adjusted. */ +#define R_NIOS2_BFD_RELOC_32 12 /* 32 bit symbol value + addend. */ +#define R_NIOS2_BFD_RELOC_16 13 /* 16 bit symbol value + addend. */ +#define R_NIOS2_BFD_RELOC_8 14 /* 8 bit symbol value + addend. */ +#define R_NIOS2_GPREL 15 /* 16 bit GP pointer offset. */ +#define R_NIOS2_GNU_VTINHERIT 16 /* GNU C++ vtable hierarchy. */ +#define R_NIOS2_GNU_VTENTRY 17 /* GNU C++ vtable member usage. */ +#define R_NIOS2_UJMP 18 /* Unconditional branch. */ +#define R_NIOS2_CJMP 19 /* Conditional branch. */ +#define R_NIOS2_CALLR 20 /* Indirect call through register. */ +#define R_NIOS2_ALIGN 21 /* Alignment requirement for + linker relaxation. */ +#define R_NIOS2_GOT16 22 /* 16 bit GOT entry. */ +#define R_NIOS2_CALL16 23 /* 16 bit GOT entry for function. */ +#define R_NIOS2_GOTOFF_LO 24 /* %lo of offset to GOT pointer. */ +#define R_NIOS2_GOTOFF_HA 25 /* %hiadj of offset to GOT pointer. */ +#define R_NIOS2_PCREL_LO 26 /* %lo of PC relative offset. */ +#define R_NIOS2_PCREL_HA 27 /* %hiadj of PC relative offset. */ +#define R_NIOS2_TLS_GD16 28 /* 16 bit GOT offset for TLS GD. */ +#define R_NIOS2_TLS_LDM16 29 /* 16 bit GOT offset for TLS LDM. */ +#define R_NIOS2_TLS_LDO16 30 /* 16 bit module relative offset. */ +#define R_NIOS2_TLS_IE16 31 /* 16 bit GOT offset for TLS IE. */ +#define R_NIOS2_TLS_LE16 32 /* 16 bit LE TP-relative offset. */ +#define R_NIOS2_TLS_DTPMOD 33 /* Module number. */ +#define R_NIOS2_TLS_DTPREL 34 /* Module-relative offset. */ +#define R_NIOS2_TLS_TPREL 35 /* TP-relative offset. */ +#define R_NIOS2_COPY 36 /* Copy symbol at runtime. */ +#define R_NIOS2_GLOB_DAT 37 /* Create GOT entry. */ +#define R_NIOS2_JUMP_SLOT 38 /* Create PLT entry. */ +#define R_NIOS2_RELATIVE 39 /* Adjust by program base. */ +#define R_NIOS2_GOTOFF 40 /* 16 bit offset to GOT pointer. */ +#define R_NIOS2_CALL26_NOAT 41 /* Direct call in .noat section. */ +#define R_NIOS2_GOT_LO 42 /* %lo() of GOT entry. */ +#define R_NIOS2_GOT_HA 43 /* %hiadj() of GOT entry. */ +#define R_NIOS2_CALL_LO 44 /* %lo() of function GOT entry. */ +#define R_NIOS2_CALL_HA 45 /* %hiadj() of function GOT entry. */ + +/* TILEPro relocations. */ +#define R_TILEPRO_NONE 0 /* No reloc */ +#define R_TILEPRO_32 1 /* Direct 32 bit */ +#define R_TILEPRO_16 2 /* Direct 16 bit */ +#define R_TILEPRO_8 3 /* Direct 8 bit */ +#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ +#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ +#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ +#define R_TILEPRO_LO16 7 /* Low 16 bit */ +#define R_TILEPRO_HI16 8 /* High 16 bit */ +#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ +#define R_TILEPRO_COPY 10 /* Copy relocation */ +#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ +#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ +#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ +#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ +#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ +#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ +#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ +#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ +#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ +#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ +#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ +#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ +#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ +#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ +#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ +#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ +#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ +#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ +#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ +#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ +#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ +#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ +#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ +#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ +#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ +#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ +#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ +#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ +#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ +#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ +#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ +#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ +#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ +#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ +#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ +#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ +#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ +#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ +/* Relocs 56-59 are currently not defined. */ +#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ +#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ +#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ +#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ +#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ +#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ +#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ +#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ + +#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ + +#define R_TILEPRO_NUM 130 + + +/* TILE-Gx relocations. */ +#define R_TILEGX_NONE 0 /* No reloc */ +#define R_TILEGX_64 1 /* Direct 64 bit */ +#define R_TILEGX_32 2 /* Direct 32 bit */ +#define R_TILEGX_16 3 /* Direct 16 bit */ +#define R_TILEGX_8 4 /* Direct 8 bit */ +#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ +#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ +#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ +#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ +#define R_TILEGX_HW0 9 /* hword 0 16-bit */ +#define R_TILEGX_HW1 10 /* hword 1 16-bit */ +#define R_TILEGX_HW2 11 /* hword 2 16-bit */ +#define R_TILEGX_HW3 12 /* hword 3 16-bit */ +#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ +#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ +#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ +#define R_TILEGX_COPY 16 /* Copy relocation */ +#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ +#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ +#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ +#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ +#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ +#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ +#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ +#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ +#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ +#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ +#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ +#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ +#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ +#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ +#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ +#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ +#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ +#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ +#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ +#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ +#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ +#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ +#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ +#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ +#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ +#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ +#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ +#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ +#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ +#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ +#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ +#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ +#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ +#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ +#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */ +#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ +#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ +/* Relocs 90-91 are currently not defined. */ +#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ +#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ +/* Relocs 104-105 are currently not defined. */ +#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ +#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ +#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ +#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ +#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ +#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ +#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ +#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ +#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ +#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ + +#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ + +#define R_TILEGX_NUM 130 + +/* RISC-V ELF Flags */ +#define EF_RISCV_RVC 0x0001 +#define EF_RISCV_FLOAT_ABI 0x0006 +#define EF_RISCV_FLOAT_ABI_SOFT 0x0000 +#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002 +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004 +#define EF_RISCV_FLOAT_ABI_QUAD 0x0006 + +/* RISC-V relocations. */ +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 +#define R_RISCV_IRELATIVE 58 + +#define R_RISCV_NUM 59 + +/* BPF specific declarations. */ + +#define R_BPF_NONE 0 /* No reloc */ +#define R_BPF_64_64 1 +#define R_BPF_64_32 10 + +/* Imagination Meta specific relocations. */ + +#define R_METAG_HIADDR16 0 +#define R_METAG_LOADDR16 1 +#define R_METAG_ADDR32 2 /* 32bit absolute address */ +#define R_METAG_NONE 3 /* No reloc */ +#define R_METAG_RELBRANCH 4 +#define R_METAG_GETSETOFF 5 + +/* Backward compatibility */ +#define R_METAG_REG32OP1 6 +#define R_METAG_REG32OP2 7 +#define R_METAG_REG32OP3 8 +#define R_METAG_REG16OP1 9 +#define R_METAG_REG16OP2 10 +#define R_METAG_REG16OP3 11 +#define R_METAG_REG32OP4 12 + +#define R_METAG_HIOG 13 +#define R_METAG_LOOG 14 + +#define R_METAG_REL8 15 +#define R_METAG_REL16 16 + +/* GNU */ +#define R_METAG_GNU_VTINHERIT 30 +#define R_METAG_GNU_VTENTRY 31 + +/* PIC relocations */ +#define R_METAG_HI16_GOTOFF 32 +#define R_METAG_LO16_GOTOFF 33 +#define R_METAG_GETSET_GOTOFF 34 +#define R_METAG_GETSET_GOT 35 +#define R_METAG_HI16_GOTPC 36 +#define R_METAG_LO16_GOTPC 37 +#define R_METAG_HI16_PLT 38 +#define R_METAG_LO16_PLT 39 +#define R_METAG_RELBRANCH_PLT 40 +#define R_METAG_GOTOFF 41 +#define R_METAG_PLT 42 +#define R_METAG_COPY 43 +#define R_METAG_JMP_SLOT 44 +#define R_METAG_RELATIVE 45 +#define R_METAG_GLOB_DAT 46 + +/* TLS relocations */ +#define R_METAG_TLS_GD 47 +#define R_METAG_TLS_LDM 48 +#define R_METAG_TLS_LDO_HI16 49 +#define R_METAG_TLS_LDO_LO16 50 +#define R_METAG_TLS_LDO 51 +#define R_METAG_TLS_IE 52 +#define R_METAG_TLS_IENONPIC 53 +#define R_METAG_TLS_IENONPIC_HI16 54 +#define R_METAG_TLS_IENONPIC_LO16 55 +#define R_METAG_TLS_TPOFF 56 +#define R_METAG_TLS_DTPMOD 57 +#define R_METAG_TLS_DTPOFF 58 +#define R_METAG_TLS_LE 59 +#define R_METAG_TLS_LE_HI16 60 +#define R_METAG_TLS_LE_LO16 61 + +/* NDS32 relocations. */ +#define R_NDS32_NONE 0 +#define R_NDS32_32_RELA 20 +#define R_NDS32_COPY 39 +#define R_NDS32_GLOB_DAT 40 +#define R_NDS32_JMP_SLOT 41 +#define R_NDS32_RELATIVE 42 +#define R_NDS32_TLS_TPOFF 102 +#define R_NDS32_TLS_DESC 119 + +/* ARCompact/ARCv2 specific relocs. */ +#define R_ARC_NONE 0x0 +#define R_ARC_8 0x1 +#define R_ARC_16 0x2 +#define R_ARC_24 0x3 +#define R_ARC_32 0x4 +#define R_ARC_B26 0x5 +#define R_ARC_B22_PCREL 0x6 +#define R_ARC_H30 0x7 +#define R_ARC_N8 0x8 +#define R_ARC_N16 0x9 +#define R_ARC_N24 0xA +#define R_ARC_N32 0xB +#define R_ARC_SDA 0xC +#define R_ARC_SECTOFF 0xD +#define R_ARC_S21H_PCREL 0xE +#define R_ARC_S21W_PCREL 0xF +#define R_ARC_S25H_PCREL 0x10 +#define R_ARC_S25W_PCREL 0x11 +#define R_ARC_SDA32 0x12 +#define R_ARC_SDA_LDST 0x13 +#define R_ARC_SDA_LDST1 0x14 +#define R_ARC_SDA_LDST2 0x15 +#define R_ARC_SDA16_LD 0x16 +#define R_ARC_SDA16_LD1 0x17 +#define R_ARC_SDA16_LD2 0x18 +#define R_ARC_S13_PCREL 0x19 +#define R_ARC_W 0x1A +#define R_ARC_32_ME 0x1B +#define R_ARC_N32_ME 0x1C +#define R_ARC_SECTOFF_ME 0x1D +#define R_ARC_SDA32_ME 0x1E +#define R_ARC_W_ME 0x1F +#define R_ARC_H30_ME 0x20 +#define R_ARC_SECTOFF_U8 0x21 +#define R_ARC_SECTOFF_S9 0x22 +#define R_AC_SECTOFF_U8 0x23 +#define R_AC_SECTOFF_U8_1 0x24 +#define R_AC_SECTOFF_U8_2 0x25 +#define R_AC_SECTOFF_S9 0x26 +#define R_AC_SECTOFF_S9_1 0x27 +#define R_AC_SECTOFF_S9_2 0x28 +#define R_ARC_SECTOFF_ME_1 0x29 +#define R_ARC_SECTOFF_ME_2 0x2A +#define R_ARC_SECTOFF_1 0x2B +#define R_ARC_SECTOFF_2 0x2C +#define R_ARC_PC32 0x32 +#define R_ARC_GOTPC32 0x33 +#define R_ARC_PLT32 0x34 +#define R_ARC_COPY 0x35 +#define R_ARC_GLOB_DAT 0x36 +#define R_ARC_JUMP_SLOT 0x37 +#define R_ARC_RELATIVE 0x38 +#define R_ARC_GOTOFF 0x39 +#define R_ARC_GOTPC 0x3A +#define R_ARC_GOT32 0x3B + +#define R_ARC_TLS_DTPMOD 0x42 +#define R_ARC_TLS_DTPOFF 0x43 +#define R_ARC_TLS_TPOFF 0x44 +#define R_ARC_TLS_GD_GOT 0x45 +#define R_ARC_TLS_GD_LD 0x46 +#define R_ARC_TLS_GD_CALL 0x47 +#define R_ARC_TLS_IE_GOT 0x48 +#define R_ARC_TLS_DTPOFF_S9 0x4a +#define R_ARC_TLS_LE_S9 0x4a +#define R_ARC_TLS_LE_32 0x4b + +#endif /* elf.h */ diff --git a/libelf/elf32_checksum.c b/libelf/elf32_checksum.c new file mode 100644 index 00000000..c5f27bbe --- /dev/null +++ b/libelf/elf32_checksum.c @@ -0,0 +1,168 @@ +/* Compute simple checksum from permanent parts of the ELF file. + Copyright (C) 2002, 2003, 2004, 2005, 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "gelf.h" +#include "libelfP.h" +#include "elf-knowledge.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +#define process_block(crc, data) \ + __libelf_crc32 (crc, data->d_buf, data->d_size) + + +long int +elfw2(LIBELFBITS,checksum) (Elf *elf) +{ + size_t shstrndx; + Elf_Scn *scn; + long int result = 0; + unsigned char *ident; + bool same_byte_order; + + if (elf == NULL) + return -1l; + + /* Find the section header string table. */ + if (INTUSE(elf_getshdrstrndx) (elf, &shstrndx) < 0) + { + /* This can only happen if the ELF handle is not for real. */ + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1l; + } + + /* Determine whether the byte order of the file and that of the host + is the same. */ + ident = elf->state.ELFW(elf,LIBELFBITS).ehdr->e_ident; + same_byte_order = ((ident[EI_DATA] == ELFDATA2LSB + && __BYTE_ORDER == __LITTLE_ENDIAN) + || (ident[EI_DATA] == ELFDATA2MSB + && __BYTE_ORDER == __BIG_ENDIAN)); + + /* If we don't have native byte order, we will likely need to + convert the data with xlate functions. We do it upfront instead + of relocking mid-iteration. */ + if (!likely (same_byte_order)) + rwlock_wrlock (elf->lock); + else + rwlock_rdlock (elf->lock); + + /* Iterate over all sections to find those which are not strippable. */ + scn = NULL; + while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + Elf_Data *data; + + /* Get the section header. */ + shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem); + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = -1l; + goto out; + } + + if (SECTION_STRIP_P (shdr, + INTUSE(elf_strptr) (elf, shstrndx, shdr->sh_name), + true)) + /* The section can be stripped. Don't use it. */ + continue; + + /* Do not look at NOBITS sections. */ + if (shdr->sh_type == SHT_NOBITS) + continue; + + /* To compute the checksum we need to get to the data. For + repeatable results we must use the external format. The data + we get with 'elf'getdata' might be changed for endianness + reasons. Therefore we use 'elf_rawdata' if possible. But + this function can fail if the data was constructed by the + program. In this case we have to use 'elf_getdata' and + eventually convert the data to the external format. */ + data = INTUSE(elf_rawdata) (scn, NULL); + if (data != NULL) + { + /* The raw data is available. */ + result = process_block (result, data); + + /* Maybe the user added more data. These blocks cannot be + read using 'elf_rawdata'. Simply proceed with looking + for more data block with 'elf_getdata'. */ + } + + /* Iterate through the list of data blocks. */ + while ((data = INTUSE(elf_getdata) (scn, data)) != NULL) + /* If the file byte order is the same as the host byte order + process the buffer directly. If the data is just a stream + of bytes which the library will not convert we can use it + as well. */ + if (likely (same_byte_order) || data->d_type == ELF_T_BYTE) + result = process_block (result, data); + else + { + /* Convert the data to file byte order. */ + if (INTUSE(elfw2(LIBELFBITS,xlatetof)) (data, data, ident[EI_DATA]) + == NULL) + { + result = -1l; + goto out; + } + + result = process_block (result, data); + + /* And convert it back. */ + if (INTUSE(elfw2(LIBELFBITS,xlatetom)) (data, data, ident[EI_DATA]) + == NULL) + { + result = -1l; + goto out; + } + } + } + + out: + rwlock_unlock (elf->lock); + return result; +} +INTDEF(elfw2(LIBELFBITS,checksum)) diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c new file mode 100644 index 00000000..139f4a91 --- /dev/null +++ b/libelf/elf32_fsize.c @@ -0,0 +1,60 @@ +/* Return the size of an object file type. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +size_t +elfw2(LIBELFBITS, fsize) (Elf_Type type, size_t count, unsigned int version) +{ + /* We do not have differences between file and memory sizes. Better + not since otherwise `mmap' would not work. */ + if (unlikely (version != EV_CURRENT)) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return 0; + } + + if (unlikely (type >= ELF_T_NUM)) + { + __libelf_seterrno (ELF_E_UNKNOWN_TYPE); + return 0; + } + + return (count * __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][type]); +} diff --git a/libelf/elf32_getchdr.c b/libelf/elf32_getchdr.c new file mode 100644 index 00000000..982a614c --- /dev/null +++ b/libelf/elf32_getchdr.c @@ -0,0 +1,83 @@ +/* Return section compression header. + Copyright (C) 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libelfP.h" +#include "common.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +ElfW2(LIBELFBITS,Chdr) * +elfw2(LIBELFBITS,getchdr) (Elf_Scn *scn) +{ + ElfW2(LIBELFBITS,Shdr) *shdr = elfw2(LIBELFBITS,getshdr) (scn); + if (shdr == NULL) + return NULL; + + /* Must have SHF_COMPRESSED flag set. Allocated or no bits sections + can never be compressed. */ + if ((shdr->sh_flags & SHF_ALLOC) != 0) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); + return NULL; + } + + if (shdr->sh_type == SHT_NULL + || shdr->sh_type == SHT_NOBITS) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE); + return NULL; + } + + if ((shdr->sh_flags & SHF_COMPRESSED) == 0) + { + __libelf_seterrno (ELF_E_NOT_COMPRESSED); + return NULL; + } + + /* This makes sure the data is in the correct format, so we don't + need to swap fields. */ + Elf_Data *d = elf_getdata (scn, NULL); + if (d == NULL) + return NULL; + + if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf; +} diff --git a/libelf/elf32_getehdr.c b/libelf/elf32_getehdr.c new file mode 100644 index 00000000..89e3c402 --- /dev/null +++ b/libelf/elf32_getehdr.c @@ -0,0 +1,96 @@ +/* Get ELF header. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +static ElfW2(LIBELFBITS,Ehdr) * +getehdr_impl (Elf *elf, int wrlock) +{ + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + again: + if (elf->class == 0) + { + if (!wrlock) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + wrlock = 1; + goto again; + } + elf->class = ELFW(ELFCLASS,LIBELFBITS); + } + else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + return NULL; + } + + return elf->state.ELFW(elf,LIBELFBITS).ehdr; +} + +ElfW2(LIBELFBITS,Ehdr) * +internal_function +__elfw2(LIBELFBITS,getehdr_wrlock) (Elf *elf) +{ + return getehdr_impl (elf, 1); +} + +ElfW2(LIBELFBITS,Ehdr) * +elfw2(LIBELFBITS,getehdr) (Elf *elf) +{ + ElfW2(LIBELFBITS,Ehdr) *result; + if (elf == NULL) + return NULL; + + rwlock_rdlock (elf->lock); + result = getehdr_impl (elf, 0); + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c new file mode 100644 index 00000000..99b4ac09 --- /dev/null +++ b/libelf/elf32_getphdr.c @@ -0,0 +1,265 @@ +/* Get ELF program header table. + Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include "libelfP.h" +#include "common.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + +ElfW2(LIBELFBITS,Phdr) * +__elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf) +{ + ElfW2(LIBELFBITS,Phdr) *result; + + /* If the program header entry has already been filled in the code + below must already have been run. So the class is set, too. No + need to waste any more time here. */ + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + if (likely (result != NULL)) + return result; + + if (elf->class == 0) + elf->class = ELFW(ELFCLASS,LIBELFBITS); + else if (elf->class != ELFW(ELFCLASS,LIBELFBITS)) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + result = NULL; + goto out; + } + + if (likely (result == NULL)) + { + /* Read the section header table. */ + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* If no program header exists return NULL. */ + size_t phnum; + if (__elf_getphdrnum_rdlock (elf, &phnum) != 0) + goto out; + if (phnum == 0 || ehdr->e_phoff == 0) + { + __libelf_seterrno (ELF_E_NO_PHDR); + goto out; + } + + /* Check this doesn't overflow. */ + size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr)); + + if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr)) + || ehdr->e_phoff > elf->maximum_size + || elf->maximum_size - ehdr->e_phoff < size) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + if (elf->map_address != NULL) + { + /* First see whether the information in the ELF header is + valid and it does not ask for too much. */ + if (unlikely (ehdr->e_phoff >= elf->maximum_size) + || unlikely (elf->maximum_size - ehdr->e_phoff < size)) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_PHDR); + goto out; + } + + /* All the data is already mapped. Use it. */ + void *file_phdr = ((char *) elf->map_address + + elf->start_offset + ehdr->e_phoff); + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || ((uintptr_t) file_phdr + & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)) + /* Simply use the mapped data. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr; + else + { + ElfW2(LIBELFBITS,Phdr) *notcvt; + ElfW2(LIBELFBITS,Phdr) *phdr; + + /* Allocate memory for the program headers. We know the number + of entries from the ELF header. */ + phdr = elf->state.ELFW(elf,LIBELFBITS).phdr = + (ElfW2(LIBELFBITS,Phdr) *) malloc (size); + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= + ELF_F_MALLOCED | ELF_F_DIRTY; + + /* Now copy the data and at the same time convert the + byte order. */ + + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) + { + assert (! ALLOW_UNALIGNED); + memcpy (phdr, file_phdr, size); + } + else + { + bool copy = ! (ALLOW_UNALIGNED + || ((uintptr_t) file_phdr + & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) + - 1)) == 0); + if (! copy) + notcvt = file_phdr; + else + { + notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size); + if (unlikely (notcvt == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + memcpy (notcvt, file_phdr, size); + } + + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type); + CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset); + CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr); + CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr); + CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz); + CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz); + CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags); + CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align); + } + + if (copy) + free (notcvt); + } + } + } + else if (likely (elf->fildes != -1)) + { + /* Allocate memory for the program headers. We know the number + of entries from the ELF header. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = + (ElfW2(LIBELFBITS,Phdr) *) malloc (size); + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED; + + /* Read the header. */ + ssize_t n = pread_retry (elf->fildes, + elf->state.ELFW(elf,LIBELFBITS).phdr, size, + elf->start_offset + ehdr->e_phoff); + if (unlikely ((size_t) n != size)) + { + /* Severe problems. We cannot read the data. */ + __libelf_seterrno (ELF_E_READ_ERROR); + free (elf->state.ELFW(elf,LIBELFBITS).phdr); + elf->state.ELFW(elf,LIBELFBITS).phdr = NULL; + goto out; + } + + /* If the byte order of the file is not the same as the one + of the host convert the data now. */ + if (ehdr->e_ident[EI_DATA] != MY_ELFDATA) + { + ElfW2(LIBELFBITS,Phdr) *phdr + = elf->state.ELFW(elf,LIBELFBITS).phdr; + + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + CONVERT (phdr[cnt].p_type); + CONVERT (phdr[cnt].p_offset); + CONVERT (phdr[cnt].p_vaddr); + CONVERT (phdr[cnt].p_paddr); + CONVERT (phdr[cnt].p_filesz); + CONVERT (phdr[cnt].p_memsz); + CONVERT (phdr[cnt].p_flags); + CONVERT (phdr[cnt].p_align); + } + } + } + else + { + /* The file descriptor was already enabled and not all data was + read. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + goto out; + } + + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + } + + out: + return result; +} + +ElfW2(LIBELFBITS,Phdr) * +elfw2(LIBELFBITS,getphdr) (Elf *elf) +{ + ElfW2(LIBELFBITS,Phdr) *result; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* If the program header entry has already been filled in the code + * in getphdr_wrlock must already have been run. So the class is + * set, too. No need to waste any more time here. */ + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + if (likely (result != NULL)) + return result; + + rwlock_wrlock (elf->lock); + result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf); + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,getphdr)) diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c new file mode 100644 index 00000000..237d9122 --- /dev/null +++ b/libelf/elf32_getshdr.c @@ -0,0 +1,299 @@ +/* Return section header. + Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include "libelfP.h" +#include "common.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +static ElfW2(LIBELFBITS,Shdr) * +load_shdr_wrlock (Elf_Scn *scn) +{ + ElfW2(LIBELFBITS,Shdr) *result; + + /* Read the section header table. */ + Elf *elf = scn->elf; + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* Try again, maybe the data is there now. */ + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result != NULL) + goto out; + + size_t shnum; + if (__elf_getshdrnum_rdlock (elf, &shnum) != 0 + || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr))) + goto out; + size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr)); + + /* Allocate memory for the section headers. We know the number + of entries from the ELF header. */ + ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr = + (ElfW2(LIBELFBITS,Shdr) *) malloc (size); + if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1; + + if (elf->map_address != NULL) + { + /* First see whether the information in the ELF header is + valid and it does not ask for too much. */ + if (unlikely (ehdr->e_shoff >= elf->maximum_size) + || unlikely (elf->maximum_size - ehdr->e_shoff < size)) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + goto free_and_out; + } + + ElfW2(LIBELFBITS,Shdr) *notcvt; + + /* All the data is already mapped. If we could use it + directly this would already have happened. Unless + we allocated the memory ourselves and the ELF_F_MALLOCED + flag is set. */ + void *file_shdr = ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff); + + assert ((elf->flags & ELF_F_MALLOCED) + || ehdr->e_ident[EI_DATA] != MY_ELFDATA + || elf->cmd == ELF_C_READ_MMAP + || (! ALLOW_UNALIGNED + && ((uintptr_t) file_shdr + & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0)); + + /* Now copy the data and at the same time convert the byte order. */ + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) + { + assert ((elf->flags & ELF_F_MALLOCED) + || elf->cmd == ELF_C_READ_MMAP + || ! ALLOW_UNALIGNED); + memcpy (shdr, file_shdr, size); + } + else + { + bool copy = ! (ALLOW_UNALIGNED + || ((uintptr_t) file_shdr + & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) + == 0); + if (! copy) + notcvt = (ElfW2(LIBELFBITS,Shdr) *) + ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff); + else + { + notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size); + if (unlikely (notcvt == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + memcpy (notcvt, ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff), + size); + } + + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name); + CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type); + CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags); + CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr); + CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset); + CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size); + CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link); + CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info); + CONVERT_TO (shdr[cnt].sh_addralign, + notcvt[cnt].sh_addralign); + CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize); + + /* If this is a section with an extended index add a + reference in the section which uses the extended + index. */ + if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX + && shdr[cnt].sh_link < shnum) + elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index + = cnt; + + /* Set the own shndx_index field in case it has not yet + been set. */ + if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0) + elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index + = -1; + } + + if (copy) + free (notcvt); + } + } + else if (likely (elf->fildes != -1)) + { + /* Read the header. */ + ssize_t n = pread_retry (elf->fildes, + elf->state.ELFW(elf,LIBELFBITS).shdr, size, + elf->start_offset + ehdr->e_shoff); + if (unlikely ((size_t) n != size)) + { + /* Severe problems. We cannot read the data. */ + __libelf_seterrno (ELF_E_READ_ERROR); + goto free_and_out; + } + + /* If the byte order of the file is not the same as the one + of the host convert the data now. */ + if (ehdr->e_ident[EI_DATA] != MY_ELFDATA) + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + CONVERT (shdr[cnt].sh_name); + CONVERT (shdr[cnt].sh_type); + CONVERT (shdr[cnt].sh_flags); + CONVERT (shdr[cnt].sh_addr); + CONVERT (shdr[cnt].sh_offset); + CONVERT (shdr[cnt].sh_size); + CONVERT (shdr[cnt].sh_link); + CONVERT (shdr[cnt].sh_info); + CONVERT (shdr[cnt].sh_addralign); + CONVERT (shdr[cnt].sh_entsize); + } + } + else + { + /* The file descriptor was already enabled and not all data was + read. Undo the allocation. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + + free_and_out: + free (shdr); + elf->state.ELFW(elf,LIBELFBITS).shdr = NULL; + elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0; + + goto out; + } + + /* Set the pointers in the `scn's. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS) + = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt]; + + result = scn->shdr.ELFW(e,LIBELFBITS); + assert (result != NULL); + +out: + return result; +} + +static bool +scn_valid (Elf_Scn *scn) +{ + if (scn == NULL) + return false; + + if (unlikely (scn->elf->state.elf.ehdr == NULL)) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + return false; + } + + if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + return false; + } + + return true; +} + +ElfW2(LIBELFBITS,Shdr) * +internal_function +__elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn) +{ + ElfW2(LIBELFBITS,Shdr) *result; + + if (!scn_valid (scn)) + return NULL; + + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result == NULL) + { + rwlock_unlock (scn->elf->lock); + rwlock_wrlock (scn->elf->lock); + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result == NULL) + result = load_shdr_wrlock (scn); + } + + return result; +} + +ElfW2(LIBELFBITS,Shdr) * +internal_function +__elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn) +{ + ElfW2(LIBELFBITS,Shdr) *result; + + if (!scn_valid (scn)) + return NULL; + + result = scn->shdr.ELFW(e,LIBELFBITS); + if (result == NULL) + result = load_shdr_wrlock (scn); + + return result; +} + +ElfW2(LIBELFBITS,Shdr) * +elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn) +{ + ElfW2(LIBELFBITS,Shdr) *result; + + if (!scn_valid (scn)) + return NULL; + + rwlock_rdlock (scn->elf->lock); + result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn); + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/elf32_newehdr.c b/libelf/elf32_newehdr.c new file mode 100644 index 00000000..775d1157 --- /dev/null +++ b/libelf/elf32_newehdr.c @@ -0,0 +1,91 @@ +/* Create new ELF header. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +ElfW2(LIBELFBITS,Ehdr) * +elfw2(LIBELFBITS,newehdr) (Elf *elf) +{ + ElfW2(LIBELFBITS,Ehdr) *result; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == 0) + elf->class = ELFW(ELFCLASS,LIBELFBITS); + else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + result = NULL; + goto out; + } + + /* Don't create an ELF header if one already exists. */ + if (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL) + { + /* We use the memory in the ELF descriptor. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr = + &elf->state.ELFW(elf,LIBELFBITS).ehdr_mem; + + /* We clear this memory. */ + memset (elf->state.ELFW(elf,LIBELFBITS).ehdr, '\0', + sizeof (ElfW2(LIBELFBITS,Ehdr))); + + /* Mark the ELF header has modified. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + result = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,newehdr)) diff --git a/libelf/elf32_newphdr.c b/libelf/elf32_newphdr.c new file mode 100644 index 00000000..7dd78ca9 --- /dev/null +++ b/libelf/elf32_newphdr.c @@ -0,0 +1,193 @@ +/* Create new ELF program header table. + Copyright (C) 1999-2010, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +ElfW2(LIBELFBITS,Phdr) * +elfw2(LIBELFBITS,newphdr) (Elf *elf, size_t count) +{ + ElfW2(LIBELFBITS,Phdr) *result; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This check is correct, it is for sh_info, which is either + Elf32_Word or Elf64_Word, both being 32 bits. But count is size_t + so might not fit on 32bit ELF files. */ + if (unlikely ((ElfW2(LIBELFBITS,Word)) count != count)) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == 0) + elf->class = ELFW(ELFCLASS,LIBELFBITS); + else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS))) + { + __libelf_seterrno (ELF_E_INVALID_CLASS); + result = NULL; + goto out; + } + + if (unlikely (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL)) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + result = NULL; + goto out; + } + + /* A COUNT of zero means remove existing table. */ + if (count == 0) + { + /* Free the old program header. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL) + { + if (elf->state.ELFW(elf,LIBELFBITS).phdr_flags & ELF_F_MALLOCED) + free (elf->state.ELFW(elf,LIBELFBITS).phdr); + + /* Set the pointer to NULL. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = NULL; + /* Set the `e_phnum' member to the new value. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = 0; + /* Also clear any old PN_XNUM extended value. */ + if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0) + elf->state.ELFW(elf,LIBELFBITS).scns.data[0] + .shdr.ELFW(e,LIBELFBITS)->sh_info = 0; + /* Also set the size. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize = + sizeof (ElfW2(LIBELFBITS,Phdr)); + + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY; + elf->flags |= ELF_F_DIRTY; + __libelf_seterrno (ELF_E_NOERROR); + } + + result = NULL; + } + else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count + || count == PN_XNUM + || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + { + if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr)))) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + goto out; + } + + Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; + if (unlikely (count >= PN_XNUM && scn0->shdr.ELFW(e,LIBELFBITS) == NULL)) + { + /* Something is wrong with section zero, but we need it to write + the extended phdr count. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = NULL; + goto out; + } + + /* Allocate a new program header with the appropriate number of + elements. */ + result = (ElfW2(LIBELFBITS,Phdr) *) + realloc (elf->state.ELFW(elf,LIBELFBITS).phdr, + count * sizeof (ElfW2(LIBELFBITS,Phdr))); + if (result == NULL) + __libelf_seterrno (ELF_E_NOMEM); + else + { + /* Now set the result. */ + elf->state.ELFW(elf,LIBELFBITS).phdr = result; + if (count >= PN_XNUM) + { + /* We have to write COUNT into the zeroth section's sh_info. */ + if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt == 0) + { + assert (elf->state.ELFW(elf,LIBELFBITS).scns.max > 0); + elf->state.ELFW(elf,LIBELFBITS).scns.cnt = 1; + } + scn0->shdr.ELFW(e,LIBELFBITS)->sh_info = count; + scn0->shdr_flags |= ELF_F_DIRTY; + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = PN_XNUM; + } + else + /* Set the `e_phnum' member to the new value. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count; + /* Clear the whole memory. */ + memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr))); + /* Also set the size. */ + elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize = + elf_typesize (LIBELFBITS, ELF_T_PHDR, 1); + /* Remember we allocated the array and mark the structure is + modified. */ + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= + ELF_F_DIRTY | ELF_F_MALLOCED; + /* We have to rewrite the entire file if the size of the + program header is changed. */ + elf->flags |= ELF_F_DIRTY; + } + } + else + { + /* We have the same number of entries. Just clear the array. */ + assert (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize + == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1)); + + /* Mark the structure as modified. */ + elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY; + + result = elf->state.ELFW(elf,LIBELFBITS).phdr; + memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr))); + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,newphdr)) diff --git a/libelf/elf32_offscn.c b/libelf/elf32_offscn.c new file mode 100644 index 00000000..9e757c84 --- /dev/null +++ b/libelf/elf32_offscn.c @@ -0,0 +1,99 @@ +/* Get section at specific index. + Copyright (C) 2005, 2008, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +Elf_Scn * +elfw2(LIBELFBITS,offscn) (Elf *elf, ElfW2(LIBELFBITS,Off) offset) +{ + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns; + + /* If we have not looked at section headers before, + we might need to read them in first. */ + if (runp->cnt > 0 + && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL) + && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL)) + return NULL; + + rwlock_rdlock (elf->lock); + + Elf_Scn *result = NULL; + + /* Find the section in the list. */ + while (1) + { + for (unsigned int i = 0; i < runp->cnt; ++i) + if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset) + { + result = &runp->data[i]; + + /* If this section is empty, the following one has the same + sh_offset. We presume the caller is looking for a nonempty + section, so keep looking if this one is empty. */ + if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0 + && runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_type != SHT_NOBITS) + goto out; + } + + runp = runp->next; + if (runp == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OFFSET); + break; + } + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elfw2(LIBELFBITS,offscn)) diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c new file mode 100644 index 00000000..f67e6261 --- /dev/null +++ b/libelf/elf32_updatefile.c @@ -0,0 +1,855 @@ +/* Write changed data structures. + Copyright (C) 2000-2010, 2014, 2015, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "libelfP.h" + + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +static int +compare_sections (const void *a, const void *b) +{ + const Elf_Scn **scna = (const Elf_Scn **) a; + const Elf_Scn **scnb = (const Elf_Scn **) b; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset + < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset) + return -1; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset + > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset) + return 1; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size + < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size) + return -1; + + if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size + > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size) + return 1; + + if ((*scna)->index < (*scnb)->index) + return -1; + + if ((*scna)->index > (*scnb)->index) + return 1; + + return 0; +} + + +/* Insert the sections in the list into the provided array and sort + them according to their start offsets. For sections with equal + start offsets, the size is used; for sections with equal start + offsets and sizes, the section index is used. Sorting by size + ensures that zero-length sections are processed first, which + is what we want since they do not advance our file writing position. */ +static void +sort_sections (Elf_Scn **scns, Elf_ScnList *list) +{ + Elf_Scn **scnp = scns; + do + for (size_t cnt = 0; cnt < list->cnt; ++cnt) + *scnp++ = &list->data[cnt]; + while ((list = list->next) != NULL); + + qsort (scns, scnp - scns, sizeof (*scns), compare_sections); +} + + +static inline void +fill_mmap (size_t offset, char *last_position, char *scn_start, + char *const shdr_start, char *const shdr_end) +{ + size_t written = 0; + + if (last_position < shdr_start) + { + written = MIN (scn_start + offset - last_position, + shdr_start - last_position); + + memset (last_position, __libelf_fill_byte, written); + } + + if (last_position + written != scn_start + offset + && shdr_end < scn_start + offset) + { + char *fill_start = MAX (shdr_end, scn_start); + memset (fill_start, __libelf_fill_byte, + scn_start + offset - fill_start); + } +} + +int +internal_function +__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) +{ + bool previous_scn_changed = false; + + /* We need the ELF header several times. */ + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* Write out the ELF header. */ + if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY) + { + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Ehdr)) + == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)); + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#undef fctp +#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR] + + /* Do the real work. */ + (*fctp) ((char *) elf->map_address + elf->start_offset, ehdr, + sizeof (ElfW2(LIBELFBITS,Ehdr)), 1); + } + else if (elf->map_address + elf->start_offset != ehdr) + memcpy (elf->map_address + elf->start_offset, ehdr, + sizeof (ElfW2(LIBELFBITS,Ehdr))); + + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY; + + /* We start writing sections after the ELF header only if there is + no program header. */ + previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL; + } + + size_t phnum; + if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) + return -1; + + /* Write out the program header table. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL + && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags) + & ELF_F_DIRTY)) + { + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Phdr)) + == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1)); + + /* Maybe the user wants a gap between the ELF header and the program + header. */ + if (ehdr->e_phoff > ehdr->e_ehsize) + memset (elf->map_address + elf->start_offset + ehdr->e_ehsize, + __libelf_fill_byte, ehdr->e_phoff - ehdr->e_ehsize); + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#undef fctp +#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR] + + /* Do the real work. */ + (*fctp) (elf->map_address + elf->start_offset + ehdr->e_phoff, + elf->state.ELFW(elf,LIBELFBITS).phdr, + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1); + } + else + memmove (elf->map_address + elf->start_offset + ehdr->e_phoff, + elf->state.ELFW(elf,LIBELFBITS).phdr, + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); + + elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY; + + /* We modified the program header. Maybe this created a gap so + we have to write fill bytes, if necessary. */ + previous_scn_changed = true; + } + + /* From now on we have to keep track of the last position to eventually + fill the gaps with the prescribed fill byte. */ + char *last_position = ((char *) elf->map_address + elf->start_offset + + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1), + ehdr->e_phoff) + + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum)); + + /* Write all the sections. Well, only those which are modified. */ + if (shnum > 0) + { + if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *))) + return 1; + + Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; + Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *)); + if (unlikely (scns == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + char *const shdr_start = ((char *) elf->map_address + elf->start_offset + + ehdr->e_shoff); + char *const shdr_end = shdr_start + shnum * ehdr->e_shentsize; + +#undef shdr_fctp +#define shdr_fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR] +#define shdr_dest ((ElfW2(LIBELFBITS,Shdr) *) shdr_start) + + /* Get all sections into the array and sort them. */ + sort_sections (scns, list); + + /* We possibly have to copy the section header data because moving + the sections might overwrite the data. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + + if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced + && (scn->shdr_flags & ELF_F_MALLOCED) == 0 + && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index]) + { + assert ((char *) elf->map_address + elf->start_offset + < (char *) scn->shdr.ELFW(e,LIBELFBITS)); + assert ((char *) scn->shdr.ELFW(e,LIBELFBITS) + < ((char *) elf->map_address + elf->start_offset + + elf->maximum_size)); + + void *p = malloc (sizeof (ElfW2(LIBELFBITS,Shdr))); + if (unlikely (p == NULL)) + { + free (scns); + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + scn->shdr.ELFW(e,LIBELFBITS) + = memcpy (p, scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr))); + } + + /* If the file is mmaped and the original position of the + section in the file is lower than the new position we + need to save the section content since otherwise it is + overwritten before it can be copied. If there are + multiple data segments in the list only the first can be + from the file. */ + if (((char *) elf->map_address + elf->start_offset + <= (char *) scn->data_list.data.d.d_buf) + && ((char *) scn->data_list.data.d.d_buf + < ((char *) elf->map_address + elf->start_offset + + elf->maximum_size)) + && (((char *) elf->map_address + elf->start_offset + + scn->shdr.ELFW(e,LIBELFBITS)->sh_offset) + > (char *) scn->data_list.data.d.d_buf)) + { + void *p = malloc (scn->data_list.data.d.d_size); + if (unlikely (p == NULL)) + { + free (scns); + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + scn->data_list.data.d.d_buf = scn->data_base + = memcpy (p, scn->data_list.data.d.d_buf, + scn->data_list.data.d.d_size); + } + } + + /* Iterate over all the section in the order in which they + appear in the output file. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + if (scn->index == 0) + { + /* The dummy section header entry. It should not be + possible to mark this "section" as dirty. */ + assert ((scn->flags & ELF_F_DIRTY) == 0); + continue; + } + + ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); + if (shdr->sh_type == SHT_NOBITS) + goto next; + + char *scn_start = ((char *) elf->map_address + + elf->start_offset + shdr->sh_offset); + Elf_Data_List *dl = &scn->data_list; + bool scn_changed = false; + + if (scn->data_list_rear != NULL) + do + { + assert (dl->data.d.d_off >= 0); + assert ((GElf_Off) dl->data.d.d_off <= shdr->sh_size); + assert (dl->data.d.d_size <= (shdr->sh_size + - (GElf_Off) dl->data.d.d_off)); + + /* If there is a gap, fill it. */ + if (scn_start + dl->data.d.d_off > last_position + && (dl->data.d.d_off == 0 + || ((scn->flags | dl->flags | elf->flags) + & ELF_F_DIRTY) != 0)) + { + fill_mmap (dl->data.d.d_off, last_position, scn_start, + shdr_start, shdr_end); + } + + last_position = scn_start + dl->data.d.d_off; + + if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY) + { + /* Let it go backward if the sections use a bogus + layout with overlaps. We'll overwrite the stupid + user's section data with the latest one, rather than + crashing. */ + + if (unlikely (change_bo + && dl->data.d.d_size != 0 + && dl->data.d.d_type != ELF_T_BYTE)) + { +#undef fctp +#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type] + + size_t align; + align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS), + dl->data.d.d_type); + if ((((uintptr_t) last_position) + & (uintptr_t) (align - 1)) == 0) + { + /* No need to copy, we can convert directly. */ + (*fctp) (last_position, dl->data.d.d_buf, + dl->data.d.d_size, 1); + } + else + { + /* We have to do the conversion on properly + aligned memory first. align is a power of 2, + but posix_memalign only works for alignments + which are a multiple of sizeof (void *). + So use normal malloc for smaller alignments. */ + size_t size = dl->data.d.d_size; + void *converted; + if (align < sizeof (void *)) + converted = malloc (size); + else + { + int res; + res = posix_memalign (&converted, align, size); + if (res != 0) + converted = NULL; + } + + if (converted == NULL) + { + free (scns); + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } + + (*fctp) (converted, dl->data.d.d_buf, size, 1); + + /* And then write it to the mmapped file. */ + memcpy (last_position, converted, size); + free (converted); + } + + last_position += dl->data.d.d_size; + } + else if (dl->data.d.d_size != 0) + { + memmove (last_position, dl->data.d.d_buf, + dl->data.d.d_size); + last_position += dl->data.d.d_size; + } + + scn_changed = true; + } + else + last_position += dl->data.d.d_size; + + assert (scn_start + dl->data.d.d_off + dl->data.d.d_size + == last_position); + + dl->flags &= ~ELF_F_DIRTY; + + dl = dl->next; + } + while (dl != NULL); + else + { + /* If the previous section (or the ELF/program + header) changed we might have to fill the gap. */ + if (scn_start > last_position && previous_scn_changed) + fill_mmap (0, last_position, scn_start, + shdr_start, shdr_end); + + /* We have to trust the existing section header information. */ + last_position = scn_start + shdr->sh_size; + } + + + previous_scn_changed = scn_changed; + next: + scn->flags &= ~ELF_F_DIRTY; + } + + /* Fill the gap between last section and section header table if + necessary. */ + if ((elf->flags & ELF_F_DIRTY) + && last_position < ((char *) elf->map_address + elf->start_offset + + ehdr->e_shoff)) + memset (last_position, __libelf_fill_byte, + (char *) elf->map_address + elf->start_offset + ehdr->e_shoff + - last_position); + + /* Write the section header table entry if necessary. */ + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + + if ((scn->shdr_flags | elf->flags) & ELF_F_DIRTY) + { + if (unlikely (change_bo)) + (*shdr_fctp) (&shdr_dest[scn->index], + scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr)), 1); + else + memcpy (&shdr_dest[scn->index], + scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr))); + + /* If we previously made a copy of the section header + entry we now have to adjust the pointer again so + point to new place in the mapping. */ + if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced + && (scn->shdr_flags & ELF_F_MALLOCED) == 0 + && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index]) + { + free (scn->shdr.ELFW(e,LIBELFBITS)); + scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index]; + } + + scn->shdr_flags &= ~ELF_F_DIRTY; + } + } + free (scns); + } + + /* That was the last part. Clear the overall flag. */ + elf->flags &= ~ELF_F_DIRTY; + + /* Make sure the content hits the disk. */ + char *msync_start = ((char *) elf->map_address + + (elf->start_offset & ~(sysconf (_SC_PAGESIZE) - 1))); + char *msync_end = ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff + + ehdr->e_shentsize * shnum); + (void) msync (msync_start, msync_end - msync_start, MS_SYNC); + + return 0; +} + + +/* Size of the buffer we use to generate the blocks of fill bytes. */ +#define FILLBUFSIZE 4096 + +/* If we have to convert the section buffer contents we have to use + temporary buffer. Only buffers up to MAX_TMPBUF bytes are allocated + on the stack. */ +#define MAX_TMPBUF 32768 + + +/* Helper function to write out fill bytes. */ +static int +fill (int fd, int64_t pos, size_t len, char *fillbuf, size_t *filledp) +{ + size_t filled = *filledp; + size_t fill_len = MIN (len, FILLBUFSIZE); + + if (unlikely (fill_len > filled) && filled < FILLBUFSIZE) + { + /* Initialize a few more bytes. */ + memset (fillbuf + filled, __libelf_fill_byte, fill_len - filled); + *filledp = filled = fill_len; + } + + do + { + /* This many bytes we want to write in this round. */ + size_t n = MIN (filled, len); + + if (unlikely ((size_t) pwrite_retry (fd, fillbuf, n, pos) != n)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + pos += n; + len -= n; + } + while (len > 0); + + return 0; +} + + +int +internal_function +__elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) +{ + char fillbuf[FILLBUFSIZE]; + size_t filled = 0; + bool previous_scn_changed = false; + + /* We need the ELF header several times. */ + ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr; + + /* Write out the ELF header. */ + if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY) + { + ElfW2(LIBELFBITS,Ehdr) tmp_ehdr; + ElfW2(LIBELFBITS,Ehdr) *out_ehdr = ehdr; + + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Ehdr)) + == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)); + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#undef fctp +#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR] + + /* Write the converted ELF header in a temporary buffer. */ + (*fctp) (&tmp_ehdr, ehdr, sizeof (ElfW2(LIBELFBITS,Ehdr)), 1); + + /* This is the buffer we want to write. */ + out_ehdr = &tmp_ehdr; + } + + /* Write out the ELF header. */ + if (unlikely (pwrite_retry (elf->fildes, out_ehdr, + sizeof (ElfW2(LIBELFBITS,Ehdr)), 0) + != sizeof (ElfW2(LIBELFBITS,Ehdr)))) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY; + + /* We start writing sections after the ELF header only if there is + no program header. */ + previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL; + } + + /* If the type sizes should be different at some time we have to + rewrite this code. */ + assert (sizeof (ElfW2(LIBELFBITS,Phdr)) + == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1)); + + size_t phnum; + if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) + return -1; + + /* Write out the program header table. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL + && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags) + & ELF_F_DIRTY)) + { + ElfW2(LIBELFBITS,Phdr) *tmp_phdr = NULL; + ElfW2(LIBELFBITS,Phdr) *out_phdr = elf->state.ELFW(elf,LIBELFBITS).phdr; + + /* Maybe the user wants a gap between the ELF header and the program + header. */ + if (ehdr->e_phoff > ehdr->e_ehsize + && unlikely (fill (elf->fildes, ehdr->e_ehsize, + ehdr->e_phoff - ehdr->e_ehsize, fillbuf, &filled) + != 0)) + return 1; + + if (unlikely (change_bo)) + { + /* Today there is only one version of the ELF header. */ +#undef fctp +#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR] + + /* Allocate sufficient memory. */ + tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *) + malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); + if (unlikely (tmp_phdr == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } + + /* Write the converted ELF header in a temporary buffer. */ + (*fctp) (tmp_phdr, elf->state.ELFW(elf,LIBELFBITS).phdr, + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1); + + /* This is the buffer we want to write. */ + out_phdr = tmp_phdr; + } + + /* Write out the ELF header. */ + size_t phdr_size = sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum; + if (unlikely ((size_t) pwrite_retry (elf->fildes, out_phdr, + phdr_size, ehdr->e_phoff) + != phdr_size)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return 1; + } + + /* This is a no-op we we have not allocated any memory. */ + free (tmp_phdr); + + elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY; + + /* We modified the program header. Maybe this created a gap so + we have to write fill bytes, if necessary. */ + previous_scn_changed = true; + } + + /* From now on we have to keep track of the last position to eventually + fill the gaps with the prescribed fill byte. */ + int64_t last_offset; + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + last_offset = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); + else + last_offset = (ehdr->e_phoff + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); + + /* Write all the sections. Well, only those which are modified. */ + if (shnum > 0) + { + if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *) + + sizeof (ElfW2(LIBELFBITS,Shdr))))) + return 1; + + int64_t shdr_offset = elf->start_offset + ehdr->e_shoff; +#undef shdr_fctp +#define shdr_fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR] + + ElfW2(LIBELFBITS,Shdr) *shdr_data; + ElfW2(LIBELFBITS,Shdr) *shdr_data_mem = NULL; + if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL + || (elf->flags & ELF_F_DIRTY)) + { + shdr_data_mem = (ElfW2(LIBELFBITS,Shdr) *) + malloc (shnum * sizeof (ElfW2(LIBELFBITS,Shdr))); + if (unlikely (shdr_data_mem == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + shdr_data = shdr_data_mem; + } + else + shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr; + int shdr_flags = elf->flags; + + /* Get all sections into the array and sort them. */ + Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; + Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *)); + if (unlikely (scns == NULL)) + { + free (shdr_data_mem); + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + sort_sections (scns, list); + + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = scns[cnt]; + if (scn->index == 0) + { + /* The dummy section header entry. It should not be + possible to mark this "section" as dirty. */ + assert ((scn->flags & ELF_F_DIRTY) == 0); + goto next; + } + + ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); + if (shdr->sh_type == SHT_NOBITS) + goto next; + + int64_t scn_start = elf->start_offset + shdr->sh_offset; + Elf_Data_List *dl = &scn->data_list; + bool scn_changed = false; + + if (scn->data_list_rear != NULL) + do + { + /* If there is a gap, fill it. */ + if (scn_start + dl->data.d.d_off > last_offset + && ((previous_scn_changed && dl->data.d.d_off == 0) + || ((scn->flags | dl->flags | elf->flags) + & ELF_F_DIRTY) != 0)) + { + if (unlikely (fill (elf->fildes, last_offset, + (scn_start + dl->data.d.d_off) + - last_offset, fillbuf, + &filled) != 0)) + { + fail_free: + free (shdr_data_mem); + free (scns); + return 1; + } + } + + last_offset = scn_start + dl->data.d.d_off; + + if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY) + { + char tmpbuf[MAX_TMPBUF]; + void *buf = dl->data.d.d_buf; + + /* Let it go backward if the sections use a bogus + layout with overlaps. We'll overwrite the stupid + user's section data with the latest one, rather than + crashing. */ + + if (unlikely (change_bo)) + { +#undef fctp +#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type] + + buf = tmpbuf; + if (dl->data.d.d_size > MAX_TMPBUF) + { + buf = malloc (dl->data.d.d_size); + if (unlikely (buf == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto fail_free; + } + } + + /* Do the real work. */ + (*fctp) (buf, dl->data.d.d_buf, dl->data.d.d_size, 1); + } + + ssize_t n = pwrite_retry (elf->fildes, buf, + dl->data.d.d_size, + last_offset); + if (unlikely ((size_t) n != dl->data.d.d_size)) + { + if (buf != dl->data.d.d_buf && buf != tmpbuf) + free (buf); + + __libelf_seterrno (ELF_E_WRITE_ERROR); + goto fail_free; + } + + if (buf != dl->data.d.d_buf && buf != tmpbuf) + free (buf); + + scn_changed = true; + } + + last_offset += dl->data.d.d_size; + + dl->flags &= ~ELF_F_DIRTY; + + dl = dl->next; + } + while (dl != NULL); + else + { + /* If the previous section (or the ELF/program + header) changed we might have to fill the gap. */ + if (scn_start > last_offset && previous_scn_changed) + { + if (unlikely (fill (elf->fildes, last_offset, + scn_start - last_offset, fillbuf, + &filled) != 0)) + goto fail_free; + } + + last_offset = scn_start + shdr->sh_size; + } + + previous_scn_changed = scn_changed; + next: + /* Collect the section header table information. */ + if (unlikely (change_bo)) + (*shdr_fctp) (&shdr_data[scn->index], + scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr)), 1); + else if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL + || (elf->flags & ELF_F_DIRTY)) + memcpy (&shdr_data[scn->index], scn->shdr.ELFW(e,LIBELFBITS), + sizeof (ElfW2(LIBELFBITS,Shdr))); + + shdr_flags |= scn->shdr_flags; + scn->shdr_flags &= ~ELF_F_DIRTY; + } + + /* Fill the gap between last section and section header table if + necessary. */ + if ((elf->flags & ELF_F_DIRTY) && last_offset < shdr_offset + && unlikely (fill (elf->fildes, last_offset, + shdr_offset - last_offset, + fillbuf, &filled) != 0)) + goto fail_free; + + /* Write out the section header table. */ + if (shdr_flags & ELF_F_DIRTY + && unlikely ((size_t) pwrite_retry (elf->fildes, shdr_data, + sizeof (ElfW2(LIBELFBITS,Shdr)) + * shnum, shdr_offset) + != sizeof (ElfW2(LIBELFBITS,Shdr)) * shnum)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + goto fail_free; + } + + free (shdr_data_mem); + free (scns); + } + + /* That was the last part. Clear the overall flag. */ + elf->flags &= ~ELF_F_DIRTY; + + return 0; +} diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c new file mode 100644 index 00000000..d0d4d1eb --- /dev/null +++ b/libelf/elf32_updatenull.c @@ -0,0 +1,461 @@ +/* Update data structures for changes. + Copyright (C) 2000-2010, 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include "libelfP.h" +#include "elf-knowledge.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + +/* Some fields contain 32/64 sizes. We cannot use Elf32/64_Word for those, + since those are both 32bits. Elf32/64_Xword is always 64bits. */ +#define Elf32_SizeWord Elf32_Word +#define Elf64_SizeWord Elf64_Xword + + +static int +ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr, + size_t shnum, int *change_bop) +{ + /* Always write the magic bytes. */ + if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) + { + memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG); + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + /* Always set the file class. */ + update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS), + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + + /* Set the data encoding if necessary. */ + if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE)) + { + ehdr->e_ident[EI_DATA] = + BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB; + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM)) + { + __libelf_seterrno (ELF_E_DATA_ENCODING); + return 1; + } + else + *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN + && ehdr->e_ident[EI_DATA] != ELFDATA2LSB) + || (BYTE_ORDER == BIG_ENDIAN + && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)); + + /* Unconditionally overwrite the ELF version. */ + update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT, + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + + if (unlikely (ehdr->e_version == EV_NONE)) + { + ehdr->e_version = EV_CURRENT; + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + else if (unlikely (ehdr->e_version != EV_CURRENT)) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return 1; + } + + if (unlikely (shnum >= SHN_LORESERVE)) + { + update_if_changed (ehdr->e_shnum, 0, + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + } + else + update_if_changed (ehdr->e_shnum, shnum, + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); + + if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1))) + { + ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + /* If phnum is zero make sure e_phoff is also zero and not some random + value. That would cause trouble in update_file. */ + if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0) + { + ehdr->e_phoff = 0; + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + + return 0; +} + + +int64_t +internal_function +__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) +{ + ElfW2(LIBELFBITS,Ehdr) *ehdr; + int changed = 0; + int ehdr_flags = 0; + + ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf); + + /* Set the default values. */ + if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0) + return -1; + + /* At least the ELF header is there. */ + ElfW2(LIBELFBITS,SizeWord) size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); + + /* Set the program header position. */ + if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) + (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf); + if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL) + { + size_t phnum; + if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0)) + return -1; + + if (elf->flags & ELF_F_LAYOUT) + { + /* The user is supposed to fill out e_phoff. Use it and + e_phnum to determine the maximum extend. */ + size = MAX (size, + ehdr->e_phoff + + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum)); + } + else + { + update_if_changed (ehdr->e_phoff, + elf_typesize (LIBELFBITS, ELF_T_EHDR, 1), + ehdr_flags); + + /* We need no alignment here. */ + size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum); + } + } + + if (shnum > 0) + { + struct Elf_Scn *scn1 = NULL; + Elf_ScnList *list; + bool first = true; + + assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0); + + if (shnum >= SHN_LORESERVE) + { + /* We have to fill in the number of sections in the header + of the zeroth section. */ + Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; + + update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size, + shnum, scn0->shdr_flags); + } + + /* Go over all sections and find out how large they are. */ + list = &elf->state.ELFW(elf,LIBELFBITS).scns; + + /* Find the first section. */ + if (list->cnt > 1) + scn1 = &list->data[1]; + else if (list->next != NULL) + scn1 = &list->next->data[0]; + + /* Load the section headers if necessary. This loads the + headers for all sections. */ + if (scn1 != NULL && scn1->shdr.ELFW(e,LIBELFBITS) == NULL) + (void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn1); + + do + { + for (size_t cnt = first == true; cnt < list->cnt; ++cnt) + { + Elf_Scn *scn = &list->data[cnt]; + ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); + int64_t offset = 0; + + assert (shdr != NULL); + ElfW2(LIBELFBITS,SizeWord) sh_entsize = shdr->sh_entsize; + ElfW2(LIBELFBITS,SizeWord) sh_align = shdr->sh_addralign ?: 1; + if (unlikely (! powerof2 (sh_align))) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return -1; + } + + /* Set the sh_entsize value if we can reliably detect it. */ + switch (shdr->sh_type) + { + case SHT_SYMTAB: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); + break; + case SHT_RELA: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1); + break; + case SHT_GROUP: + /* Only relocatable files can contain section groups. */ + if (ehdr->e_type != ET_REL) + { + __libelf_seterrno (ELF_E_GROUP_NOT_REL); + return -1; + } + FALLTHROUGH; + case SHT_SYMTAB_SHNDX: + sh_entsize = elf_typesize (32, ELF_T_WORD, 1); + break; + case SHT_HASH: + sh_entsize = SH_ENTSIZE_HASH (ehdr); + break; + case SHT_DYNAMIC: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1); + break; + case SHT_REL: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1); + break; + case SHT_DYNSYM: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); + break; + case SHT_SUNW_move: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1); + break; + case SHT_SUNW_syminfo: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); + break; + default: + break; + } + + /* If the section header contained the wrong entry size + correct it and mark the header as modified. */ + update_if_changed (shdr->sh_entsize, sh_entsize, + scn->shdr_flags); + + /* Likewise for the alignment of a compressed section. + For a SHF_COMPRESSED section set the correct + sh_addralign value, which must match the d_align of + the data (see __libelf_set_rawdata in elf_getdata.c). */ + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + sh_align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS), + ELF_T_CHDR); + update_if_changed (shdr->sh_addralign, sh_align, + scn->shdr_flags); + } + + if (scn->data_read == 0 + && __libelf_set_rawdata_wrlock (scn) != 0) + /* Something went wrong. The error value is already set. */ + return -1; + + /* Iterate over all data blocks. */ + if (list->data[cnt].data_list_rear != NULL) + { + Elf_Data_List *dl = &scn->data_list; + + while (dl != NULL) + { + Elf_Data *data = &dl->data.d; + if (dl == &scn->data_list && data->d_buf == NULL + && scn->rawdata.d.d_buf != NULL) + data = &scn->rawdata.d; + + if (unlikely (data->d_version != EV_CURRENT)) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return -1; + } + + if (unlikely (! powerof2 (data->d_align))) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return -1; + } + + sh_align = MAX (sh_align, data->d_align); + + if (elf->flags & ELF_F_LAYOUT) + { + /* The user specified the offset and the size. + All we have to do is check whether this block + fits in the size specified for the section. */ + if (unlikely ((ElfW2(LIBELFBITS,SizeWord)) + (data->d_off + data->d_size) + > shdr->sh_size)) + { + __libelf_seterrno (ELF_E_SECTION_TOO_SMALL); + return -1; + } + } + else + { + /* Determine the padding. */ + offset = ((offset + data->d_align - 1) + & ~(data->d_align - 1)); + + update_if_changed (data->d_off, offset, changed); + + offset += data->d_size; + } + + /* Next data block. */ + dl = dl->next; + } + } + else + /* Get the size of the section from the raw data. If + none is available the value is zero. */ + offset += scn->rawdata.d.d_size; + + if (elf->flags & ELF_F_LAYOUT) + { + size = MAX (size, + (shdr->sh_type != SHT_NOBITS + ? shdr->sh_offset + shdr->sh_size : 0)); + + /* The alignment must be a power of two. This is a + requirement from the ELF specification. Additionally + we test for the alignment of the section being large + enough for the largest alignment required by a data + block. */ + if (unlikely (! powerof2 (shdr->sh_addralign)) + || unlikely ((shdr->sh_addralign ?: 1) < sh_align)) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return -1; + } + } + else + { + /* How much alignment do we need for this section. */ + update_if_changed (shdr->sh_addralign, sh_align, + scn->shdr_flags); + + size = (size + sh_align - 1) & ~(sh_align - 1); + int offset_changed = 0; + update_if_changed (shdr->sh_offset, size, offset_changed); + changed |= offset_changed; + + if (offset_changed && scn->data_list_rear == NULL) + { + /* The position of the section in the file + changed. Create the section data list. */ + if (__elf_getdata_rdlock (scn, NULL) == NULL) + return -1; + } + + /* See whether the section size is correct. */ + int size_changed = 0; + update_if_changed (shdr->sh_size, + (ElfW2(LIBELFBITS,SizeWord)) offset, + size_changed); + changed |= size_changed; + + if (shdr->sh_type != SHT_NOBITS) + size += offset; + + scn->shdr_flags |= (offset_changed | size_changed); + scn->flags |= changed; + } + + /* Check that the section size is actually a multiple of + the entry size. */ + if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1 + && (elf->flags & ELF_F_PERMISSIVE) == 0) + { + /* For compressed sections check the uncompressed size. */ + ElfW2(LIBELFBITS,SizeWord) sh_size; + if ((shdr->sh_flags & SHF_COMPRESSED) == 0) + sh_size = shdr->sh_size; + else + { + ElfW2(LIBELFBITS,Chdr) *chdr; + chdr = elfw2(LIBELFBITS,getchdr) (scn); + if (unlikely (chdr == NULL)) + return -1; + sh_size = chdr->ch_size; + } + + if (unlikely (sh_size % shdr->sh_entsize != 0)) + { + __libelf_seterrno (ELF_E_INVALID_SHENTSIZE); + return -1; + } + } + } + + assert (list->next == NULL || list->cnt == list->max); + + first = false; + } + while ((list = list->next) != NULL); + + /* Store section information. */ + update_if_changed (ehdr->e_shentsize, + elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags); + if (elf->flags & ELF_F_LAYOUT) + { + /* The user is supposed to fill out e_shoff. Use it and + e_shnum (or sh_size of the dummy, first section header) + to determine the maximum extend. */ + size = MAX (size, + (ehdr->e_shoff + + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum)))); + } + else + { + /* Align for section header table. + + Yes, we use `sizeof' and not `__alignof__' since we do not + want to be surprised by architectures with less strict + alignment rules. */ +#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off)) + size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1); + + update_if_changed (ehdr->e_shoff, size, elf->flags); + + /* Account for the section header size. */ + size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum); + } + } + + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags; + + return size; +} diff --git a/libelf/elf32_xlatetof.c b/libelf/elf32_xlatetof.c new file mode 100644 index 00000000..082d833f --- /dev/null +++ b/libelf/elf32_xlatetof.c @@ -0,0 +1,109 @@ +/* Convert from memory to file representation. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +Elf_Data * +elfw2(LIBELFBITS, xlatetof) (Elf_Data *dest, const Elf_Data *src, + unsigned int encode) +{ + /* First test whether the input data is really suitable for this + type. This means, whether there is an integer number of records. + Note that for this implementation the memory and file size of the + data types are identical. */ + size_t recsize = __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type]; + + if (src->d_size % recsize != 0) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + /* Next see whether the converted data fits in the output buffer. */ + if (src->d_size > dest->d_size) + { + __libelf_seterrno (ELF_E_DEST_SIZE); + return NULL; + } + + /* Test the encode parameter. */ + if (encode != ELFDATA2LSB && encode != ELFDATA2MSB) + { + __libelf_seterrno (ELF_E_INVALID_ENCODING); + return NULL; + } + + /* Determine the translation function to use. + + At this point we make an assumption which is valid for all + existing implementations so far: the memory and file sizes are + the same. This has very important consequences: + a) The requirement that the source and destination buffer can + overlap can easily be fulfilled. + b) We need only one function to convert from and memory to file + and vice versa since the function only has to copy and/or + change the byte order. + */ + if ((__BYTE_ORDER == __LITTLE_ENDIAN && encode == ELFDATA2LSB) + || (__BYTE_ORDER == __BIG_ENDIAN && encode == ELFDATA2MSB)) + { + /* We simply have to copy since the byte order is the same. */ + if (src->d_buf != dest->d_buf) + memmove (dest->d_buf, src->d_buf, src->d_size); + } + else + { + xfct_t fctp; + fctp = __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type]; + + /* Do the real work. */ + (*fctp) (dest->d_buf, src->d_buf, src->d_size, 1); + } + + /* Now set the real destination type and length since the operation was + successful. */ + dest->d_type = src->d_type; + dest->d_size = src->d_size; + + return dest; +} +INTDEF(elfw2(LIBELFBITS, xlatetof)) diff --git a/libelf/elf32_xlatetom.c b/libelf/elf32_xlatetom.c new file mode 100644 index 00000000..cb0bb8d5 --- /dev/null +++ b/libelf/elf32_xlatetom.c @@ -0,0 +1,114 @@ +/* Convert from file to memory representation. + Copyright (C) 1998, 1999, 2000, 2002, 2012, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +Elf_Data * +elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src, + unsigned int encode) +{ + /* First test whether the input data is really suitable for this + type. This means, whether there is an integer number of records. + Note that for this implementation the memory and file size of the + data types are identical. */ + size_t recsize = __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type]; + + + /* We shouldn't require integer number of records when processing + notes. Payload bytes follow the header immediately, it's not an + array of records as is the case otherwise. */ + if (src->d_type != ELF_T_NHDR && src->d_type != ELF_T_NHDR8 + && src->d_size % recsize != 0) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + /* Next see whether the converted data fits in the output buffer. */ + if (src->d_size > dest->d_size) + { + __libelf_seterrno (ELF_E_DEST_SIZE); + return NULL; + } + + /* Test the encode parameter. */ + if (encode != ELFDATA2LSB && encode != ELFDATA2MSB) + { + __libelf_seterrno (ELF_E_INVALID_ENCODING); + return NULL; + } + + /* Determine the translation function to use. + + At this point we make an assumption which is valid for all + existing implementations so far: the memory and file sizes are + the same. This has very important consequences: + a) The requirement that the source and destination buffer can + overlap can easily be fulfilled. + b) We need only one function to convert from and memory to file + and vice versa since the function only has to copy and/or + change the byte order. + */ + if ((BYTE_ORDER == LITTLE_ENDIAN && encode == ELFDATA2LSB) + || (BYTE_ORDER == BIG_ENDIAN && encode == ELFDATA2MSB)) + { + /* We simply have to copy since the byte order is the same. */ + if (src->d_buf != dest->d_buf) + memmove (dest->d_buf, src->d_buf, src->d_size); + } + else + { + xfct_t fctp; + fctp = __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type]; + + /* Do the real work. */ + (*fctp) (dest->d_buf, src->d_buf, src->d_size, 0); + } + + /* Now set the real destination type and length since the operation was + successful. */ + dest->d_type = src->d_type; + dest->d_size = src->d_size; + + return dest; +} +INTDEF(elfw2(LIBELFBITS, xlatetom)) diff --git a/libelf/elf64_checksum.c b/libelf/elf64_checksum.c new file mode 100644 index 00000000..18022401 --- /dev/null +++ b/libelf/elf64_checksum.c @@ -0,0 +1,31 @@ +/* Compute simple checksum from permanent parts of the ELF file. + Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_checksum.c" diff --git a/libelf/elf64_fsize.c b/libelf/elf64_fsize.c new file mode 100644 index 00000000..1ee1067d --- /dev/null +++ b/libelf/elf64_fsize.c @@ -0,0 +1,31 @@ +/* Return the size of an object file type. + Copyright (C) 1998, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_fsize.c" diff --git a/libelf/elf64_getchdr.c b/libelf/elf64_getchdr.c new file mode 100644 index 00000000..6588b791 --- /dev/null +++ b/libelf/elf64_getchdr.c @@ -0,0 +1,30 @@ +/* Return section compression header. + Copyright (C) 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_getchdr.c" diff --git a/libelf/elf64_getehdr.c b/libelf/elf64_getehdr.c new file mode 100644 index 00000000..b35e7f66 --- /dev/null +++ b/libelf/elf64_getehdr.c @@ -0,0 +1,31 @@ +/* Return program header table. + Copyright (C) 1998, 1999, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_getehdr.c" diff --git a/libelf/elf64_getphdr.c b/libelf/elf64_getphdr.c new file mode 100644 index 00000000..c1ee60f4 --- /dev/null +++ b/libelf/elf64_getphdr.c @@ -0,0 +1,31 @@ +/* Return program header table. + Copyright (C) 1998, 1999, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_getphdr.c" diff --git a/libelf/elf64_getshdr.c b/libelf/elf64_getshdr.c new file mode 100644 index 00000000..c50cc71a --- /dev/null +++ b/libelf/elf64_getshdr.c @@ -0,0 +1,31 @@ +/* Return section header. + Copyright (C) 1998, 1999, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_getshdr.c" diff --git a/libelf/elf64_newehdr.c b/libelf/elf64_newehdr.c new file mode 100644 index 00000000..65dd0f72 --- /dev/null +++ b/libelf/elf64_newehdr.c @@ -0,0 +1,31 @@ +/* Create new program header table. + Copyright (C) 1999, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_newehdr.c" diff --git a/libelf/elf64_newphdr.c b/libelf/elf64_newphdr.c new file mode 100644 index 00000000..58bfc73c --- /dev/null +++ b/libelf/elf64_newphdr.c @@ -0,0 +1,31 @@ +/* Create new program header table. + Copyright (C) 1999, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_newphdr.c" diff --git a/libelf/elf64_offscn.c b/libelf/elf64_offscn.c new file mode 100644 index 00000000..1b37b366 --- /dev/null +++ b/libelf/elf64_offscn.c @@ -0,0 +1,31 @@ +/* Return program header table. + Copyright (C) 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_offscn.c" diff --git a/libelf/elf64_updatefile.c b/libelf/elf64_updatefile.c new file mode 100644 index 00000000..6941fe9a --- /dev/null +++ b/libelf/elf64_updatefile.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2000, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_updatefile.c" diff --git a/libelf/elf64_updatenull.c b/libelf/elf64_updatenull.c new file mode 100644 index 00000000..8333b5b2 --- /dev/null +++ b/libelf/elf64_updatenull.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2000, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_updatenull.c" diff --git a/libelf/elf64_xlatetof.c b/libelf/elf64_xlatetof.c new file mode 100644 index 00000000..aacf5b08 --- /dev/null +++ b/libelf/elf64_xlatetof.c @@ -0,0 +1,31 @@ +/* Convert from memory to file representation. + Copyright (C) 1998, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_xlatetof.c" diff --git a/libelf/elf64_xlatetom.c b/libelf/elf64_xlatetom.c new file mode 100644 index 00000000..034262cf --- /dev/null +++ b/libelf/elf64_xlatetom.c @@ -0,0 +1,31 @@ +/* Convert from file to memory representation. + Copyright (C) 1998, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#define LIBELFBITS 64 +#include "elf32_xlatetom.c" diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c new file mode 100644 index 00000000..32648c15 --- /dev/null +++ b/libelf/elf_begin.c @@ -0,0 +1,1204 @@ +/* Create descriptor for processing file. + Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "libelfP.h" +#include "common.h" + + +/* Create descriptor for archive in memory. */ +static inline Elf * +file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent) +{ + Elf *elf; + + /* Create a descriptor. */ + elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, + ELF_K_AR, 0); + if (elf != NULL) + { + /* We don't read all the symbol tables in advance. All this will + happen on demand. */ + elf->state.ar.offset = offset + SARMAG; + + elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name; + } + + return elf; +} + + +static size_t +get_shnum (void *map_address, unsigned char *e_ident, int fildes, + int64_t offset, size_t maxsize) +{ + size_t result; + union + { + Elf32_Ehdr *e32; + Elf64_Ehdr *e64; + void *p; + } ehdr; + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr_mem; + bool is32 = e_ident[EI_CLASS] == ELFCLASS32; + + if ((is32 && maxsize < sizeof (Elf32_Ehdr)) + || (!is32 && maxsize < sizeof (Elf64_Ehdr))) + { + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } + + /* Make the ELF header available. */ + if (e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) e_ident + & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr)) + - 1)) == 0))) + ehdr.p = e_ident; + else + { + /* We already read the ELF header. We have to copy the header + since we possibly modify the data here and the caller + expects the memory it passes in to be preserved. */ + ehdr.p = &ehdr_mem; + + if (is32) + { + if (ALLOW_UNALIGNED) + { + ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum; + ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff; + } + else + memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (ehdr_mem.e32.e_shnum); + CONVERT (ehdr_mem.e32.e_shoff); + } + } + else + { + if (ALLOW_UNALIGNED) + { + ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum; + ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff; + } + else + memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (ehdr_mem.e64.e_shnum); + CONVERT (ehdr_mem.e64.e_shoff); + } + } + } + + if (is32) + { + /* Get the number of sections from the ELF header. */ + result = ehdr.e32->e_shnum; + + if (unlikely (result == 0) && ehdr.e32->e_shoff != 0) + { + if (unlikely (ehdr.e32->e_shoff >= maxsize) + || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr))) + /* Cannot read the first section header. */ + return 0; + + if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) map_address + ehdr.e32->e_shoff)) + & (__alignof__ (Elf32_Shdr) - 1)) == 0)) + /* We can directly access the memory. */ + result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff + + offset))->sh_size; + else + { + Elf32_Word size; + ssize_t r; + + if (likely (map_address != NULL)) + /* gcc will optimize the memcpy to a simple memory + access while taking care of alignment issues. */ + memcpy (&size, &((Elf32_Shdr *) ((char *) map_address + + ehdr.e32->e_shoff + + offset))->sh_size, + sizeof (Elf32_Word)); + else + if (unlikely ((r = pread_retry (fildes, &size, + sizeof (Elf32_Word), + offset + ehdr.e32->e_shoff + + offsetof (Elf32_Shdr, + sh_size))) + != sizeof (Elf32_Word))) + { + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } + + if (e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (size); + + result = size; + } + } + + /* If the section headers were truncated, pretend none were there. */ + if (ehdr.e32->e_shoff > maxsize + || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result) + result = 0; + } + else + { + /* Get the number of sections from the ELF header. */ + result = ehdr.e64->e_shnum; + + if (unlikely (result == 0) && ehdr.e64->e_shoff != 0) + { + if (unlikely (ehdr.e64->e_shoff >= maxsize) + || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)) + /* Cannot read the first section header. */ + return 0; + + Elf64_Xword size; + if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) map_address + ehdr.e64->e_shoff)) + & (__alignof__ (Elf64_Shdr) - 1)) == 0)) + /* We can directly access the memory. */ + size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff + + offset))->sh_size; + else + { + ssize_t r; + if (likely (map_address != NULL)) + /* gcc will optimize the memcpy to a simple memory + access while taking care of alignment issues. */ + memcpy (&size, &((Elf64_Shdr *) ((char *) map_address + + ehdr.e64->e_shoff + + offset))->sh_size, + sizeof (Elf64_Xword)); + else + if (unlikely ((r = pread_retry (fildes, &size, + sizeof (Elf64_Xword), + offset + ehdr.e64->e_shoff + + offsetof (Elf64_Shdr, + sh_size))) + != sizeof (Elf64_Xword))) + { + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } + + if (e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (size); + } + + /* Although sh_size is an Elf64_Xword and can contain a 64bit + value, we only expect an 32bit value max. GElf_Word is + 32bit unsigned. */ + if (size > ~((GElf_Word) 0)) + { + /* Invalid value, it is too large. */ + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } + + result = size; + } + + /* If the section headers were truncated, pretend none were there. */ + if (ehdr.e64->e_shoff > maxsize + || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result) + result = 0; + } + + return result; +} + + +/* Create descriptor for ELF file in memory. */ +static Elf * +file_read_elf (int fildes, void *map_address, unsigned char *e_ident, + int64_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent) +{ + /* Verify the binary is of the class we can handle. */ + if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32 + && e_ident[EI_CLASS] != ELFCLASS64) + /* We also can only handle two encodings. */ + || (e_ident[EI_DATA] != ELFDATA2LSB + && e_ident[EI_DATA] != ELFDATA2MSB))) + { + /* Cannot handle this. */ + __libelf_seterrno (ELF_E_INVALID_ELF); + return NULL; + } + + /* Determine the number of sections. Returns -1 and sets libelf errno + if the file handle or elf file is invalid. Returns zero if there + are no section headers (or they cannot be read). */ + size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize); + if (scncnt == (size_t) -1l) + /* Could not determine the number of sections. */ + return NULL; + + /* Check for too many sections. */ + if (e_ident[EI_CLASS] == ELFCLASS32) + { + if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr))) + { + __libelf_seterrno (ELF_E_INVALID_ELF); + return NULL; + } + } + else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr))) + { + __libelf_seterrno (ELF_E_INVALID_ELF); + return NULL; + } + + /* We can now allocate the memory. Even if there are no section headers, + we allocate space for a zeroth section in case we need it later. */ + const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP) + ? 1 : 0); + Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, + ELF_K_ELF, scnmax * sizeof (Elf_Scn)); + if (elf == NULL) + /* Not enough memory. allocate_elf will have set libelf errno. */ + return NULL; + + assert ((unsigned int) scncnt == scncnt); + assert (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)); + elf->state.elf32.scns.cnt = scncnt; + elf->state.elf32.scns.max = scnmax; + + /* Some more or less arbitrary value. */ + elf->state.elf.scnincr = 10; + + /* Make the class easily available. */ + elf->class = e_ident[EI_CLASS]; + + if (e_ident[EI_CLASS] == ELFCLASS32) + { + /* This pointer might not be directly usable if the alignment is + not sufficient for the architecture. */ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset); + + /* This is a 32-bit binary. */ + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0)) + { + /* We can use the mmapped memory. */ + elf->state.elf32.ehdr = ehdr; + } + else + { + /* Copy the ELF header. */ + elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident, + sizeof (Elf32_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (elf->state.elf32.ehdr_mem.e_type); + CONVERT (elf->state.elf32.ehdr_mem.e_machine); + CONVERT (elf->state.elf32.ehdr_mem.e_version); + CONVERT (elf->state.elf32.ehdr_mem.e_entry); + CONVERT (elf->state.elf32.ehdr_mem.e_phoff); + CONVERT (elf->state.elf32.ehdr_mem.e_shoff); + CONVERT (elf->state.elf32.ehdr_mem.e_flags); + CONVERT (elf->state.elf32.ehdr_mem.e_ehsize); + CONVERT (elf->state.elf32.ehdr_mem.e_phentsize); + CONVERT (elf->state.elf32.ehdr_mem.e_phnum); + CONVERT (elf->state.elf32.ehdr_mem.e_shentsize); + CONVERT (elf->state.elf32.ehdr_mem.e_shnum); + CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx); + } + } + + /* Don't precache the phdr pointer here. + elf32_getphdr will validate it against the size when asked. */ + + Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff; + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write. */ + && (ALLOW_UNALIGNED + || (((uintptr_t) ((char *) ehdr + e_shoff) + & (__alignof__ (Elf32_Shdr) - 1)) == 0))) + { + if (unlikely (scncnt > 0 && e_shoff >= maxsize) + || unlikely (maxsize - e_shoff + < scncnt * sizeof (Elf32_Shdr))) + { + free_and_out: + free (elf); + __libelf_seterrno (ELF_E_INVALID_ELF); + return NULL; + } + elf->state.elf32.shdr + = (Elf32_Shdr *) ((char *) ehdr + e_shoff); + + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf32.scns.data[cnt].index = cnt; + elf->state.elf32.scns.data[cnt].elf = elf; + elf->state.elf32.scns.data[cnt].shdr.e32 = + &elf->state.elf32.shdr[cnt]; + if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize) + && likely (elf->state.elf32.shdr[cnt].sh_size + <= maxsize - elf->state.elf32.shdr[cnt].sh_offset)) + elf->state.elf32.scns.data[cnt].rawdata_base = + elf->state.elf32.scns.data[cnt].data_base = + ((char *) map_address + offset + + elf->state.elf32.shdr[cnt].sh_offset); + elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns; + + /* If this is a section with an extended index add a + reference in the section which uses the extended + index. */ + if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX + && elf->state.elf32.shdr[cnt].sh_link < scncnt) + elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index + = cnt; + + /* Set the own shndx_index field in case it has not yet + been set. */ + if (elf->state.elf32.scns.data[cnt].shndx_index == 0) + elf->state.elf32.scns.data[cnt].shndx_index = -1; + } + } + else + { + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf32.scns.data[cnt].index = cnt; + elf->state.elf32.scns.data[cnt].elf = elf; + elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns; + } + } + + /* So far only one block with sections. */ + elf->state.elf32.scns_last = &elf->state.elf32.scns; + } + else + { + /* This pointer might not be directly usable if the alignment is + not sufficient for the architecture. */ + Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset); + + /* This is a 64-bit binary. */ + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0)) + { + /* We can use the mmapped memory. */ + elf->state.elf64.ehdr = ehdr; + } + else + { + /* Copy the ELF header. */ + elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident, + sizeof (Elf64_Ehdr)); + + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (elf->state.elf64.ehdr_mem.e_type); + CONVERT (elf->state.elf64.ehdr_mem.e_machine); + CONVERT (elf->state.elf64.ehdr_mem.e_version); + CONVERT (elf->state.elf64.ehdr_mem.e_entry); + CONVERT (elf->state.elf64.ehdr_mem.e_phoff); + CONVERT (elf->state.elf64.ehdr_mem.e_shoff); + CONVERT (elf->state.elf64.ehdr_mem.e_flags); + CONVERT (elf->state.elf64.ehdr_mem.e_ehsize); + CONVERT (elf->state.elf64.ehdr_mem.e_phentsize); + CONVERT (elf->state.elf64.ehdr_mem.e_phnum); + CONVERT (elf->state.elf64.ehdr_mem.e_shentsize); + CONVERT (elf->state.elf64.ehdr_mem.e_shnum); + CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx); + } + } + + /* Don't precache the phdr pointer here. + elf64_getphdr will validate it against the size when asked. */ + + Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff; + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write. */ + && (ALLOW_UNALIGNED + || (((uintptr_t) ((char *) ehdr + e_shoff) + & (__alignof__ (Elf64_Shdr) - 1)) == 0))) + { + if (unlikely (scncnt > 0 && e_shoff >= maxsize) + || unlikely (maxsize - e_shoff + < scncnt * sizeof (Elf64_Shdr))) + goto free_and_out; + elf->state.elf64.shdr + = (Elf64_Shdr *) ((char *) ehdr + e_shoff); + + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf64.scns.data[cnt].index = cnt; + elf->state.elf64.scns.data[cnt].elf = elf; + elf->state.elf64.scns.data[cnt].shdr.e64 = + &elf->state.elf64.shdr[cnt]; + if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize) + && likely (elf->state.elf64.shdr[cnt].sh_size + <= maxsize - elf->state.elf64.shdr[cnt].sh_offset)) + elf->state.elf64.scns.data[cnt].rawdata_base = + elf->state.elf64.scns.data[cnt].data_base = + ((char *) map_address + offset + + elf->state.elf64.shdr[cnt].sh_offset); + elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns; + + /* If this is a section with an extended index add a + reference in the section which uses the extended + index. */ + if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX + && elf->state.elf64.shdr[cnt].sh_link < scncnt) + elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index + = cnt; + + /* Set the own shndx_index field in case it has not yet + been set. */ + if (elf->state.elf64.scns.data[cnt].shndx_index == 0) + elf->state.elf64.scns.data[cnt].shndx_index = -1; + } + } + else + { + for (size_t cnt = 0; cnt < scncnt; ++cnt) + { + elf->state.elf64.scns.data[cnt].index = cnt; + elf->state.elf64.scns.data[cnt].elf = elf; + elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns; + } + } + + /* So far only one block with sections. */ + elf->state.elf64.scns_last = &elf->state.elf64.scns; + } + + return elf; +} + + +Elf * +internal_function +__libelf_read_mmaped_file (int fildes, void *map_address, int64_t offset, + size_t maxsize, Elf_Cmd cmd, Elf *parent) +{ + /* We have to find out what kind of file this is. We handle ELF + files and archives. To find out what we have we must look at the + header. The header for an ELF file is EI_NIDENT bytes in size, + the header for an archive file SARMAG bytes long. */ + unsigned char *e_ident = (unsigned char *) map_address + offset; + + /* See what kind of object we have here. */ + Elf_Kind kind = determine_kind (e_ident, maxsize); + + switch (kind) + { + case ELF_K_ELF: + return file_read_elf (fildes, map_address, e_ident, offset, maxsize, + cmd, parent); + + case ELF_K_AR: + return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent); + + default: + break; + } + + /* This case is easy. Since we cannot do anything with this file + create a dummy descriptor. */ + return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, + ELF_K_NONE, 0); +} + + +static Elf * +read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd, + Elf *parent) +{ + /* We have to find out what kind of file this is. We handle ELF + files and archives. To find out what we have we must read the + header. The identification header for an ELF file is EI_NIDENT + bytes in size, but we read the whole ELF header since we will + need it anyway later. For archives the header in SARMAG bytes + long. Read the maximum of these numbers. + + XXX We have to change this for the extended `ar' format some day. + + Use a union to ensure alignment. We might later access the + memory as a ElfXX_Ehdr. */ + union + { + Elf64_Ehdr ehdr; + unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)]; + } mem; + + /* Read the head of the file. */ + ssize_t nread = pread_retry (fildes, mem.header, + MIN (MAX (sizeof (Elf64_Ehdr), SARMAG), + maxsize), + offset); + if (unlikely (nread == -1)) + { + /* We cannot even read the head of the file. Maybe FILDES is associated + with an unseekable device. This is nothing we can handle. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + return NULL; + } + + /* See what kind of object we have here. */ + Elf_Kind kind = determine_kind (mem.header, nread); + + switch (kind) + { + case ELF_K_AR: + return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent); + + case ELF_K_ELF: + /* Make sure at least the ELF header is contained in the file. */ + if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32 + ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))) + return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd, + parent); + FALLTHROUGH; + + default: + break; + } + + /* This case is easy. Since we cannot do anything with this file + create a dummy descriptor. */ + return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent, + ELF_K_NONE, 0); +} + + +/* Open a file for reading. If possible we will try to mmap() the file. */ +static struct Elf * +read_file (int fildes, int64_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent) +{ + void *map_address = NULL; + int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP + || cmd == ELF_C_WRITE_MMAP + || cmd == ELF_C_READ_MMAP_PRIVATE); + + if (parent == NULL) + { + if (maxsize == ~((size_t) 0)) + { + /* We don't know in the moment how large the file is. + Determine it now. */ + struct stat st; + + if (fstat (fildes, &st) == 0 + && (sizeof (size_t) >= sizeof (st.st_size) + || st.st_size <= ~((size_t) 0))) + maxsize = (size_t) st.st_size; + } + } + else + { + /* The parent is already loaded. Use it. */ + assert (maxsize != ~((size_t) 0)); + } + + if (use_mmap) + { + if (parent == NULL) + { + /* We try to map the file ourself. */ + map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP + ? PROT_READ + : PROT_READ|PROT_WRITE), + cmd == ELF_C_READ_MMAP_PRIVATE + || cmd == ELF_C_READ_MMAP + ? MAP_PRIVATE : MAP_SHARED, + fildes, offset); + + if (map_address == MAP_FAILED) + map_address = NULL; + } + else + { + map_address = parent->map_address; + } + } + + /* If we have the file in memory optimize the access. */ + if (map_address != NULL) + { + assert (map_address != MAP_FAILED); + + struct Elf *result = __libelf_read_mmaped_file (fildes, map_address, + offset, maxsize, cmd, + parent); + + /* If something went wrong during the initialization unmap the + memory if we mmaped here. */ + if (result == NULL + && (parent == NULL + || parent->map_address != map_address)) + munmap (map_address, maxsize); + else if (parent == NULL) + /* Remember that we mmap()ed the memory. */ + result->flags |= ELF_F_MMAPPED; + + return result; + } + + /* Otherwise we have to do it the hard way. We read as much as necessary + from the file whenever we need information which is not available. */ + return read_unmmaped_file (fildes, offset, maxsize, cmd, parent); +} + + +/* Find the entry with the long names for the content of this archive. */ +static const char * +read_long_names (Elf *elf) +{ + off_t offset = SARMAG; /* This is the first entry. */ + struct ar_hdr hdrm; + struct ar_hdr *hdr; + char *newp; + size_t len; + + while (1) + { + if (elf->map_address != NULL) + { + if ((size_t) offset > elf->maximum_size + || elf->maximum_size - offset < sizeof (struct ar_hdr)) + return NULL; + + /* The data is mapped. */ + hdr = (struct ar_hdr *) (elf->map_address + offset); + } + else + { + /* Read the header from the file. */ + if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm), + elf->start_offset + offset) + != sizeof (hdrm))) + return NULL; + + hdr = &hdrm; + } + + /* The ar_size is given as a fixed size decimal string, right + padded with spaces. Make sure we read it properly even if + there is no terminating space. */ + char buf[sizeof (hdr->ar_size) + 1]; + const char *string = hdr->ar_size; + if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ') + { + *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0'; + string = buf; + } + len = atol (string); + + if (memcmp (hdr->ar_name, "// ", 16) == 0) + break; + + offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l); + } + + /* Sanity check len early if we can. */ + if (elf->map_address != NULL) + { + if (len > elf->maximum_size - offset - sizeof (struct ar_hdr)) + return NULL; + } + + /* Due to the stupid format of the long name table entry (which are not + NUL terminted) we have to provide an appropriate representation anyhow. + Therefore we always make a copy which has the appropriate form. */ + newp = (char *) malloc (len); + if (newp != NULL) + { + char *runp; + + if (elf->map_address != NULL) + { + /* Simply copy it over. */ + elf->state.ar.long_names = (char *) memcpy (newp, + elf->map_address + offset + + sizeof (struct ar_hdr), + len); + } + else + { + if (unlikely ((size_t) pread_retry (elf->fildes, newp, len, + elf->start_offset + offset + + sizeof (struct ar_hdr)) + != len)) + { + /* We were not able to read all data. */ + free (newp); + elf->state.ar.long_names = NULL; + return NULL; + } + elf->state.ar.long_names = newp; + } + + elf->state.ar.long_names_len = len; + + /* Now NUL-terminate the strings. */ + runp = newp; + while (1) + { + char *startp = runp; + runp = (char *) memchr (runp, '/', newp + len - runp); + if (runp == NULL) + { + /* This was the last entry. Clear any left overs. */ + memset (startp, '\0', newp + len - startp); + break; + } + + /* NUL-terminate the string. */ + *runp++ = '\0'; + + /* A sanity check. Somebody might have generated invalid + archive. */ + if (runp >= newp + len) + break; + } + } + + return newp; +} + + +/* Read the next archive header. */ +int +internal_function +__libelf_next_arhdr_wrlock (Elf *elf) +{ + struct ar_hdr *ar_hdr; + Elf_Arhdr *elf_ar_hdr; + + if (elf->map_address != NULL) + { + /* See whether this entry is in the file. */ + if (unlikely ((size_t) elf->state.ar.offset + > elf->start_offset + elf->maximum_size + || (elf->start_offset + elf->maximum_size + - elf->state.ar.offset) < sizeof (struct ar_hdr))) + { + /* This record is not anymore in the file. */ + __libelf_seterrno (ELF_E_RANGE); + return -1; + } + ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset); + } + else + { + ar_hdr = &elf->state.ar.ar_hdr; + + if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr), + elf->state.ar.offset) + != sizeof (struct ar_hdr))) + { + /* Something went wrong while reading the file. */ + __libelf_seterrno (ELF_E_RANGE); + return -1; + } + } + + /* One little consistency check. */ + if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0)) + { + /* This is no valid archive. */ + __libelf_seterrno (ELF_E_ARCHIVE_FMAG); + return -1; + } + + /* Copy the raw name over to a NUL terminated buffer. */ + *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0'; + + elf_ar_hdr = &elf->state.ar.elf_ar_hdr; + + /* Now convert the `struct ar_hdr' into `Elf_Arhdr'. + Determine whether this is a special entry. */ + if (ar_hdr->ar_name[0] == '/') + { + if (ar_hdr->ar_name[1] == ' ' + && memcmp (ar_hdr->ar_name, "/ ", 16) == 0) + /* This is the index. */ + elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2); + else if (ar_hdr->ar_name[1] == 'S' + && memcmp (ar_hdr->ar_name, "/SYM64/ ", 16) == 0) + /* 64-bit index. */ + elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8); + else if (ar_hdr->ar_name[1] == '/' + && memcmp (ar_hdr->ar_name, "// ", 16) == 0) + /* This is the array with the long names. */ + elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3); + else if (likely (isdigit (ar_hdr->ar_name[1]))) + { + size_t offset; + + /* This is a long name. First we have to read the long name + table, if this hasn't happened already. */ + if (unlikely (elf->state.ar.long_names == NULL + && read_long_names (elf) == NULL)) + { + /* No long name table although it is reference. The archive is + broken. */ + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + + offset = atol (ar_hdr->ar_name + 1); + if (unlikely (offset >= elf->state.ar.long_names_len)) + { + /* The index in the long name table is larger than the table. */ + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + elf_ar_hdr->ar_name = elf->state.ar.long_names + offset; + } + else + { + /* This is none of the known special entries. */ + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + } + else + { + char *endp; + + /* It is a normal entry. Copy over the name. */ + endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name, + '/', 16); + if (endp != NULL) + endp[-1] = '\0'; + else + { + /* In the old BSD style of archive, there is no / terminator. + Instead, there is space padding at the end of the name. */ + size_t i = 15; + do + elf->state.ar.ar_name[i] = '\0'; + while (i > 0 && elf->state.ar.ar_name[--i] == ' '); + } + + elf_ar_hdr->ar_name = elf->state.ar.ar_name; + } + + if (unlikely (ar_hdr->ar_size[0] == ' ')) + /* Something is really wrong. We cannot live without a size for + the member since it will not be possible to find the next + archive member. */ + { + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + + /* Since there are no specialized functions to convert ASCII to + time_t, uid_t, gid_t, mode_t, and off_t we use either atol or + atoll depending on the size of the types. We are also prepared + for the case where the whole field in the `struct ar_hdr' is + filled in which case we cannot simply use atol/l but instead have + to create a temporary copy. */ + +#define INT_FIELD(FIELD) \ + do \ + { \ + char buf[sizeof (ar_hdr->FIELD) + 1]; \ + const char *string = ar_hdr->FIELD; \ + if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \ + { \ + *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \ + = '\0'; \ + string = buf; \ + } \ + if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \ + elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \ + else \ + elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \ + } \ + while (0) + + INT_FIELD (ar_date); + INT_FIELD (ar_uid); + INT_FIELD (ar_gid); + INT_FIELD (ar_mode); + INT_FIELD (ar_size); + + if (elf_ar_hdr->ar_size < 0) + { + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + + /* Truncated file? */ + size_t maxsize; + maxsize = (elf->start_offset + elf->maximum_size + - elf->state.ar.offset - sizeof (struct ar_hdr)); + if ((size_t) elf_ar_hdr->ar_size > maxsize) + elf_ar_hdr->ar_size = maxsize; + + return 0; +} + + +/* We were asked to return a clone of an existing descriptor. This + function must be called with the lock on the parent descriptor + being held. */ +static Elf * +dup_elf (int fildes, Elf_Cmd cmd, Elf *ref) +{ + struct Elf *result; + + if (fildes == -1) + /* Allow the user to pass -1 as the file descriptor for the new file. */ + fildes = ref->fildes; + /* The file descriptor better should be the same. If it was disconnected + already (using `elf_cntl') we do not test it. */ + else if (unlikely (ref->fildes != -1 && fildes != ref->fildes)) + { + __libelf_seterrno (ELF_E_FD_MISMATCH); + return NULL; + } + + /* The mode must allow reading. I.e., a descriptor creating with a + command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is + not allowed. */ + if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP + && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP + && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP + && ref->cmd != ELF_C_READ_MMAP_PRIVATE)) + { + __libelf_seterrno (ELF_E_INVALID_OP); + return NULL; + } + + /* Now it is time to distinguish between reading normal files and + archives. Normal files can easily be handled be incrementing the + reference counter and return the same descriptor. */ + if (ref->kind != ELF_K_AR) + { + ++ref->ref_count; + return ref; + } + + /* This is an archive. We must create a descriptor for the archive + member the internal pointer of the archive file descriptor is + pointing to. First read the header of the next member if this + has not happened already. */ + if (ref->state.ar.elf_ar_hdr.ar_name == NULL + && __libelf_next_arhdr_wrlock (ref) != 0) + /* Something went wrong. Maybe there is no member left. */ + return NULL; + + /* We have all the information we need about the next archive member. + Now create a descriptor for it. */ + result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr), + ref->state.ar.elf_ar_hdr.ar_size, cmd, ref); + + /* Enlist this new descriptor in the list of children. */ + if (result != NULL) + { + result->next = ref->state.ar.children; + ref->state.ar.children = result; + } + + return result; +} + + +/* Return descriptor for empty file ready for writing. */ +static struct Elf * +write_file (int fd, Elf_Cmd cmd) +{ + /* We simply create an empty `Elf' structure. */ +#define NSCNSALLOC 10 + Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF, + NSCNSALLOC * sizeof (Elf_Scn)); + + if (result != NULL) + { + /* We have to write to the file in any case. */ + result->flags = ELF_F_DIRTY; + + /* Some more or less arbitrary value. */ + result->state.elf.scnincr = NSCNSALLOC; + + /* We have allocated room for some sections. */ + assert (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)); + result->state.elf.scns_last = &result->state.elf32.scns; + result->state.elf32.scns.max = NSCNSALLOC; + } + + return result; +} + +/* Lock if necessary before dup an archive. */ +static inline Elf * +lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref) +{ + /* We need wrlock to dup an archive. */ + if (ref->kind == ELF_K_AR) + { + rwlock_unlock (ref->lock); + rwlock_wrlock (ref->lock); + } + /* Duplicate the descriptor. */ + return dup_elf (fildes, cmd, ref); +} + +/* Return a descriptor for the file belonging to FILDES. */ +Elf * +elf_begin (int fildes, Elf_Cmd cmd, Elf *ref) +{ + Elf *retval; + + if (unlikely (__libelf_version != EV_CURRENT)) + { + /* Version wasn't set so far. */ + __libelf_seterrno (ELF_E_NO_VERSION); + return NULL; + } + + if (ref != NULL) + /* Make sure the descriptor is not suddenly going away. */ + rwlock_rdlock (ref->lock); + else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF)) + { + /* We cannot do anything productive without a file descriptor. */ + __libelf_seterrno (ELF_E_INVALID_FILE); + return NULL; + } + + switch (cmd) + { + case ELF_C_NULL: + /* We simply return a NULL pointer. */ + retval = NULL; + break; + + case ELF_C_READ_MMAP_PRIVATE: + /* If we have a reference it must also be opened this way. */ + if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE)) + { + __libelf_seterrno (ELF_E_INVALID_CMD); + retval = NULL; + break; + } + FALLTHROUGH; + + case ELF_C_READ: + case ELF_C_READ_MMAP: + if (ref != NULL) + retval = lock_dup_elf (fildes, cmd, ref); + else + /* Create descriptor for existing file. */ + retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); + break; + + case ELF_C_RDWR: + case ELF_C_RDWR_MMAP: + /* If we have a REF object it must also be opened using this + command. */ + if (ref != NULL) + { + if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP + && ref->cmd != ELF_C_WRITE + && ref->cmd != ELF_C_WRITE_MMAP)) + { + /* This is not ok. REF must also be opened for writing. */ + __libelf_seterrno (ELF_E_INVALID_CMD); + retval = NULL; + } + else + retval = lock_dup_elf (fildes, cmd, ref); + } + else + /* Create descriptor for existing file. */ + retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); + break; + + case ELF_C_WRITE: + case ELF_C_WRITE_MMAP: + /* We ignore REF and prepare a descriptor to write a new file. */ + retval = write_file (fildes, cmd); + break; + + default: + __libelf_seterrno (ELF_E_INVALID_CMD); + retval = NULL; + break; + } + + /* Release the lock. */ + if (ref != NULL) + rwlock_unlock (ref->lock); + + return retval; +} +INTDEF(elf_begin) diff --git a/libelf/elf_clone.c b/libelf/elf_clone.c new file mode 100644 index 00000000..e6fe4729 --- /dev/null +++ b/libelf/elf_clone.c @@ -0,0 +1,81 @@ +/* Create clone of a given descriptor. + Copyright (C) 2003, 2004 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libelfP.h" +#include "common.h" + + +Elf * +elf_clone (Elf *elf, Elf_Cmd cmd) +{ + Elf *retval = NULL; + + if (elf == NULL) + /* Some earlier mistake. */ + return NULL; + + /* Make sure the descriptor is not suddenly going away. */ + rwlock_rdlock (elf->lock); + + if (cmd != ELF_C_EMPTY) + // XXX TODO handle ELF_C_READ/WRITE etc + goto out; + + retval = allocate_elf (elf->fildes, elf->map_address, elf->start_offset, + elf->maximum_size, elf->cmd, elf->parent, elf->kind, + elf->state.elf32.scns.max * sizeof (Elf_Scn)); + if (retval != NULL) + { + /* We have to write to the file in any case. */ + retval->flags = ELF_F_DIRTY; + + /* Some more or less arbitrary value. */ + retval->state.elf.scnincr = 10; + + /* We have allocated room for some sections. */ + assert (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)); + retval->state.elf.scns_last = &retval->state.elf32.scns; + retval->state.elf32.scns.max = elf->state.elf32.scns.max; + + retval->class = elf->class; + } + + /* Release the lock. */ + out: + rwlock_unlock (elf->lock); + + return retval; +} diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c new file mode 100644 index 00000000..fd681789 --- /dev/null +++ b/libelf/elf_cntl.c @@ -0,0 +1,81 @@ +/* Control an ELF file desrciptor. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libelfP.h" + + +int +elf_cntl (Elf *elf, Elf_Cmd cmd) +{ + int result = 0; + + if (elf == NULL) + return -1; + + if (elf->fildes == -1) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_wrlock (elf->lock); + + switch (cmd) + { + case ELF_C_FDREAD: + /* If not all of the file is in the memory read it now. */ + if (elf->map_address == NULL && __libelf_readall (elf) == NULL) + { + /* We were not able to read everything. */ + result = -1; + break; + } + FALLTHROUGH; + + case ELF_C_FDDONE: + /* Mark the file descriptor as not usable. */ + elf->fildes = -1; + break; + + default: + __libelf_seterrno (ELF_E_INVALID_CMD); + result = -1; + break; + } + + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c new file mode 100644 index 00000000..df0144e8 --- /dev/null +++ b/libelf/elf_compress.c @@ -0,0 +1,535 @@ +/* Compress or decompress a section. + Copyright (C) 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "libelfP.h" +#include "common.h" + +#include +#include +#include +#include +#include + +/* Cleanup and return result. Don't leak memory. */ +static void * +do_deflate_cleanup (void *result, z_stream *z, void *out_buf, + Elf_Data *cdatap) +{ + deflateEnd (z); + free (out_buf); + if (cdatap != NULL) + free (cdatap->d_buf); + return result; +} + +#define deflate_cleanup(result, cdata) \ + do_deflate_cleanup(result, &z, out_buf, cdata) + +/* Given a section, uses the (in-memory) Elf_Data to extract the + original data size (including the given header size) and data + alignment. Returns a buffer that has at least hsize bytes (for the + caller to fill in with a header) plus zlib compressed date. Also + returns the new buffer size in new_size (hsize + compressed data + size). Returns (void *) -1 when FORCE is false and the compressed + data would be bigger than the original data. */ +void * +internal_function +__libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data, + size_t *orig_size, size_t *orig_addralign, + size_t *new_size, bool force) +{ + /* The compressed data is the on-disk data. We simplify the + implementation a bit by asking for the (converted) in-memory + data (which might be all there is if the user created it with + elf_newdata) and then convert back to raw if needed before + compressing. Should be made a bit more clever to directly + use raw if that is directly available. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return NULL; + + /* When not forced and we immediately know we would use more data by + compressing, because of the header plus zlib overhead (five bytes + per 16 KB block, plus a one-time overhead of six bytes for the + entire stream), don't do anything. */ + Elf_Data *next_data = elf_getdata (scn, data); + if (next_data == NULL && !force + && data->d_size <= hsize + 5 + 6) + return (void *) -1; + + *orig_addralign = data->d_align; + *orig_size = data->d_size; + + /* Guess an output block size. 1/8th of the original Elf_Data plus + hsize. Make the first chunk twice that size (25%), then increase + by a block (12.5%) when necessary. */ + size_t block = (data->d_size / 8) + hsize; + size_t out_size = 2 * block; + void *out_buf = malloc (out_size); + if (out_buf == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return NULL; + } + + /* Caller gets to fill in the header at the start. Just skip it here. */ + size_t used = hsize; + + z_stream z; + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = Z_NULL; + int zrc = deflateInit (&z, Z_BEST_COMPRESSION); + if (zrc != Z_OK) + { + __libelf_seterrno (ELF_E_COMPRESS_ERROR); + return deflate_cleanup(NULL, NULL); + } + + Elf_Data cdata; + cdata.d_buf = NULL; + + /* Loop over data buffers. */ + int flush = Z_NO_FLUSH; + do + { + /* Convert to raw if different endianness. */ + cdata = *data; + bool convert = ei_data != MY_ELFDATA && data->d_size > 0; + if (convert) + { + /* Don't do this conversion in place, we might want to keep + the original data around, caller decides. */ + cdata.d_buf = malloc (data->d_size); + if (cdata.d_buf == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return deflate_cleanup (NULL, NULL); + } + if (gelf_xlatetof (scn->elf, &cdata, data, ei_data) == NULL) + return deflate_cleanup (NULL, &cdata); + } + + z.avail_in = cdata.d_size; + z.next_in = cdata.d_buf; + + /* Get next buffer to see if this is the last one. */ + data = next_data; + if (data != NULL) + { + *orig_addralign = MAX (*orig_addralign, data->d_align); + *orig_size += data->d_size; + next_data = elf_getdata (scn, data); + } + else + flush = Z_FINISH; + + /* Flush one data buffer. */ + do + { + z.avail_out = out_size - used; + z.next_out = out_buf + used; + zrc = deflate (&z, flush); + if (zrc == Z_STREAM_ERROR) + { + __libelf_seterrno (ELF_E_COMPRESS_ERROR); + return deflate_cleanup (NULL, convert ? &cdata : NULL); + } + used += (out_size - used) - z.avail_out; + + /* Bail out if we are sure the user doesn't want the + compression forced and we are using more compressed data + than original data. */ + if (!force && flush == Z_FINISH && used >= *orig_size) + return deflate_cleanup ((void *) -1, convert ? &cdata : NULL); + + if (z.avail_out == 0) + { + void *bigger = realloc (out_buf, out_size + block); + if (bigger == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return deflate_cleanup (NULL, convert ? &cdata : NULL); + } + out_buf = bigger; + out_size += block; + } + } + while (z.avail_out == 0); /* Need more output buffer. */ + + if (convert) + { + free (cdata.d_buf); + cdata.d_buf = NULL; + } + } + while (flush != Z_FINISH); /* More data blocks. */ + + if (zrc != Z_STREAM_END) + { + __libelf_seterrno (ELF_E_COMPRESS_ERROR); + return deflate_cleanup (NULL, NULL); + } + + deflateEnd (&z); + *new_size = used; + return out_buf; +} + +void * +internal_function +__libelf_decompress (void *buf_in, size_t size_in, size_t size_out) +{ + /* Catch highly unlikely compression ratios so we don't allocate + some giant amount of memory for nothing. The max compression + factor 1032:1 comes from http://www.zlib.net/zlib_tech.html */ + if (unlikely (size_out / 1032 > size_in)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + /* Malloc might return NULL when requestion zero size. This is highly + unlikely, it would only happen when the compression was forced. + But we do need a non-NULL buffer to return and set as result. + Just make sure to always allocate at least 1 byte. */ + void *buf_out = malloc (size_out ?: 1); + if (unlikely (buf_out == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return NULL; + } + + z_stream z = + { + .next_in = buf_in, + .avail_in = size_in, + .next_out = buf_out, + .avail_out = size_out + }; + int zrc = inflateInit (&z); + while (z.avail_in > 0 && likely (zrc == Z_OK)) + { + z.next_out = buf_out + (size_out - z.avail_out); + zrc = inflate (&z, Z_FINISH); + if (unlikely (zrc != Z_STREAM_END)) + { + zrc = Z_DATA_ERROR; + break; + } + zrc = inflateReset (&z); + } + + if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0)) + { + free (buf_out); + buf_out = NULL; + __libelf_seterrno (ELF_E_DECOMPRESS_ERROR); + } + + inflateEnd(&z); + return buf_out; +} + +void * +internal_function +__libelf_decompress_elf (Elf_Scn *scn, size_t *size_out, size_t *addralign) +{ + GElf_Chdr chdr; + if (gelf_getchdr (scn, &chdr) == NULL) + return NULL; + + if (chdr.ch_type != ELFCOMPRESS_ZLIB) + { + __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE); + return NULL; + } + + if (! powerof2 (chdr.ch_addralign)) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return NULL; + } + + /* Take the in-memory representation, so we can even handle a + section that has just been constructed (maybe it was copied + over from some other ELF file first with elf_newdata). This + is slightly inefficient when the raw data needs to be + converted since then we'll be converting the whole buffer and + not just Chdr. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return NULL; + + int elfclass = scn->elf->class; + size_t hsize = (elfclass == ELFCLASS32 + ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr)); + size_t size_in = data->d_size - hsize; + void *buf_in = data->d_buf + hsize; + void *buf_out = __libelf_decompress (buf_in, size_in, chdr.ch_size); + *size_out = chdr.ch_size; + *addralign = chdr.ch_addralign; + return buf_out; +} + +/* Assumes buf is a malloced buffer. */ +void +internal_function +__libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align, + Elf_Type type) +{ + /* This is the new raw data, replace and possibly free old data. */ + scn->rawdata.d.d_off = 0; + scn->rawdata.d.d_version = EV_CURRENT; + scn->rawdata.d.d_buf = buf; + scn->rawdata.d.d_size = size; + scn->rawdata.d.d_align = align; + scn->rawdata.d.d_type = type; + + /* Existing existing data is no longer valid. */ + scn->data_list_rear = NULL; + if (scn->data_base != scn->rawdata_base) + free (scn->data_base); + scn->data_base = NULL; + if (scn->elf->map_address == NULL + || scn->rawdata_base == scn->zdata_base + || (scn->flags & ELF_F_MALLOCED) != 0) + free (scn->rawdata_base); + + scn->rawdata_base = buf; + scn->flags |= ELF_F_MALLOCED; + + /* Pretend we (tried to) read the data from the file and setup the + data (might have to convert the Chdr to native format). */ + scn->data_read = 1; + scn->flags |= ELF_F_FILEDATA; + __libelf_set_data_list_rdlock (scn, 1); +} + +int +elf_compress (Elf_Scn *scn, int type, unsigned int flags) +{ + if (scn == NULL) + return -1; + + if ((flags & ~ELF_CHF_FORCE) != 0) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return -1; + } + + bool force = (flags & ELF_CHF_FORCE) != 0; + + Elf *elf = scn->elf; + GElf_Ehdr ehdr; + if (gelf_getehdr (elf, &ehdr) == NULL) + return -1; + + int elfclass = elf->class; + int elfdata = ehdr.e_ident[EI_DATA]; + + Elf64_Xword sh_flags; + Elf64_Word sh_type; + Elf64_Xword sh_addralign; + if (elfclass == ELFCLASS32) + { + Elf32_Shdr *shdr = elf32_getshdr (scn); + if (shdr == NULL) + return -1; + + sh_flags = shdr->sh_flags; + sh_type = shdr->sh_type; + sh_addralign = shdr->sh_addralign; + } + else + { + Elf64_Shdr *shdr = elf64_getshdr (scn); + if (shdr == NULL) + return -1; + + sh_flags = shdr->sh_flags; + sh_type = shdr->sh_type; + sh_addralign = shdr->sh_addralign; + } + + if ((sh_flags & SHF_ALLOC) != 0) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); + return -1; + } + + if (sh_type == SHT_NULL || sh_type == SHT_NOBITS) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE); + return -1; + } + + int compressed = (sh_flags & SHF_COMPRESSED); + if (type == ELFCOMPRESS_ZLIB) + { + /* Compress/Deflate. */ + if (compressed == 1) + { + __libelf_seterrno (ELF_E_ALREADY_COMPRESSED); + return -1; + } + + size_t hsize = (elfclass == ELFCLASS32 + ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr)); + size_t orig_size, orig_addralign, new_size; + void *out_buf = __libelf_compress (scn, hsize, elfdata, + &orig_size, &orig_addralign, + &new_size, force); + + /* Compression would make section larger, don't change anything. */ + if (out_buf == (void *) -1) + return 0; + + /* Compression failed, return error. */ + if (out_buf == NULL) + return -1; + + /* Put the header in front of the data. */ + if (elfclass == ELFCLASS32) + { + Elf32_Chdr chdr; + chdr.ch_type = ELFCOMPRESS_ZLIB; + chdr.ch_size = orig_size; + chdr.ch_addralign = orig_addralign; + if (elfdata != MY_ELFDATA) + { + CONVERT (chdr.ch_type); + CONVERT (chdr.ch_size); + CONVERT (chdr.ch_addralign); + } + memcpy (out_buf, &chdr, sizeof (Elf32_Chdr)); + } + else + { + Elf64_Chdr chdr; + chdr.ch_type = ELFCOMPRESS_ZLIB; + chdr.ch_reserved = 0; + chdr.ch_size = orig_size; + chdr.ch_addralign = sh_addralign; + if (elfdata != MY_ELFDATA) + { + CONVERT (chdr.ch_type); + CONVERT (chdr.ch_reserved); + CONVERT (chdr.ch_size); + CONVERT (chdr.ch_addralign); + } + memcpy (out_buf, &chdr, sizeof (Elf64_Chdr)); + } + + /* Note we keep the sh_entsize as is, we assume it is setup + correctly and ignored when SHF_COMPRESSED is set. */ + if (elfclass == ELFCLASS32) + { + Elf32_Shdr *shdr = elf32_getshdr (scn); + shdr->sh_size = new_size; + shdr->sh_addralign = __libelf_type_align (ELFCLASS32, ELF_T_CHDR); + shdr->sh_flags |= SHF_COMPRESSED; + } + else + { + Elf64_Shdr *shdr = elf64_getshdr (scn); + shdr->sh_size = new_size; + shdr->sh_addralign = __libelf_type_align (ELFCLASS64, ELF_T_CHDR); + shdr->sh_flags |= SHF_COMPRESSED; + } + + __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR); + + /* The section is now compressed, we could keep the uncompressed + data around, but since that might have been multiple Elf_Data + buffers let the user uncompress it explicitly again if they + want it to simplify bookkeeping. */ + scn->zdata_base = NULL; + + return 1; + } + else if (type == 0) + { + /* Decompress/Inflate. */ + if (compressed == 0) + { + __libelf_seterrno (ELF_E_NOT_COMPRESSED); + return -1; + } + + /* If the data is already decompressed (by elf_strptr), then we + only need to setup the rawdata and section header. XXX what + about elf_newdata? */ + if (scn->zdata_base == NULL) + { + size_t size_out, addralign; + void *buf_out = __libelf_decompress_elf (scn, &size_out, &addralign); + if (buf_out == NULL) + return -1; + + scn->zdata_base = buf_out; + scn->zdata_size = size_out; + scn->zdata_align = addralign; + } + + /* Note we keep the sh_entsize as is, we assume it is setup + correctly and ignored when SHF_COMPRESSED is set. */ + if (elfclass == ELFCLASS32) + { + Elf32_Shdr *shdr = elf32_getshdr (scn); + shdr->sh_size = scn->zdata_size; + shdr->sh_addralign = scn->zdata_align; + shdr->sh_flags &= ~SHF_COMPRESSED; + } + else + { + Elf64_Shdr *shdr = elf64_getshdr (scn); + shdr->sh_size = scn->zdata_size; + shdr->sh_addralign = scn->zdata_align; + shdr->sh_flags &= ~SHF_COMPRESSED; + } + + __libelf_reset_rawdata (scn, scn->zdata_base, + scn->zdata_size, scn->zdata_align, + __libelf_data_type (&ehdr, sh_type, + scn->zdata_align)); + + return 1; + } + else + { + __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE); + return -1; + } +} diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c new file mode 100644 index 00000000..3d2977e7 --- /dev/null +++ b/libelf/elf_compress_gnu.c @@ -0,0 +1,212 @@ +/* Compress or decompress a section. + Copyright (C) 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "libelfP.h" +#include "common.h" + +int +elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) +{ + if (scn == NULL) + return -1; + + if ((flags & ~ELF_CHF_FORCE) != 0) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return -1; + } + + bool force = (flags & ELF_CHF_FORCE) != 0; + + Elf *elf = scn->elf; + GElf_Ehdr ehdr; + if (gelf_getehdr (elf, &ehdr) == NULL) + return -1; + + int elfclass = elf->class; + int elfdata = ehdr.e_ident[EI_DATA]; + + Elf64_Xword sh_flags; + Elf64_Word sh_type; + Elf64_Xword sh_addralign; + if (elfclass == ELFCLASS32) + { + Elf32_Shdr *shdr = elf32_getshdr (scn); + if (shdr == NULL) + return -1; + + sh_flags = shdr->sh_flags; + sh_type = shdr->sh_type; + sh_addralign = shdr->sh_addralign; + } + else + { + Elf64_Shdr *shdr = elf64_getshdr (scn); + if (shdr == NULL) + return -1; + + sh_flags = shdr->sh_flags; + sh_type = shdr->sh_type; + sh_addralign = shdr->sh_addralign; + } + + /* Allocated sections, or sections that are already are compressed + cannot (also) be GNU compressed. */ + if ((sh_flags & SHF_ALLOC) != 0 || (sh_flags & SHF_COMPRESSED)) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); + return -1; + } + + if (sh_type == SHT_NULL || sh_type == SHT_NOBITS) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE); + return -1; + } + + /* For GNU compression we cannot really know whether the section is + already compressed or not. Just try and see what happens... */ + // int compressed = (sh_flags & SHF_COMPRESSED); + if (inflate == 1) + { + size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size. */ + size_t orig_size, new_size, orig_addralign; + void *out_buf = __libelf_compress (scn, hsize, elfdata, + &orig_size, &orig_addralign, + &new_size, force); + + /* Compression would make section larger, don't change anything. */ + if (out_buf == (void *) -1) + return 0; + + /* Compression failed, return error. */ + if (out_buf == NULL) + return -1; + + uint64_t be64_size = htobe64 (orig_size); + memmove (out_buf, "ZLIB", 4); + memmove (out_buf + 4, &be64_size, sizeof (be64_size)); + + /* We don't know anything about sh_entsize, sh_addralign and + sh_flags won't have a SHF_COMPRESSED hint in the GNU format. + Just adjust the sh_size. */ + if (elfclass == ELFCLASS32) + { + Elf32_Shdr *shdr = elf32_getshdr (scn); + shdr->sh_size = new_size; + } + else + { + Elf64_Shdr *shdr = elf64_getshdr (scn); + shdr->sh_size = new_size; + } + + __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE); + + /* The section is now compressed, we could keep the uncompressed + data around, but since that might have been multiple Elf_Data + buffers let the user uncompress it explicitly again if they + want it to simplify bookkeeping. */ + scn->zdata_base = NULL; + + return 1; + } + else if (inflate == 0) + { + /* In theory the user could have constructed a compressed section + by hand. And in practice they do. For example when copying + a section from one file to another using elf_newdata. So we + have to use elf_getdata (not elf_rawdata). */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return -1; + + size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size. */ + if (data->d_size < hsize || memcmp (data->d_buf, "ZLIB", 4) != 0) + { + __libelf_seterrno (ELF_E_NOT_COMPRESSED); + return -1; + } + + /* There is a 12-byte header of "ZLIB" followed by + an 8-byte big-endian size. There is only one type and + Alignment isn't preserved separately. */ + uint64_t gsize; + memcpy (&gsize, data->d_buf + 4, sizeof gsize); + gsize = be64toh (gsize); + + /* One more sanity check, size should be bigger than original + data size plus some overhead (4 chars ZLIB + 8 bytes size + 6 + bytes zlib stream overhead + 5 bytes overhead max for one 16K + block) and should fit into a size_t. */ + if (gsize + 4 + 8 + 6 + 5 < data->d_size || gsize > SIZE_MAX) + { + __libelf_seterrno (ELF_E_NOT_COMPRESSED); + return -1; + } + + size_t size = gsize; + size_t size_in = data->d_size - hsize; + void *buf_in = data->d_buf + hsize; + void *buf_out = __libelf_decompress (buf_in, size_in, size); + if (buf_out == NULL) + return -1; + + /* We don't know anything about sh_entsize, sh_addralign and + sh_flags won't have a SHF_COMPRESSED hint in the GNU format. + Just adjust the sh_size. */ + if (elfclass == ELFCLASS32) + { + Elf32_Shdr *shdr = elf32_getshdr (scn); + shdr->sh_size = size; + } + else + { + Elf64_Shdr *shdr = elf64_getshdr (scn); + shdr->sh_size = size; + } + + __libelf_reset_rawdata (scn, buf_out, size, sh_addralign, + __libelf_data_type (&ehdr, sh_type, + sh_addralign)); + + scn->zdata_base = buf_out; + + return 1; + } + else + { + __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE); + return -1; + } +} diff --git a/libelf/elf_end.c b/libelf/elf_end.c new file mode 100644 index 00000000..160f0b88 --- /dev/null +++ b/libelf/elf_end.c @@ -0,0 +1,239 @@ +/* Free resources associated with Elf descriptor. + Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "libelfP.h" + + +int +elf_end (Elf *elf) +{ + Elf *parent; + + if (elf == NULL) + /* This is allowed and is a no-op. */ + return 0; + + /* Make sure we are alone. */ + rwlock_wrlock (elf->lock); + + if (elf->ref_count != 0 && --elf->ref_count != 0) + { + /* Not yet the last activation. */ + int result = elf->ref_count; + rwlock_unlock (elf->lock); + return result; + } + + if (elf->kind == ELF_K_AR) + { + /* We cannot remove the descriptor now since we still have some + descriptors which depend on it. But we can free the archive + symbol table since this is only available via the archive ELF + descriptor. The long name table cannot be freed yet since + the archive headers for the ELF files in the archive point + into this array. */ + if (elf->state.ar.ar_sym != (Elf_Arsym *) -1l) + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + + if (elf->state.ar.children != NULL) + return 0; + } + + /* Remove this structure from the children list. */ + parent = elf->parent; + if (parent != NULL) + { + /* This is tricky. Lock must be acquire from the father to + the child but here we already have the child lock. We + solve this problem by giving free the child lock. The + state of REF_COUNT==0 is handled all over the library, so + this should be ok. */ + rwlock_unlock (elf->lock); + rwlock_rdlock (parent->lock); + rwlock_wrlock (elf->lock); + + if (parent->state.ar.children == elf) + parent->state.ar.children = elf->next; + else + { + struct Elf *child = parent->state.ar.children; + + while (child->next != elf) + child = child->next; + + child->next = elf->next; + } + + rwlock_unlock (parent->lock); + } + + /* This was the last activation. Free all resources. */ + switch (elf->kind) + { + case ELF_K_AR: + if (elf->state.ar.long_names != NULL) + free (elf->state.ar.long_names); + break; + + case ELF_K_ELF: + { + Elf_Data_Chunk *rawchunks + = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.rawchunks) + == offsetof (struct Elf, state.elf64.rawchunks)) + ? elf->state.elf32.rawchunks + : elf->state.elf64.rawchunks); + while (rawchunks != NULL) + { + Elf_Data_Chunk *next = rawchunks->next; + if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED) + free (rawchunks->data.d.d_buf); + free (rawchunks); + rawchunks = next; + } + + Elf_ScnList *list = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns + : &elf->state.elf64.scns); + + do + { + /* Free all separately allocated section headers. */ + size_t cnt = list->max; + + while (cnt-- > 0) + { + /* These pointers can be NULL; it's safe to use + 'free' since it will check for this. */ + Elf_Scn *scn = &list->data[cnt]; + Elf_Data_List *runp; + + if ((scn->shdr_flags & ELF_F_MALLOCED) != 0) + /* It doesn't matter which pointer. */ + free (scn->shdr.e32); + + /* Free zdata if uncompressed, but not yet used as + rawdata_base. If it is already used it will be + freed below. */ + if (scn->zdata_base != scn->rawdata_base) + free (scn->zdata_base); + + /* If the file has the same byte order and the + architecture doesn't require overly stringent + alignment the raw data buffer is the same as the + one used for presenting to the caller. */ + if (scn->data_base != scn->rawdata_base) + free (scn->data_base); + + /* The section data is allocated if we couldn't mmap + the file. Or if we had to decompress. */ + if (elf->map_address == NULL + || scn->rawdata_base == scn->zdata_base + || (scn->flags & ELF_F_MALLOCED) != 0) + free (scn->rawdata_base); + + /* Free the list of data buffers for the section. + We don't free the buffers themselves since this + is the users job. */ + runp = scn->data_list.next; + while (runp != NULL) + { + Elf_Data_List *oldp = runp; + runp = runp->next; + if ((oldp->flags & ELF_F_MALLOCED) != 0) + free (oldp); + } + } + + /* Free the memory for the array. */ + Elf_ScnList *oldp = list; + list = list->next; + assert (list == NULL || oldp->cnt == oldp->max); + if (oldp != (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns + : &elf->state.elf64.scns)) + free (oldp); + } + while (list != NULL); + } + + /* Free the section header. */ + if (elf->state.elf.shdr_malloced != 0) + free (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.shdr) + == offsetof (struct Elf, state.elf64.shdr)) + ? (void *) elf->state.elf32.shdr + : (void *) elf->state.elf64.shdr); + + /* Free the program header. */ + if ((elf->state.elf.phdr_flags & ELF_F_MALLOCED) != 0) + free (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.phdr) + == offsetof (struct Elf, state.elf64.phdr)) + ? (void *) elf->state.elf32.phdr + : (void *) elf->state.elf64.phdr); + break; + + default: + break; + } + + if (elf->map_address != NULL && parent == NULL) + { + /* The file was read or mapped for this descriptor. */ + if ((elf->flags & ELF_F_MALLOCED) != 0) + free (elf->map_address); + else if ((elf->flags & ELF_F_MMAPPED) != 0) + munmap (elf->map_address, elf->maximum_size); + } + + rwlock_unlock (elf->lock); + rwlock_fini (elf->lock); + + /* Finally the descriptor itself. */ + free (elf); + + return (parent != NULL && parent->ref_count == 0 + ? INTUSE(elf_end) (parent) : 0); +} +INTDEF(elf_end) diff --git a/libelf/elf_error.c b/libelf/elf_error.c new file mode 100644 index 00000000..5364e685 --- /dev/null +++ b/libelf/elf_error.c @@ -0,0 +1,355 @@ +/* Error handling in libelf. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "libelfP.h" + + +/* The error number. */ +static __thread int global_error; + + +int +elf_errno (void) +{ + int result = global_error; + global_error = ELF_E_NOERROR; + return result; +} + + +/* Return the appropriate message for the error. */ +static const char msgstr[] = +{ +#define ELF_E_NOERROR_IDX 0 + N_("no error") + "\0" +#define ELF_E_UNKNOWN_ERROR_IDX (ELF_E_NOERROR_IDX + sizeof "no error") + N_("unknown error") + "\0" +#define ELF_E_UNKNOWN_VERSION_IDX \ + (ELF_E_UNKNOWN_ERROR_IDX + sizeof "unknown error") + N_("unknown version") + "\0" +#define ELF_E_UNKNOWN_TYPE_IDX \ + (ELF_E_UNKNOWN_VERSION_IDX + sizeof "unknown version") + N_("unknown type") + "\0" +#define ELF_E_INVALID_HANDLE_IDX \ + (ELF_E_UNKNOWN_TYPE_IDX + sizeof "unknown type") + N_("invalid `Elf' handle") + "\0" +#define ELF_E_SOURCE_SIZE_IDX \ + (ELF_E_INVALID_HANDLE_IDX + sizeof "invalid `Elf' handle") + N_("invalid size of source operand") + "\0" +#define ELF_E_DEST_SIZE_IDX \ + (ELF_E_SOURCE_SIZE_IDX + sizeof "invalid size of source operand") + N_("invalid size of destination operand") + "\0" +#define ELF_E_INVALID_ENCODING_IDX \ + (ELF_E_DEST_SIZE_IDX + sizeof "invalid size of destination operand") + N_("invalid encoding") + "\0" +#define ELF_E_NOMEM_IDX \ + (ELF_E_INVALID_ENCODING_IDX + sizeof "invalid encoding") + N_("out of memory") + "\0" +#define ELF_E_INVALID_FILE_IDX \ + (ELF_E_NOMEM_IDX + sizeof "out of memory") + N_("invalid file descriptor") + "\0" +#define ELF_E_INVALID_ELF_IDX \ + (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor") + N_("invalid ELF file data") + "\0" +#define ELF_E_INVALID_OP_IDX \ + (ELF_E_INVALID_ELF_IDX + sizeof "invalid ELF file data") + N_("invalid operation") + "\0" +#define ELF_E_NO_VERSION_IDX \ + (ELF_E_INVALID_OP_IDX + sizeof "invalid operation") + N_("ELF version not set") + "\0" +#define ELF_E_INVALID_CMD_IDX \ + (ELF_E_NO_VERSION_IDX + sizeof "ELF version not set") + N_("invalid command") + "\0" +#define ELF_E_RANGE_IDX \ + (ELF_E_INVALID_CMD_IDX + sizeof "invalid command") + N_("offset out of range") + "\0" +#define ELF_E_ARCHIVE_FMAG_IDX \ + (ELF_E_RANGE_IDX + sizeof "offset out of range") + N_("invalid fmag field in archive header") + "\0" +#define ELF_E_INVALID_ARCHIVE_IDX \ + (ELF_E_ARCHIVE_FMAG_IDX + sizeof "invalid fmag field in archive header") + N_("invalid archive file") + "\0" +#define ELF_E_NO_ARCHIVE_IDX \ + (ELF_E_INVALID_ARCHIVE_IDX + sizeof "invalid archive file") + N_("descriptor is not for an archive") + "\0" +#define ELF_E_NO_INDEX_IDX \ + (ELF_E_NO_ARCHIVE_IDX + sizeof "descriptor is not for an archive") + N_("no index available") + "\0" +#define ELF_E_READ_ERROR_IDX \ + (ELF_E_NO_INDEX_IDX + sizeof "no index available") + N_("cannot read data from file") + "\0" +#define ELF_E_WRITE_ERROR_IDX \ + (ELF_E_READ_ERROR_IDX + sizeof "cannot read data from file") + N_("cannot write data to file") + "\0" +#define ELF_E_INVALID_CLASS_IDX \ + (ELF_E_WRITE_ERROR_IDX + sizeof "cannot write data to file") + N_("invalid binary class") + "\0" +#define ELF_E_INVALID_INDEX_IDX \ + (ELF_E_INVALID_CLASS_IDX + sizeof "invalid binary class") + N_("invalid section index") + "\0" +#define ELF_E_INVALID_OPERAND_IDX \ + (ELF_E_INVALID_INDEX_IDX + sizeof "invalid section index") + N_("invalid operand") + "\0" +#define ELF_E_INVALID_SECTION_IDX \ + (ELF_E_INVALID_OPERAND_IDX + sizeof "invalid operand") + N_("invalid section") + "\0" +#define ELF_E_INVALID_COMMAND_IDX \ + (ELF_E_INVALID_SECTION_IDX + sizeof "invalid section") + N_("invalid command") + "\0" +#define ELF_E_WRONG_ORDER_EHDR_IDX \ + (ELF_E_INVALID_COMMAND_IDX + sizeof "invalid command") + N_("executable header not created first") + "\0" +#define ELF_E_FD_DISABLED_IDX \ + (ELF_E_WRONG_ORDER_EHDR_IDX + sizeof "executable header not created first") + N_("file descriptor disabled") + "\0" +#define ELF_E_FD_MISMATCH_IDX \ + (ELF_E_FD_DISABLED_IDX + sizeof "file descriptor disabled") + N_("archive/member file descriptor mismatch") + "\0" +#define ELF_E_OFFSET_RANGE_IDX \ + (ELF_E_FD_MISMATCH_IDX + sizeof "archive/member file descriptor mismatch") + N_("offset out of range") + "\0" +#define ELF_E_NOT_NUL_SECTION_IDX \ + (ELF_E_OFFSET_RANGE_IDX + sizeof "offset out of range") + N_("cannot manipulate null section") + "\0" +#define ELF_E_DATA_MISMATCH_IDX \ + (ELF_E_NOT_NUL_SECTION_IDX + sizeof "cannot manipulate null section") + N_("data/scn mismatch") + "\0" +#define ELF_E_INVALID_SECTION_HEADER_IDX \ + (ELF_E_DATA_MISMATCH_IDX + sizeof "data/scn mismatch") + N_("invalid section header") + "\0" +#define ELF_E_INVALID_DATA_IDX \ + (ELF_E_INVALID_SECTION_HEADER_IDX + sizeof "invalid section header") + N_("invalid data") + "\0" +#define ELF_E_DATA_ENCODING_IDX \ + (ELF_E_INVALID_DATA_IDX + sizeof "invalid data") + N_("unknown data encoding") + "\0" +#define ELF_E_SECTION_TOO_SMALL_IDX \ + (ELF_E_DATA_ENCODING_IDX + sizeof "unknown data encoding") + N_("section `sh_size' too small for data") + "\0" +#define ELF_E_INVALID_ALIGN_IDX \ + (ELF_E_SECTION_TOO_SMALL_IDX + sizeof "section `sh_size' too small for data") + N_("invalid section alignment") + "\0" +#define ELF_E_INVALID_SHENTSIZE_IDX \ + (ELF_E_INVALID_ALIGN_IDX + sizeof "invalid section alignment") + N_("invalid section entry size") + "\0" +#define ELF_E_UPDATE_RO_IDX \ + (ELF_E_INVALID_SHENTSIZE_IDX + sizeof "invalid section entry size") + N_("update() for write on read-only file") + "\0" +#define ELF_E_NOFILE_IDX \ + (ELF_E_UPDATE_RO_IDX + sizeof "update() for write on read-only file") + N_("no such file") + "\0" +#define ELF_E_GROUP_NOT_REL_IDX \ + (ELF_E_NOFILE_IDX + sizeof "no such file") + N_("only relocatable files can contain section groups") + "\0" +#define ELF_E_INVALID_PHDR_IDX \ + (ELF_E_GROUP_NOT_REL_IDX \ + + sizeof "only relocatable files can contain section groups") + N_("program header only allowed in executables, shared objects, and \ +core files") + "\0" +#define ELF_E_NO_PHDR_IDX \ + (ELF_E_INVALID_PHDR_IDX \ + + sizeof "program header only allowed in executables, shared objects, and \ +core files") + N_("file has no program header") + "\0" +#define ELF_E_INVALID_OFFSET_IDX \ + (ELF_E_NO_PHDR_IDX \ + + sizeof "file has no program header") + N_("invalid offset") + "\0" +#define ELF_E_INVALID_SECTION_TYPE_IDX \ + (ELF_E_INVALID_OFFSET_IDX \ + + sizeof "invalid offset") + N_("invalid section type") + "\0" +#define ELF_E_INVALID_SECTION_FLAGS_IDX \ + (ELF_E_INVALID_SECTION_TYPE_IDX \ + + sizeof "invalid section type") + N_("invalid section flags") + "\0" +#define ELF_E_NOT_COMPRESSED_IDX \ + (ELF_E_INVALID_SECTION_FLAGS_IDX \ + + sizeof "invalid section flags") + N_("section does not contain compressed data") + "\0" +#define ELF_E_ALREADY_COMPRESSED_IDX \ + (ELF_E_NOT_COMPRESSED_IDX \ + + sizeof "section does not contain compressed data") + N_("section contains compressed data") + "\0" +#define ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX \ + (ELF_E_ALREADY_COMPRESSED_IDX \ + + sizeof "section contains compressed data") + N_("unknown compression type") + "\0" +#define ELF_E_COMPRESS_ERROR_IDX \ + (ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX \ + + sizeof "unknown compression type") + N_("cannot compress data") + "\0" +#define ELF_E_DECOMPRESS_ERROR_IDX \ + (ELF_E_COMPRESS_ERROR_IDX \ + + sizeof "cannot compress data") + N_("cannot decompress data") +}; + + +static const uint_fast16_t msgidx[ELF_E_NUM] = +{ + [ELF_E_NOERROR] = ELF_E_NOERROR_IDX, + [ELF_E_UNKNOWN_ERROR] = ELF_E_UNKNOWN_ERROR_IDX, + [ELF_E_UNKNOWN_VERSION] = ELF_E_UNKNOWN_VERSION_IDX, + [ELF_E_UNKNOWN_TYPE] = ELF_E_UNKNOWN_TYPE_IDX, + [ELF_E_INVALID_HANDLE] = ELF_E_INVALID_HANDLE_IDX, + [ELF_E_SOURCE_SIZE] = ELF_E_SOURCE_SIZE_IDX, + [ELF_E_DEST_SIZE] = ELF_E_DEST_SIZE_IDX, + [ELF_E_INVALID_ENCODING] = ELF_E_INVALID_ENCODING_IDX, + [ELF_E_NOMEM] = ELF_E_NOMEM_IDX, + [ELF_E_INVALID_FILE] = ELF_E_INVALID_FILE_IDX, + [ELF_E_INVALID_ELF] = ELF_E_INVALID_ELF_IDX, + [ELF_E_INVALID_OP] = ELF_E_INVALID_OP_IDX, + [ELF_E_NO_VERSION] = ELF_E_NO_VERSION_IDX, + [ELF_E_INVALID_CMD] = ELF_E_INVALID_CMD_IDX, + [ELF_E_RANGE] = ELF_E_RANGE_IDX, + [ELF_E_ARCHIVE_FMAG] = ELF_E_ARCHIVE_FMAG_IDX, + [ELF_E_INVALID_ARCHIVE] = ELF_E_INVALID_ARCHIVE_IDX, + [ELF_E_NO_ARCHIVE] = ELF_E_NO_ARCHIVE_IDX, + [ELF_E_NO_INDEX] = ELF_E_NO_INDEX_IDX, + [ELF_E_READ_ERROR] = ELF_E_READ_ERROR_IDX, + [ELF_E_WRITE_ERROR] = ELF_E_WRITE_ERROR_IDX, + [ELF_E_INVALID_CLASS] = ELF_E_INVALID_CLASS_IDX, + [ELF_E_INVALID_INDEX] = ELF_E_INVALID_INDEX_IDX, + [ELF_E_INVALID_OPERAND] = ELF_E_INVALID_OPERAND_IDX, + [ELF_E_INVALID_SECTION] = ELF_E_INVALID_SECTION_IDX, + [ELF_E_INVALID_COMMAND] = ELF_E_INVALID_COMMAND_IDX, + [ELF_E_WRONG_ORDER_EHDR] = ELF_E_WRONG_ORDER_EHDR_IDX, + [ELF_E_FD_DISABLED] = ELF_E_FD_DISABLED_IDX, + [ELF_E_FD_MISMATCH] = ELF_E_FD_MISMATCH_IDX, + [ELF_E_OFFSET_RANGE] = ELF_E_OFFSET_RANGE_IDX, + [ELF_E_NOT_NUL_SECTION] = ELF_E_NOT_NUL_SECTION_IDX, + [ELF_E_DATA_MISMATCH] = ELF_E_DATA_MISMATCH_IDX, + [ELF_E_INVALID_SECTION_HEADER] = ELF_E_INVALID_SECTION_HEADER_IDX, + [ELF_E_INVALID_DATA] = ELF_E_INVALID_DATA_IDX, + [ELF_E_DATA_ENCODING] = ELF_E_DATA_ENCODING_IDX, + [ELF_E_SECTION_TOO_SMALL] = ELF_E_SECTION_TOO_SMALL_IDX, + [ELF_E_INVALID_ALIGN] = ELF_E_INVALID_ALIGN_IDX, + [ELF_E_INVALID_SHENTSIZE] = ELF_E_INVALID_SHENTSIZE_IDX, + [ELF_E_UPDATE_RO] = ELF_E_UPDATE_RO_IDX, + [ELF_E_NOFILE] = ELF_E_NOFILE_IDX, + [ELF_E_GROUP_NOT_REL] = ELF_E_GROUP_NOT_REL_IDX, + [ELF_E_INVALID_PHDR] = ELF_E_INVALID_PHDR_IDX, + [ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX, + [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX, + [ELF_E_INVALID_SECTION_TYPE] = ELF_E_INVALID_SECTION_TYPE_IDX, + [ELF_E_INVALID_SECTION_FLAGS] = ELF_E_INVALID_SECTION_FLAGS_IDX, + [ELF_E_NOT_COMPRESSED] = ELF_E_NOT_COMPRESSED_IDX, + [ELF_E_ALREADY_COMPRESSED] = ELF_E_ALREADY_COMPRESSED_IDX, + [ELF_E_UNKNOWN_COMPRESSION_TYPE] = ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX, + [ELF_E_COMPRESS_ERROR] = ELF_E_COMPRESS_ERROR_IDX, + [ELF_E_DECOMPRESS_ERROR] = ELF_E_DECOMPRESS_ERROR_IDX +}; +#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0]))) + + +void +internal_function +__libelf_seterrno (int value) +{ + global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR; +} + + +const char * +elf_errmsg (int error) +{ + int last_error = global_error; + + if (error == 0) + { + assert (msgidx[last_error] < sizeof (msgstr)); + return last_error != 0 ? _(msgstr + msgidx[last_error]) : NULL; + } + else if (error < -1 || error >= nmsgidx) + return _(msgstr + ELF_E_UNKNOWN_ERROR_IDX); + + assert (msgidx[error == -1 ? last_error : error] < sizeof (msgstr)); + return _(msgstr + msgidx[error == -1 ? last_error : error]); +} diff --git a/libelf/elf_fill.c b/libelf/elf_fill.c new file mode 100644 index 00000000..6ebdf63a --- /dev/null +++ b/libelf/elf_fill.c @@ -0,0 +1,46 @@ +/* Set fill byte used when constructing ELF objects. + Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libelfP.h" + + +int __libelf_fill_byte; + + +void +elf_fill (int fill) +{ + __libelf_fill_byte = fill; +} diff --git a/libelf/elf_flagdata.c b/libelf/elf_flagdata.c new file mode 100644 index 00000000..cd2b1237 --- /dev/null +++ b/libelf/elf_flagdata.c @@ -0,0 +1,68 @@ +/* Manipulate ELF data flag. + Copyright (C) 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +unsigned int +elf_flagdata (Elf_Data *data, Elf_Cmd cmd, unsigned int flags) +{ + Elf_Data_Scn *data_scn; + unsigned int result; + + if (data == NULL) + return 0; + + data_scn = (Elf_Data_Scn *) data; + + if (data_scn == NULL || unlikely (data_scn->s->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (data_scn->s->flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (data_scn->s->flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagehdr.c b/libelf/elf_flagehdr.c new file mode 100644 index 00000000..a98276d5 --- /dev/null +++ b/libelf/elf_flagehdr.c @@ -0,0 +1,65 @@ +/* Manipulate ELF header flags. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +unsigned int +elf_flagehdr (Elf *elf, Elf_Cmd cmd, unsigned int flags) +{ + unsigned int result; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (elf->state.elf.ehdr_flags |= (flags & ELF_F_DIRTY)); + else if (cmd == ELF_C_CLR) + result = (elf->state.elf.ehdr_flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagelf.c b/libelf/elf_flagelf.c new file mode 100644 index 00000000..bd90a21f --- /dev/null +++ b/libelf/elf_flagelf.c @@ -0,0 +1,67 @@ +/* Manipulate ELF file flags. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +unsigned int +elf_flagelf (Elf *elf, Elf_Cmd cmd, unsigned int flags) +{ + unsigned int result; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (elf->flags + |= (flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE))); + else if (likely (cmd == ELF_C_CLR)) + result = (elf->flags + &= ~(flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE))); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagphdr.c b/libelf/elf_flagphdr.c new file mode 100644 index 00000000..0682d1f4 --- /dev/null +++ b/libelf/elf_flagphdr.c @@ -0,0 +1,65 @@ +/* Manipulate ELF program header flags. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +unsigned int +elf_flagphdr (Elf *elf, Elf_Cmd cmd, unsigned int flags) +{ + unsigned int result; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (elf->state.elf.phdr_flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (elf->state.elf.phdr_flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagscn.c b/libelf/elf_flagscn.c new file mode 100644 index 00000000..2164a8c9 --- /dev/null +++ b/libelf/elf_flagscn.c @@ -0,0 +1,65 @@ +/* Manipulate ELF section flags. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +unsigned int +elf_flagscn (Elf_Scn *scn, Elf_Cmd cmd, unsigned int flags) +{ + unsigned int result; + + if (scn == NULL) + return 0; + + if (unlikely (scn->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (scn->flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (scn->flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_flagshdr.c b/libelf/elf_flagshdr.c new file mode 100644 index 00000000..febf4abf --- /dev/null +++ b/libelf/elf_flagshdr.c @@ -0,0 +1,65 @@ +/* Manipulate ELF section header flags. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +unsigned int +elf_flagshdr (Elf_Scn *scn, Elf_Cmd cmd, unsigned int flags) +{ + unsigned int result; + + if (scn == NULL) + return 0; + + if (unlikely (scn->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + if (likely (cmd == ELF_C_SET)) + result = (scn->shdr_flags |= (flags & ELF_F_DIRTY)); + else if (likely (cmd == ELF_C_CLR)) + result = (scn->shdr_flags &= ~(flags & ELF_F_DIRTY)); + else + { + __libelf_seterrno (ELF_E_INVALID_COMMAND); + return 0; + } + + return result; +} diff --git a/libelf/elf_getarhdr.c b/libelf/elf_getarhdr.c new file mode 100644 index 00000000..509f1da5 --- /dev/null +++ b/libelf/elf_getarhdr.c @@ -0,0 +1,73 @@ +/* Read header of next archive member. + Copyright (C) 1998, 1999, 2000, 2002, 2008, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +Elf_Arhdr * +elf_getarhdr (Elf *elf) +{ + if (elf == NULL) + return NULL; + + Elf *parent = elf->parent; + + /* Calling this function is not ok for any file type but archives. */ + if (parent == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OP); + return NULL; + } + + /* Make sure we have read the archive header. */ + if (parent->state.ar.elf_ar_hdr.ar_name == NULL + && __libelf_next_arhdr_wrlock (parent) != 0) + { + rwlock_wrlock (parent->lock); + int st = __libelf_next_arhdr_wrlock (parent); + rwlock_unlock (parent->lock); + + if (st != 0) + /* Something went wrong. Maybe there is no member left. */ + return NULL; + } + + /* We can be sure the parent is an archive. */ + assert (parent->kind == ELF_K_AR); + + return &parent->state.ar.elf_ar_hdr; +} diff --git a/libelf/elf_getaroff.c b/libelf/elf_getaroff.c new file mode 100644 index 00000000..5c102ad6 --- /dev/null +++ b/libelf/elf_getaroff.c @@ -0,0 +1,53 @@ +/* Return offset in archive for current file ELF. + Copyright (C) 2005, 2008, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int64_t +elf_getaroff (Elf *elf) +{ + /* Be gratious, the specs demand it. */ + if (elf == NULL || elf->parent == NULL) + return ELF_C_NULL; + + /* We can be sure the parent is an archive. */ + Elf *parent = elf->parent; + assert (parent->kind == ELF_K_AR); + + return elf->start_offset - sizeof (struct ar_hdr) - parent->start_offset; +} diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c new file mode 100644 index 00000000..1f031fca --- /dev/null +++ b/libelf/elf_getarsym.c @@ -0,0 +1,331 @@ +/* Return symbol table of archive. + Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "libelfP.h" + + +static int +read_number_entries (uint64_t *nump, Elf *elf, size_t *offp, bool index64_p) +{ + union u + { + uint64_t ret64; + uint32_t ret32; + } u; + + size_t w = index64_p ? 8 : 4; + if (elf->map_address != NULL) + /* Use memcpy instead of pointer dereference so as not to assume the + field is naturally aligned within the file. */ + memcpy (&u, elf->map_address + *offp, sizeof u); + else if ((size_t) pread_retry (elf->fildes, &u, w, *offp) != w) + return -1; + + *offp += w; + + if (__BYTE_ORDER == __LITTLE_ENDIAN) + *nump = index64_p ? bswap_64 (u.ret64) : bswap_32 (u.ret32); + else + *nump = index64_p ? u.ret64 : u.ret32; + + return 0; +} + +Elf_Arsym * +elf_getarsym (Elf *elf, size_t *ptr) +{ + if (elf->kind != ELF_K_AR) + { + /* This is no archive. */ + __libelf_seterrno (ELF_E_NO_ARCHIVE); + return NULL; + } + + if (ptr != NULL) + /* In case of an error or when we know the value store the expected + value now. Doing this allows us easier exits in an error case. */ + *ptr = elf->state.ar.ar_sym_num; + + if (elf->state.ar.ar_sym == (Elf_Arsym *) -1l) + { + /* There is no index. */ + __libelf_seterrno (ELF_E_NO_INDEX); + return NULL; + } + + Elf_Arsym *result = elf->state.ar.ar_sym; + if (result == NULL) + { + /* We have not yet read the index. */ + rwlock_wrlock (elf->lock); + + /* In case we find no index remember this for the next call. */ + elf->state.ar.ar_sym = (Elf_Arsym *) -1l; + + /* We might have to allocate some temporary data for reading. */ + void *temp_data = NULL; + + struct ar_hdr *index_hdr; + if (elf->map_address == NULL) + { + /* We must read index from the file. */ + assert (elf->fildes != -1); + if (pread_retry (elf->fildes, &elf->state.ar.ar_hdr, + sizeof (struct ar_hdr), elf->start_offset + SARMAG) + != sizeof (struct ar_hdr)) + { + /* It is not possible to read the index. Maybe it does not + exist. */ + __libelf_seterrno (ELF_E_READ_ERROR); + goto out; + } + + index_hdr = &elf->state.ar.ar_hdr; + } + else + { + if (SARMAG + sizeof (struct ar_hdr) > elf->maximum_size) + { + /* There is no room for the full archive. */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + index_hdr = (struct ar_hdr *) (elf->map_address + + elf->start_offset + SARMAG); + } + + /* Now test whether this really is an archive. */ + if (memcmp (index_hdr->ar_fmag, ARFMAG, 2) != 0) + { + /* Invalid magic bytes. */ + __libelf_seterrno (ELF_E_ARCHIVE_FMAG); + goto out; + } + + bool index64_p; + /* Now test whether this is the index. If the name is "/", this + is 32-bit index, if it's "/SYM64/", it's 64-bit index. + + XXX This is not entirely true. There are some more forms. + Which of them shall we handle? */ + if (memcmp (index_hdr->ar_name, "/ ", 16) == 0) + index64_p = false; + else if (memcmp (index_hdr->ar_name, "/SYM64/ ", 16) == 0) + index64_p = true; + else + { + /* If the index is not the first entry, there is no index. + + XXX Is this true? */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + int w = index64_p ? 8 : 4; + + /* We have an archive. The first word in there is the number of + entries in the table. */ + uint64_t n = 0; + size_t off = elf->start_offset + SARMAG + sizeof (struct ar_hdr); + if (read_number_entries (&n, elf, &off, index64_p) < 0) + { + /* Cannot read the number of entries. */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + /* Now we can perform some first tests on whether all the data + needed for the index is available. */ + char tmpbuf[17]; + memcpy (tmpbuf, index_hdr->ar_size, 10); + tmpbuf[10] = '\0'; + size_t index_size = atol (tmpbuf); + + if (index_size > elf->maximum_size + || elf->maximum_size - index_size < SARMAG + sizeof (struct ar_hdr) +#if SIZE_MAX <= 4294967295U + || n >= SIZE_MAX / sizeof (Elf_Arsym) +#endif + || n > index_size / w) + { + /* This index table cannot be right since it does not fit into + the file. */ + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + /* Now we can allocate the arrays needed to store the index. */ + size_t ar_sym_len = (n + 1) * sizeof (Elf_Arsym); + elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len); + if (elf->state.ar.ar_sym != NULL) + { + void *file_data; /* unit32_t[n] or uint64_t[n] */ + char *str_data; + size_t sz = n * w; + + if (elf->map_address == NULL) + { + temp_data = malloc (sz); + if (unlikely (temp_data == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + file_data = temp_data; + + ar_sym_len += index_size - n * w; + Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym, + ar_sym_len); + if (newp == NULL) + { + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + elf->state.ar.ar_sym = newp; + + char *new_str = (char *) (elf->state.ar.ar_sym + n + 1); + + /* Now read the data from the file. */ + if ((size_t) pread_retry (elf->fildes, file_data, sz, off) != sz + || ((size_t) pread_retry (elf->fildes, new_str, + index_size - sz, off + sz) + != index_size - sz)) + { + /* We were not able to read the data. */ + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + __libelf_seterrno (ELF_E_NO_INDEX); + goto out; + } + + str_data = (char *) new_str; + } + else + { + file_data = (void *) (elf->map_address + off); + if (!ALLOW_UNALIGNED + && ((uintptr_t) file_data & -(uintptr_t) n) != 0) + { + temp_data = malloc (sz); + if (unlikely (temp_data == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + file_data = memcpy (temp_data, elf->map_address + off, sz); + } + str_data = (char *) (elf->map_address + off + sz); + } + + /* Now we can build the data structure. */ + Elf_Arsym *arsym = elf->state.ar.ar_sym; + uint64_t (*u64)[n] = file_data; + uint32_t (*u32)[n] = file_data; + for (size_t cnt = 0; cnt < n; ++cnt) + { + arsym[cnt].as_name = str_data; + if (index64_p) + { + uint64_t tmp = (*u64)[cnt]; + if (__BYTE_ORDER == __LITTLE_ENDIAN) + tmp = bswap_64 (tmp); + + arsym[cnt].as_off = tmp; + + /* Check whether 64-bit offset fits into 32-bit + size_t. */ + if (sizeof (arsym[cnt].as_off) < 8 + && arsym[cnt].as_off != tmp) + { + if (elf->map_address == NULL) + { + free (elf->state.ar.ar_sym); + elf->state.ar.ar_sym = NULL; + } + + __libelf_seterrno (ELF_E_RANGE); + goto out; + } + } + else if (__BYTE_ORDER == __LITTLE_ENDIAN) + arsym[cnt].as_off = bswap_32 ((*u32)[cnt]); + else + arsym[cnt].as_off = (*u32)[cnt]; + + arsym[cnt].as_hash = _dl_elf_hash (str_data); +#if HAVE_DECL_RAWMEMCHR + str_data = rawmemchr (str_data, '\0') + 1; +#else + char c; + do { + c = *str_data; + str_data++; + } while (c); +#endif + } + + /* At the end a special entry. */ + arsym[n].as_name = NULL; + arsym[n].as_off = 0; + arsym[n].as_hash = ~0UL; + + /* Tell the caller how many entries we have. */ + elf->state.ar.ar_sym_num = n + 1; + } + + result = elf->state.ar.ar_sym; + + out: + free (temp_data); + rwlock_unlock (elf->lock); + } + + if (ptr != NULL) + *ptr = elf->state.ar.ar_sym_num; + + return result; +} diff --git a/libelf/elf_getbase.c b/libelf/elf_getbase.c new file mode 100644 index 00000000..4890d336 --- /dev/null +++ b/libelf/elf_getbase.c @@ -0,0 +1,44 @@ +/* Return offset of first byte for the object. + Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int64_t +elf_getbase (Elf *elf) +{ + return elf == NULL ? (int64_t) -1 : elf->start_offset; +} diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c new file mode 100644 index 00000000..6ed44504 --- /dev/null +++ b/libelf/elf_getdata.c @@ -0,0 +1,573 @@ +/* Return the next data element from the section after possibly converting it. + Copyright (C) 1998-2005, 2006, 2007, 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "libelfP.h" +#include +#include "common.h" +#include "elf-knowledge.h" + + +#define TYPEIDX(Sh_Type) \ + (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM \ + ? Sh_Type \ + : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW \ + ? SHT_NUM + Sh_Type - SHT_GNU_HASH \ + : 0)) + +/* Associate section types with libelf types. */ +static const Elf_Type shtype_map[TYPEIDX (SHT_HISUNW) + 1] = + { + [SHT_SYMTAB] = ELF_T_SYM, + [SHT_RELA] = ELF_T_RELA, + [SHT_HASH] = ELF_T_WORD, + [SHT_DYNAMIC] = ELF_T_DYN, + [SHT_REL] = ELF_T_REL, + [SHT_DYNSYM] = ELF_T_SYM, + [SHT_INIT_ARRAY] = ELF_T_ADDR, + [SHT_FINI_ARRAY] = ELF_T_ADDR, + [SHT_PREINIT_ARRAY] = ELF_T_ADDR, + [SHT_GROUP] = ELF_T_WORD, + [SHT_SYMTAB_SHNDX] = ELF_T_WORD, + [SHT_NOTE] = ELF_T_NHDR, /* Need alignment to guess ELF_T_NHDR8. */ + [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF, + [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED, + [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF, + [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO, + [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE, + [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB, + [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH, + }; + +/* Associate libelf types with their internal alignment requirements. */ +const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] = + { +# define TYPE_ALIGNS(Bits) \ + { \ + [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)), \ + [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)), \ + [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)), \ + [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)), \ + [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)), \ + [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)), \ + [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)), \ + [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \ + [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)), \ + [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)), \ + [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)), \ + [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)), \ + [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)), \ + [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)), \ + [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)), \ + [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)), \ + [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)), \ + [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)), \ + [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)), \ + [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \ + [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \ + [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \ + [ELF_T_GNUHASH] = __alignof__ (Elf32_Word), \ + [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)), \ + [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)), \ + [ELF_T_NHDR8] = 8 /* Special case for GNU Property note. */ \ + } + [ELFCLASS32 - 1] = TYPE_ALIGNS (32), + [ELFCLASS64 - 1] = TYPE_ALIGNS (64), +# undef TYPE_ALIGNS + }; + + +Elf_Type +internal_function +__libelf_data_type (GElf_Ehdr *ehdr, int sh_type, GElf_Xword align) +{ + /* Some broken ELF ABI for 64-bit machines use the wrong hash table + entry size. See elf-knowledge.h for more information. */ + if (sh_type == SHT_HASH && ehdr->e_ident[EI_CLASS] == ELFCLASS64) + { + return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD); + } + else + { + Elf_Type t = shtype_map[TYPEIDX (sh_type)]; + /* Special case for GNU Property notes. */ + if (t == ELF_T_NHDR && align == 8) + t = ELF_T_NHDR8; + return t; + } +} + +/* Convert the data in the current section. */ +static void +convert_data (Elf_Scn *scn, int eclass, + int data, size_t size, Elf_Type type) +{ + const size_t align = __libelf_type_align (eclass, type); + + /* Do we need to convert the data and/or adjust for alignment? */ + if (data == MY_ELFDATA || type == ELF_T_BYTE) + { + if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0) + /* No need to copy, we can use the raw data. */ + scn->data_base = scn->rawdata_base; + else + { + scn->data_base = (char *) malloc (size); + if (scn->data_base == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return; + } + + /* The copy will be appropriately aligned for direct access. */ + memcpy (scn->data_base, scn->rawdata_base, size); + } + } + else + { + xfct_t fp; + + scn->data_base = (char *) malloc (size); + if (scn->data_base == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return; + } + + /* Make sure the source is correctly aligned for the conversion + function to directly access the data elements. */ + char *rawdata_source; + if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0) + rawdata_source = scn->rawdata_base; + else + { + rawdata_source = (char *) malloc (size); + if (rawdata_source == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return; + } + + /* The copy will be appropriately aligned for direct access. */ + memcpy (rawdata_source, scn->rawdata_base, size); + } + + /* Get the conversion function. */ + fp = __elf_xfctstom[eclass - 1][type]; + + fp (scn->data_base, rawdata_source, size, 0); + + if (rawdata_source != scn->rawdata_base) + free (rawdata_source); + } + + scn->data_list.data.d.d_buf = scn->data_base; + scn->data_list.data.d.d_size = size; + scn->data_list.data.d.d_type = type; + scn->data_list.data.d.d_off = scn->rawdata.d.d_off; + scn->data_list.data.d.d_align = scn->rawdata.d.d_align; + scn->data_list.data.d.d_version = scn->rawdata.d.d_version; + + scn->data_list.data.s = scn; +} + + +/* Store the information for the raw data in the `rawdata' element. */ +int +internal_function +__libelf_set_rawdata_wrlock (Elf_Scn *scn) +{ + Elf64_Off offset; + Elf64_Xword size; + Elf64_Xword align; + Elf64_Xword flags; + int type; + Elf *elf = scn->elf; + + if (elf->class == ELFCLASS32) + { + Elf32_Shdr *shdr + = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn); + + if (shdr == NULL) + /* Something went terribly wrong. */ + return 1; + + offset = shdr->sh_offset; + size = shdr->sh_size; + type = shdr->sh_type; + align = shdr->sh_addralign; + flags = shdr->sh_flags; + } + else + { + Elf64_Shdr *shdr + = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn); + + if (shdr == NULL) + /* Something went terribly wrong. */ + return 1; + + offset = shdr->sh_offset; + size = shdr->sh_size; + type = shdr->sh_type; + align = shdr->sh_addralign; + flags = shdr->sh_flags; + } + + /* If the section has no data (for whatever reason), leave the `d_buf' + pointer NULL. */ + if (size != 0 && type != SHT_NOBITS) + { + /* First a test whether the section is valid at all. */ + size_t entsize; + + /* Compressed data has a header, but then compressed data. + Make sure to set the alignment of the header explicitly, + don't trust the file alignment for the section, it is + often wrong. */ + if ((flags & SHF_COMPRESSED) != 0) + { + entsize = 1; + align = __libelf_type_align (elf->class, ELF_T_CHDR); + } + else if (type == SHT_HASH) + { + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem); + if (unlikely (ehdr == NULL)) + return 1; + entsize = SH_ENTSIZE_HASH (ehdr); + } + else + { + Elf_Type t = shtype_map[TYPEIDX (type)]; + if (t == ELF_T_NHDR && align == 8) + t = ELF_T_NHDR8; + if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8 + || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64)) + entsize = 1; + else + entsize = __libelf_type_sizes[elf->class - 1][t]; + } + + /* We assume it is an array of bytes if it is none of the structured + sections we know of. */ + if (entsize == 0) + entsize = 1; + + if (unlikely (size % entsize != 0)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return 1; + } + + /* We can use the mapped or loaded data if available. */ + if (elf->map_address != NULL) + { + /* First see whether the information in the section header is + valid and it does not ask for too much. Check for unsigned + overflow. */ + if (unlikely (offset > elf->maximum_size + || elf->maximum_size - offset < size)) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + return 1; + } + + scn->rawdata_base = scn->rawdata.d.d_buf + = (char *) elf->map_address + elf->start_offset + offset; + } + else if (likely (elf->fildes != -1)) + { + /* First see whether the information in the section header is + valid and it does not ask for too much. Check for unsigned + overflow. */ + if (unlikely (offset > elf->maximum_size + || elf->maximum_size - offset < size)) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + return 1; + } + + /* We have to read the data from the file. Allocate the needed + memory. */ + scn->rawdata_base = scn->rawdata.d.d_buf + = (char *) malloc (size); + if (scn->rawdata.d.d_buf == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return 1; + } + + ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size, + elf->start_offset + offset); + if (unlikely ((size_t) n != size)) + { + /* Cannot read the data. */ + free (scn->rawdata.d.d_buf); + scn->rawdata_base = scn->rawdata.d.d_buf = NULL; + __libelf_seterrno (ELF_E_READ_ERROR); + return 1; + } + } + else + { + /* The file descriptor is already closed, we cannot get the data + anymore. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + return 1; + } + } + + scn->rawdata.d.d_size = size; + + /* Compressed data always has type ELF_T_CHDR regardless of the + section type. */ + if ((flags & SHF_COMPRESSED) != 0) + scn->rawdata.d.d_type = ELF_T_CHDR; + else + { + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem); + if (unlikely (ehdr == NULL)) + return 1; + scn->rawdata.d.d_type = __libelf_data_type (ehdr, type, align); + } + scn->rawdata.d.d_off = 0; + + /* Make sure the alignment makes sense. d_align should be aligned both + in the section (trivially true since d_off is zero) and in the file. + Unfortunately we cannot be too strict because there are ELF files + out there that fail this requirement. We will try to fix those up + in elf_update when writing out the image. But for very large + alignment values this can bloat the image considerably. So here + just check and clamp the alignment value to not be bigger than the + actual offset of the data in the file. Given that there is always + at least an ehdr this will only trigger for alignment values > 64 + which should be uncommon. */ + align = align ?: 1; + if (type != SHT_NOBITS && align > offset) + align = offset; + scn->rawdata.d.d_align = align; + if (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr))) + scn->rawdata.d.d_version = + elf->state.elf32.ehdr->e_ident[EI_VERSION]; + else + scn->rawdata.d.d_version = + elf->state.elf64.ehdr->e_ident[EI_VERSION]; + + scn->rawdata.s = scn; + + scn->data_read = 1; + + /* We actually read data from the file. At least we tried. */ + scn->flags |= ELF_F_FILEDATA; + + return 0; +} + +int +internal_function +__libelf_set_rawdata (Elf_Scn *scn) +{ + int result; + + if (scn == NULL) + return 1; + + rwlock_wrlock (scn->elf->lock); + result = __libelf_set_rawdata_wrlock (scn); + rwlock_unlock (scn->elf->lock); + + return result; +} + +void +internal_function +__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked) +{ + if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0) + { + Elf *elf = scn->elf; + + /* Upgrade the lock to a write lock if necessary and check + nobody else already did the work. */ + if (!wrlocked) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + if (scn->data_list_rear != NULL) + return; + } + + /* Convert according to the version and the type. */ + convert_data (scn, elf->class, + (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? elf->state.elf32.ehdr->e_ident[EI_DATA] + : elf->state.elf64.ehdr->e_ident[EI_DATA]), + scn->rawdata.d.d_size, scn->rawdata.d.d_type); + } + else + { + /* This is an empty or NOBITS section. There is no buffer but + the size information etc is important. */ + scn->data_list.data.d = scn->rawdata.d; + scn->data_list.data.s = scn; + } + + scn->data_list_rear = &scn->data_list; +} + +Elf_Data * +internal_function +__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data) +{ + Elf_Data *result = NULL; + Elf *elf; + int locked = 0; + + if (scn == NULL) + return NULL; + + if (unlikely (scn->elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* We will need this multiple times later on. */ + elf = scn->elf; + + /* If `data' is not NULL this means we are not addressing the initial + data in the file. But this also means this data is already read + (since otherwise it is not possible to have a valid `data' pointer) + and all the data structures are initialized as well. In this case + we can simply walk the list of data records. */ + if (data != NULL) + { + Elf_Data_List *runp; + + /* It is not possible that if DATA is not NULL the first entry is + returned. But this also means that there must be a first data + entry. */ + if (scn->data_list_rear == NULL + /* The section the reference data is for must match the section + parameter. */ + || unlikely (((Elf_Data_Scn *) data)->s != scn)) + { + __libelf_seterrno (ELF_E_DATA_MISMATCH); + goto out; + } + + /* We start searching with the first entry. */ + runp = &scn->data_list; + + while (1) + { + /* If `data' does not match any known record punt. */ + if (runp == NULL) + { + __libelf_seterrno (ELF_E_DATA_MISMATCH); + goto out; + } + + if (&runp->data.d == data) + /* Found the entry. */ + break; + + runp = runp->next; + } + + /* Return the data for the next data record. */ + result = runp->next ? &runp->next->data.d : NULL; + goto out; + } + + /* If the data for this section was not yet initialized do it now. */ + if (scn->data_read == 0) + { + /* We cannot acquire a write lock while we are holding a read + lock. Therefore give up the read lock and then get the write + lock. But this means that the data could meanwhile be + modified, therefore start the tests again. */ + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + locked = 1; + + /* Read the data from the file. There is always a file (or + memory region) associated with this descriptor since + otherwise the `data_read' flag would be set. */ + if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0) + /* Something went wrong. The error value is already set. */ + goto out; + } + + /* At this point we know the raw data is available. But it might be + empty in case the section has size zero (for whatever reason). + Now create the converted data in case this is necessary. */ + if (scn->data_list_rear == NULL) + __libelf_set_data_list_rdlock (scn, locked); + + /* Return the first data element in the list. */ + result = &scn->data_list.data.d; + + out: + return result; +} + +Elf_Data * +elf_getdata (Elf_Scn *scn, Elf_Data *data) +{ + Elf_Data *result; + + if (scn == NULL) + return NULL; + + rwlock_rdlock (scn->elf->lock); + result = __elf_getdata_rdlock (scn, data); + rwlock_unlock (scn->elf->lock); + + return result; +} +INTDEF(elf_getdata) diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c new file mode 100644 index 00000000..1072f7de --- /dev/null +++ b/libelf/elf_getdata_rawchunk.c @@ -0,0 +1,185 @@ +/* Return converted data from raw chunk of ELF file. + Copyright (C) 2007, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include "libelfP.h" +#include "common.h" + +Elf_Data * +elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) +{ + if (unlikely (elf == NULL)) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + /* No valid descriptor. */ + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + if (unlikely (offset < 0 || (uint64_t) offset > elf->maximum_size + || elf->maximum_size - (uint64_t) offset < size)) + + { + /* Invalid request. */ + __libelf_seterrno (ELF_E_INVALID_OP); + return NULL; + } + + if (type >= ELF_T_NUM) + { + __libelf_seterrno (ELF_E_UNKNOWN_TYPE); + return NULL; + } + + /* Get the raw bytes from the file. */ + void *rawchunk; + int flags = 0; + Elf_Data *result = NULL; + + rwlock_rdlock (elf->lock); + + size_t align = __libelf_type_align (elf->class, type); + if (elf->map_address != NULL) + { + /* If the file is mmap'ed we can use it directly, if aligned for type. */ + char *rawdata = elf->map_address + elf->start_offset + offset; + if (((uintptr_t) rawdata & (align - 1)) == 0) + rawchunk = rawdata; + else + { + /* We allocate the memory and memcpy it to get aligned data. */ + rawchunk = malloc (size); + if (rawchunk == NULL) + goto nomem; + memcpy (rawchunk, rawdata, size); + flags = ELF_F_MALLOCED; + } + } + else + { + /* We allocate the memory and read the data from the file. */ + rawchunk = malloc (size); + if (rawchunk == NULL) + { + nomem: + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + + /* Read the file content. */ + if (unlikely ((size_t) pread_retry (elf->fildes, rawchunk, size, + elf->start_offset + offset) + != size)) + { + /* Something went wrong. */ + free (rawchunk); + __libelf_seterrno (ELF_E_READ_ERROR); + goto out; + } + + flags = ELF_F_MALLOCED; + } + + /* Copy and/or convert the data as needed for aligned native-order access. */ + void *buffer; + if (elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA) + { + if (((uintptr_t) rawchunk & (align - 1)) == 0) + /* No need to copy, we can use the raw data. */ + buffer = rawchunk; + else + { + /* A malloc'd block is always sufficiently aligned. */ + assert (flags == 0); + + buffer = malloc (size); + if (unlikely (buffer == NULL)) + goto nomem; + flags = ELF_F_MALLOCED; + + /* The copy will be appropriately aligned for direct access. */ + memcpy (buffer, rawchunk, size); + } + } + else + { + if (flags) + buffer = rawchunk; + else + { + buffer = malloc (size); + if (unlikely (buffer == NULL)) + goto nomem; + flags = ELF_F_MALLOCED; + } + + /* Call the conversion function. */ + (*__elf_xfctstom[elf->class - 1][type])(buffer, rawchunk, size, 0); + } + + /* Allocate the dummy container to point at this buffer. */ + Elf_Data_Chunk *chunk = calloc (1, sizeof *chunk); + if (chunk == NULL) + { + if (flags) + free (buffer); + goto nomem; + } + + chunk->dummy_scn.elf = elf; + chunk->dummy_scn.flags = flags; + chunk->data.s = &chunk->dummy_scn; + chunk->data.d.d_buf = buffer; + chunk->data.d.d_size = size; + chunk->data.d.d_type = type; + chunk->data.d.d_align = align; + chunk->data.d.d_version = EV_CURRENT; + + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + + chunk->next = elf->state.elf.rawchunks; + elf->state.elf.rawchunks = chunk; + result = &chunk->data.d; + + out: + rwlock_unlock (elf->lock); + return result; +} diff --git a/libelf/elf_getident.c b/libelf/elf_getident.c new file mode 100644 index 00000000..5abf8c94 --- /dev/null +++ b/libelf/elf_getident.c @@ -0,0 +1,61 @@ +/* Retrieve file identification data. + Copyright (C) 1998, 1999, 2000, 2002, 2004, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libelfP.h" + + +char * +elf_getident (Elf *elf, size_t *ptr) +{ + /* In case this is no ELF file, the handle is invalid and we return + NULL. */ + if (elf == NULL || elf->kind != ELF_K_ELF) + { + if (ptr != NULL) + *ptr = 0; + return NULL; + } + + /* We already read the ELF header. Return a pointer to it and store + the length in *PTR. */ + if (ptr != NULL) + *ptr = EI_NIDENT; + + return (char *) (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? elf->state.elf32.ehdr->e_ident + : elf->state.elf64.ehdr->e_ident); +} diff --git a/libelf/elf_getphdrnum.c b/libelf/elf_getphdrnum.c new file mode 100644 index 00000000..60ebec58 --- /dev/null +++ b/libelf/elf_getphdrnum.c @@ -0,0 +1,151 @@ +/* Return number of program headers in the ELF file. + Copyright (C) 2010, 2014, 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +internal_function +__elf_getphdrnum_rdlock (Elf *elf, size_t *dst) +{ + if (unlikely (elf->state.elf64.ehdr == NULL)) + { + /* Maybe no ELF header was created yet. */ + *dst = 0; + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + return -1; + } + + *dst = (elf->class == ELFCLASS32 + ? elf->state.elf32.ehdr->e_phnum + : elf->state.elf64.ehdr->e_phnum); + + if (*dst == PN_XNUM) + { + const Elf_ScnList *const scns = (elf->class == ELFCLASS32 + ? &elf->state.elf32.scns + : &elf->state.elf64.scns); + + /* If there are no section headers, perhaps this is really just 65536 + written without PN_XNUM support. Either that or it's bad data. */ + + if (elf->class == ELFCLASS32) + { + if (likely (scns->cnt > 0)) + { + Elf_Scn *scn = &elf->state.elf32.scns.data[0]; + Elf32_Shdr *shdr = scn->shdr.e32 ?: __elf32_getshdr_rdlock (scn); + if (shdr) + *dst = shdr->sh_info; + } + } + else + { + if (likely (scns->cnt > 0)) + { + Elf_Scn *scn = &elf->state.elf64.scns.data[0]; + Elf64_Shdr *shdr = scn->shdr.e64 ?: __elf64_getshdr_rdlock (scn); + if (shdr) + *dst = shdr->sh_info; + } + } + } + + return 0; +} + +int +internal_function +__elf_getphdrnum_chk_rdlock (Elf *elf, size_t *dst) +{ + int result = __elf_getphdrnum_rdlock (elf, dst); + + /* If the phdrs haven't been created or read in yet then do some + sanity checking to make sure phnum and phoff are consistent. */ + if (elf->state.elf.phdr == NULL) + { + Elf64_Off off = (elf->class == ELFCLASS32 + ? elf->state.elf32.ehdr->e_phoff + : elf->state.elf64.ehdr->e_phoff); + if (unlikely (off == 0)) + { + *dst = 0; + return result; + } + + if (unlikely (off >= elf->maximum_size)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return -1; + } + + /* Check for too many sections. */ + size_t phdr_size = (elf->class == ELFCLASS32 + ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr)); + if (unlikely (*dst > SIZE_MAX / phdr_size)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return -1; + } + + /* Truncated file? Don't return more than can be indexed. */ + if (unlikely (elf->maximum_size - off < *dst * phdr_size)) + *dst = (elf->maximum_size - off) / phdr_size; + } + + return result; +} + +int +elf_getphdrnum (Elf *elf, size_t *dst) +{ + int result; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_rdlock (elf->lock); + result = __elf_getphdrnum_chk_rdlock (elf, dst); + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_getscn.c b/libelf/elf_getscn.c new file mode 100644 index 00000000..e1fbaaaa --- /dev/null +++ b/libelf/elf_getscn.c @@ -0,0 +1,120 @@ +/* Get section at specific index. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +Elf_Scn * +elf_getscn (Elf *elf, size_t idx) +{ + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (elf->lock); + + Elf_Scn *result = NULL; + + /* Find the section in the list. */ + Elf_ScnList *runp = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns); + + /* Section zero is special. It always exists even if there is no + "first" section. And it is needed to store "overflow" values + from the Elf header. */ + if (idx == 0 && runp->cnt == 0 && runp->max > 0) + { + Elf_Scn *scn0 = &runp->data[0]; + if (elf->class == ELFCLASS32) + { + scn0->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr)); + if (scn0->shdr.e32 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + else + { + scn0->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr)); + if (scn0->shdr.e64 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + scn0->elf = elf; + scn0->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; + scn0->list = elf->state.elf.scns_last; + scn0->data_read = 1; + runp->cnt = 1; + } + + while (1) + { + if (idx < runp->max) + { + if (idx < runp->cnt) + result = &runp->data[idx]; + else + __libelf_seterrno (ELF_E_INVALID_INDEX); + break; + } + + idx -= runp->max; + + runp = runp->next; + if (runp == NULL) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + break; + } + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_getscn) diff --git a/libelf/elf_getshdrnum.c b/libelf/elf_getshdrnum.c new file mode 100644 index 00000000..18e5d14a --- /dev/null +++ b/libelf/elf_getshdrnum.c @@ -0,0 +1,87 @@ +/* Return number of sections in the ELF file. + Copyright (C) 2002, 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +internal_function +__elf_getshdrnum_rdlock (Elf *elf, size_t *dst) +{ + int result = 0; + int idx; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + idx = elf->state.elf.scns_last->cnt; + if (idx != 0 + || (elf->state.elf.scns_last + != (elf->class == ELFCLASS32 + || (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns))) + /* There is at least one section. */ + *dst = 1 + elf->state.elf.scns_last->data[idx - 1].index; + else + *dst = 0; + + return result; +} + +int +elf_getshdrnum (Elf *elf, size_t *dst) +{ + int result; + + if (elf == NULL) + return -1; + + rwlock_rdlock (elf->lock); + result = __elf_getshdrnum_rdlock (elf, dst); + rwlock_unlock (elf->lock); + + return result; +} +/* Alias for the deprecated name. */ +strong_alias (elf_getshdrnum, elf_getshnum) diff --git a/libelf/elf_getshdrstrndx.c b/libelf/elf_getshdrstrndx.c new file mode 100644 index 00000000..ad884fd3 --- /dev/null +++ b/libelf/elf_getshdrstrndx.c @@ -0,0 +1,235 @@ +/* Return section index of section header string table. + Copyright (C) 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include "libelfP.h" +#include "common.h" + + +int +elf_getshdrstrndx (Elf *elf, size_t *dst) +{ + int result = 0; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_rdlock (elf->lock); + + /* We rely here on the fact that the `elf' element is a common prefix + of `elf32' and `elf64'. */ + assert (offsetof (struct Elf, state.elf.ehdr) + == offsetof (struct Elf, state.elf32.ehdr)); + assert (sizeof (elf->state.elf.ehdr) + == sizeof (elf->state.elf32.ehdr)); + assert (offsetof (struct Elf, state.elf.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)); + assert (sizeof (elf->state.elf.ehdr) + == sizeof (elf->state.elf64.ehdr)); + + if (unlikely (elf->state.elf.ehdr == NULL)) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + result = -1; + } + else + { + Elf32_Word num; + + num = (elf->class == ELFCLASS32 + ? elf->state.elf32.ehdr->e_shstrndx + : elf->state.elf64.ehdr->e_shstrndx); + + /* Determine whether the index is too big to fit in the ELF + header. */ + if (unlikely (num == SHN_XINDEX)) + { + /* Yes. Search the zeroth section header. */ + if (elf->class == ELFCLASS32) + { + size_t offset; + if (unlikely (elf->state.elf32.scns.cnt == 0)) + { + /* Cannot use SHN_XINDEX without section headers. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = -1; + goto out; + } + + if (elf->state.elf32.scns.data[0].shdr.e32 != NULL) + { + num = elf->state.elf32.scns.data[0].shdr.e32->sh_link; + goto success; + } + + offset = elf->state.elf32.ehdr->e_shoff; + + if (elf->map_address != NULL + && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) elf->map_address + + elf->start_offset + offset)) + & (__alignof__ (Elf32_Shdr) - 1)) == 0)) + { + /* First see whether the information in the ELF header is + valid and it does not ask for too much. */ + if (unlikely (elf->maximum_size - offset + < sizeof (Elf32_Shdr))) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = -1; + goto out; + } + + /* We can directly access the memory. */ + num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset + + offset))->sh_link; + } + else + { + /* We avoid reading in all the section headers. Just read + the first one. */ + Elf32_Shdr shdr_mem; + ssize_t r; + + if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem, + sizeof (Elf32_Shdr), offset)) + != sizeof (Elf32_Shdr))) + { + /* We must be able to read this ELF section header. */ + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); + result = -1; + goto out; + } + + if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (shdr_mem.sh_link); + num = shdr_mem.sh_link; + } + } + else + { + if (unlikely (elf->state.elf64.scns.cnt == 0)) + { + /* Cannot use SHN_XINDEX without section headers. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = -1; + goto out; + } + + if (elf->state.elf64.scns.data[0].shdr.e64 != NULL) + { + num = elf->state.elf64.scns.data[0].shdr.e64->sh_link; + goto success; + } + + size_t offset = elf->state.elf64.ehdr->e_shoff; + + if (elf->map_address != NULL + && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((size_t) ((char *) elf->map_address + + elf->start_offset + offset)) + & (__alignof__ (Elf64_Shdr) - 1)) == 0)) + { + /* First see whether the information in the ELF header is + valid and it does not ask for too much. */ + if (unlikely (elf->maximum_size - offset + < sizeof (Elf64_Shdr))) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + result = -1; + goto out; + } + + /* We can directly access the memory. */ + num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset + + offset))->sh_link; + } + else + { + /* We avoid reading in all the section headers. Just read + the first one. */ + Elf64_Shdr shdr_mem; + ssize_t r; + + if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem, + sizeof (Elf64_Shdr), offset)) + != sizeof (Elf64_Shdr))) + { + /* We must be able to read this ELF section header. */ + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); + result = -1; + goto out; + } + + if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA) + CONVERT (shdr_mem.sh_link); + num = shdr_mem.sh_link; + } + } + } + + /* Store the result. */ + success: + *dst = num; + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_getshdrstrndx) +/* Alias for the deprecated name. */ +strong_alias (elf_getshdrstrndx, elf_getshstrndx) diff --git a/libelf/elf_gnu_hash.c b/libelf/elf_gnu_hash.c new file mode 100644 index 00000000..5a1b8523 --- /dev/null +++ b/libelf/elf_gnu_hash.c @@ -0,0 +1,46 @@ +/* GNU-style Hash function used in ELF implementations. + Copyright (C) 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 2006. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* Get the implementation. */ +#include + +unsigned long int +elf_gnu_hash (const char *string) +{ + uint_fast32_t h = 5381; + for (unsigned char c = *string; c != '\0'; c = *++string) + h = h * 33 + c; + return h & 0xffffffff; +} diff --git a/libelf/elf_hash.c b/libelf/elf_hash.c new file mode 100644 index 00000000..345697e1 --- /dev/null +++ b/libelf/elf_hash.c @@ -0,0 +1,44 @@ +/* Hash function used in ELF implementations. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* Get the implementation. */ +#include + +unsigned long int +elf_hash (const char *string) +{ + return _dl_elf_hash (string); +} +INTDEF(elf_hash) diff --git a/libelf/elf_kind.c b/libelf/elf_kind.c new file mode 100644 index 00000000..0fb3f0c2 --- /dev/null +++ b/libelf/elf_kind.c @@ -0,0 +1,44 @@ +/* Return the kind of file associated with the descriptor. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +Elf_Kind +elf_kind (Elf *elf) +{ + return elf == NULL ? ELF_K_NONE : elf->kind; +} diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c new file mode 100644 index 00000000..a47f1d24 --- /dev/null +++ b/libelf/elf_memory.c @@ -0,0 +1,50 @@ +/* Create descriptor for memory region. + Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +Elf * +elf_memory (char *image, size_t size) +{ + if (image == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ, NULL); +} diff --git a/libelf/elf_ndxscn.c b/libelf/elf_ndxscn.c new file mode 100644 index 00000000..488c4e5f --- /dev/null +++ b/libelf/elf_ndxscn.c @@ -0,0 +1,47 @@ +/* Get index of section. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +size_t +elf_ndxscn (Elf_Scn *scn) +{ + if (scn == NULL) + return SHN_UNDEF; + + return scn->index; +} diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c new file mode 100644 index 00000000..896f22cd --- /dev/null +++ b/libelf/elf_newdata.c @@ -0,0 +1,136 @@ +/* Create new, empty section data. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +Elf_Data * +elf_newdata (Elf_Scn *scn) +{ + Elf_Data_List *result = NULL; + + if (scn == NULL) + return NULL; + + if (unlikely (scn->index == 0)) + { + /* It is not allowed to add something to the 0th section. */ + __libelf_seterrno (ELF_E_NOT_NUL_SECTION); + return NULL; + } + + if (scn->elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? scn->elf->state.elf32.ehdr == NULL + : scn->elf->state.elf64.ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + return NULL; + } + + rwlock_wrlock (scn->elf->lock); + + /* data_read is set when data has been read from the ELF image or + when a new section has been created by elf_newscn. If data has + been read from the ELF image, then rawdata_base will point to raw + data. If data_read has been set by elf_newscn, then rawdata_base + will be NULL. data_list_rear will be set by elf_getdata if the + data has been converted, or by this function, elf_newdata, when + new data has been added. + + Currently elf_getdata and elf_update rely on the fact that when + data_list_read is not NULL all they have to do is walk the data + list. They will ignore any (unread) raw data in that case. + + So we need to make sure the data list is setup if there is + already data available. */ + if (scn->data_read + && scn->rawdata_base != NULL + && scn->data_list_rear == NULL) + __libelf_set_data_list_rdlock (scn, 1); + + if (scn->data_read && scn->data_list_rear == NULL) + { + /* This means the section was created by the user and this is the + first data. */ + result = &scn->data_list; + result->flags = ELF_F_DIRTY; + } + else + { + /* It would be more efficient to create new data without + reading/converting the data from the file. But then we + have to remember this. Currently elf_getdata and + elf_update rely on the fact that they don't have to + load/convert any data if data_list_rear is set. */ + if (scn->data_read == 0) + { + if (__libelf_set_rawdata_wrlock (scn) != 0) + /* Something went wrong. The error value is already set. */ + goto out; + __libelf_set_data_list_rdlock (scn, 1); + } + + /* Create a new, empty data descriptor. */ + result = (Elf_Data_List *) calloc (1, sizeof (Elf_Data_List)); + if (result == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + + result->flags = ELF_F_DIRTY | ELF_F_MALLOCED; + } + + /* Set the predefined values. */ + result->data.d.d_version = EV_CURRENT; + + result->data.s = scn; + + /* Add to the end of the list. */ + if (scn->data_list_rear != NULL) + scn->data_list_rear->next = result; + + scn->data_list_rear = result; + + out: + rwlock_unlock (scn->elf->lock); + + /* Please note that the following is thread safe and is also defined + for RESULT == NULL since it still return NULL. */ + return &result->data.d; +} diff --git a/libelf/elf_newscn.c b/libelf/elf_newscn.c new file mode 100644 index 00000000..d15a642e --- /dev/null +++ b/libelf/elf_newscn.c @@ -0,0 +1,162 @@ +/* Append new section. + Copyright (C) 1998,1999,2000,2001,2002,2005,2009,2014,2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "libelfP.h" + + +Elf_Scn * +elf_newscn (Elf *elf) +{ + Elf_Scn *result = NULL; + bool first = false; + + if (elf == NULL) + return NULL; + + /* We rely on the prefix of the `elf', `elf32', and `elf64' element + being the same. */ + assert (offsetof (Elf, state.elf.scns_last) + == offsetof (Elf, state.elf32.scns_last)); + assert (offsetof (Elf, state.elf.scns_last) + == offsetof (Elf, state.elf64.scns_last)); + assert (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns)); + + rwlock_wrlock (elf->lock); + + again: + if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max) + { + result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt]; + + if (++elf->state.elf.scns_last->cnt == 1 + && (elf->state.elf.scns_last + == (elf->class == ELFCLASS32 + || (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns))) + /* This is zeroth section. */ + first = true; + else + { + assert (elf->state.elf.scns_last->cnt > 1); + result->index = result[-1].index + 1; + } + } + else + { + /* We must allocate a new element. */ + Elf_ScnList *newp = NULL; + + assert (elf->state.elf.scnincr > 0); + + if ( +#if SIZE_MAX <= 4294967295U + likely (elf->state.elf.scnincr + < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList)) +#else + 1 +#endif + ) + newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList) + + ((elf->state.elf.scnincr *= 2) + * sizeof (Elf_Scn)), 1); + if (newp == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + + result = &newp->data[0]; + + /* One section used. */ + ++newp->cnt; + + /* This is the number of sections we allocated. */ + newp->max = elf->state.elf.scnincr; + + /* Remember the index for the first section in this block. */ + newp->data[0].index + = 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index; + + /* Enqueue the new list element. */ + elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp; + } + + /* Create a section header for this section. */ + if (elf->class == ELFCLASS32) + { + result->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr)); + if (result->shdr.e32 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + else + { + result->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr)); + if (result->shdr.e64 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + + result->elf = elf; + result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; + result->list = elf->state.elf.scns_last; + + /* Initialize the data part. */ + result->data_read = 1; + if (unlikely (first)) + { + /* For the first section we mark the data as already available. */ + //result->data_list_rear = &result->data_list; + first = false; + goto again; + } + + result->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_next.c b/libelf/elf_next.c new file mode 100644 index 00000000..6edafd2e --- /dev/null +++ b/libelf/elf_next.c @@ -0,0 +1,72 @@ +/* Advance in archive to next element. + Copyright (C) 1998-2009, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +Elf_Cmd +elf_next (Elf *elf) +{ + Elf *parent; + Elf_Cmd ret; + + /* Be gratious, the specs demand it. */ + if (elf == NULL || elf->parent == NULL) + return ELF_C_NULL; + + /* We can be sure the parent is an archive. */ + parent = elf->parent; + assert (parent->kind == ELF_K_AR); + + rwlock_wrlock (parent->lock); + + /* Now advance the offset. */ + parent->state.ar.offset += (sizeof (struct ar_hdr) + + ((parent->state.ar.elf_ar_hdr.ar_size + 1) + & ~1l)); + + /* Get the next archive header. */ + ret = __libelf_next_arhdr_wrlock (parent) != 0 ? ELF_C_NULL : elf->cmd; + + /* If necessary, mark the archive header as unusable. */ + if (ret == ELF_C_NULL) + parent->state.ar.elf_ar_hdr.ar_name = NULL; + + rwlock_unlock (parent->lock); + + return ret; +} diff --git a/libelf/elf_nextscn.c b/libelf/elf_nextscn.c new file mode 100644 index 00000000..d2f3e7cb --- /dev/null +++ b/libelf/elf_nextscn.c @@ -0,0 +1,83 @@ +/* Get next section. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +Elf_Scn * +elf_nextscn (Elf *elf, Elf_Scn *scn) +{ + Elf_ScnList *list; + Elf_Scn *result = NULL; + + if (elf == NULL) + return NULL; + + rwlock_rdlock (elf->lock); + + if (scn == NULL) + { + /* If no section handle is given return the first (not 0th) section. + Set scn to the 0th section and perform nextscn. */ + if (elf->class == ELFCLASS32 + || (offsetof (Elf, state.elf32.scns) + == offsetof (Elf, state.elf64.scns))) + list = &elf->state.elf32.scns; + else + list = &elf->state.elf64.scns; + + scn = &list->data[0]; + } + else + list = scn->list; + + if (scn + 1 < &list->data[list->cnt]) + result = scn + 1; + else if (scn + 1 == &list->data[list->max] + && (list = list->next) != NULL) + { + /* If there is another element in the section list it must + have at least one entry. */ + assert (list->cnt > 0); + result = &list->data[0]; + } + + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_nextscn) diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c new file mode 100644 index 00000000..f1850e7b --- /dev/null +++ b/libelf/elf_rand.c @@ -0,0 +1,63 @@ +/* Select specific element in archive. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +size_t +elf_rand (Elf *elf, size_t offset) +{ + /* Be gratious, the specs demand it. */ + if (elf == NULL || elf->kind != ELF_K_AR) + return 0; + + rwlock_wrlock (elf->lock); + + /* Save the old offset and set the offset. */ + elf->state.ar.offset = elf->start_offset + offset; + + /* Get the next archive header. */ + if (__libelf_next_arhdr_wrlock (elf) != 0) + { + /* Mark the archive header as unusable. */ + elf->state.ar.elf_ar_hdr.ar_name = NULL; + return 0; + } + + rwlock_unlock (elf->lock); + + return offset; +} diff --git a/libelf/elf_rawdata.c b/libelf/elf_rawdata.c new file mode 100644 index 00000000..db28f5dc --- /dev/null +++ b/libelf/elf_rawdata.c @@ -0,0 +1,76 @@ +/* Return raw section content. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "libelfP.h" + + +Elf_Data * +elf_rawdata (Elf_Scn *scn, Elf_Data *data) +{ + if (scn == NULL || scn->elf->kind != ELF_K_ELF) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* If `data' is not NULL this means we are not addressing the initial + data in the file. But this also means this data is already read + (since otherwise it is not possible to have a valid `data' pointer) + and all the data structures are initialized as well. In this case + we can simply walk the list of data records. */ + if (data != NULL + || (scn->data_read != 0 && (scn->flags & ELF_F_FILEDATA) == 0)) + { + /* We don't allow accessing any but the data read from the file + as raw. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return NULL; + } + + /* If the data for this section was not yet initialized do it now. */ + if (scn->data_read == 0) + { + /* First thing we do is to read the data from the file. There is + always a file (or memory region) associated with this descriptor + since otherwise the `data_read' flag would be set. */ + if (__libelf_set_rawdata (scn) != 0) + /* Something went wrong. The error value is already set. */ + return NULL; + } + + /* Return the first data element in the list. */ + return &scn->rawdata.d; +} +INTDEF(elf_rawdata) diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c new file mode 100644 index 00000000..b3837f4f --- /dev/null +++ b/libelf/elf_rawfile.c @@ -0,0 +1,67 @@ +/* Retrieve uninterpreted file contents. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +char * +elf_rawfile (Elf *elf, size_t *ptr) +{ + char *result; + + if (elf == NULL) + { + /* No valid descriptor. */ + __libelf_seterrno (ELF_E_INVALID_HANDLE); + error_out: + if (ptr != NULL) + *ptr = 0; + return NULL; + } + + /* If the file is not mmap'ed and not previously loaded, do it now. */ + if (elf->map_address == NULL && __libelf_readall (elf) == NULL) + goto error_out; + + rwlock_rdlock (elf->lock); + if (ptr != NULL) + *ptr = elf->maximum_size; + + result = (char *) elf->map_address + elf->start_offset; + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c new file mode 100644 index 00000000..384d2512 --- /dev/null +++ b/libelf/elf_readall.c @@ -0,0 +1,152 @@ +/* Read all of the file associated with the descriptor. + Copyright (C) 1998-2009, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include "libelfP.h" +#include "common.h" + + +static void +set_address (Elf *elf, size_t offset) +{ + if (elf->kind == ELF_K_AR) + { + Elf *child = elf->state.ar.children; + + while (child != NULL) + { + if (child->map_address == NULL) + { + child->map_address = elf->map_address; + child->start_offset -= offset; + if (child->kind == ELF_K_AR) + child->state.ar.offset -= offset; + + set_address (child, offset); + } + + child = child->next; + } + } +} + + +char * +internal_function +__libelf_readall (Elf *elf) +{ + /* Get the file. */ + rwlock_wrlock (elf->lock); + + if (elf->map_address == NULL && unlikely (elf->fildes == -1)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + rwlock_unlock (elf->lock); + return NULL; + } + + /* If the file is not mmap'ed and not previously loaded, do it now. */ + if (elf->map_address == NULL) + { + char *mem = NULL; + + /* If this is an archive and we have derived descriptors get the + locks for all of them. */ + libelf_acquire_all (elf); + + if (elf->maximum_size == ~((size_t) 0)) + { + /* We don't yet know how large the file is. Determine that now. */ + struct stat st; + + if (fstat (elf->fildes, &st) < 0) + goto read_error; + + if (sizeof (size_t) >= sizeof (st.st_size) + || st.st_size <= ~((size_t) 0)) + elf->maximum_size = (size_t) st.st_size; + else + { + errno = EOVERFLOW; + goto read_error; + } + } + + /* Allocate all the memory we need. */ + mem = (char *) malloc (elf->maximum_size); + if (mem != NULL) + { + /* Read the file content. */ + if (unlikely ((size_t) pread_retry (elf->fildes, mem, + elf->maximum_size, + elf->start_offset) + != elf->maximum_size)) + { + /* Something went wrong. */ + read_error: + __libelf_seterrno (ELF_E_READ_ERROR); + free (mem); + } + else + { + /* Remember the address. */ + elf->map_address = mem; + + /* Also remember that we allocated the memory. */ + elf->flags |= ELF_F_MALLOCED; + + /* Propagate the information down to all children and + their children. */ + set_address (elf, elf->start_offset); + + /* Correct the own offsets. */ + if (elf->kind == ELF_K_AR) + elf->state.ar.offset -= elf->start_offset; + elf->start_offset = 0; + } + } + else + __libelf_seterrno (ELF_E_NOMEM); + + /* Free the locks on the children. */ + libelf_release_all (elf); + } + + rwlock_unlock (elf->lock); + + return (char *) elf->map_address; +} diff --git a/libelf/elf_scnshndx.c b/libelf/elf_scnshndx.c new file mode 100644 index 00000000..5b783faa --- /dev/null +++ b/libelf/elf_scnshndx.c @@ -0,0 +1,50 @@ +/* Get the section index of the extended section index table. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 2007. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libelfP.h" + + +int +elf_scnshndx (Elf_Scn *scn) +{ + if (unlikely (scn->shndx_index == 0)) + { + /* We do not have the value yet. We get it as a side effect of + getting a section header. */ + GElf_Shdr shdr_mem; + (void) INTUSE(gelf_getshdr) (scn, &shdr_mem); + } + + return scn->shndx_index; +} +INTDEF(elf_scnshndx) diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c new file mode 100644 index 00000000..76f2caf1 --- /dev/null +++ b/libelf/elf_strptr.c @@ -0,0 +1,240 @@ +/* Return string pointer from string section. + Copyright (C) 1998-2002, 2004, 2008, 2009, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +static void * +get_zdata (Elf_Scn *strscn) +{ + size_t zsize, zalign; + void *zdata = __libelf_decompress_elf (strscn, &zsize, &zalign); + if (zdata == NULL) + return NULL; + + strscn->zdata_base = zdata; + strscn->zdata_size = zsize; + strscn->zdata_align = zalign; + + return zdata; +} + +static bool validate_str (const char *str, size_t from, size_t to) +{ +#if HAVE_DECL_MEMRCHR + return memrchr (&str[from], '\0', to - from) != NULL; +#else + do { + if (to <= from) + return false; + + to--; + } while (str[to]); + + return true; +#endif +} + +char * +elf_strptr (Elf *elf, size_t idx, size_t offset) +{ + if (elf == NULL) + return NULL; + + if (elf->kind != ELF_K_ELF) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (elf->lock); + + char *result = NULL; + Elf_Scn *strscn; + + /* Find the section in the list. */ + Elf_ScnList *runp = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) + == offsetof (struct Elf, state.elf64.scns)) + ? &elf->state.elf32.scns : &elf->state.elf64.scns); + while (1) + { + if (idx < runp->max) + { + if (idx < runp->cnt) + strscn = &runp->data[idx]; + else + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + break; + } + + idx -= runp->max; + + runp = runp->next; + if (runp == NULL) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + } + + size_t sh_size = 0; + if (elf->class == ELFCLASS32) + { + Elf32_Shdr *shdr = strscn->shdr.e32 ?: __elf32_getshdr_rdlock (strscn); + if (unlikely (shdr == NULL || shdr->sh_type != SHT_STRTAB)) + { + /* This is no string section. */ + __libelf_seterrno (ELF_E_INVALID_SECTION); + goto out; + } + + if ((shdr->sh_flags & SHF_COMPRESSED) == 0) + sh_size = shdr->sh_size; + else + { + if (strscn->zdata_base == NULL && get_zdata (strscn) == NULL) + goto out; + sh_size = strscn->zdata_size; + } + + if (unlikely (offset >= sh_size)) + { + /* The given offset is too big, it is beyond this section. */ + __libelf_seterrno (ELF_E_OFFSET_RANGE); + goto out; + } + } + else + { + Elf64_Shdr *shdr = strscn->shdr.e64 ?: __elf64_getshdr_rdlock (strscn); + if (unlikely (shdr == NULL || shdr->sh_type != SHT_STRTAB)) + { + /* This is no string section. */ + __libelf_seterrno (ELF_E_INVALID_SECTION); + goto out; + } + + if ((shdr->sh_flags & SHF_COMPRESSED) == 0) + sh_size = shdr->sh_size; + else + { + if (strscn->zdata_base == NULL && get_zdata (strscn) == NULL) + goto out; + sh_size = strscn->zdata_size; + } + + if (unlikely (offset >= sh_size)) + { + /* The given offset is too big, it is beyond this section. */ + __libelf_seterrno (ELF_E_OFFSET_RANGE); + goto out; + } + } + + if (strscn->rawdata_base == NULL && ! strscn->data_read) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + if (strscn->rawdata_base == NULL && ! strscn->data_read + /* Read the section data. */ + && __libelf_set_rawdata_wrlock (strscn) != 0) + goto out; + } + + if (unlikely (strscn->zdata_base != NULL)) + { + /* Make sure the string is NUL terminated. Start from the end, + which very likely is a NUL char. */ + if (likely (validate_str (strscn->zdata_base, offset, sh_size))) + result = &strscn->zdata_base[offset]; + else + __libelf_seterrno (ELF_E_INVALID_INDEX); + } + else if (likely (strscn->data_list_rear == NULL)) + { + // XXX The above is currently correct since elf_newdata will + // make sure to convert the rawdata into the datalist if + // necessary. But it would be more efficient to keep the rawdata + // unconverted and only then iterate over the rest of the (newly + // added data) list. Note that when the ELF file is mmapped + // rawdata_base can be set while rawdata.d hasn't been + // initialized yet (when data_read is zero). So we cannot just + // look at the rawdata.d.d_size. + + /* Make sure the string is NUL terminated. Start from the end, + which very likely is a NUL char. */ + if (likely (validate_str (strscn->rawdata_base, offset, sh_size))) + result = &strscn->rawdata_base[offset]; + else + __libelf_seterrno (ELF_E_INVALID_INDEX); + } + else + { + /* This is a file which is currently created. Use the list of + data blocks. */ + struct Elf_Data_List *dl = &strscn->data_list; + while (dl != NULL) + { + if (offset >= (size_t) dl->data.d.d_off + && offset < dl->data.d.d_off + dl->data.d.d_size) + { + /* Make sure the string is NUL terminated. Start from + the end, which very likely is a NUL char. */ + if (likely (validate_str ((char *) dl->data.d.d_buf, + offset - dl->data.d.d_off, + dl->data.d.d_size))) + result = ((char *) dl->data.d.d_buf + + (offset - dl->data.d.d_off)); + else + __libelf_seterrno (ELF_E_INVALID_INDEX); + break; + } + + dl = dl->next; + } + } + + out: + rwlock_unlock (elf->lock); + + return result; +} +INTDEF(elf_strptr) diff --git a/libelf/elf_update.c b/libelf/elf_update.c new file mode 100644 index 00000000..9b8867ce --- /dev/null +++ b/libelf/elf_update.c @@ -0,0 +1,238 @@ +/* Update data structures for changes and write them out. + Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "libelfP.h" + + +static int64_t +write_file (Elf *elf, int64_t size, int change_bo, size_t shnum) +{ + int class = elf->class; + + /* Check the mode bits now, before modification might change them. */ + struct stat st; + if (unlikely (fstat (elf->fildes, &st) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + + /* Adjust the size in any case. We do this even if we use `write'. + We cannot do this if this file is in an archive. We also don't + do it *now* if we are shortening the file since this would + prevent programs to use the data of the file in generating the + new file. We truncate the file later in this case. */ + if (elf->parent == NULL + && (elf->maximum_size == ~((size_t) 0) + || (size_t) size > elf->maximum_size) + && unlikely (ftruncate (elf->fildes, size) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + + /* Try to map the file if this isn't done yet. */ + if (elf->map_address == NULL && elf->cmd == ELF_C_WRITE_MMAP) + { + elf->map_address = mmap (NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, elf->fildes, 0); + if (unlikely (elf->map_address == MAP_FAILED)) + elf->map_address = NULL; + else + elf->flags |= ELF_F_MMAPPED; + } + + if (elf->map_address != NULL) + { + /* When using mmap we want to make sure the file content is + really there. Only using ftruncate might mean the file is + extended, but space isn't allocated yet. This might cause a + SIGBUS once we write into the mmapped space and the disk is + full. In glibc posix_fallocate is required to extend the + file and allocate enough space even if the underlying + filesystem would normally return EOPNOTSUPP. But other + implementations might not work as expected. And the glibc + fallback case might fail (with unexpected errnos) in some cases. + So we only report an error when the call fails and errno is + ENOSPC. Otherwise we ignore the error and treat it as just hint. */ + if (elf->parent == NULL + && (elf->maximum_size == ~((size_t) 0) + || (size_t) size > elf->maximum_size)) + { + if (unlikely (posix_fallocate (elf->fildes, 0, size) != 0)) + if (errno == ENOSPC) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + + /* Extend the mmap address if needed. */ + if (elf->cmd == ELF_C_RDWR_MMAP + && (size_t) size > elf->maximum_size) + { + if (mremap (elf->map_address, elf->maximum_size, + size, 0) == MAP_FAILED) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + elf->maximum_size = size; + } + + } + + /* The file is mmaped. */ + if ((class == ELFCLASS32 + ? __elf32_updatemmap (elf, change_bo, shnum) + : __elf64_updatemmap (elf, change_bo, shnum)) != 0) + /* Some problem while writing. */ + size = -1; + } + else + { + /* The file is not mmaped. */ + if ((class == ELFCLASS32 + ? __elf32_updatefile (elf, change_bo, shnum) + : __elf64_updatefile (elf, change_bo, shnum)) != 0) + /* Some problem while writing. */ + size = -1; + } + + /* Reduce the file size if necessary. */ + if (size != -1 + && elf->parent == NULL + && elf->maximum_size != ~((size_t) 0) + && (size_t) size < elf->maximum_size + && unlikely (ftruncate (elf->fildes, size) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + size = -1; + } + + /* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID + mode bits. So make sure we restore them afterwards if they were set. + This is not atomic if someone else chmod's the file while we operate. */ + if (size != -1 + && unlikely (st.st_mode & (S_ISUID | S_ISGID)) + /* fchmod ignores the bits we cannot change. */ + && unlikely (fchmod (elf->fildes, st.st_mode) != 0)) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + size = -1; + } + + if (size != -1 && elf->parent == NULL) + elf->maximum_size = size; + + return size; +} + + +int64_t +elf_update (Elf *elf, Elf_Cmd cmd) +{ + size_t shnum; + int64_t size; + int change_bo = 0; + + if (cmd != ELF_C_NULL + && cmd != ELF_C_WRITE + && unlikely (cmd != ELF_C_WRITE_MMAP)) + { + __libelf_seterrno (ELF_E_INVALID_CMD); + return -1; + } + + if (elf == NULL) + return -1; + + if (elf->kind != ELF_K_ELF) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_wrlock (elf->lock); + + /* Make sure we have an ELF header. */ + if (elf->state.elf.ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + size = -1; + goto out; + } + + /* Determine the number of sections. */ + shnum = (elf->state.elf.scns_last->cnt == 0 + ? 0 + : 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt - 1].index); + + /* Update the ELF descriptor. First, place the program header. It + will come right after the ELF header. The count the size of all + sections and finally place the section table. */ + size = (elf->class == ELFCLASS32 + ? __elf32_updatenull_wrlock (elf, &change_bo, shnum) + : __elf64_updatenull_wrlock (elf, &change_bo, shnum)); + if (likely (size != -1) + /* See whether we actually have to write out the data. */ + && (cmd == ELF_C_WRITE || cmd == ELF_C_WRITE_MMAP)) + { + if (elf->cmd != ELF_C_RDWR + && elf->cmd != ELF_C_RDWR_MMAP + && elf->cmd != ELF_C_WRITE + && unlikely (elf->cmd != ELF_C_WRITE_MMAP)) + { + __libelf_seterrno (ELF_E_UPDATE_RO); + size = -1; + } + else if (unlikely (elf->fildes == -1)) + { + /* We closed the file already. */ + __libelf_seterrno (ELF_E_FD_DISABLED); + size = -1; + } + else + size = write_file (elf, size, change_bo, shnum); + } + + out: + rwlock_unlock (elf->lock); + + return size; +} diff --git a/libelf/elf_version.c b/libelf/elf_version.c new file mode 100644 index 00000000..6ec534ab --- /dev/null +++ b/libelf/elf_version.c @@ -0,0 +1,62 @@ +/* Coordinate ELF library and application versions. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +/* Currently selected version. Should be EV_CURRENT. + Will be EV_NONE if elf_version () has not been called yet. */ +unsigned int __libelf_version = EV_NONE; + +unsigned int +elf_version (unsigned int version) +{ + if (version == EV_NONE) + return EV_CURRENT; + + if (likely (version == EV_CURRENT)) + { + /* Phew, we know this version. */ + + /* Signal that the version is now initialized. */ + __libelf_version = EV_CURRENT; + + /* And return the last (or initial) version. */ + return EV_CURRENT; + } + + /* We cannot handle this version. */ + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return EV_NONE; +} +INTDEF(elf_version) diff --git a/libelf/exttypes.h b/libelf/exttypes.h new file mode 100644 index 00000000..7bacd654 --- /dev/null +++ b/libelf/exttypes.h @@ -0,0 +1,104 @@ +/* External ELF types. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _EXTTYPES_H +#define _EXTTYPES_H 1 + +/* Integral types. */ +typedef char Elf32_Ext_Addr[ELF32_FSZ_ADDR]; +typedef char Elf32_Ext_Off[ELF32_FSZ_OFF]; +typedef char Elf32_Ext_Half[ELF32_FSZ_HALF]; +typedef char Elf32_Ext_Sword[ELF32_FSZ_SWORD]; +typedef char Elf32_Ext_Word[ELF32_FSZ_WORD]; +typedef char Elf32_Ext_Sxword[ELF32_FSZ_SXWORD]; +typedef char Elf32_Ext_Xword[ELF32_FSZ_XWORD]; + +typedef char Elf64_Ext_Addr[ELF64_FSZ_ADDR]; +typedef char Elf64_Ext_Off[ELF64_FSZ_OFF]; +typedef char Elf64_Ext_Half[ELF64_FSZ_HALF]; +typedef char Elf64_Ext_Sword[ELF64_FSZ_SWORD]; +typedef char Elf64_Ext_Word[ELF64_FSZ_WORD]; +typedef char Elf64_Ext_Sxword[ELF64_FSZ_SXWORD]; +typedef char Elf64_Ext_Xword[ELF64_FSZ_XWORD]; + + +/* Define the composed types. */ +#define START(Bits, Name, EName) typedef struct { +#define END(Bits, Name) } ElfW2(Bits, Name) +#define TYPE_NAME(Type, Name) Type Name; +#define TYPE_EXTRA(Text) Text +#define TYPE_XLATE(Text) + +/* Get the abstract definitions. */ +#include "abstract.h" + +/* And define the types. */ +Ehdr32 (Ext_); +Phdr32 (Ext_); +Shdr32 (Ext_); +Sym32 (Ext_); +Rel32 (Ext_); +Rela32 (Ext_); +Note32 (Ext_); +Dyn32 (Ext_); +Verdef32 (Ext_); +Verdaux32 (Ext_); +Verneed32 (Ext_); +Vernaux32 (Ext_); +Syminfo32 (Ext_); +Move32 (Ext_); +Lib32 (Ext_); +auxv_t32 (Ext_); +Chdr32 (Ext_); + +Ehdr64 (Ext_); +Phdr64 (Ext_); +Shdr64 (Ext_); +Sym64 (Ext_); +Rel64 (Ext_); +Rela64 (Ext_); +Note64 (Ext_); +Dyn64 (Ext_); +Verdef64 (Ext_); +Verdaux64 (Ext_); +Verneed64 (Ext_); +Vernaux64 (Ext_); +Syminfo64 (Ext_); +Move64 (Ext_); +Lib64 (Ext_); +auxv_t64 (Ext_); +Chdr64 (Ext_); + +#undef START +#undef END +#undef TYPE_NAME +#undef TYPE_EXTRA +#undef TYPE_XLATE + +#endif /* exttypes.h */ diff --git a/libelf/gelf.h b/libelf/gelf.h new file mode 100644 index 00000000..7a3c87aa --- /dev/null +++ b/libelf/gelf.h @@ -0,0 +1,342 @@ +/* This file defines generic ELF types, structures, and macros. + Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _GELF_H +#define _GELF_H 1 + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Class independent type definitions. Correctly speaking this is not + true. We assume that 64-bit binaries are the largest class and + therefore all other classes can be represented without loss. */ + +/* Type for a 16-bit quantity. */ +typedef Elf64_Half GElf_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef Elf64_Word GElf_Word; +typedef Elf64_Sword GElf_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef Elf64_Xword GElf_Xword; +typedef Elf64_Sxword GElf_Sxword; + +/* Type of addresses. */ +typedef Elf64_Addr GElf_Addr; + +/* Type of file offsets. */ +typedef Elf64_Off GElf_Off; + + +/* The ELF file header. This appears at the start of every ELF file. */ +typedef Elf64_Ehdr GElf_Ehdr; + +/* Section header. */ +typedef Elf64_Shdr GElf_Shdr; + +/* Section index. */ +/* XXX This should probably be a larger type in preparation of times when + regular section indices can be larger. */ +typedef Elf64_Section GElf_Section; + +/* Symbol table entry. */ +typedef Elf64_Sym GElf_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ +typedef Elf64_Syminfo GElf_Syminfo; + +/* Relocation table entry without addend (in section of type SHT_REL). */ +typedef Elf64_Rel GElf_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ +typedef Elf64_Rela GElf_Rela; + +/* Program segment header. */ +typedef Elf64_Phdr GElf_Phdr; + +/* Header of a compressed section. */ +typedef Elf64_Chdr GElf_Chdr; + +/* Dynamic section entry. */ +typedef Elf64_Dyn GElf_Dyn; + + +/* Version definition sections. */ +typedef Elf64_Verdef GElf_Verdef; + +/* Auxiliary version information. */ +typedef Elf64_Verdaux GElf_Verdaux; + +/* Version dependency section. */ +typedef Elf64_Verneed GElf_Verneed; + +/* Auxiliary needed version information. */ +typedef Elf64_Vernaux GElf_Vernaux; + + +/* Type for version symbol information. */ +typedef Elf64_Versym GElf_Versym; + + +/* Auxiliary vector. */ +typedef Elf64_auxv_t GElf_auxv_t; + + +/* Note section contents. */ +typedef Elf64_Nhdr GElf_Nhdr; + + +/* Move structure. */ +typedef Elf64_Move GElf_Move; + + +/* Library list structure. */ +typedef Elf64_Lib GElf_Lib; + + +/* How to extract and insert information held in the st_info field. */ + +#define GELF_ST_BIND(val) ELF64_ST_BIND (val) +#define GELF_ST_TYPE(val) ELF64_ST_TYPE (val) +#define GELF_ST_INFO(bind, type) ELF64_ST_INFO (bind, type) + +/* How to extract information held in the st_other field. */ + +#define GELF_ST_VISIBILITY(val) ELF64_ST_VISIBILITY (val) + + +/* How to extract and insert information held in the r_info field. */ + +#define GELF_R_SYM(info) ELF64_R_SYM (info) +#define GELF_R_TYPE(info) ELF64_R_TYPE (info) +#define GELF_R_INFO(sym, type) ELF64_R_INFO (sym, type) + + +/* How to extract and insert information held in the m_info field. */ +#define GELF_M_SYM(info) ELF64_M_SYM (info) +#define GELF_M_SIZE(info) ELF64_M_SIZE (info) +#define GELF_M_INFO(sym, size) ELF64_M_INFO (sym, size) + + +/* Get class of the file associated with ELF. */ +extern int gelf_getclass (Elf *__elf); + + +/* Return size of array of COUNT elements of the type denoted by TYPE + in the external representation. The binary class is taken from ELF. + The result is based on version VERSION of the ELF standard. */ +extern size_t gelf_fsize (Elf *__elf, Elf_Type __type, size_t __count, + unsigned int __version); + +/* Retrieve object file header. */ +extern GElf_Ehdr *gelf_getehdr (Elf *__elf, GElf_Ehdr *__dest); + +/* Update the ELF header. */ +extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src); + +/* Create new ELF header if none exists. Creates an Elf32_Ehdr if CLASS + is ELFCLASS32 or an Elf64_Ehdr if CLASS is ELFCLASS64. Returns NULL + on error. */ +extern void *gelf_newehdr (Elf *__elf, int __class); + +/* Get section at OFFSET. */ +extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset); + +/* Retrieve section header. */ +extern GElf_Shdr *gelf_getshdr (Elf_Scn *__scn, GElf_Shdr *__dst); + +/* Update section header. */ +extern int gelf_update_shdr (Elf_Scn *__scn, GElf_Shdr *__src); + +/* Retrieve program header table entry. */ +extern GElf_Phdr *gelf_getphdr (Elf *__elf, int __ndx, GElf_Phdr *__dst); + +/* Update the program header. */ +extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src); + +/* Create new program header with PHNUM entries. Creates either an + Elf32_Phdr or an Elf64_Phdr depending on whether the given ELF is + ELFCLASS32 or ELFCLASS64. Returns NULL on error. */ +extern void *gelf_newphdr (Elf *__elf, size_t __phnum); + +/* Get compression header of section if any. Returns NULL and sets + elf_errno if the section isn't compressed or an error occurred. */ +extern GElf_Chdr *gelf_getchdr (Elf_Scn *__scn, GElf_Chdr *__dst); + +/* Convert data structure from the representation in the file represented + by ELF to their memory representation. */ +extern Elf_Data *gelf_xlatetom (Elf *__elf, Elf_Data *__dest, + const Elf_Data *__src, unsigned int __encode); + +/* Convert data structure from to the representation in memory + represented by ELF file representation. */ +extern Elf_Data *gelf_xlatetof (Elf *__elf, Elf_Data *__dest, + const Elf_Data *__src, unsigned int __encode); + + +/* Retrieve REL relocation info at the given index. */ +extern GElf_Rel *gelf_getrel (Elf_Data *__data, int __ndx, GElf_Rel *__dst); + +/* Retrieve RELA relocation info at the given index. */ +extern GElf_Rela *gelf_getrela (Elf_Data *__data, int __ndx, GElf_Rela *__dst); + +/* Update REL relocation information at given index. */ +extern int gelf_update_rel (Elf_Data *__dst, int __ndx, GElf_Rel *__src); + +/* Update RELA relocation information at given index. */ +extern int gelf_update_rela (Elf_Data *__dst, int __ndx, GElf_Rela *__src); + + +/* Retrieve symbol information from the symbol table at the given index. */ +extern GElf_Sym *gelf_getsym (Elf_Data *__data, int __ndx, GElf_Sym *__dst); + +/* Update symbol information in the symbol table at the given index. */ +extern int gelf_update_sym (Elf_Data *__data, int __ndx, GElf_Sym *__src); + + +/* Retrieve symbol information and separate section index from the + symbol table at the given index. */ +extern GElf_Sym *gelf_getsymshndx (Elf_Data *__symdata, Elf_Data *__shndxdata, + int __ndx, GElf_Sym *__sym, + Elf32_Word *__xshndx); + +/* Update symbol information and separate section index in the symbol + table at the given index. */ +extern int gelf_update_symshndx (Elf_Data *__symdata, Elf_Data *__shndxdata, + int __ndx, GElf_Sym *__sym, + Elf32_Word __xshndx); + + +/* Retrieve additional symbol information from the symbol table at the + given index. */ +extern GElf_Syminfo *gelf_getsyminfo (Elf_Data *__data, int __ndx, + GElf_Syminfo *__dst); + +/* Update additional symbol information in the symbol table at the + given index. */ +extern int gelf_update_syminfo (Elf_Data *__data, int __ndx, + GElf_Syminfo *__src); + + +/* Get information from dynamic table at the given index. */ +extern GElf_Dyn *gelf_getdyn (Elf_Data *__data, int __ndx, GElf_Dyn *__dst); + +/* Update information in dynamic table at the given index. */ +extern int gelf_update_dyn (Elf_Data *__dst, int __ndx, GElf_Dyn *__src); + + +/* Get move structure at the given index. */ +extern GElf_Move *gelf_getmove (Elf_Data *__data, int __ndx, GElf_Move *__dst); + +/* Update move structure at the given index. */ +extern int gelf_update_move (Elf_Data *__data, int __ndx, + GElf_Move *__src); + + +/* Get library from table at the given index. */ +extern GElf_Lib *gelf_getlib (Elf_Data *__data, int __ndx, GElf_Lib *__dst); + +/* Update library in table at the given index. */ +extern int gelf_update_lib (Elf_Data *__data, int __ndx, GElf_Lib *__src); + + + +/* Retrieve symbol version information at given index. */ +extern GElf_Versym *gelf_getversym (Elf_Data *__data, int __ndx, + GElf_Versym *__dst); + +/* Update symbol version information. */ +extern int gelf_update_versym (Elf_Data *__data, int __ndx, + GElf_Versym *__src); + + +/* Retrieve required symbol version information at given offset. */ +extern GElf_Verneed *gelf_getverneed (Elf_Data *__data, int __offset, + GElf_Verneed *__dst); + +/* Update required symbol version information. */ +extern int gelf_update_verneed (Elf_Data *__data, int __offset, + GElf_Verneed *__src); + +/* Retrieve additional required symbol version information at given offset. */ +extern GElf_Vernaux *gelf_getvernaux (Elf_Data *__data, int __offset, + GElf_Vernaux *__dst); + +/* Update additional required symbol version information. */ +extern int gelf_update_vernaux (Elf_Data *__data, int __offset, + GElf_Vernaux *__src); + + +/* Retrieve symbol version definition information at given offset. */ +extern GElf_Verdef *gelf_getverdef (Elf_Data *__data, int __offset, + GElf_Verdef *__dst); + +/* Update symbol version definition information. */ +extern int gelf_update_verdef (Elf_Data *__data, int __offset, + GElf_Verdef *__src); + +/* Retrieve additional symbol version definition information at given + offset. */ +extern GElf_Verdaux *gelf_getverdaux (Elf_Data *__data, int __offset, + GElf_Verdaux *__dst); + +/* Update additional symbol version definition information. */ +extern int gelf_update_verdaux (Elf_Data *__data, int __offset, + GElf_Verdaux *__src); + + +/* Get auxv entry at the given index. */ +extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx, + GElf_auxv_t *__dst); + +/* Update auxv entry at the given index. */ +extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src); + + +/* Get note header at the given offset into the data, and the offsets of + the note's name and descriptor data. Returns the offset of the next + note header, or 0 for an invalid offset or corrupt note header. */ +extern size_t gelf_getnote (Elf_Data *__data, size_t __offset, + GElf_Nhdr *__result, + size_t *__name_offset, size_t *__desc_offset); + + +/* Compute simple checksum from permanent parts of the ELF file. */ +extern long int gelf_checksum (Elf *__elf); + +#ifdef __cplusplus +} +#endif + +#endif /* gelf.h */ diff --git a/libelf/gelf_checksum.c b/libelf/gelf_checksum.c new file mode 100644 index 00000000..831c54cb --- /dev/null +++ b/libelf/gelf_checksum.c @@ -0,0 +1,48 @@ +/* Convert from file to memory representation. Generic ELF version. + Copyright (C) 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +long int +gelf_checksum (Elf *elf) +{ + if (elf == NULL) + return -1l; + + return (elf->class == ELFCLASS32 + ? INTUSE(elf32_checksum) (elf) : INTUSE(elf64_checksum) (elf)); +} diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c new file mode 100644 index 00000000..493d7916 --- /dev/null +++ b/libelf/gelf_fsize.c @@ -0,0 +1,103 @@ +/* Return the size of an object file type. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +/* These are the sizes for all the known types. */ +const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] = +{ + [ELFCLASS32 - 1] = { +#define TYPE_SIZES(LIBELFBITS) \ + [ELF_T_ADDR] = ELFW2(LIBELFBITS, FSZ_ADDR), \ + [ELF_T_OFF] = ELFW2(LIBELFBITS, FSZ_OFF), \ + [ELF_T_BYTE] = 1, \ + [ELF_T_HALF] = ELFW2(LIBELFBITS, FSZ_HALF), \ + [ELF_T_WORD] = ELFW2(LIBELFBITS, FSZ_WORD), \ + [ELF_T_SWORD] = ELFW2(LIBELFBITS, FSZ_SWORD), \ + [ELF_T_XWORD] = ELFW2(LIBELFBITS, FSZ_XWORD), \ + [ELF_T_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD), \ + [ELF_T_EHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)), \ + [ELF_T_SHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Shdr)), \ + [ELF_T_SYM] = sizeof (ElfW2(LIBELFBITS, Ext_Sym)), \ + [ELF_T_REL] = sizeof (ElfW2(LIBELFBITS, Ext_Rel)), \ + [ELF_T_RELA] = sizeof (ElfW2(LIBELFBITS, Ext_Rela)), \ + [ELF_T_PHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Phdr)), \ + [ELF_T_DYN] = sizeof (ElfW2(LIBELFBITS, Ext_Dyn)), \ + [ELF_T_VDEF] = sizeof (ElfW2(LIBELFBITS, Ext_Verdef)), \ + [ELF_T_VDAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)), \ + [ELF_T_VNEED] = sizeof (ElfW2(LIBELFBITS, Ext_Verneed)), \ + [ELF_T_VNAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)), \ + [ELF_T_NHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \ + /* Note the header size is the same, but padding is different. */ \ + [ELF_T_NHDR8] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \ + [ELF_T_SYMINFO] = sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)), \ + [ELF_T_MOVE] = sizeof (ElfW2(LIBELFBITS, Ext_Move)), \ + [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \ + [ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \ + [ELF_T_CHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Chdr)), \ + [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD) + TYPE_SIZES (32) + }, + [ELFCLASS64 - 1] = { + TYPE_SIZES (64) + } +}; + + +size_t +gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version) +{ + /* We do not have differences between file and memory sizes. Better + not since otherwise `mmap' would not work. */ + if (elf == NULL) + return 0; + + if (version != EV_CURRENT) + { + __libelf_seterrno (ELF_E_UNKNOWN_VERSION); + return 0; + } + + if (type >= ELF_T_NUM) + { + __libelf_seterrno (ELF_E_UNKNOWN_TYPE); + return 0; + } + + return count * __libelf_type_sizes[elf->class - 1][type]; +} +INTDEF(gelf_fsize) diff --git a/libelf/gelf_getauxv.c b/libelf/gelf_getauxv.c new file mode 100644 index 00000000..1591be2a --- /dev/null +++ b/libelf/gelf_getauxv.c @@ -0,0 +1,107 @@ +/* Get information from auxiliary vector at the given index. + Copyright (C) 2007, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_auxv_t * +gelf_getauxv (Elf_Data *data, int ndx, GElf_auxv_t *dst) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + GElf_auxv_t *result = NULL; + Elf *elf; + + if (data_scn == NULL) + return NULL; + + if (unlikely (data_scn->d.d_type != ELF_T_AUXV)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + elf = data_scn->s->elf; + + rwlock_rdlock (elf->lock); + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (elf->class == ELFCLASS32) + { + Elf32_auxv_t *src; + + /* Here it gets a bit more complicated. The format of the vector + entries has to be converted. The user better have provided a + buffer where we can store the information. While copying the data + we convert the format. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ + dst->a_type = src->a_type; + dst->a_un.a_val = src->a_un.a_val; + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + memcpy (dst, data_scn->d.d_buf + ndx * sizeof (GElf_auxv_t), + sizeof (GElf_auxv_t)); + } + + result = dst; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getchdr.c b/libelf/gelf_getchdr.c new file mode 100644 index 00000000..394bf4b3 --- /dev/null +++ b/libelf/gelf_getchdr.c @@ -0,0 +1,69 @@ +/* Return section compression header. + Copyright (C) 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libelfP.h" +#include +#include + + +GElf_Chdr * +gelf_getchdr (Elf_Scn *scn, GElf_Chdr *dest) +{ + if (scn == NULL) + return NULL; + + if (dest == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Chdr *chdr = elf32_getchdr (scn); + if (chdr == NULL) + return NULL; + dest->ch_type = chdr->ch_type; + dest->ch_size = chdr->ch_size; + dest->ch_addralign = chdr->ch_addralign; + } + else + { + Elf64_Chdr *chdr = elf64_getchdr (scn); + if (chdr == NULL) + return NULL; + *dest = *chdr; + } + + return dest; +} +INTDEF(gelf_getchdr) diff --git a/libelf/gelf_getclass.c b/libelf/gelf_getclass.c new file mode 100644 index 00000000..7d0924bd --- /dev/null +++ b/libelf/gelf_getclass.c @@ -0,0 +1,44 @@ +/* Return the class of file associated with the descriptor. + Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_getclass (Elf *elf) +{ + return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class; +} diff --git a/libelf/gelf_getdyn.c b/libelf/gelf_getdyn.c new file mode 100644 index 00000000..a0090e14 --- /dev/null +++ b/libelf/gelf_getdyn.c @@ -0,0 +1,108 @@ +/* Get information from dynamic table at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Dyn * +gelf_getdyn (Elf_Data *data, int ndx, GElf_Dyn *dst) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + GElf_Dyn *result = NULL; + Elf *elf; + + if (data_scn == NULL) + return NULL; + + if (unlikely (data_scn->d.d_type != ELF_T_DYN)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + elf = data_scn->s->elf; + + rwlock_rdlock (elf->lock); + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (elf->class == ELFCLASS32) + { + Elf32_Dyn *src; + + /* Here it gets a bit more complicated. The format of the symbol + table entries has to be adopted. The user better has provided + a buffer where we can store the information. While copying the + data we are converting the format. */ + if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ + dst->d_tag = src->d_tag; + /* It OK to copy `d_val' since `d_ptr' has the same size. */ + dst->d_un.d_val = src->d_un.d_val; + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_Dyn) == sizeof (Elf64_Dyn)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (INVALID_NDX (ndx, GElf_Dyn, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Dyn *) data_scn->d.d_buf)[ndx]; + } + + result = dst; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getehdr.c b/libelf/gelf_getehdr.c new file mode 100644 index 00000000..abeb70c4 --- /dev/null +++ b/libelf/gelf_getehdr.c @@ -0,0 +1,108 @@ +/* Get ELF header. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "libelfP.h" + + +GElf_Ehdr * +internal_function +__gelf_getehdr_rdlock (Elf *elf, GElf_Ehdr *dest) +{ + GElf_Ehdr *result = NULL; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* The following is an optimization: the ehdr element is at the same + position in both the elf32 and elf64 structure. */ + if (offsetof (struct Elf, state.elf32.ehdr) + != offsetof (struct Elf, state.elf64.ehdr)) + abort (); + /* Just pick one of the values. */ + if (unlikely (elf->state.elf64.ehdr == NULL)) + /* Maybe no ELF header was created yet. */ + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + else if (elf->class == ELFCLASS32) + { + Elf32_Ehdr *ehdr = elf->state.elf32.ehdr; + + /* Convert the 32-bit struct to an 64-bit one. */ + memcpy (dest->e_ident, ehdr->e_ident, EI_NIDENT); +#define COPY(name) \ + dest->name = ehdr->name + COPY (e_type); + COPY (e_machine); + COPY (e_version); + COPY (e_entry); + COPY (e_phoff); + COPY (e_shoff); + COPY (e_flags); + COPY (e_ehsize); + COPY (e_phentsize); + COPY (e_phnum); + COPY (e_shentsize); + COPY (e_shnum); + COPY (e_shstrndx); + + result = dest; + } + else + result = memcpy (dest, elf->state.elf64.ehdr, sizeof (*dest)); + + return result; +} + +GElf_Ehdr * +gelf_getehdr (Elf *elf, GElf_Ehdr *dest) +{ + GElf_Ehdr *result; + if (elf == NULL) + return NULL; + + rwlock_rdlock (elf->lock); + result = __gelf_getehdr_rdlock (elf, dest); + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getlib.c b/libelf/gelf_getlib.c new file mode 100644 index 00000000..a8ac4785 --- /dev/null +++ b/libelf/gelf_getlib.c @@ -0,0 +1,77 @@ +/* Get library from table at the given index. + Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Lib * +gelf_getlib (Elf_Data *data, int ndx, GElf_Lib *dst) +{ + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_LIB)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + rwlock_rdlock (data_scn->s->elf->lock); + + /* The on disk format of Elf32_Lib and Elf64_Lib is identical. So + we can simplify things significantly. */ + assert (sizeof (GElf_Lib) == sizeof (Elf32_Lib)); + assert (sizeof (GElf_Lib) == sizeof (Elf64_Lib)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + GElf_Lib *result = NULL; + if (INVALID_NDX (ndx, GElf_Lib, data)) + __libelf_seterrno (ELF_E_INVALID_INDEX); + else + { + *dst = ((GElf_Lib *) data->d_buf)[ndx]; + + result = dst; + } + + rwlock_unlock (data_scn->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getmove.c b/libelf/gelf_getmove.c new file mode 100644 index 00000000..18efedcc --- /dev/null +++ b/libelf/gelf_getmove.c @@ -0,0 +1,79 @@ +/* Get move structure at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Move * +gelf_getmove (Elf_Data *data, int ndx, GElf_Move *dst) +{ + GElf_Move *result = NULL; + Elf *elf; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_MOVE)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Move) == sizeof (Elf32_Move)); + assert (sizeof (GElf_Move) == sizeof (Elf64_Move)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (INVALID_NDX (ndx, GElf_Move, data)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + elf = ((Elf_Data_Scn *) data)->s->elf; + rwlock_rdlock (elf->lock); + + *dst = ((GElf_Move *) data->d_buf)[ndx]; + + rwlock_unlock (elf->lock); + + result = dst; + + out: + return result; +} diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c new file mode 100644 index 00000000..0f7b9d68 --- /dev/null +++ b/libelf/gelf_getnote.c @@ -0,0 +1,116 @@ +/* Get note information at the supplied offset. + Copyright (C) 2007, 2014, 2015, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + +size_t +gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result, + size_t *name_offset, size_t *desc_offset) +{ + if (data == NULL) + return 0; + + if (unlikely (data->d_type != ELF_T_NHDR && data->d_type != ELF_T_NHDR8)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Nhdr) == sizeof (Elf32_Nhdr)); + assert (sizeof (GElf_Nhdr) == sizeof (Elf64_Nhdr)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + offset is OK. */ + if (unlikely (offset > data->d_size + || data->d_size - offset < sizeof (GElf_Nhdr))) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + offset = 0; + } + else + { + const GElf_Nhdr *n = data->d_buf + offset; + offset += sizeof *n; + + if (offset > data->d_size) + offset = 0; + else + { + /* This is slightly tricky, offset is guaranteed to be 4 + byte aligned, which is what we need for the name_offset. + And normally desc_offset is also 4 byte aligned, but not + for GNU Property notes, then it should be 8. So align + the offset, after adding the namesz, and include padding + in descsz to get to the end. */ + *name_offset = offset; + if (n->n_namesz > data->d_size + || offset > data->d_size - n->n_namesz) + offset = 0; + else + { + offset += n->n_namesz; + /* Include padding. Check below for overflow. */ + GElf_Word descsz = (data->d_type == ELF_T_NHDR8 + ? NOTE_ALIGN8 (n->n_descsz) + : NOTE_ALIGN4 (n->n_descsz)); + + if (data->d_type == ELF_T_NHDR8) + offset = NOTE_ALIGN8 (offset); + else + offset = NOTE_ALIGN4 (offset); + + if (unlikely (offset > data->d_size + || data->d_size - offset < descsz + || (descsz == 0 && n->n_descsz != 0))) + offset = 0; + else + { + *desc_offset = offset; + offset += descsz; + *result = *n; + } + } + } + } + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return offset; +} diff --git a/libelf/gelf_getphdr.c b/libelf/gelf_getphdr.c new file mode 100644 index 00000000..c719e4be --- /dev/null +++ b/libelf/gelf_getphdr.c @@ -0,0 +1,135 @@ +/* Return program header table entry. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Phdr * +gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst) +{ + GElf_Phdr *result = NULL; + + if (elf == NULL) + return NULL; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + if (dst == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + rwlock_rdlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + /* Copy the elements one-by-one. */ + Elf32_Phdr *phdr = elf->state.elf32.phdr; + + if (phdr == NULL) + { + rwlock_unlock (elf->lock); + phdr = INTUSE(elf32_getphdr) (elf); + if (phdr == NULL) + /* The error number is already set. */ + return NULL; + rwlock_rdlock (elf->lock); + } + + /* Test whether the index is ok. */ + size_t phnum; + if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* We know the result now. */ + result = dst; + + /* Now correct the pointer to point to the correct element. */ + phdr += ndx; + +#define COPY(Name) result->Name = phdr->Name + COPY (p_type); + COPY (p_offset); + COPY (p_vaddr); + COPY (p_paddr); + COPY (p_filesz); + COPY (p_memsz); + COPY (p_flags); + COPY (p_align); + } + else + { + /* Copy the elements one-by-one. */ + Elf64_Phdr *phdr = elf->state.elf64.phdr; + + if (phdr == NULL) + { + rwlock_unlock (elf->lock); + phdr = INTUSE(elf64_getphdr) (elf); + if (phdr == NULL) + /* The error number is already set. */ + return NULL; + rwlock_rdlock (elf->lock); + } + + /* Test whether the index is ok. */ + size_t phnum; + if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* We only have to copy the data. */ + result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr)); + } + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_getrel.c b/libelf/gelf_getrel.c new file mode 100644 index 00000000..309e3d37 --- /dev/null +++ b/libelf/gelf_getrel.c @@ -0,0 +1,99 @@ +/* Get REL relocation information at given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +GElf_Rel * +gelf_getrel (Elf_Data *data, int ndx, GElf_Rel *dst) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + GElf_Rel *result; + + if (data_scn == NULL) + return NULL; + + if (unlikely (data_scn->d.d_type != ELF_T_REL)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + scn = data_scn->s; + + rwlock_rdlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + /* We have to convert the data. */ + if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + { + Elf32_Rel *src = &((Elf32_Rel *) data_scn->d.d_buf)[ndx]; + + dst->r_offset = src->r_offset; + dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info), + ELF32_R_TYPE (src->r_info)); + + result = dst; + } + } + else + { + /* Simply copy the data after we made sure we are actually getting + correct data. */ + if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + result = memcpy (dst, &((Elf64_Rel *) data_scn->d.d_buf)[ndx], + sizeof (Elf64_Rel)); + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_getrela.c b/libelf/gelf_getrela.c new file mode 100644 index 00000000..d695f659 --- /dev/null +++ b/libelf/gelf_getrela.c @@ -0,0 +1,100 @@ +/* Get RELA relocation information at given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +GElf_Rela * +gelf_getrela (Elf_Data *data, int ndx, GElf_Rela *dst) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + GElf_Rela *result; + + if (data_scn == NULL) + return NULL; + + if (unlikely (data_scn->d.d_type != ELF_T_RELA)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + scn = data_scn->s; + + rwlock_rdlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + /* We have to convert the data. */ + if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + { + Elf32_Rela *src = &((Elf32_Rela *) data_scn->d.d_buf)[ndx]; + + dst->r_offset = src->r_offset; + dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info), + ELF32_R_TYPE (src->r_info)); + dst->r_addend = src->r_addend; + + result = dst; + } + } + else + { + /* Simply copy the data after we made sure we are actually getting + correct data. */ + if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + result = memcpy (dst, &((Elf64_Rela *) data_scn->d.d_buf)[ndx], + sizeof (Elf64_Rela)); + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_getshdr.c b/libelf/gelf_getshdr.c new file mode 100644 index 00000000..3858c8e1 --- /dev/null +++ b/libelf/gelf_getshdr.c @@ -0,0 +1,103 @@ +/* Return section header. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +GElf_Shdr * +gelf_getshdr (Elf_Scn *scn, GElf_Shdr *dst) +{ + GElf_Shdr *result = NULL; + + if (scn == NULL) + return NULL; + + if (dst == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + return NULL; + } + + rwlock_rdlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + /* Copy the elements one-by-one. */ + Elf32_Shdr *shdr + = scn->shdr.e32 ?: __elf32_getshdr_rdlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + +#define COPY(name) \ + dst->name = shdr->name + COPY (sh_name); + COPY (sh_type); + COPY (sh_flags); + COPY (sh_addr); + COPY (sh_offset); + COPY (sh_size); + COPY (sh_link); + COPY (sh_info); + COPY (sh_addralign); + COPY (sh_entsize); + + result = dst; + } + else + { + Elf64_Shdr *shdr + = scn->shdr.e64 ?: __elf64_getshdr_rdlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + + /* We only have to copy the data. */ + result = memcpy (dst, shdr, sizeof (GElf_Shdr)); + } + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} +INTDEF(gelf_getshdr) diff --git a/libelf/gelf_getsym.c b/libelf/gelf_getsym.c new file mode 100644 index 00000000..01534d2c --- /dev/null +++ b/libelf/gelf_getsym.c @@ -0,0 +1,114 @@ +/* Get symbol information from symbol table at the given index. + Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Sym * +gelf_getsym (Elf_Data *data, int ndx, GElf_Sym *dst) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + GElf_Sym *result = NULL; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_SYM)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (data_scn->s->elf->lock); + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (data_scn->s->elf->class == ELFCLASS32) + { + Elf32_Sym *src; + + /* Here it gets a bit more complicated. The format of the symbol + table entries has to be adopted. The user better has provided + a buffer where we can store the information. While copying the + data we are converting the format. */ + if (INVALID_NDX (ndx, Elf32_Sym, data)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_Sym *) data->d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ +#define COPY(name) \ + dst->name = src->name + COPY (st_name); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + COPY (st_value); + COPY (st_size); + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (INVALID_NDX (ndx, GElf_Sym, data)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Sym *) data->d_buf)[ndx]; + } + + result = dst; + + out: + rwlock_unlock (data_scn->s->elf->lock); + + return result; +} +INTDEF(gelf_getsym) diff --git a/libelf/gelf_getsyminfo.c b/libelf/gelf_getsyminfo.c new file mode 100644 index 00000000..8360ed38 --- /dev/null +++ b/libelf/gelf_getsyminfo.c @@ -0,0 +1,77 @@ +/* Get additional symbol information from symbol table at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Syminfo * +gelf_getsyminfo (Elf_Data *data, int ndx, GElf_Syminfo *dst) +{ + GElf_Syminfo *result = NULL; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_SYMINFO)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo)); + assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (INVALID_NDX (ndx, GElf_Syminfo, data)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Syminfo *) data->d_buf)[ndx]; + + result = dst; + + out: + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getsymshndx.c b/libelf/gelf_getsymshndx.c new file mode 100644 index 00000000..17c90fc6 --- /dev/null +++ b/libelf/gelf_getsymshndx.c @@ -0,0 +1,136 @@ +/* Get symbol information and separate section index from symbol table + at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Sym * +gelf_getsymshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx, + GElf_Sym *dst, Elf32_Word *dstshndx) +{ + Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata; + Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata; + GElf_Sym *result = NULL; + Elf32_Word shndx = 0; + + if (symdata == NULL) + return NULL; + + if (unlikely (symdata->d_type != ELF_T_SYM) + || (likely (shndxdata_scn != NULL) + && unlikely (shndxdata->d_type != ELF_T_WORD))) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + rwlock_rdlock (symdata_scn->s->elf->lock); + + /* The user is not required to pass a data descriptor for an extended + section index table. */ + if (likely (shndxdata_scn != NULL)) + { + if (INVALID_NDX (ndx, Elf32_Word, &shndxdata_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + shndx = ((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx]; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + if (symdata_scn->s->elf->class == ELFCLASS32) + { + Elf32_Sym *src; + + /* Here it gets a bit more complicated. The format of the symbol + table entries has to be adopted. The user better has provided + a buffer where we can store the information. While copying the + data we are converting the format. */ + if (INVALID_NDX (ndx, Elf32_Sym, symdata)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + src = &((Elf32_Sym *) symdata->d_buf)[ndx]; + + /* This might look like a simple copy operation but it's + not. There are zero- and sign-extensions going on. */ +#define COPY(name) \ + dst->name = src->name + COPY (st_name); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + COPY (st_value); + COPY (st_size); + } + else + { + /* If this is a 64 bit object it's easy. */ + assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym)); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (INVALID_NDX (ndx, GElf_Sym, symdata)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + *dst = ((GElf_Sym *) symdata->d_buf)[ndx]; + } + + /* Now we can store the section index. */ + if (dstshndx != NULL) + *dstshndx = shndx; + + result = dst; + + out: + rwlock_unlock (symdata_scn->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getverdaux.c b/libelf/gelf_getverdaux.c new file mode 100644 index 00000000..739a7657 --- /dev/null +++ b/libelf/gelf_getverdaux.c @@ -0,0 +1,79 @@ +/* Get additional symbol version definition information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Verdaux * +gelf_getverdaux (Elf_Data *data, int offset, GElf_Verdaux *dst) +{ + GElf_Verdaux *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VDEF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Verdaux) > data->d_size) + || unlikely (offset % __alignof__ (GElf_Verdaux) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Verdaux *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verdaux)); + + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getverdef.c b/libelf/gelf_getverdef.c new file mode 100644 index 00000000..651f4fad --- /dev/null +++ b/libelf/gelf_getverdef.c @@ -0,0 +1,78 @@ +/* Get symbol version definition information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Verdef * +gelf_getverdef (Elf_Data *data, int offset, GElf_Verdef *dst) +{ + GElf_Verdef *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VDEF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); + assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Verdef) > data->d_size) + || unlikely (offset % __alignof__ (GElf_Verdef) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Verdef *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verdef)); + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getvernaux.c b/libelf/gelf_getvernaux.c new file mode 100644 index 00000000..e47fb0a2 --- /dev/null +++ b/libelf/gelf_getvernaux.c @@ -0,0 +1,81 @@ +/* Get additional required symbol version information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Vernaux * +gelf_getvernaux (Elf_Data *data, int offset, GElf_Vernaux *dst) +{ + GElf_Vernaux *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VNEED)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. And fortunately the `ElfXXX_Vernaux' records + also have the same size. */ + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Vernaux) > data->d_size) + || unlikely (offset % sizeof (GElf_Vernaux) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Vernaux *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verneed)); + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getverneed.c b/libelf/gelf_getverneed.c new file mode 100644 index 00000000..c1f5d340 --- /dev/null +++ b/libelf/gelf_getverneed.c @@ -0,0 +1,81 @@ +/* Get required symbol version information at the given offset. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Verneed * +gelf_getverneed (Elf_Data *data, int offset, GElf_Verneed *dst) +{ + GElf_Verneed *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_VNEED)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. And fortunately the `ElfXXX_Vernaux' records + also have the same size. */ + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Vernaux)); + + rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (unlikely (offset < 0) + || unlikely (offset + sizeof (GElf_Verneed) > data->d_size) + || unlikely (offset % sizeof (GElf_Verneed) != 0)) + { + __libelf_seterrno (ELF_E_OFFSET_RANGE); + result = NULL; + } + else + result = (GElf_Verneed *) memcpy (dst, (char *) data->d_buf + offset, + sizeof (GElf_Verneed)); + + rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock); + + return result; +} diff --git a/libelf/gelf_getversym.c b/libelf/gelf_getversym.c new file mode 100644 index 00000000..68d23c72 --- /dev/null +++ b/libelf/gelf_getversym.c @@ -0,0 +1,86 @@ +/* Get symbol version information at the given index. + Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +GElf_Versym * +gelf_getversym (Elf_Data *data, int ndx, GElf_Versym *dst) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + GElf_Versym *result; + + if (data == NULL) + return NULL; + + if (unlikely (data->d_type != ELF_T_HALF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return NULL; + } + + /* This is the one place where we have to take advantage of the fact + that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. + The interface is broken so that it requires this hack. */ + scn = data_scn->s; + + /* It's easy to handle this type. It has the same size for 32 and + 64 bit objects. */ + assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym)); + assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym)); + + rwlock_rdlock (scn->elf->lock); + + /* The data is already in the correct form. Just make sure the + index is OK. */ + if (INVALID_NDX (ndx, GElf_Versym, data)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + } + else + { + *dst = ((GElf_Versym *) data->d_buf)[ndx]; + + result = dst; + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_newehdr.c b/libelf/gelf_newehdr.c new file mode 100644 index 00000000..27889066 --- /dev/null +++ b/libelf/gelf_newehdr.c @@ -0,0 +1,46 @@ +/* Create new ELF header. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +void * +gelf_newehdr (Elf *elf, int class) +{ + return (class == ELFCLASS32 + ? (void *) INTUSE(elf32_newehdr) (elf) + : (void *) INTUSE(elf64_newehdr) (elf)); +} diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c new file mode 100644 index 00000000..84aad781 --- /dev/null +++ b/libelf/gelf_newphdr.c @@ -0,0 +1,46 @@ +/* Create new ELF program header. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +void * +gelf_newphdr ( Elf *elf, size_t phnum) +{ + return (elf->class == ELFCLASS32 + ? (void *) INTUSE(elf32_newphdr) (elf, phnum) + : (void *) INTUSE(elf64_newphdr) (elf, phnum)); +} diff --git a/libelf/gelf_offscn.c b/libelf/gelf_offscn.c new file mode 100644 index 00000000..cf206f5b --- /dev/null +++ b/libelf/gelf_offscn.c @@ -0,0 +1,55 @@ +/* Create new ELF header. + Copyright (C) 2005, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +Elf_Scn * +gelf_offscn (Elf *elf, GElf_Off offset) +{ + if (elf->class == ELFCLASS32) + { + if ((Elf32_Off) offset != offset) + { + __libelf_seterrno (ELF_E_INVALID_OFFSET); + return NULL; + } + + return INTUSE(elf32_offscn) (elf, (Elf32_Off) offset); + } + + return INTUSE(elf64_offscn) (elf, offset); +} diff --git a/libelf/gelf_update_auxv.c b/libelf/gelf_update_auxv.c new file mode 100644 index 00000000..e4e5229c --- /dev/null +++ b/libelf/gelf_update_auxv.c @@ -0,0 +1,111 @@ +/* Update information in dynamic table at the given index. + Copyright (C) 2007, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_auxv (Elf_Data *data, int ndx, GElf_auxv_t *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (ndx < 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_AUXV)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_auxv_t *auxv; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->a_type > 0xffffffffll) + || unlikely (src->a_un.a_val > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + auxv = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx]; + + auxv->a_type = src->a_type; + auxv->a_un.a_val = src->a_un.a_val; + } + else + { + /* Check whether we have to resize the data buffer. */ + if (unlikely ((ndx + 1) * sizeof (Elf64_auxv_t) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_auxv_t *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_dyn.c b/libelf/gelf_update_dyn.c new file mode 100644 index 00000000..5c515d26 --- /dev/null +++ b/libelf/gelf_update_dyn.c @@ -0,0 +1,107 @@ +/* Update information in dynamic table at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_dyn (Elf_Data *data, int ndx, GElf_Dyn *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (data_scn->d.d_type != ELF_T_DYN)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Dyn *dyn; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->d_tag < -0x80000000ll) + || unlikely (src->d_tag > 0x7fffffffll) + || unlikely (src->d_un.d_val > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + dyn = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx]; + + dyn->d_tag = src->d_tag; + dyn->d_un.d_val = src->d_un.d_val; + } + else + { + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf64_Dyn, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Dyn *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_ehdr.c b/libelf/gelf_update_ehdr.c new file mode 100644 index 00000000..73d5af7a --- /dev/null +++ b/libelf/gelf_update_ehdr.c @@ -0,0 +1,118 @@ +/* Update ELF header. + Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_ehdr (Elf *elf, GElf_Ehdr *src) +{ + int result = 0; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + Elf32_Ehdr *ehdr = elf->state.elf32.ehdr; + + if (ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + goto out; + } + + /* We have to convert the data to the 32 bit format. This might + overflow some fields so we have to test for this case before + copying. */ + if (unlikely (src->e_entry > 0xffffffffull) + || unlikely (src->e_phoff > 0xffffffffull) + || unlikely (src->e_shoff > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Copy the data. */ + memcpy (ehdr->e_ident, src->e_ident, EI_NIDENT); +#define COPY(name) \ + ehdr->name = src->name + COPY (e_type); + COPY (e_machine); + COPY (e_version); + COPY (e_entry); + COPY (e_phoff); + COPY (e_shoff); + COPY (e_flags); + COPY (e_ehsize); + COPY (e_phentsize); + COPY (e_phnum); + COPY (e_shentsize); + COPY (e_shnum); + COPY (e_shstrndx); + } + else + { + Elf64_Ehdr *ehdr = elf->state.elf64.ehdr; + + if (ehdr == NULL) + { + __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR); + goto out; + } + + /* Just copy the data. */ + memcpy (ehdr, src, sizeof (Elf64_Ehdr)); + } + + /* Mark the ELF header as modified. */ + elf->state.elf.ehdr_flags |= ELF_F_DIRTY; + + result = 1; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_update_lib.c b/libelf/gelf_update_lib.c new file mode 100644 index 00000000..d0f235e8 --- /dev/null +++ b/libelf/gelf_update_lib.c @@ -0,0 +1,75 @@ +/* Update library in table at the given index. + Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2004. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_lib (Elf_Data *data, int ndx, GElf_Lib *src) +{ + if (data == NULL) + return 0; + + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + if (unlikely (data_scn->d.d_type != ELF_T_LIB)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + Elf_Scn *scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + /* Check whether we have to resize the data buffer. */ + int result = 0; + if (INVALID_NDX (ndx, Elf64_Lib, &data_scn->d)) + __libelf_seterrno (ELF_E_INVALID_INDEX); + else + { + ((Elf64_Lib *) data_scn->d.d_buf)[ndx] = *src; + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + } + + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_move.c b/libelf/gelf_update_move.c new file mode 100644 index 00000000..4190ee30 --- /dev/null +++ b/libelf/gelf_update_move.c @@ -0,0 +1,77 @@ +/* Update move structure at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_move (Elf_Data *data, int ndx, GElf_Move *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Move) == sizeof (Elf32_Move)); + assert (sizeof (GElf_Move) == sizeof (Elf64_Move)); + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, GElf_Move, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_MOVE)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + ((GElf_Move *) data_scn->d.d_buf)[ndx] = *src; + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_phdr.c b/libelf/gelf_update_phdr.c new file mode 100644 index 00000000..a848677f --- /dev/null +++ b/libelf/gelf_update_phdr.c @@ -0,0 +1,143 @@ +/* Update program header program header table entry. + Copyright (C) 2000-2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src) +{ + int result = 0; + + if (elf == NULL) + return 0; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return 0; + } + + rwlock_wrlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + Elf32_Phdr *phdr = elf->state.elf32.phdr; + + /* We have to convert the data to the 32 bit format. This might + overflow some fields so we have to test for this case before + copying. */ + if (unlikely (src->p_offset > 0xffffffffull) + || unlikely (src->p_vaddr > 0xffffffffull) + || unlikely (src->p_paddr > 0xffffffffull) + || unlikely (src->p_filesz > 0xffffffffull) + || unlikely (src->p_memsz > 0xffffffffull) + || unlikely (src->p_align > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + if (phdr == NULL) + { + phdr = __elf32_getphdr_wrlock (elf); + if (phdr == NULL) + /* The error number is already set. */ + goto out; + } + + /* Test whether the index is ok. */ + size_t phnum; + if (ndx >= elf->state.elf32.ehdr->e_phnum + && (elf->state.elf32.ehdr->e_phnum != PN_XNUM + || __elf_getphdrnum_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* Now correct the pointer to point to the correct element. */ + phdr += ndx; + +#define COPY(name) \ + phdr->name = src->name + COPY (p_type); + COPY (p_offset); + COPY (p_vaddr); + COPY (p_paddr); + COPY (p_filesz); + COPY (p_memsz); + COPY (p_flags); + COPY (p_align); + } + else + { + Elf64_Phdr *phdr = elf->state.elf64.phdr; + + if (phdr == NULL) + { + phdr = __elf64_getphdr_wrlock (elf); + if (phdr == NULL) + /* The error number is already set. */ + goto out; + } + + /* Test whether the index is ok. */ + size_t phnum; + if (ndx >= elf->state.elf64.ehdr->e_phnum + && (elf->state.elf64.ehdr->e_phnum != PN_XNUM + || __elf_getphdrnum_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + /* Just copy the data. */ + memcpy (phdr + ndx, src, sizeof (Elf64_Phdr)); + } + + /* Mark the program header as modified. */ + elf->state.elf.phdr_flags |= ELF_F_DIRTY; + + result = 1; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_update_rel.c b/libelf/gelf_update_rel.c new file mode 100644 index 00000000..14f62e97 --- /dev/null +++ b/libelf/gelf_update_rel.c @@ -0,0 +1,108 @@ +/* Update REL relocation information at given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_rel (Elf_Data *dst, int ndx, GElf_Rel *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst; + Elf_Scn *scn; + int result = 0; + + if (dst == NULL) + return 0; + + if (unlikely (data_scn->d.d_type != ELF_T_REL)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Rel *rel; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->r_offset > 0xffffffffull) + || unlikely (GELF_R_SYM (src->r_info) > 0xffffff) + || unlikely (GELF_R_TYPE (src->r_info) > 0xff)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + rel = &((Elf32_Rel *) data_scn->d.d_buf)[ndx]; + + rel->r_offset = src->r_offset; + rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), + GELF_R_TYPE (src->r_info)); + } + else + { + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Rel *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_rela.c b/libelf/gelf_update_rela.c new file mode 100644 index 00000000..88252703 --- /dev/null +++ b/libelf/gelf_update_rela.c @@ -0,0 +1,111 @@ +/* Update RELA relocation information at given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_rela (Elf_Data *dst, int ndx, GElf_Rela *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst; + Elf_Scn *scn; + int result = 0; + + if (dst == NULL) + return 0; + + if (unlikely (data_scn->d.d_type != ELF_T_RELA)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Rela *rel; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->r_offset > 0xffffffffull) + || unlikely (GELF_R_SYM (src->r_info) > 0xffffff) + || unlikely (GELF_R_TYPE (src->r_info) > 0xff) + || unlikely (src->r_addend < -0x80000000ll) + || unlikely (src->r_addend > 0x7fffffffll)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + rel = &((Elf32_Rela *) data_scn->d.d_buf)[ndx]; + + rel->r_offset = src->r_offset; + rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), + GELF_R_TYPE (src->r_info)); + rel->r_addend = src->r_addend; + } + else + { + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Rela *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_shdr.c b/libelf/gelf_update_shdr.c new file mode 100644 index 00000000..c93c6ec0 --- /dev/null +++ b/libelf/gelf_update_shdr.c @@ -0,0 +1,111 @@ +/* Update section header. + Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +int +gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src) +{ + int result = 0; + Elf *elf; + + if (scn == NULL || src == NULL) + return 0; + + elf = scn->elf; + rwlock_wrlock (elf->lock); + + if (elf->class == ELFCLASS32) + { + Elf32_Shdr *shdr + = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + + if (unlikely (src->sh_flags > 0xffffffffull) + || unlikely (src->sh_addr > 0xffffffffull) + || unlikely (src->sh_offset > 0xffffffffull) + || unlikely (src->sh_size > 0xffffffffull) + || unlikely (src->sh_addralign > 0xffffffffull) + || unlikely (src->sh_entsize > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + +#define COPY(name) \ + shdr->name = src->name + COPY (sh_name); + COPY (sh_type); + COPY (sh_flags); + COPY (sh_addr); + COPY (sh_offset); + COPY (sh_size); + COPY (sh_link); + COPY (sh_info); + COPY (sh_addralign); + COPY (sh_entsize); + } + else + { + Elf64_Shdr *shdr + = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn); + + if (shdr == NULL) + { + __libelf_seterrno (ELF_E_INVALID_OPERAND); + goto out; + } + + /* We only have to copy the data. */ + (void) memcpy (shdr, src, sizeof (GElf_Shdr)); + } + + /* Mark the section header as modified. */ + scn->shdr_flags |= ELF_F_DIRTY; + + result = 1; + + out: + rwlock_unlock (elf->lock); + + return result; +} diff --git a/libelf/gelf_update_sym.c b/libelf/gelf_update_sym.c new file mode 100644 index 00000000..0f478857 --- /dev/null +++ b/libelf/gelf_update_sym.c @@ -0,0 +1,116 @@ +/* Update symbol information in symbol table at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_sym (Elf_Data *data, int ndx, GElf_Sym *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (data_scn->d.d_type != ELF_T_SYM)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Sym *sym; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->st_value > 0xffffffffull) + || unlikely (src->st_size > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf32_Sym, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + sym = &((Elf32_Sym *) data_scn->d.d_buf)[ndx]; + +#define COPY(name) \ + sym->name = src->name + COPY (st_name); + COPY (st_value); + COPY (st_size); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + } + else + { + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf64_Sym, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Sym *) data_scn->d.d_buf)[ndx] = *src; + } + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_syminfo.c b/libelf/gelf_update_syminfo.c new file mode 100644 index 00000000..6f7f3025 --- /dev/null +++ b/libelf/gelf_update_syminfo.c @@ -0,0 +1,83 @@ +/* Update additional symbol information in symbol table at the given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_syminfo (Elf_Data *data, int ndx, GElf_Syminfo *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + Elf_Scn *scn; + int result = 0; + + if (data == NULL) + return 0; + + if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo)); + assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo)); + + scn = data_scn->s; + rwlock_wrlock (scn->elf->lock); + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, GElf_Syminfo, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((GElf_Syminfo *) data_scn->d.d_buf)[ndx] = *src; + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_symshndx.c b/libelf/gelf_update_symshndx.c new file mode 100644 index 00000000..eb80afac --- /dev/null +++ b/libelf/gelf_update_symshndx.c @@ -0,0 +1,145 @@ +/* Update symbol information and section index in symbol table at the + given index. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_symshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx, + GElf_Sym *src, Elf32_Word srcshndx) +{ + Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata; + Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata; + Elf_Scn *scn; + Elf32_Word *shndx = NULL; + int result = 0; + + if (symdata == NULL) + return 0; + + if (unlikely (symdata_scn->d.d_type != ELF_T_SYM)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + scn = symdata_scn->s; + /* We simply have to believe the user that the two sections belong to + the same ELF file. */ + rwlock_wrlock (scn->elf->lock); + + /* The user is not required to pass a data descriptor for an extended + section index table. */ + if (shndxdata_scn != NULL) + { + if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + shndx = &((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx]; + } + /* But if s/he does not the extended sectio index must be zero. */ + else if (unlikely (srcshndx != 0)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + if (scn->elf->class == ELFCLASS32) + { + Elf32_Sym *sym; + + /* There is the possibility that the values in the input are + too large. */ + if (unlikely (src->st_value > 0xffffffffull) + || unlikely (src->st_size > 0xffffffffull)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf32_Sym, &symdata_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + sym = &((Elf32_Sym *) symdata_scn->d.d_buf)[ndx]; + +#define COPY(name) \ + sym->name = src->name + COPY (st_name); + COPY (st_value); + COPY (st_size); + /* Please note that we can simply copy the `st_info' element since + the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same + for the 64 bit variant. */ + COPY (st_info); + COPY (st_other); + COPY (st_shndx); + } + else + { + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, Elf64_Sym, &symdata_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + goto out; + } + + ((Elf64_Sym *) symdata_scn->d.d_buf)[ndx] = *src; + } + + /* Now we can store the section index. */ + if (shndx != NULL) + *shndx = srcshndx; + + result = 1; + + /* Mark the section as modified. */ + scn->flags |= ELF_F_DIRTY; + + out: + rwlock_unlock (scn->elf->lock); + + return result; +} diff --git a/libelf/gelf_update_verdaux.c b/libelf/gelf_update_verdaux.c new file mode 100644 index 00000000..f3554fdc --- /dev/null +++ b/libelf/gelf_update_verdaux.c @@ -0,0 +1,78 @@ +/* Update additional symbol version definition information. + Copyright (C) 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_verdaux (Elf_Data *data, int offset, GElf_Verdaux *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Verdaux)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VDEF)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdaux)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_verdef.c b/libelf/gelf_update_verdef.c new file mode 100644 index 00000000..adb5db14 --- /dev/null +++ b/libelf/gelf_update_verdef.c @@ -0,0 +1,78 @@ +/* Update symbol version definition information. + Copyright (C) 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_verdef (Elf_Data *data, int offset, GElf_Verdef *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); + assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Verdef)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VDEF)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdef)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_vernaux.c b/libelf/gelf_update_vernaux.c new file mode 100644 index 00000000..854afabb --- /dev/null +++ b/libelf/gelf_update_vernaux.c @@ -0,0 +1,78 @@ +/* Update additional required symbol version information. + Copyright (C) 2001, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_vernaux (Elf_Data *data, int offset, GElf_Vernaux *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Vernaux)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VNEED)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Vernaux)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_verneed.c b/libelf/gelf_update_verneed.c new file mode 100644 index 00000000..bf5af5a3 --- /dev/null +++ b/libelf/gelf_update_verneed.c @@ -0,0 +1,78 @@ +/* Update required symbol version information. + Copyright (C) 2001, 2002, 201r Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_verneed (Elf_Data *data, int offset, GElf_Verneed *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); + + /* Check whether we have to resize the data buffer. */ + if (unlikely (offset < 0) + || unlikely ((offset + sizeof (GElf_Verneed)) > data_scn->d.d_size)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_VNEED)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verneed)); + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_update_versym.c b/libelf/gelf_update_versym.c new file mode 100644 index 00000000..9949dffb --- /dev/null +++ b/libelf/gelf_update_versym.c @@ -0,0 +1,77 @@ +/* Update symbol version information. + Copyright (C) 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "libelfP.h" + + +int +gelf_update_versym (Elf_Data *data, int ndx, GElf_Versym *src) +{ + Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; + + if (data == NULL) + return 0; + + /* The types for 32 and 64 bit are the same. Lucky us. */ + assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym)); + assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym)); + + /* Check whether we have to resize the data buffer. */ + if (INVALID_NDX (ndx, GElf_Versym, &data_scn->d)) + { + __libelf_seterrno (ELF_E_INVALID_INDEX); + return 0; + } + + if (unlikely (data_scn->d.d_type != ELF_T_HALF)) + { + /* The type of the data better should match. */ + __libelf_seterrno (ELF_E_DATA_MISMATCH); + return 0; + } + + rwlock_wrlock (data_scn->s->elf->lock); + + ((GElf_Versym *) data_scn->d.d_buf)[ndx] = *src; + + /* Mark the section as modified. */ + data_scn->s->flags |= ELF_F_DIRTY; + + rwlock_unlock (data_scn->s->elf->lock); + + return 1; +} diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c new file mode 100644 index 00000000..b9e7fd65 --- /dev/null +++ b/libelf/gelf_xlate.c @@ -0,0 +1,210 @@ +/* Transformation functions for ELF data types. + Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007,2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "libelfP.h" + +#ifndef LIBELFBITS +# define LIBELFBITS 32 +#endif + + +/* Well, what shall I say. Nothing to do here. */ +#define elf_cvt_Byte(dest, src, n) \ + (__builtin_constant_p (n) && (n) == 1 \ + ? (void) (*((char *) (dest)) = *((char *) (src))) \ + : Elf32_cvt_Byte (dest, src, n)) +static void +(elf_cvt_Byte) (void *dest, const void *src, size_t n, + int encode __attribute__ ((unused))) +{ + if (n != 0) + memmove (dest, src, n); +} + + +/* We'll optimize the definition of the conversion functions here a + bit. We need only functions for 16, 32, and 64 bits. The + functions referenced in the table will be aliases for one of these + functions. Which one is decided by the ELFxx_FSZ_type. */ + +#if ALLOW_UNALIGNED + +#define FETCH(Bits, ptr) (*(const uint##Bits##_t *) ptr) +#define STORE(Bits, ptr, val) (*(uint##Bits##_t *) ptr = val) + +#else + +union unaligned + { + uint16_t u16; + uint32_t u32; + uint64_t u64; + } attribute_packed; + +#define FETCH(Bits, ptr) (((const union unaligned *) ptr)->u##Bits) +#define STORE(Bits, ptr, val) (((union unaligned *) ptr)->u##Bits = val) + +#endif + +/* Now define the conversion functions for the basic types. We use here + the fact that file and memory types are the same and that we have the + ELFxx_FSZ_* macros. + + At the same time we define inline functions which we will use to + convert the complex types. */ +#define FUNDAMENTAL(NAME, Name, Bits) \ + INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name)) +#define INLINE2(Bytes, FName, TName) \ + INLINE3 (Bytes, FName, TName) +#define INLINE3(Bytes, FName, TName) \ + static inline void FName##1 (void *dest, const void *ptr) \ + { \ + switch (Bytes) \ + { \ + case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break; \ + case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break; \ + case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break; \ + default: \ + abort (); \ + } \ + } \ + \ + static void FName (void *dest, const void *ptr, size_t len, \ + int encode __attribute__ ((unused))) \ + { \ + size_t n = len / sizeof (TName); \ + if (dest < ptr) \ + while (n-- > 0) \ + { \ + FName##1 (dest, ptr); \ + dest += Bytes; \ + ptr += Bytes; \ + } \ + else \ + { \ + dest += len; \ + ptr += len; \ + while (n-- > 0) \ + { \ + ptr -= Bytes; \ + dest -= Bytes; \ + FName##1 (dest, ptr); \ + } \ + } \ + } + + +/* Now the tricky part: define the transformation functions for the + complex types. We will use the definitions of the types in + abstract.h. */ +#define START(Bits, Name, EName) \ + static void \ + ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len, \ + int encode __attribute__ ((unused))) \ + { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest; \ + ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src; \ + size_t n; \ + for (n = len / sizeof (ElfW2(Bits, Name)); n > 0; ++tdest, ++tsrc, --n) { +#define END(Bits, Name) } } +#define TYPE_EXTRA(Code) +#define TYPE_XLATE(Code) Code +#define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name) +#define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name); +#define TYPE(Name, Bits) TYPE2 (Name, Bits) +#define TYPE2(Name, Bits) TYPE3 (Name##Bits) +#define TYPE3(Name) Name (cvt_) + +/* Signal that we are generating conversion functions. */ +#define GENERATE_CONVERSION + +/* First generate the 32-bit conversion functions. */ +#define LIBELFBITS 32 +#include "gelf_xlate.h" + +/* Now generate the 64-bit conversion functions. */ +#define LIBELFBITS 64 +#include "gelf_xlate.h" + + +/* We have a few functions which we must create by hand since the sections + do not contain records of only one type. */ +#include "version_xlate.h" +#include "gnuhash_xlate.h" +#include "note_xlate.h" +#include "chdr_xlate.h" + + +/* Now the externally visible table with the function pointers. */ +const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] = +{ + [ELFCLASS32 - 1] = { +#define define_xfcts(Bits) \ + [ELF_T_BYTE] = elf_cvt_Byte, \ + [ELF_T_ADDR] = ElfW2(Bits, cvt_Addr), \ + [ELF_T_DYN] = ElfW2(Bits, cvt_Dyn), \ + [ELF_T_EHDR] = ElfW2(Bits, cvt_Ehdr), \ + [ELF_T_HALF] = ElfW2(Bits, cvt_Half), \ + [ELF_T_OFF] = ElfW2(Bits, cvt_Off), \ + [ELF_T_PHDR] = ElfW2(Bits, cvt_Phdr), \ + [ELF_T_RELA] = ElfW2(Bits, cvt_Rela), \ + [ELF_T_REL] = ElfW2(Bits, cvt_Rel), \ + [ELF_T_SHDR] = ElfW2(Bits, cvt_Shdr), \ + [ELF_T_SWORD] = ElfW2(Bits, cvt_Sword), \ + [ELF_T_SYM] = ElfW2(Bits, cvt_Sym), \ + [ELF_T_WORD] = ElfW2(Bits, cvt_Word), \ + [ELF_T_XWORD] = ElfW2(Bits, cvt_Xword), \ + [ELF_T_SXWORD] = ElfW2(Bits, cvt_Sxword), \ + [ELF_T_VDEF] = elf_cvt_Verdef, \ + [ELF_T_VDAUX] = elf_cvt_Verdef, \ + [ELF_T_VNEED] = elf_cvt_Verneed, \ + [ELF_T_VNAUX] = elf_cvt_Verneed, \ + [ELF_T_NHDR] = elf_cvt_note4, \ + [ELF_T_NHDR8] = elf_cvt_note8, \ + [ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo), \ + [ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \ + [ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \ + [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t), \ + [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr) + define_xfcts (32), + [ELF_T_GNUHASH] = Elf32_cvt_Word + }, + [ELFCLASS64 - 1] = { + define_xfcts (64), + [ELF_T_GNUHASH] = elf_cvt_gnuhash + } +}; diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h new file mode 100644 index 00000000..3c0e4bf6 --- /dev/null +++ b/libelf/gelf_xlate.h @@ -0,0 +1,57 @@ +/* Helper file for type conversion function generation. + Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + + +/* Simple types. */ +FUNDAMENTAL (ADDR, Addr, LIBELFBITS); +FUNDAMENTAL (OFF, Off, LIBELFBITS); +FUNDAMENTAL (HALF, Half, LIBELFBITS); +FUNDAMENTAL (WORD, Word, LIBELFBITS); +FUNDAMENTAL (SWORD, Sword, LIBELFBITS); +FUNDAMENTAL (XWORD, Xword, LIBELFBITS); +FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS); + +/* The structured types. */ +TYPE (Ehdr, LIBELFBITS) +TYPE (Phdr, LIBELFBITS) +TYPE (Shdr, LIBELFBITS) +TYPE (Sym, LIBELFBITS) +TYPE (Rel, LIBELFBITS) +TYPE (Rela, LIBELFBITS) +TYPE (Note, LIBELFBITS) +TYPE (Dyn, LIBELFBITS) +TYPE (Syminfo, LIBELFBITS) +TYPE (Move, LIBELFBITS) +TYPE (Lib, LIBELFBITS) +TYPE (auxv_t, LIBELFBITS) +TYPE (Chdr, LIBELFBITS) + + +/* Prepare for the next round. */ +#undef LIBELFBITS diff --git a/libelf/gelf_xlatetof.c b/libelf/gelf_xlatetof.c new file mode 100644 index 00000000..e2661805 --- /dev/null +++ b/libelf/gelf_xlatetof.c @@ -0,0 +1,50 @@ +/* Convert from memory to file representation. Generic ELF version. + Copyright (C) 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +Elf_Data * +gelf_xlatetof (Elf *elf, Elf_Data *dest, const Elf_Data * src, + unsigned int encode) +{ + if (elf == NULL) + return NULL; + + return (elf->class == ELFCLASS32 + ? INTUSE(elf32_xlatetof) (dest, src, encode) + : INTUSE(elf64_xlatetof) (dest, src, encode)); +} diff --git a/libelf/gelf_xlatetom.c b/libelf/gelf_xlatetom.c new file mode 100644 index 00000000..8499c711 --- /dev/null +++ b/libelf/gelf_xlatetom.c @@ -0,0 +1,50 @@ +/* Convert from file to memory representation. Generic ELF version. + Copyright (C) 2000, 2002, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "libelfP.h" + + +Elf_Data * +gelf_xlatetom (Elf *elf, Elf_Data *dest, const Elf_Data * src, + unsigned int encode) +{ + if (elf == NULL) + return NULL; + + return (elf->class == ELFCLASS32 + ? INTUSE(elf32_xlatetom) (dest, src, encode) + : INTUSE(elf64_xlatetom) (dest, src, encode)); +} diff --git a/libelf/gnuhash_xlate.h b/libelf/gnuhash_xlate.h new file mode 100644 index 00000000..6faf1136 --- /dev/null +++ b/libelf/gnuhash_xlate.h @@ -0,0 +1,74 @@ +/* Conversion functions for versioning information. + Copyright (C) 2006, 2007 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2006. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include + +#include "libelfP.h" + + +static void +elf_cvt_gnuhash (void *dest, const void *src, size_t len, int encode) +{ + /* The GNU hash table format on 64 bit machines mixes 32 bit and 64 bit + words. We must detangle them here. */ + Elf32_Word *dest32 = dest; + const Elf32_Word *src32 = src; + + /* First four control words, 32 bits. */ + for (unsigned int cnt = 0; cnt < 4; ++cnt) + { + if (len < 4) + return; + dest32[cnt] = bswap_32 (src32[cnt]); + len -= 4; + } + + Elf32_Word bitmask_words = encode ? src32[2] : dest32[2]; + + /* Now the 64 bit words. */ + Elf64_Xword *dest64 = (Elf64_Xword *) &dest32[4]; + const Elf64_Xword *src64 = (const Elf64_Xword *) &src32[4]; + for (unsigned int cnt = 0; cnt < bitmask_words; ++cnt) + { + if (len < 8) + return; + dest64[cnt] = bswap_64 (src64[cnt]); + len -= 8; + } + + /* The rest are 32 bit words again. */ + src32 = (const Elf32_Word *) &src64[bitmask_words]; + dest32 = (Elf32_Word *) &dest64[bitmask_words]; + while (len >= 4) + { + *dest32++ = bswap_32 (*src32++); + len -= 4; + } +} diff --git a/libelf/libelf.h b/libelf/libelf.h new file mode 100644 index 00000000..a139e733 --- /dev/null +++ b/libelf/libelf.h @@ -0,0 +1,522 @@ +/* Interface for libelf. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBELF_H +#define _LIBELF_H 1 + +#include +#include + +/* Get the ELF types. */ +#include + +#ifndef SHF_COMPRESSED + /* Older glibc elf.h might not yet define the ELF compression types. */ + #define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ + + /* Section compression header. Used when SHF_COMPRESSED is set. */ + + typedef struct + { + Elf32_Word ch_type; /* Compression format. */ + Elf32_Word ch_size; /* Uncompressed data size. */ + Elf32_Word ch_addralign; /* Uncompressed data alignment. */ + } Elf32_Chdr; + + typedef struct + { + Elf64_Word ch_type; /* Compression format. */ + Elf64_Word ch_reserved; + Elf64_Xword ch_size; /* Uncompressed data size. */ + Elf64_Xword ch_addralign; /* Uncompressed data alignment. */ + } Elf64_Chdr; + + /* Legal values for ch_type (compression algorithm). */ + #define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */ + #define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */ + #define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */ + #define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */ + #define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */ +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__))) +# define __deprecated_attribute__ __attribute__ ((__deprecated__)) +# define __pure_attribute__ __attribute__ ((__pure__)) +# define __const_attribute__ __attribute__ ((__const__)) +#else +# define __nonnull_attribute__(...) +# define __deprecated_attribute__ +# define __pure_attribute__ +# define __const_attribute__ +#endif + +#if __GNUC__ < 4 +#define __noreturn_attribute__ +#else +#define __noreturn_attribute__ __attribute__ ((noreturn)) +#endif + +#ifdef __GNUC_STDC_INLINE__ +# define __libdw_extern_inline extern __inline __attribute__ ((__gnu_inline__)) +#else +# define __libdw_extern_inline extern __inline +#endif + +/* Known translation types. */ +typedef enum +{ + ELF_T_BYTE, /* unsigned char */ + ELF_T_ADDR, /* Elf32_Addr, Elf64_Addr, ... */ + ELF_T_DYN, /* Dynamic section record. */ + ELF_T_EHDR, /* ELF header. */ + ELF_T_HALF, /* Elf32_Half, Elf64_Half, ... */ + ELF_T_OFF, /* Elf32_Off, Elf64_Off, ... */ + ELF_T_PHDR, /* Program header. */ + ELF_T_RELA, /* Relocation entry with addend. */ + ELF_T_REL, /* Relocation entry. */ + ELF_T_SHDR, /* Section header. */ + ELF_T_SWORD, /* Elf32_Sword, Elf64_Sword, ... */ + ELF_T_SYM, /* Symbol record. */ + ELF_T_WORD, /* Elf32_Word, Elf64_Word, ... */ + ELF_T_XWORD, /* Elf32_Xword, Elf64_Xword, ... */ + ELF_T_SXWORD, /* Elf32_Sxword, Elf64_Sxword, ... */ + ELF_T_VDEF, /* Elf32_Verdef, Elf64_Verdef, ... */ + ELF_T_VDAUX, /* Elf32_Verdaux, Elf64_Verdaux, ... */ + ELF_T_VNEED, /* Elf32_Verneed, Elf64_Verneed, ... */ + ELF_T_VNAUX, /* Elf32_Vernaux, Elf64_Vernaux, ... */ + ELF_T_NHDR, /* Elf32_Nhdr, Elf64_Nhdr, ... */ + ELF_T_SYMINFO, /* Elf32_Syminfo, Elf64_Syminfo, ... */ + ELF_T_MOVE, /* Elf32_Move, Elf64_Move, ... */ + ELF_T_LIB, /* Elf32_Lib, Elf64_Lib, ... */ + ELF_T_GNUHASH, /* GNU-style hash section. */ + ELF_T_AUXV, /* Elf32_auxv_t, Elf64_auxv_t, ... */ + ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */ + ELF_T_NHDR8, /* Special GNU Properties note. Same as Nhdr, + except padding. */ + /* Keep this the last entry. */ + ELF_T_NUM +} Elf_Type; + +/* Descriptor for data to be converted to or from memory format. */ +typedef struct +{ + void *d_buf; /* Pointer to the actual data. */ + Elf_Type d_type; /* Type of this piece of data. */ + unsigned int d_version; /* ELF version. */ + size_t d_size; /* Size in bytes. */ + int64_t d_off; /* Offset into section. */ + size_t d_align; /* Alignment in section. */ +} Elf_Data; + + +/* Commands for `...'. */ +typedef enum +{ + ELF_C_NULL, /* Nothing, terminate, or compute only. */ + ELF_C_READ, /* Read .. */ + ELF_C_RDWR, /* Read and write .. */ + ELF_C_WRITE, /* Write .. */ + ELF_C_CLR, /* Clear flag. */ + ELF_C_SET, /* Set flag. */ + ELF_C_FDDONE, /* Signal that file descriptor will not be + used anymore. */ + ELF_C_FDREAD, /* Read rest of data so that file descriptor + is not used anymore. */ + /* The following are extensions. */ + ELF_C_READ_MMAP, /* Read, but mmap the file if possible. */ + ELF_C_RDWR_MMAP, /* Read and write, with mmap. */ + ELF_C_WRITE_MMAP, /* Write, with mmap. */ + ELF_C_READ_MMAP_PRIVATE, /* Read, but memory is writable, results are + not written to the file. */ + ELF_C_EMPTY, /* Copy basic file data but not the content. */ + /* Keep this the last entry. */ + ELF_C_NUM +} Elf_Cmd; + + +/* Flags for the ELF structures. */ +enum +{ + ELF_F_DIRTY = 0x1, +#define ELF_F_DIRTY ELF_F_DIRTY + ELF_F_LAYOUT = 0x4, +#define ELF_F_LAYOUT ELF_F_LAYOUT + ELF_F_PERMISSIVE = 0x8 +#define ELF_F_PERMISSIVE ELF_F_PERMISSIVE +}; + +/* Flags for elf_compress[_gnu]. */ +enum +{ + ELF_CHF_FORCE = 0x1 +#define ELF_CHF_FORCE ELF_CHF_FORCE +}; + +/* Identification values for recognized object files. */ +typedef enum +{ + ELF_K_NONE, /* Unknown. */ + ELF_K_AR, /* Archive. */ + ELF_K_COFF, /* Stupid old COFF. */ + ELF_K_ELF, /* ELF file. */ + /* Keep this the last entry. */ + ELF_K_NUM +} Elf_Kind; + + +/* Archive member header. */ +typedef struct +{ + char *ar_name; /* Name of archive member. */ + time_t ar_date; /* File date. */ + uid_t ar_uid; /* User ID. */ + gid_t ar_gid; /* Group ID. */ + mode_t ar_mode; /* File mode. */ + int64_t ar_size; /* File size. */ + char *ar_rawname; /* Original name of archive member. */ +} Elf_Arhdr; + + +/* Archive symbol table entry. */ +typedef struct +{ + char *as_name; /* Symbol name. */ + size_t as_off; /* Offset for this file in the archive. */ + unsigned long int as_hash; /* Hash value of the name. */ +} Elf_Arsym; + + +/* Descriptor for the ELF file. */ +typedef struct Elf Elf; + +/* Descriptor for ELF file section. */ +typedef struct Elf_Scn Elf_Scn; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return descriptor for ELF file to work according to CMD. */ +extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref); + +/* Create a clone of an existing ELF descriptor. */ + extern Elf *elf_clone (Elf *__elf, Elf_Cmd __cmd); + +/* Create descriptor for memory region. */ +extern Elf *elf_memory (char *__image, size_t __size); + +/* Advance archive descriptor to next element. */ +extern Elf_Cmd elf_next (Elf *__elf); + +/* Free resources allocated for ELF. */ +extern int elf_end (Elf *__elf); + +/* Update ELF descriptor and write file to disk. */ +extern int64_t elf_update (Elf *__elf, Elf_Cmd __cmd); + +/* Determine what kind of file is associated with ELF. */ +extern Elf_Kind elf_kind (Elf *__elf) __pure_attribute__; + +/* Get the base offset for an object file. */ +extern int64_t elf_getbase (Elf *__elf); + + +/* Retrieve file identification data. */ +extern char *elf_getident (Elf *__elf, size_t *__nbytes); + +/* Retrieve class-dependent object file header. */ +extern Elf32_Ehdr *elf32_getehdr (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Ehdr *elf64_getehdr (Elf *__elf); + +/* Create ELF header if none exists. */ +extern Elf32_Ehdr *elf32_newehdr (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Ehdr *elf64_newehdr (Elf *__elf); + +/* Get the number of program headers in the ELF file. If the file uses + more headers than can be represented in the e_phnum field of the ELF + header the information from the sh_info field in the zeroth section + header is used. */ +extern int elf_getphdrnum (Elf *__elf, size_t *__dst); + +/* Retrieve class-dependent program header table. */ +extern Elf32_Phdr *elf32_getphdr (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Phdr *elf64_getphdr (Elf *__elf); + +/* Create ELF program header. */ +extern Elf32_Phdr *elf32_newphdr (Elf *__elf, size_t __cnt); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern Elf64_Phdr *elf64_newphdr (Elf *__elf, size_t __cnt); + + +/* Get section at INDEX. */ +extern Elf_Scn *elf_getscn (Elf *__elf, size_t __index); + +/* Get section at OFFSET. */ +extern Elf_Scn *elf32_offscn (Elf *__elf, Elf32_Off __offset); +/* Similar bug this time the binary calls is ELFCLASS64. */ +extern Elf_Scn *elf64_offscn (Elf *__elf, Elf64_Off __offset); + +/* Get index of section. */ +extern size_t elf_ndxscn (Elf_Scn *__scn); + +/* Get section with next section index. */ +extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn); + +/* Create a new section and append it at the end of the table. */ +extern Elf_Scn *elf_newscn (Elf *__elf); + +/* Get the section index of the extended section index table for the + given symbol table. */ +extern int elf_scnshndx (Elf_Scn *__scn); + +/* Get the number of sections in the ELF file. If the file uses more + sections than can be represented in the e_shnum field of the ELF + header the information from the sh_size field in the zeroth section + header is used. */ +extern int elf_getshdrnum (Elf *__elf, size_t *__dst); +/* Sun messed up the implementation of 'elf_getshnum' in their implementation. + It was agreed to make the same functionality available under a different + name and obsolete the old name. */ +extern int elf_getshnum (Elf *__elf, size_t *__dst) + __deprecated_attribute__; + + +/* Get the section index of the section header string table in the ELF + file. If the index cannot be represented in the e_shstrndx field of + the ELF header the information from the sh_link field in the zeroth + section header is used. */ +extern int elf_getshdrstrndx (Elf *__elf, size_t *__dst); +/* Sun messed up the implementation of 'elf_getshstrndx' in their + implementation. It was agreed to make the same functionality available + under a different name and obsolete the old name. */ +extern int elf_getshstrndx (Elf *__elf, size_t *__dst) + __deprecated_attribute__; + + +/* Retrieve section header of ELFCLASS32 binary. */ +extern Elf32_Shdr *elf32_getshdr (Elf_Scn *__scn); +/* Similar for ELFCLASS64. */ +extern Elf64_Shdr *elf64_getshdr (Elf_Scn *__scn); + +/* Returns compression header for a section if section data is + compressed. Returns NULL and sets elf_errno if the section isn't + compressed or an error occurred. */ +extern Elf32_Chdr *elf32_getchdr (Elf_Scn *__scn); +extern Elf64_Chdr *elf64_getchdr (Elf_Scn *__scn); + +/* Compress or decompress the data of a section and adjust the section + header. + + elf_compress works by setting or clearing the SHF_COMPRESS flag + from the section Shdr and will encode or decode a Elf32_Chdr or + Elf64_Chdr at the start of the section data. elf_compress_gnu will + encode or decode any section, but is traditionally only used for + sections that have a name starting with ".debug" when + uncompressed or ".zdebug" when compressed and stores just the + uncompressed size. The GNU compression method is deprecated and + should only be used for legacy support. + + elf_compress takes a compression type that should be either zero to + decompress or an ELFCOMPRESS algorithm to use for compression. + Currently only ELFCOMPRESS_ZLIB is supported. elf_compress_gnu + will compress in the traditional GNU compression format when + compress is one and decompress the section data when compress is + zero. + + The FLAGS argument can be zero or ELF_CHF_FORCE. If FLAGS contains + ELF_CHF_FORCE then it will always compress the section, even if + that would not reduce the size of the data section (including the + header). Otherwise elf_compress and elf_compress_gnu will compress + the section only if the total data size is reduced. + + On successful compression or decompression the function returns + one. If (not forced) compression is requested and the data section + would not actually reduce in size, the section is not actually + compressed and zero is returned. Otherwise -1 is returned and + elf_errno is set. + + It is an error to request compression for a section that already + has SHF_COMPRESSED set, or (for elf_compress) to request + decompression for an section that doesn't have SHF_COMPRESSED set. + If a section has SHF_COMPRESSED set then calling elf_compress_gnu + will result in an error. The section has to be decompressed first + using elf_compress. Calling elf_compress on a section compressed + with elf_compress_gnu is fine, but probably useless. + + It is always an error to call these functions on SHT_NOBITS + sections or if the section has the SHF_ALLOC flag set. + elf_compress_gnu will not check whether the section name starts + with ".debug" or .zdebug". It is the responsibility of the caller + to make sure the deprecated GNU compression method is only called + on correctly named sections (and to change the name of the section + when using elf_compress_gnu). + + All previous returned Shdrs and Elf_Data buffers are invalidated by + this call and should no longer be accessed. + + Note that although this changes the header and data returned it + doesn't mark the section as dirty. To keep the changes when + calling elf_update the section has to be flagged ELF_F_DIRTY. */ +extern int elf_compress (Elf_Scn *scn, int type, unsigned int flags); +extern int elf_compress_gnu (Elf_Scn *scn, int compress, unsigned int flags); + +/* Set or clear flags for ELF file. */ +extern unsigned int elf_flagelf (Elf *__elf, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the ELF header. */ +extern unsigned int elf_flagehdr (Elf *__elf, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the ELF program header. */ +extern unsigned int elf_flagphdr (Elf *__elf, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the given ELF section. */ +extern unsigned int elf_flagscn (Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the given ELF data. */ +extern unsigned int elf_flagdata (Elf_Data *__data, Elf_Cmd __cmd, + unsigned int __flags); +/* Similarly for the given ELF section header. */ +extern unsigned int elf_flagshdr (Elf_Scn *__scn, Elf_Cmd __cmd, + unsigned int __flags); + + +/* Get data from section while translating from file representation to + memory representation. The Elf_Data d_type is set based on the + section type if known. Otherwise d_type is set to ELF_T_BYTE. If + the section contains compressed data then d_type is always set to + ELF_T_CHDR. */ +extern Elf_Data *elf_getdata (Elf_Scn *__scn, Elf_Data *__data); + +/* Get uninterpreted section content. */ +extern Elf_Data *elf_rawdata (Elf_Scn *__scn, Elf_Data *__data); + +/* Create new data descriptor for section SCN. */ +extern Elf_Data *elf_newdata (Elf_Scn *__scn); + +/* Get data translated from a chunk of the file contents as section data + would be for TYPE. The resulting Elf_Data pointer is valid until + elf_end (ELF) is called. */ +extern Elf_Data *elf_getdata_rawchunk (Elf *__elf, + int64_t __offset, size_t __size, + Elf_Type __type); + + +/* Return pointer to string at OFFSET in section INDEX. */ +extern char *elf_strptr (Elf *__elf, size_t __index, size_t __offset); + + +/* Return header of archive. */ +extern Elf_Arhdr *elf_getarhdr (Elf *__elf); + +/* Return offset in archive for current file ELF. */ +extern int64_t elf_getaroff (Elf *__elf); + +/* Select archive element at OFFSET. */ +extern size_t elf_rand (Elf *__elf, size_t __offset); + +/* Get symbol table of archive. */ +extern Elf_Arsym *elf_getarsym (Elf *__elf, size_t *__narsyms); + + +/* Control ELF descriptor. */ +extern int elf_cntl (Elf *__elf, Elf_Cmd __cmd); + +/* Retrieve uninterpreted file contents. */ +extern char *elf_rawfile (Elf *__elf, size_t *__nbytes); + + +/* Return size of array of COUNT elements of the type denoted by TYPE + in the external representation. The binary class is taken from ELF. + The result is based on version VERSION of the ELF standard. */ +extern size_t elf32_fsize (Elf_Type __type, size_t __count, + unsigned int __version) + __const_attribute__; +/* Similar but this time the binary calls is ELFCLASS64. */ +extern size_t elf64_fsize (Elf_Type __type, size_t __count, + unsigned int __version) + __const_attribute__; + + +/* Convert data structure from the representation in the file represented + by ELF to their memory representation. */ +extern Elf_Data *elf32_xlatetom (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); +/* Same for 64 bit class. */ +extern Elf_Data *elf64_xlatetom (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); + +/* Convert data structure from to the representation in memory + represented by ELF file representation. */ +extern Elf_Data *elf32_xlatetof (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); +/* Same for 64 bit class. */ +extern Elf_Data *elf64_xlatetof (Elf_Data *__dest, const Elf_Data *__src, + unsigned int __encode); + + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int elf_errno (void); + +/* Return error string for ERROR. If ERROR is zero, return error string + for most recent error or NULL is none occurred. If ERROR is -1 the + behaviour is similar to the last case except that not NULL but a legal + string is returned. */ +extern const char *elf_errmsg (int __error); + + +/* Coordinate ELF library and application versions. */ +extern unsigned int elf_version (unsigned int __version); + +/* Set fill bytes used to fill holes in data structures. */ +extern void elf_fill (int __fill); + +/* Compute hash value. */ +extern unsigned long int elf_hash (const char *__string) + __pure_attribute__; + +/* Compute hash value using the GNU-specific hash function. */ +extern unsigned long int elf_gnu_hash (const char *__string) + __pure_attribute__; + + +/* Compute simple checksum from permanent parts of the ELF file. */ +extern long int elf32_checksum (Elf *__elf); +/* Similar but this time the binary calls is ELFCLASS64. */ +extern long int elf64_checksum (Elf *__elf); + +#ifdef __cplusplus +} +#endif + +#endif /* libelf.h */ diff --git a/libelf/libelf.map b/libelf/libelf.map new file mode 100644 index 00000000..10dc5059 --- /dev/null +++ b/libelf/libelf.map @@ -0,0 +1,150 @@ +ELFUTILS_1.0 { + global: + elf32_checksum; + elf32_fsize; + elf32_getehdr; + elf32_getphdr; + elf32_getshdr; + elf32_newehdr; + elf32_newphdr; + elf32_xlatetof; + elf32_xlatetom; + elf64_checksum; + elf64_fsize; + elf64_getehdr; + elf64_getphdr; + elf64_getshdr; + elf64_newehdr; + elf64_newphdr; + elf64_xlatetof; + elf64_xlatetom; + elf_begin; + elf_clone; + elf_cntl; + elf_end; + elf_errmsg; + elf_errno; + elf_fill; + elf_flagdata; + elf_flagehdr; + elf_flagelf; + elf_flagphdr; + elf_flagscn; + elf_flagshdr; + elf_getarhdr; + elf_getarsym; + elf_getbase; + elf_getdata; + elf_getident; + elf_getscn; + elf_getshnum; + elf_getshstrndx; + elf_hash; + elf_kind; + elf_memory; + elf_ndxscn; + elf_newdata; + elf_newscn; + elf_next; + elf_nextscn; + elf_rand; + elf_rawdata; + elf_rawfile; + elf_scncnt; + elf_strptr; + elf_update; + elf_version; + gelf_checksum; + gelf_fsize; + gelf_getclass; + gelf_getdyn; + gelf_getehdr; + gelf_getmove; + gelf_getphdr; + gelf_getrel; + gelf_getrela; + gelf_getshdr; + gelf_getsym; + gelf_getsyminfo; + gelf_getsymshndx; + gelf_getverdaux; + gelf_getverdef; + gelf_getvernaux; + gelf_getverneed; + gelf_getversym; + gelf_newehdr; + gelf_newphdr; + gelf_update_dyn; + gelf_update_ehdr; + gelf_update_move; + gelf_update_phdr; + gelf_update_rel; + gelf_update_rela; + gelf_update_shdr; + gelf_update_sym; + gelf_update_syminfo; + gelf_update_symshndx; + gelf_update_verdaux; + gelf_update_verdef; + gelf_update_vernaux; + gelf_update_verneed; + gelf_update_versym; + gelf_xlatetof; + gelf_xlatetom; + nlist; + + local: + *; +}; + +ELFUTILS_1.1 { + global: + gelf_getlib; + gelf_update_lib; +} ELFUTILS_1.0; + +ELFUTILS_1.1.1 { + global: + elf32_offscn; + elf64_offscn; + gelf_offscn; + elf_getaroff; +} ELFUTILS_1.1; + +ELFUTILS_1.2 { + global: + elf_gnu_hash; +} ELFUTILS_1.1.1; + +ELFUTILS_1.3 { + global: + elf_getdata_rawchunk; + gelf_getauxv; + gelf_update_auxv; + gelf_getnote; +} ELFUTILS_1.2; + +ELFUTILS_1.4 { + global: + elf_scnshndx; +} ELFUTILS_1.3; + +ELFUTILS_1.5 { + global: + elf_getshdrnum; elf_getshdrstrndx; +} ELFUTILS_1.4; + +ELFUTILS_1.6 { + global: + elf_getphdrnum; +} ELFUTILS_1.5; + +ELFUTILS_1.7 { + global: + elf32_getchdr; + elf64_getchdr; + gelf_getchdr; + + elf_compress; + elf_compress_gnu; +} ELFUTILS_1.6; diff --git a/libelf/libelfP.h b/libelf/libelfP.h new file mode 100644 index 00000000..fc1aebec --- /dev/null +++ b/libelf/libelfP.h @@ -0,0 +1,615 @@ +/* Internal interfaces for libelf. + Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _LIBELFP_H +#define _LIBELFP_H 1 + +#include +#include + +#include +#include +#include +#include +#include + + +/* Helper Macros to write 32 bit and 64 bit functions. */ +#define __elfw2_(Bits, Name) __elf##Bits##_##Name +#define elfw2_(Bits, Name) elf##Bits##_##Name +#define ElfW2_(Bits, Name) Elf##Bits##_##Name +#define ELFW2_(Bits, Name) ELF##Bits##_##Name +#define ELFW_(Name, Bits) Name##Bits +#define __elfw2(Bits, Name) __elfw2_(Bits, Name) +#define elfw2(Bits, Name) elfw2_(Bits, Name) +#define ElfW2(Bits, Name) ElfW2_(Bits, Name) +#define ELFW2(Bits, Name) ELFW2_(Bits, Name) +#define ELFW(Name, Bits) ELFW_(Name, Bits) + + +/* Sizes of the external types, for 32 bits objects. */ +#define ELF32_FSZ_ADDR 4 +#define ELF32_FSZ_OFF 4 +#define ELF32_FSZ_HALF 2 +#define ELF32_FSZ_WORD 4 +#define ELF32_FSZ_SWORD 4 +#define ELF32_FSZ_XWORD 8 +#define ELF32_FSZ_SXWORD 8 + +/* Same for 64 bits objects. */ +#define ELF64_FSZ_ADDR 8 +#define ELF64_FSZ_OFF 8 +#define ELF64_FSZ_HALF 2 +#define ELF64_FSZ_WORD 4 +#define ELF64_FSZ_SWORD 4 +#define ELF64_FSZ_XWORD 8 +#define ELF64_FSZ_SXWORD 8 + + +/* This is an extension of the ELF_F_* enumeration. The values here are + not part of the library interface, they are only used internally. */ +enum +{ + ELF_F_MMAPPED = 0x40, + ELF_F_MALLOCED = 0x80, + ELF_F_FILEDATA = 0x100 +}; + + +/* Get definition of all the external types. */ +#include "exttypes.h" + + +/* Error values. */ +enum +{ + ELF_E_NOERROR = 0, + ELF_E_UNKNOWN_ERROR, + ELF_E_UNKNOWN_VERSION, + ELF_E_UNKNOWN_TYPE, + ELF_E_INVALID_HANDLE, + ELF_E_SOURCE_SIZE, + ELF_E_DEST_SIZE, + ELF_E_INVALID_ENCODING, + ELF_E_NOMEM, + ELF_E_INVALID_FILE, + ELF_E_INVALID_ELF, + ELF_E_INVALID_OP, + ELF_E_NO_VERSION, + ELF_E_INVALID_CMD, + ELF_E_RANGE, + ELF_E_ARCHIVE_FMAG, + ELF_E_INVALID_ARCHIVE, + ELF_E_NO_ARCHIVE, + ELF_E_NO_INDEX, + ELF_E_READ_ERROR, + ELF_E_WRITE_ERROR, + ELF_E_INVALID_CLASS, + ELF_E_INVALID_INDEX, + ELF_E_INVALID_OPERAND, + ELF_E_INVALID_SECTION, + ELF_E_INVALID_COMMAND, + ELF_E_WRONG_ORDER_EHDR, + ELF_E_FD_DISABLED, + ELF_E_FD_MISMATCH, + ELF_E_OFFSET_RANGE, + ELF_E_NOT_NUL_SECTION, + ELF_E_DATA_MISMATCH, + ELF_E_INVALID_SECTION_HEADER, + ELF_E_INVALID_DATA, + ELF_E_DATA_ENCODING, + ELF_E_SECTION_TOO_SMALL, + ELF_E_INVALID_ALIGN, + ELF_E_INVALID_SHENTSIZE, + ELF_E_UPDATE_RO, + ELF_E_NOFILE, + ELF_E_GROUP_NOT_REL, + ELF_E_INVALID_PHDR, + ELF_E_NO_PHDR, + ELF_E_INVALID_OFFSET, + ELF_E_INVALID_SECTION_TYPE, + ELF_E_INVALID_SECTION_FLAGS, + ELF_E_NOT_COMPRESSED, + ELF_E_ALREADY_COMPRESSED, + ELF_E_UNKNOWN_COMPRESSION_TYPE, + ELF_E_COMPRESS_ERROR, + ELF_E_DECOMPRESS_ERROR, + /* Keep this as the last entry. */ + ELF_E_NUM +}; + + +/* The visible `Elf_Data' type is not sufficient for some operations due + to a misdesigned interface. Extend it for internal purposes. */ +typedef struct +{ + Elf_Data d; + Elf_Scn *s; +} Elf_Data_Scn; + + +/* List of `Elf_Data' descriptors. This is what makes up the section + contents. */ +typedef struct Elf_Data_List +{ + /* `data' *must* be the first element in the struct. */ + Elf_Data_Scn data; + struct Elf_Data_List *next; + int flags; +} Elf_Data_List; + + +/* Descriptor for ELF section. */ +struct Elf_Scn +{ + /* We have to distinguish several different situations: + + 1. the section is user created. Therefore there is no file or memory + region to read the data from. Here we have two different subcases: + + a) data was not yet added (before the first `elf_newdata' call) + + b) at least one data set is available + + 2. this is a section from a file/memory region. We have to read the + current content in one data block if we have to. But we don't + read the data until it is necessary. So we have the subcases: + + a) the section in the file has size zero (for whatever reason) + + b) the data of the file is not (yet) read + + c) the data is read and available. + + In addition to this we have different data sets, the raw and the converted + data. This distinction only exists for the data read from the file. + All user-added data set (all but the first when read from the file or + all of them for user-create sections) are the same in both formats. + We don't create the converted data before it is necessary. + + The `data_read' element signals whether data is available in the + raw format. + + If there is data from the file/memory region or if read one data + set is added the `rawdata_list_read' pointer in non-NULL and points + to the last filled data set. `raw_datalist_rear' is therefore NULL + only if there is no data set at all. + + This so far allows to distinguish all but two cases (given that the + `rawdata_list' and `data_list' entries are initialized to zero) is + between not yet loaded data from the file/memory region and a section + with zero size and type ELF_T_BYTE. */ + Elf_Data_List data_list; /* List of data buffers. */ + Elf_Data_List *data_list_rear; /* Pointer to the rear of the data list. */ + + Elf_Data_Scn rawdata; /* Uninterpreted data of the section. */ + + int data_read; /* Nonzero if the section was created by the + user or if the data from the file/memory + is read. */ + int shndx_index; /* Index of the extended section index + table for this symbol table (if this + section is a symbol table). */ + + size_t index; /* Index of this section. */ + struct Elf *elf; /* The underlying ELF file. */ + + union + { + Elf32_Shdr *e32; /* Pointer to 32bit section header. */ + Elf64_Shdr *e64; /* Pointer to 64bit section header. */ + } shdr; + + unsigned int shdr_flags; /* Section header modified? */ + unsigned int flags; /* Section changed in size? + ELF_F_MALLOCED for a Elf_Data_Chunk + dummy_scn means the rawchunks + data.d.d_buf was malloced. For normal + sections it means rawdata_base was + malloced (by elf_compress) even if + the Elf was mmapped. */ + + char *rawdata_base; /* The unmodified data of the section. */ + char *data_base; /* The converted data of the section. */ + + char *zdata_base; /* The uncompressed data of the section. */ + size_t zdata_size; /* If zdata_base != NULL, the size of data. */ + size_t zdata_align; /* If zdata_base != NULL, the addralign. */ + + struct Elf_ScnList *list; /* Pointer to the section list element the + data is in. */ +}; + + +/* List of section. */ +typedef struct Elf_ScnList +{ + unsigned int cnt; /* Number of elements of 'data' used. */ + unsigned int max; /* Number of elements of 'data' allocated. */ + struct Elf_ScnList *next; /* Next block of sections. */ + struct Elf_Scn data[0]; /* Section data. */ +} Elf_ScnList; + + +/* elf_getdata_rawchunk result. */ +typedef struct Elf_Data_Chunk +{ + Elf_Data_Scn data; + union + { + Elf_Scn dummy_scn; + struct Elf_Data_Chunk *next; + }; +} Elf_Data_Chunk; + + +/* The ELF descriptor. */ +struct Elf +{ + /* Address to which the file was mapped. NULL if not mapped. */ + void *map_address; + + /* When created for an archive member this points to the descriptor + for the archive. */ + Elf *parent; + Elf *next; /* Used in list of archive descriptors. */ + + /* What kind of file is underneath (ELF file, archive...). */ + Elf_Kind kind; + + /* Command used to create this descriptor. */ + Elf_Cmd cmd; + + /* The binary class. */ + unsigned int class; + + /* The used file descriptor. -1 if not available anymore. */ + int fildes; + + /* Offset in the archive this file starts or zero. */ + int64_t start_offset; + + /* Size of the file in the archive or the entire file size, or ~0 + for an (yet) unknown size. */ + size_t maximum_size; + + /* Describes the way the memory was allocated and if the dirty bit is + signalled it means that the whole file has to be rewritten since + the layout changed. */ + int flags; + + /* Reference counting for the descriptor. */ + int ref_count; + + /* Lock to handle multithreaded programs. */ + rwlock_define (,lock); + + union + { + struct + { + /* The next fields are only useful when testing for ==/!= NULL. */ + void *ehdr; + void *shdr; + void *phdr; + + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ + Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ + int phdr_flags; /* Flags (dirty|malloc) for program header. */ + int shdr_malloced; /* Nonzero if shdr array was allocated. */ + off_t sizestr_offset; /* Offset of the size string in the parent + if this is an archive member. */ + } elf; + + struct + { + Elf32_Ehdr *ehdr; /* Pointer to the ELF header. This is + never malloced. */ + Elf32_Shdr *shdr; /* Used when reading from a file. */ + Elf32_Phdr *phdr; /* Pointer to the program header array. */ + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ + Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ + int phdr_flags; /* Flags (dirty|malloc) for program header. */ + int shdr_malloced; /* Nonzero if shdr array was allocated. */ + int64_t sizestr_offset; /* Offset of the size string in the parent + if this is an archive member. */ + Elf32_Ehdr ehdr_mem; /* Memory used for ELF header when not + mmaped. */ + char __e32scnspad[sizeof (Elf64_Ehdr) - sizeof (Elf32_Ehdr)]; + + /* The section array. */ + Elf_ScnList scns; + } elf32; + + struct + { + Elf64_Ehdr *ehdr; /* Pointer to the ELF header. This is + never malloced. */ + Elf64_Shdr *shdr; /* Used when reading from a file. */ + Elf64_Phdr *phdr; /* Pointer to the program header array. */ + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ + Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ + int phdr_flags; /* Flags (dirty|malloc) for program header. */ + int shdr_malloced; /* Nonzero if shdr array was allocated. */ + int64_t sizestr_offset; /* Offset of the size string in the parent + if this is an archive member. */ + Elf64_Ehdr ehdr_mem; /* Memory used for ELF header when not + mmaped. */ + + /* The section array. */ + Elf_ScnList scns; + } elf64; + + struct + { + Elf *children; /* List of all descriptors for this archive. */ + Elf_Arsym *ar_sym; /* Symbol table returned by elf_getarsym. */ + size_t ar_sym_num; /* Number of entries in `ar_sym'. */ + char *long_names; /* If no index is available but long names + are used this elements points to the data.*/ + size_t long_names_len; /* Length of the long name table. */ + int64_t offset; /* Offset in file we are currently at. + elf_next() advances this to the next + member of the archive. */ + Elf_Arhdr elf_ar_hdr; /* Structure returned by 'elf_getarhdr'. */ + struct ar_hdr ar_hdr; /* Header read from file. */ + char ar_name[16]; /* NUL terminated ar_name of elf_ar_hdr. */ + char raw_name[17]; /* This is a buffer for the NUL terminated + named raw_name used in the elf_ar_hdr. */ + } ar; + } state; + + /* There absolutely never must be anything following the union. */ +}; + +/* Type of the conversion functions. These functions will convert the + byte order. */ +typedef void (*xfct_t) (void *, const void *, size_t, int); + +/* The table with the function pointers. */ +extern const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] + attribute_hidden; + + +/* Array with sizes of the external types indexed by ELF version, binary + class, and type. */ +extern const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] + attribute_hidden; +/* We often have to access the size for a type in the current version. */ +# define elf_typesize(class,type,n) \ + (__libelf_type_sizes[ELFW(ELFCLASS,class) - 1][type] * n) + +/* The byte value used for filling gaps. */ +extern int __libelf_fill_byte attribute_hidden; + +/* EV_CURRENT if the version was set, EV_NONE otherwise. */ +extern unsigned int __libelf_version attribute_hidden; + +/* Array with alignment requirements of the internal types indexed by + binary class, and type. */ +extern const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] + attribute_hidden; +# define __libelf_type_align(class, type) \ + (__libelf_type_aligns[class - 1][type] ?: 1) + +/* Given an GElf_Ehdr handle and a section type returns the Elf_Data d_type. + Should not be called when SHF_COMPRESSED is set, the d_type should + be ELF_T_BYTE. */ +extern Elf_Type __libelf_data_type (GElf_Ehdr *ehdr, + int sh_type, GElf_Xword align) + internal_function; + + +/* Create Elf descriptor from memory image. */ +extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address, + int64_t offset, size_t maxsize, + Elf_Cmd cmd, Elf *parent) + internal_function; + +/* Set error value. */ +extern void __libelf_seterrno (int value) internal_function; + +/* Get the next archive header. */ +extern int __libelf_next_arhdr_wrlock (Elf *elf) internal_function; + +/* Read all of the file associated with the descriptor. */ +extern char *__libelf_readall (Elf *elf) internal_function; + +/* Read the complete section table and convert the byte order if necessary. */ +extern int __libelf_readsections (Elf *elf) internal_function; + +/* Store the information for the raw data in the `rawdata_list' element. */ +extern int __libelf_set_rawdata (Elf_Scn *scn) internal_function; +extern int __libelf_set_rawdata_wrlock (Elf_Scn *scn) internal_function; + + +/* Helper functions for elf_update. */ +extern int64_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop, + size_t shnum) internal_function; +extern int64_t __elf64_updatenull_wrlock (Elf *elf, int *change_bop, + size_t shnum) internal_function; + +extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum) + internal_function; +extern int __elf64_updatemmap (Elf *elf, int change_bo, size_t shnum) + internal_function; +extern int __elf32_updatefile (Elf *elf, int change_bo, size_t shnum) + internal_function; +extern int __elf64_updatefile (Elf *elf, int change_bo, size_t shnum) + internal_function; + + +/* Alias for exported functions to avoid PLT entries, and + rdlock/wrlock variants of these functions. */ +extern int __elf_end_internal (Elf *__elf) attribute_hidden; +extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref) + attribute_hidden; +extern Elf32_Ehdr *__elf32_getehdr_wrlock (Elf *__elf) internal_function; +extern Elf64_Ehdr *__elf64_getehdr_wrlock (Elf *__elf) internal_function; +extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden; +extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden; +extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden; +extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden; +extern Elf32_Phdr *__elf32_getphdr_wrlock (Elf *__elf) attribute_hidden; +extern Elf64_Phdr *__elf64_getphdr_wrlock (Elf *__elf) attribute_hidden; +extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt) + attribute_hidden; +extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt) + attribute_hidden; +extern Elf_Scn *__elf32_offscn_internal (Elf *__elf, Elf32_Off __offset) + attribute_hidden; +extern Elf_Scn *__elf64_offscn_internal (Elf *__elf, Elf64_Off __offset) + attribute_hidden; +extern int __elf_getphdrnum_rdlock (Elf *__elf, size_t *__dst) + internal_function; +extern int __elf_getphdrnum_chk_rdlock (Elf *__elf, size_t *__dst) + internal_function; +extern int __elf_getshdrnum_rdlock (Elf *__elf, size_t *__dst) + internal_function; +extern int __elf_getshdrstrndx_internal (Elf *__elf, size_t *__dst) + attribute_hidden; +extern Elf32_Shdr *__elf32_getshdr_rdlock (Elf_Scn *__scn) internal_function; +extern Elf64_Shdr *__elf64_getshdr_rdlock (Elf_Scn *__scn) internal_function; +extern Elf32_Shdr *__elf32_getshdr_wrlock (Elf_Scn *__scn) internal_function; +extern Elf64_Shdr *__elf64_getshdr_wrlock (Elf_Scn *__scn) internal_function; +extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index) + attribute_hidden; +extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn) + attribute_hidden; +extern int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden; +extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data) + attribute_hidden; +extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data) + internal_function; +extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data) + attribute_hidden; +/* Should be called to setup first section data element if + data_list_rear is NULL and we know data_read is set and there is + raw data available. Might upgrade the ELF lock from a read to a + write lock. If the lock is already a write lock set wrlocked. */ +extern void __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked) + internal_function; +extern char *__elf_strptr_internal (Elf *__elf, size_t __index, + size_t __offset) attribute_hidden; +extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest, + const Elf_Data *__src, + unsigned int __encode) + attribute_hidden; +extern unsigned int __elf_version_internal (unsigned int __version) + attribute_hidden; +extern unsigned long int __elf_hash_internal (const char *__string) + __attribute__ ((__pure__)) attribute_hidden; +extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden; +extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden; + + +extern GElf_Ehdr *__gelf_getehdr_rdlock (Elf *__elf, GElf_Ehdr *__dest) + internal_function; +extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type, + size_t __count, unsigned int __version) + attribute_hidden; +extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst) + attribute_hidden; +extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx, + GElf_Sym *__dst) attribute_hidden; + + +extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len) + attribute_hidden; + +extern void * __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data, + size_t *orig_size, size_t *orig_addralign, + size_t *size, bool force) + internal_function; + +extern void * __libelf_decompress (void *buf_in, size_t size_in, + size_t size_out) internal_function; +extern void * __libelf_decompress_elf (Elf_Scn *scn, + size_t *size_out, size_t *addralign) + internal_function; + + +extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, + size_t align, Elf_Type type) + internal_function; + + +/* We often have to update a flag iff a value changed. Make this + convenient. */ +#define update_if_changed(var, exp, flag) \ + do { \ + __typeof__ (var) *_var = &(var); \ + __typeof__ (exp) _exp = (exp); \ + if (*_var != _exp) \ + { \ + *_var = _exp; \ + (flag) |= ELF_F_DIRTY; \ + } \ + } while (0) + +/* Align offset to 4 bytes as needed for note name and descriptor data. + This is almost always used, except for GNU Property notes, which use + 8 byte padding... */ +#define NOTE_ALIGN4(n) (((n) + 3) & -4U) + +/* Special note padding rule for GNU Property notes. */ +#define NOTE_ALIGN8(n) (((n) + 7) & -8U) + +/* Convenience macro. */ +#define INVALID_NDX(ndx, type, data) \ + unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx)) + +#endif /* libelfP.h */ diff --git a/libelf/libelf_crc32.c b/libelf/libelf_crc32.c new file mode 100644 index 00000000..1426faf1 --- /dev/null +++ b/libelf/libelf_crc32.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define crc32 attribute_hidden __libelf_crc32 +#define LIB_SYSTEM_H 1 +#include +#include "../lib/crc32.c" diff --git a/libelf/libelf_next_prime.c b/libelf/libelf_next_prime.c new file mode 100644 index 00000000..05229c32 --- /dev/null +++ b/libelf/libelf_next_prime.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2002 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define next_prime attribute_hidden __libelf_next_prime +#include "../lib/next_prime.c" diff --git a/libelf/nlist.c b/libelf/nlist.c new file mode 100644 index 00000000..8593c1de --- /dev/null +++ b/libelf/nlist.c @@ -0,0 +1,246 @@ +/* Extract symbol list from binary. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "libelfP.h" + + +struct hashentry +{ + const char *str; + GElf_Sym sym; +}; +#define TYPE struct hashentry +/* XXX Use a better hash function some day. */ +#define HASHFCT(str, len) INTUSE(elf_hash) (str) +#define COMPARE(p1, p2) strcmp ((p1)->str, (p2)->str) +#define CLASS static +#define PREFIX nlist_ +#define xcalloc(n, m) calloc (n, m) +#define next_prime(s) __libelf_next_prime (s) +#include + + +int +nlist (const char *filename, struct nlist *nl) +{ + int fd; + Elf *elf; + Elf_Scn *scn = NULL; + Elf_Scn *symscn = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = NULL; + Elf_Data *data; + struct nlist_fshash *table; + size_t nsyms; + size_t cnt; + + /* Open the file. */ + fd = open (filename, O_RDONLY); + if (fd == -1) + { + __libelf_seterrno (ELF_E_NOFILE); + goto fail; + } + + /* For compatibility reasons (`nlist' existed before ELF and libelf) + we don't expect the caller to set the ELF version. Do this here + as if it hasn't happened yet. */ + INTUSE(elf_version) (EV_CURRENT); + + /* Now get an ELF descriptor. */ + elf = INTUSE(elf_begin) (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + goto fail_fd; + + /* Find a symbol table. We prefer the real symbol table but if it + does not exist use the dynamic symbol table. */ + while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL) + { + shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem); + if (shdr == NULL) + goto fail_close; + + /* That is what we are looking for. */ + if (shdr->sh_type == SHT_SYMTAB) + { + symscn = scn; + break; + } + + /* Better than nothing. Remember this section. */ + if (shdr->sh_type == SHT_DYNSYM) + symscn = scn; + } + + if (symscn == NULL) + /* We haven't found anything. Fail. */ + goto fail_close; + + /* Re-get the section header in case we found only the dynamic symbol + table. */ + if (scn == NULL) + { + shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem); + if (unlikely (shdr == NULL)) + goto fail_close; + } + /* SHDR->SH_LINK now contains the index of the string section. */ + + /* Get the data for the symbol section. */ + data = INTUSE(elf_getdata) (symscn, NULL); + if (data == NULL) + goto fail_close; + + /* How many symbols are there? */ + nsyms = (shdr->sh_size + / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, EV_CURRENT)); + + /* Create the hash table. */ + table = nlist_fshash_init (nsyms); + if (table == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto fail_close; + } + + /* Iterate over all the symbols in the section. */ + for (cnt = 0; cnt < nsyms; ++cnt) + { + struct hashentry mem; + GElf_Sym *sym; + + /* Get the symbol. */ + sym = INTUSE(gelf_getsym) (data, cnt, &mem.sym); + if (sym == NULL) + goto fail_dealloc; + + /* Get the name of the symbol. */ + mem.str = INTUSE(elf_strptr) (elf, shdr->sh_link, sym->st_name); + if (mem.str == NULL) + goto fail_dealloc; + + /* Don't allow zero-length strings. */ + if (mem.str[0] == '\0') + continue; + + /* And add it to the hash table. Note that we are using the + overwrite version. This will ensure that + a) global symbols are preferred over local symbols since + they are all located at the end + b) if there are multiple local symbols with the same name + the last one is used. + */ + (void) nlist_fshash_overwrite (table, mem.str, 0, &mem); + } + + /* Now it is time to look for the symbols the user asked for. + XXX What is a `null name/null string'? This is what the + standard says terminates the list. Is it a null pointer + or a zero-length string? We test for both... */ + while (nl->n_name != NULL && nl->n_name[0] != '\0') + { + struct hashentry search; + const struct hashentry *found; + + /* Search for a matching entry in the hash table. */ + search.str = nl->n_name; + found = nlist_fshash_find (table, nl->n_name, 0, &search); + + if (found != NULL) + { + /* Found it. */ + nl->n_value = found->sym.st_value; + nl->n_scnum = found->sym.st_shndx; + nl->n_type = GELF_ST_TYPE (found->sym.st_info); + /* XXX What shall we fill in the next fields? */ + nl->n_sclass = 0; + nl->n_numaux = 0; + } + else + { + /* Not there. */ + nl->n_value = 0; + nl->n_scnum = 0; + nl->n_type = 0; + nl->n_sclass = 0; + nl->n_numaux = 0; + } + + /* Next search request. */ + ++nl; + } + + /* Free the resources. */ + nlist_fshash_fini (table); + + /* We do not need the ELF descriptor anymore. */ + (void) INTUSE(elf_end) (elf); + + /* Neither the file descriptor. */ + (void) close (fd); + + return 0; + + fail_dealloc: + nlist_fshash_fini (table); + + fail_close: + /* We do not need the ELF descriptor anymore. */ + (void) INTUSE(elf_end) (elf); + + fail_fd: + /* Neither the file descriptor. */ + (void) close (fd); + + fail: + /* We have to set all entries to zero. */ + while (nl->n_name != NULL && nl->n_name[0] != '\0') + { + nl->n_value = 0; + nl->n_scnum = 0; + nl->n_type = 0; + nl->n_sclass = 0; + nl->n_numaux = 0; + + /* Next entry. */ + ++nl; + } + + return -1; +} diff --git a/libelf/nlist.h b/libelf/nlist.h new file mode 100644 index 00000000..59909182 --- /dev/null +++ b/libelf/nlist.h @@ -0,0 +1,56 @@ +/* Interface for nlist. + Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef _NLIST_H +#define _NLIST_H 1 + + +/* Symbol list type. */ +struct nlist +{ + char *n_name; /* Symbol name. */ + long int n_value; /* Value of symbol. */ + short int n_scnum; /* Section number found in. */ + unsigned short int n_type; /* Type of symbol. */ + char n_sclass; /* Storage class. */ + char n_numaux; /* Number of auxiliary entries. */ +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Get specified entries from file. */ +extern int nlist (__const char *__filename, struct nlist *__nl); + +#ifdef __cplusplus +} +#endif + +#endif /* nlist.h */ diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h new file mode 100644 index 00000000..7e2784b0 --- /dev/null +++ b/libelf/note_xlate.h @@ -0,0 +1,98 @@ +/* Conversion functions for notes. + Copyright (C) 2007, 2009, 2014, 2018 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +static void +elf_cvt_note (void *dest, const void *src, size_t len, int encode, + bool nhdr8) +{ + /* Note that the header is always the same size, but the padding + differs for GNU Property notes. */ + assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); + + while (len >= sizeof (Elf32_Nhdr)) + { + /* Convert the header. */ + (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr), + encode); + const Elf32_Nhdr *n = encode ? src : dest; + + size_t note_len = sizeof *n; + + /* desc needs to be aligned. */ + note_len += n->n_namesz; + note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len); + if (note_len > len || note_len < sizeof *n) + { + /* Header was translated, nothing else. */ + len -= sizeof *n; + src += sizeof *n; + dest += sizeof *n; + break; + } + + /* data as a whole needs to be aligned. */ + note_len += n->n_descsz; + note_len = nhdr8 ? NOTE_ALIGN8 (note_len) : NOTE_ALIGN4 (note_len); + if (note_len > len || note_len < sizeof *n) + { + /* Header was translated, nothing else. */ + len -= sizeof *n; + src += sizeof *n; + dest += sizeof *n; + break; + } + + /* Copy or skip the note data. */ + size_t note_data_len = note_len - sizeof *n; + src += sizeof *n; + dest += sizeof *n; + if (src != dest) + memcpy (dest, src, note_data_len); + + src += note_data_len; + dest += note_data_len; + len -= note_len; + } + + /* Copy over any leftover data unconverted. Probably part of + truncated name/desc data. */ + if (unlikely (len > 0) && src != dest) + memcpy (dest, src, len); +} + +static void +elf_cvt_note4 (void *dest, const void *src, size_t len, int encode) +{ + elf_cvt_note (dest, src, len, encode, false); +} + +static void +elf_cvt_note8 (void *dest, const void *src, size_t len, int encode) +{ + elf_cvt_note (dest, src, len, encode, true); +} diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h new file mode 100644 index 00000000..9fe01c64 --- /dev/null +++ b/libelf/version_xlate.h @@ -0,0 +1,230 @@ +/* Conversion functions for versioning information. + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * 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 + + or both in parallel, as here. + + elfutils 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#include +#include + +#include "libelfP.h" + + +static void +elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode) +{ + /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux. + To recognize them we have to walk the data structure and convert + them one after the other. The ENCODE parameter specifies whether + we are encoding or decoding. When we are encoding we can immediately + use the data in the buffer; if not, we have to decode the data before + using it. */ + size_t def_offset = 0; + GElf_Verdef *ddest; + GElf_Verdef *dsrc; + + /* We rely on the types being all the same size. */ + assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux)); + assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef)); + assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux)); + + if (len == 0) + return; + + /* Below we rely on the next field offsets to be correct, start by + copying over all data as is in case some data isn't translated. + We don't want to leave (undefined) garbage in the dest buffer. */ + memmove (dest, src, len); + + do + { + size_t aux_offset; + GElf_Verdaux *asrc; + + /* Test for correct offset. */ + if (def_offset > len || len - def_offset < sizeof (GElf_Verdef)) + return; + + /* Work the tree from the first record. */ + ddest = (GElf_Verdef *) ((char *) dest + def_offset); + dsrc = (GElf_Verdef *) ((char *) src + def_offset); + + /* Decode first if necessary. */ + if (! encode) + { + ddest->vd_version = bswap_16 (dsrc->vd_version); + ddest->vd_flags = bswap_16 (dsrc->vd_flags); + ddest->vd_ndx = bswap_16 (dsrc->vd_ndx); + ddest->vd_cnt = bswap_16 (dsrc->vd_cnt); + ddest->vd_hash = bswap_32 (dsrc->vd_hash); + ddest->vd_aux = bswap_32 (dsrc->vd_aux); + ddest->vd_next = bswap_32 (dsrc->vd_next); + + aux_offset = def_offset + ddest->vd_aux; + } + else + aux_offset = def_offset + dsrc->vd_aux; + + /* Handle all the auxiliary records belonging to this definition. */ + do + { + GElf_Verdaux *adest; + + /* Test for correct offset. */ + if (aux_offset > len || len - aux_offset < sizeof (GElf_Verdaux)) + return; + + adest = (GElf_Verdaux *) ((char *) dest + aux_offset); + asrc = (GElf_Verdaux *) ((char *) src + aux_offset); + + if (encode) + aux_offset += asrc->vda_next; + + adest->vda_name = bswap_32 (asrc->vda_name); + adest->vda_next = bswap_32 (asrc->vda_next); + + if (! encode) + aux_offset += adest->vda_next; + } + while (asrc->vda_next != 0); + + /* Encode now if necessary. */ + if (encode) + { + def_offset += dsrc->vd_next; + + ddest->vd_version = bswap_16 (dsrc->vd_version); + ddest->vd_flags = bswap_16 (dsrc->vd_flags); + ddest->vd_ndx = bswap_16 (dsrc->vd_ndx); + ddest->vd_cnt = bswap_16 (dsrc->vd_cnt); + ddest->vd_hash = bswap_32 (dsrc->vd_hash); + ddest->vd_aux = bswap_32 (dsrc->vd_aux); + ddest->vd_next = bswap_32 (dsrc->vd_next); + } + else + def_offset += ddest->vd_next; + } + while (dsrc->vd_next != 0); +} + + +static void +elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode) +{ + /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux. + To recognize them we have to walk the data structure and convert + them one after the other. The ENCODE parameter specifies whether + we are encoding or decoding. When we are encoding we can immediately + use the data in the buffer; if not, we have to decode the data before + using it. */ + size_t need_offset = 0; + GElf_Verneed *ndest; + GElf_Verneed *nsrc; + + /* We rely on the types being all the same size. */ + assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux)); + assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed)); + assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux)); + + if (len == 0) + return; + + /* Below we rely on the next field offsets to be correct, start by + copying over all data as is in case some data isn't translated. + We don't want to leave (undefined) garbage in the dest buffer. */ + memmove (dest, src, len); + + do + { + size_t aux_offset; + GElf_Vernaux *asrc; + + /* Test for correct offset. */ + if (need_offset > len || len - need_offset < sizeof (GElf_Verneed)) + return; + + /* Work the tree from the first record. */ + ndest = (GElf_Verneed *) ((char *) dest + need_offset); + nsrc = (GElf_Verneed *) ((char *) src + need_offset); + + /* Decode first if necessary. */ + if (! encode) + { + ndest->vn_version = bswap_16 (nsrc->vn_version); + ndest->vn_cnt = bswap_16 (nsrc->vn_cnt); + ndest->vn_file = bswap_32 (nsrc->vn_file); + ndest->vn_aux = bswap_32 (nsrc->vn_aux); + ndest->vn_next = bswap_32 (nsrc->vn_next); + + aux_offset = need_offset + ndest->vn_aux; + } + else + aux_offset = need_offset + nsrc->vn_aux; + + /* Handle all the auxiliary records belonging to this requirement. */ + do + { + GElf_Vernaux *adest; + + /* Test for correct offset. */ + if (aux_offset > len || len - aux_offset < sizeof (GElf_Vernaux)) + return; + + adest = (GElf_Vernaux *) ((char *) dest + aux_offset); + asrc = (GElf_Vernaux *) ((char *) src + aux_offset); + + if (encode) + aux_offset += asrc->vna_next; + + adest->vna_hash = bswap_32 (asrc->vna_hash); + adest->vna_flags = bswap_16 (asrc->vna_flags); + adest->vna_other = bswap_16 (asrc->vna_other); + adest->vna_name = bswap_32 (asrc->vna_name); + adest->vna_next = bswap_32 (asrc->vna_next); + + if (! encode) + aux_offset += adest->vna_next; + } + while (asrc->vna_next != 0); + + /* Encode now if necessary. */ + if (encode) + { + need_offset += nsrc->vn_next; + + ndest->vn_version = bswap_16 (nsrc->vn_version); + ndest->vn_cnt = bswap_16 (nsrc->vn_cnt); + ndest->vn_file = bswap_32 (nsrc->vn_file); + ndest->vn_aux = bswap_32 (nsrc->vn_aux); + ndest->vn_next = bswap_32 (nsrc->vn_next); + } + else + need_offset += ndest->vn_next; + } + while (nsrc->vn_next != 0); +} diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000..8adc7656 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,556 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX to +# enable support. VERSION may be '11' (for the C++11 standard) or '14' +# (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) diff --git a/m4/biarch.m4 b/m4/biarch.m4 new file mode 100644 index 00000000..c238d8d1 --- /dev/null +++ b/m4/biarch.m4 @@ -0,0 +1,47 @@ +AC_DEFUN([utrace_CC_m32], [dnl +AC_CACHE_CHECK([$CC option for 32-bit word size], utrace_cv_CC_m32, [dnl +save_CC="$CC" +utrace_cv_CC_m32=none +for ut_try in -m32 -m31; do + [CC=`echo "$save_CC" | sed 's/ -m[36][241]//'`" $ut_try"] + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int foo (void) { return 1; }]])], + [utrace_cv_CC_m32=$ut_try]) + test x$utrace_cv_CC_m32 = xnone || break +done +CC="$save_CC"])]) + +AC_DEFUN([utrace_HOST64], [AC_REQUIRE([utrace_CC_m32]) +AS_IF([test x$utrace_cv_CC_m32 != xnone], [dnl +AC_CACHE_CHECK([for 64-bit host], utrace_cv_host64, [dnl +AC_EGREP_CPP([@utrace_host64@], [#include +#if (UINTPTR_MAX > 0xffffffffUL) +@utrace_host64@ +#endif], + utrace_cv_host64=yes, utrace_cv_host64=no)]) +AS_IF([test $utrace_cv_host64 = no], + [utrace_biarch=-m64 utrace_thisarch=$utrace_cv_CC_m32], + [utrace_biarch=$utrace_cv_CC_m32 utrace_thisarch=-m64]) + +biarch_CC=`echo "$CC" | sed "s/ *${utrace_thisarch}//"` +biarch_CC="$biarch_CC $utrace_biarch"])]) + +AC_DEFUN([utrace_BIARCH], [AC_REQUIRE([utrace_HOST64]) +utrace_biarch_forced=no +AC_ARG_WITH([biarch], + AC_HELP_STRING([--with-biarch], + [enable biarch tests despite build problems]), + [AS_IF([test "x$with_biarch" != xno], [utrace_biarch_forced=yes])]) +AS_IF([test $utrace_biarch_forced = yes], [dnl +utrace_cv_cc_biarch=yes +AC_MSG_NOTICE([enabling biarch tests regardless using $biarch_CC])], [dnl +AS_IF([test x$utrace_cv_CC_m32 != xnone], [dnl +AC_CACHE_CHECK([whether $biarch_CC makes executables we can run], + utrace_cv_cc_biarch, [dnl +save_CC="$CC" +CC="$biarch_CC" +AC_RUN_IFELSE([AC_LANG_PROGRAM([], [])], + utrace_cv_cc_biarch=yes, utrace_cv_cc_biarch=no, utrace_cv_cc_biarch=no) +CC="$save_CC"])], [utrace_cv_cc_biarch=no]) +AS_IF([test $utrace_cv_cc_biarch != yes], [dnl +AC_MSG_WARN([not running biarch tests, $biarch_CC does not work])])]) +AM_CONDITIONAL(BIARCH, [test $utrace_cv_cc_biarch = yes])]) diff --git a/m4/gettext.m4 b/m4/gettext.m4 new file mode 100644 index 00000000..4f25a27d --- /dev/null +++ b/m4/gettext.m4 @@ -0,0 +1,386 @@ +# gettext.m4 serial 71 (gettext-0.20.2) +dnl Copyright (C) 1995-2014, 2016, 2018-2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2006, 2008-2010. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL must be one of 'external', 'use-libtool'. +dnl INTLSYMBOL should be 'external' for packages other than GNU gettext, and +dnl 'use-libtool' for the packages 'gettext-runtime' and 'gettext-tools'. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value '$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])]) + ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], + [errprint([ERROR: Use of AM_GNU_GETTEXT without [external] argument is no longer supported. +])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define([gt_included_intl], + ifelse([$1], [external], [no], [yes])) + gt_NEEDS_INIT + AM_GNU_GETTEXT_NEED([$2]) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is not documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. + AC_REQUIRE([AM_NLS]) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl Add a version number to the cache macros. + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH([included-gettext], + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [eval "$gt_func_gnugettext_libc=yes"], + [eval "$gt_func_gnugettext_libc=no"])]) + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + [$gt_func_gnugettext_libintl], + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [eval "$gt_func_gnugettext_libintl=yes"], + [eval "$gt_func_gnugettext_libintl=no"]) + dnl Now see whether libintl exists and depends on libiconv. + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LTLIBICONV $LTLIBTHREAD" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + CATOBJEXT= + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Some extra flags are needed during linking. + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE([ENABLE_NLS], [1], + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE([HAVE_GETTEXT], [1], + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE([HAVE_DCGETTEXT], [1], + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl In GNU gettext we have to set BUILD_INCLUDED_LIBINTL to 'yes' + dnl because some of the testsuite requires it. + BUILD_INCLUDED_LIBINTL=yes + + dnl Make all variables we use known to autoconf. + AC_SUBST([BUILD_INCLUDED_LIBINTL]) + AC_SUBST([USE_INCLUDED_LIBINTL]) + AC_SUBST([CATOBJEXT]) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST([INTLLIBS]) + + dnl Make all documented variables known to autoconf. + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_SUBST([POSUB]) +]) + + +dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. +m4_define([gt_NEEDS_INIT], +[ + m4_divert_text([DEFAULTS], [gt_needs=]) + m4_define([gt_NEEDS_INIT], []) +]) + + +dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) +AC_DEFUN([AM_GNU_GETTEXT_NEED], +[ + m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) + + +dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], []) diff --git a/m4/host-cpu-c-abi.m4 b/m4/host-cpu-c-abi.m4 new file mode 100644 index 00000000..6db2aa25 --- /dev/null +++ b/m4/host-cpu-c-abi.m4 @@ -0,0 +1,675 @@ +# host-cpu-c-abi.m4 serial 13 +dnl Copyright (C) 2002-2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible and Sam Steingold. + +dnl Sets the HOST_CPU variable to the canonical name of the CPU. +dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its +dnl C language ABI (application binary interface). +dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in +dnl config.h. +dnl +dnl This canonical name can be used to select a particular assembly language +dnl source file that will interoperate with C code on the given host. +dnl +dnl For example: +dnl * 'i386' and 'sparc' are different canonical names, because code for i386 +dnl will not run on SPARC CPUs and vice versa. They have different +dnl instruction sets. +dnl * 'sparc' and 'sparc64' are different canonical names, because code for +dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code +dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit +dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit +dnl mode, but not both. +dnl * 'mips' and 'mipsn32' are different canonical names, because they use +dnl different argument passing and return conventions for C functions, and +dnl although the instruction set of 'mips' is a large subset of the +dnl instruction set of 'mipsn32'. +dnl * 'mipsn32' and 'mips64' are different canonical names, because they use +dnl different sizes for the C types like 'int' and 'void *', and although +dnl the instruction sets of 'mipsn32' and 'mips64' are the same. +dnl * The same canonical name is used for different endiannesses. You can +dnl determine the endianness through preprocessor symbols: +dnl - 'arm': test __ARMEL__. +dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL. +dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN. +dnl * The same name 'i386' is used for CPUs of type i386, i486, i586 +dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because +dnl - Instructions that do not exist on all of these CPUs (cmpxchg, +dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your +dnl assembly language source files use such instructions, you will +dnl need to make the distinction. +dnl - Speed of execution of the common instruction set is reasonable across +dnl the entire family of CPUs. If you have assembly language source files +dnl that are optimized for particular CPU types (like GNU gmp has), you +dnl will need to make the distinction. +dnl See . +AC_DEFUN([gl_HOST_CPU_C_ABI], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi], + [case "$host_cpu" in + +changequote(,)dnl + i[34567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=x86_64-x32], + [gl_cv_host_cpu_c_abi=x86_64])], + [gl_cv_host_cpu_c_abi=i386]) + ;; + +changequote(,)dnl + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __aarch64__ + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=arm64-ilp32], + [gl_cv_host_cpu_c_abi=arm64])], + [# Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + ]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=hppa64], + [gl_cv_host_cpu_c_abi=hppa]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=ia64-ilp32], + [gl_cv_host_cpu_c_abi=ia64]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mips64], + [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by ), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by ), and _MIPS_SIM == _ABIO32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mipsn32], + [gl_cv_host_cpu_c_abi=mips])]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=powerpc64-elfv2], + [gl_cv_host_cpu_c_abi=powerpc64]) + ], + [gl_cv_host_cpu_c_abi=powerpc]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + ]])], + [cpu=riscv64], + [cpu=riscv32]) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [main_abi=lp64], + [main_abi=ilp32]) + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + ]])], + [float_abi=d], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + ]])], + [float_abi=f], + [float_abi='']) + ]) + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=s390x], + [gl_cv_host_cpu_c_abi=s390]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=sparc64], + [gl_cv_host_cpu_c_abi=sparc]) + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + ]) + + dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same. + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + AC_SUBST([HOST_CPU]) + AC_SUBST([HOST_CPU_C_ABI]) + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h < +#include + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, + dnl Solaris 10. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + ]], + [[int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 16; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } + return result; +]])], + [am_cv_func_iconv_works=yes], , + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to +dnl avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +dnl This is tricky because of the way 'aclocal' is implemented: +dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. +dnl Otherwise aclocal's initial scan pass would miss the macro definition. +dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. +dnl Otherwise aclocal would emit many "Use of uninitialized value $1" +dnl warnings. +m4_define([gl_iconv_AC_DEFUN], + m4_version_prereq([2.64], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [m4_ifdef([gl_00GNULIB], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [[AC_DEFUN( + [$1], [$2])]])])) +gl_iconv_AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + ]], + [[]])], + [am_cv_proto_iconv_arg1=""], + [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + else + dnl When compiling GNU libiconv on a system that does not have iconv yet, + dnl pick the POSIX compliant declaration without 'const'. + am_cv_proto_iconv_arg1="" + fi + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + dnl Also substitute ICONV_CONST in the gnulib generated . + m4_ifdef([gl_ICONV_H_DEFAULTS], + [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test -n "$am_cv_proto_iconv_arg1"; then + ICONV_CONST="const" + fi + ]) +]) diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4 new file mode 100644 index 00000000..ebd9937c --- /dev/null +++ b/m4/intlmacosx.m4 @@ -0,0 +1,65 @@ +# intlmacosx.m4 serial 8 (gettext-0.20.2) +dnl Copyright (C) 2004-2014, 2016, 2019-2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Checks for special options needed on Mac OS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in Mac OS X 10.4. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFPreferencesCopyAppValue(NULL, NULL)]])], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], + [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Don't check for the API introduced in Mac OS X 10.5, CFLocaleCopyCurrent, + dnl because in macOS 10.13.4 it has the following behaviour: + dnl When two or more languages are specified in the + dnl "System Preferences > Language & Region > Preferred Languages" panel, + dnl it returns en_CC where CC is the territory (even when English is not among + dnl the preferred languages!). What we want instead is what + dnl CFLocaleCopyCurrent returned in earlier macOS releases and what + dnl CFPreferencesCopyAppValue still returns, namely ll_CC where ll is the + dnl first among the preferred languages and CC is the territory. + AC_CACHE_CHECK([for CFLocaleCopyPreferredLanguages], [gt_cv_func_CFLocaleCopyPreferredLanguages], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFLocaleCopyPreferredLanguages();]])], + [gt_cv_func_CFLocaleCopyPreferredLanguages=yes], + [gt_cv_func_CFLocaleCopyPreferredLanguages=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYPREFERREDLANGUAGES], [1], + [Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes \ + || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 new file mode 100644 index 00000000..98c348fa --- /dev/null +++ b/m4/lib-ld.m4 @@ -0,0 +1,168 @@ +# lib-ld.m4 serial 9 +dnl Copyright (C) 1996-2003, 2009-2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid +dnl collision with libtool.m4. + +dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 /dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + AC_MSG_CHECKING([for ld]) +elif test "$GCC" = yes; then + AC_MSG_CHECKING([for ld used by $CC]) +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + AC_CACHE_VAL([acl_cv_path_LD], + [ + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + ]) + AC_ARG_WITH(PACK[-prefix], +[[ --with-]]PACK[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]PACK[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" + fi + fi +]) + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + fi + done + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $dependency_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then + haveit= + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + dnl Really add $dependency_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$dependency_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + dnl Really add $dependency_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$dependency_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2" \ + && test "X$dir" != "X/usr/$acl_libdirstem3"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2" \ + && test "X$dir" != "X/usr/$acl_libdirstem3"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 new file mode 100644 index 00000000..c8a0b464 --- /dev/null +++ b/m4/lib-prefix.m4 @@ -0,0 +1,320 @@ +# lib-prefix.m4 serial 17 +dnl Copyright (C) 2001-2005, 2008-2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH([lib-prefix], +[[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a function acl_is_expected_elfclass, that tests whether standard input +dn; has a 32-bit or 64-bit ELF header, depending on the host CPU ABI, +dnl - 3 variables acl_libdirstem, acl_libdirstem2, acl_libdirstem3, containing +dnl the basename of the libdir to try in turn, either "lib" or "lib64" or +dnl "lib/64" or "lib32" or "lib/sparcv9" or "lib/amd64" or similar. +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib, lib32, and lib64. + dnl On most glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. However, on + dnl Arch Linux based distributions, it's the opposite: 32-bit libraries go + dnl under $prefix/lib32 and 64-bit libraries go under $prefix/lib. + dnl We determine the compiler's default mode by looking at the compiler's + dnl library search path. If at least one of its elements ends in /lib64 or + dnl points to a directory whose absolute pathname ends in /lib64, we use that + dnl for 64-bit ABIs. Similarly for 32-bit ABIs. Otherwise we use the default, + dnl namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT]) + + AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf], + [AC_EGREP_CPP([Extensible Linking Format], + [#ifdef __ELF__ + Extensible Linking Format + #endif + ], + [gl_cv_elf=yes], + [gl_cv_elf=no]) + ]) + if test $gl_cv_elf; then + # Extract the ELF class of a file (5th byte) in decimal. + # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + if od -A x < /dev/null >/dev/null 2>/dev/null; then + # Use POSIX od. + func_elfclass () + { + od -A n -t d1 -j 4 -N 1 + } + else + # Use BSD hexdump. + func_elfclass () + { + dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "' + echo + } + fi +changequote(,)dnl + case $HOST_CPU_C_ABI_32BIT in + yes) + # 32-bit ABI. + acl_is_expected_elfclass () + { + test "`func_elfclass | sed -e 's/[ ]//g'`" = 1 + } + ;; + no) + # 64-bit ABI. + acl_is_expected_elfclass () + { + test "`func_elfclass | sed -e 's/[ ]//g'`" = 2 + } + ;; + *) + # Unknown. + acl_is_expected_elfclass () + { + : + } + ;; + esac +changequote([,])dnl + else + acl_is_expected_elfclass () + { + : + } + fi + + dnl Allow the user to override the result by setting acl_cv_libdirstems. + AC_CACHE_CHECK([for the common suffixes of directories in the library search path], + [acl_cv_libdirstems], + [dnl Try 'lib' first, because that's the default for libdir in GNU, see + dnl . + acl_libdirstem=lib + acl_libdirstem2= + acl_libdirstem3= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl . + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + if test $HOST_CPU_C_ABI_32BIT = no; then + acl_libdirstem2=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem3=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem3=lib/amd64 ;; + esac + fi + ;; + *) + dnl If $CC generates code for a 32-bit ABI, the libraries are + dnl surely under $prefix/lib or $prefix/lib32, not $prefix/lib64. + dnl Similarly, if $CC generates code for a 64-bit ABI, the libraries + dnl are surely under $prefix/lib or $prefix/lib64, not $prefix/lib32. + dnl Find the compiler's search path. However, non-system compilers + dnl sometimes have odd library search paths. But we can't simply invoke + dnl '/usr/bin/gcc -print-search-dirs' because that would not take into + dnl account the -m32/-m31 or -m64 options from the $CC or $CFLAGS. + searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test $HOST_CPU_C_ABI_32BIT != no; then + # 32-bit or unknown ABI. + if test -d /usr/lib32; then + acl_libdirstem2=lib32 + fi + fi + if test $HOST_CPU_C_ABI_32BIT != yes; then + # 64-bit or unknown ABI. + if test -d /usr/lib64; then + acl_libdirstem3=lib64 + fi + fi + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;; + */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib32 ) acl_libdirstem2=lib32 ;; + */lib64 ) acl_libdirstem3=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + if test $HOST_CPU_C_ABI_32BIT = yes; then + # 32-bit ABI. + acl_libdirstem3= + fi + if test $HOST_CPU_C_ABI_32BIT = no; then + # 64-bit ABI. + acl_libdirstem2= + fi + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3" + ]) + dnl Decompose acl_cv_libdirstems into acl_libdirstem, acl_libdirstem2, and + dnl acl_libdirstem3. +changequote(,)dnl + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'` + acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'` +changequote([,])dnl +]) diff --git a/m4/nls.m4 b/m4/nls.m4 new file mode 100644 index 00000000..5a506fc4 --- /dev/null +++ b/m4/nls.m4 @@ -0,0 +1,32 @@ +# nls.m4 serial 6 (gettext-0.20.2) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019-2020 Free +dnl Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) diff --git a/m4/po.m4 b/m4/po.m4 new file mode 100644 index 00000000..3778fd7a --- /dev/null +++ b/m4/po.m4 @@ -0,0 +1,450 @@ +# po.m4 serial 31 (gettext-0.20.2) +dnl Copyright (C) 1995-2014, 2016, 2018-2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.60]) + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AC_PROG_MKDIR_P])dnl + AC_REQUIRE([AC_PROG_SED])dnl + AC_REQUIRE([AM_NLS])dnl + + dnl Release version of the gettext macros. This is used to ensure that + dnl the gettext macros and po/Makefile.in.in are in sync. + AC_SUBST([GETTEXT_MACRO_VERSION], [0.20]) + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) + + dnl Test whether it is GNU msgfmt >= 0.15. +changequote(,)dnl + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([GMSGFMT_015]) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Test whether it is GNU xgettext >= 0.15. +changequote(,)dnl + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac +changequote([,])dnl + AC_SUBST([XGETTEXT_015]) + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) + + dnl Test whether it is GNU msgmerge >= 0.20. + if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' + else + dnl Test whether it is GNU msgmerge >= 0.12. + if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' + else + dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is + dnl slow. But this is not a big problem, as such old gettext versions are + dnl hardly in use any more. + MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' + fi + fi + AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION]) + + dnl Support for AM_XGETTEXT_OPTION. + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) + + AC_CONFIG_COMMANDS([po-directories], [[ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + gt_tab=`printf '\t'` + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done]], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. + OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat < "$ac_file.tmp" + tab=`printf '\t'` + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" < /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + cat >> "$ac_file.tmp" <> "$ac_file.tmp" <, 1996. + +AC_PREREQ([2.50]) + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL([ac_cv_path_$1], +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$][$1]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST([$1])dnl +]) diff --git a/m4/zip.m4 b/m4/zip.m4 new file mode 100644 index 00000000..ab6fd57e --- /dev/null +++ b/m4/zip.m4 @@ -0,0 +1,20 @@ +dnl -*- Autoconf -*- test for either zlib or bzlib. +dnl Defines --with-$1 argument, $2 automake conditional, +dnl and sets AC_DEFINE(USE_$2) and LIBS. + +AC_DEFUN([eu_ZIPLIB], [dnl +AC_ARG_WITH([[$1]], +AC_HELP_STRING([--with-[$1]], [support [$1] compression in libdwfl]),, + [with_[$1]=default]) +if test $with_[$1] != no; then + AC_SEARCH_LIBS([$4], [$3], [with_[$1]=yes], + [test $with_[$1] = default || + AC_MSG_ERROR([missing -l[$3] for --with-[$1]])]) +fi +AM_CONDITIONAL([$2], test $with_[$1] = yes) +if test $with_[$1] = yes; then + AC_DEFINE(USE_[$2]) +else + with_[$1]=no +fi +AH_TEMPLATE(USE_[$2], [Support $5 decompression via -l$3.])]) diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 00000000..a3c69b56 --- /dev/null +++ b/po/ChangeLog @@ -0,0 +1,259 @@ +2021-05-22 Mark Wielaard + + * *.po: Update for 0.185. + +2021-05-10 Mark Wielaard + + * *.po: Update for 0.184. + +2021-03-21 Dmitry V. Levin + + * Makevars (XGETTEXT_OPTIONS): Update. + +2021-02-21 Piotr Drąg + + * pl.po: Updated. + +2021-02-21 Piotr Drąg + + * POTFILES.in: Add libcpu/i386_lex.l, libcpu/i386_parse.y, + src/elfclassify.c and debuginfod/debuginfod-find.c. + +2021-02-05 Mark Wielaard + + * *.po: Update for 0.183. + +2020-12-15 Dmitry V. Levin + + * Makevars: Sync with Makevars.template. + * .gitignore: New file. + + * fr.po: Remove empty translation file. + * it.po: Likewise. + * nl.po: Likewise. + * ru.po: Likewise. + * zh_CN.po: Likewise. + +2020-12-12 Dmitry V. Levin + + * *.po (msgid): Fix spelling typos. + +2020-10-31 Mark Wielaard + + * *.po: Update for 0.182. + +2020-09-08 Mark Wielaard + + * *.po: Update for 0.181. + +2020-06-11 Mark Wielaard + + * *.po: Update for 0.180. + +2020-03-30 Mark Wielaard + + * *.po: Update for 0.179. + +2019-11-26 Mark Wielaard + + * *.po: Update for 0.178. + +2019-08-13 Mark Wielaard + + * *.po: Update for 0.177. + +2019-02-14 Mark Wielaard + + * *.po: Update for 0.176. + +2018-06-11 Mark Wielaard + + * *.po: Update for 0.172. + +2018-06-01 Mark Wielaard + + * *.po: Update for 0.171. + +2017-09-01 Mark Wielaard + + * *.po: Regenerated. Replace \v with \n\n. + +2017-08-02 Mark Wielaard + + * *.po: Update for 0.170. + +2017-05-05 Mark Wielaard + + * *.po: Update for 0.169. + +2017-02-16 Ulf Hermann + + * po/POTFILES.in: Removed lib/version.c, added lib/printversion.c. + +2016-12-27 Mark Wielaard + + * *.po: Update for 0.168. + +2016-12-24 Mark Wielaard + + * Makevars (COPYRIGHT_HOLDER): Set to the elfutils developers. + (MSGID_BUGS_ADDRESS): Set to http://sourceware.org/bugzilla/ + +2016-08-24 Mark Wielaard + + * *.po: Regenerate. + +2016-08-04 Mark Wielaard + + * *.po: Update for 0.167. + +2016-07-06 Mark Wielaard + + * po/POTFILES.in: Removed libebl/eblobjecttypename.c, + src/i386_ld.c, src/ld.c, src/ldgeneric.c and src/ldscript.y. + +2016-03-31 Mark Wielaard + + * *.po: Update for 0.166. + +2016-01-11 Mark Wielaard + + * *.po: Regenerate. + +2016-01-08 Mark Wielaard + + * *.po: Update for 0.165. + +2015-10-16 Mark Wielaard + + * *.po: Regenerate. + +2015-10-15 Mark Wielaard + + * *.po: Update for 0.164. + +2015-06-19 Mark Wielaard + + * *.po: Update for 0.163. + +2015-06-15 Mark Wielaard + + * *.po: Regenerate. + +2015-06-10 Mark Wielaard + + * *.po: Update for 0.162. + +2014-12-18 Mark Wielaard + + * *.po: Update for 0.161. + +2014-08-25 Mark Wielaard + + * *.po: Update for 0.160. + +2014-05-20 Mark Wielaard + + * *.po: Regenerated. + +2014-05-17 Mark Wielaard + + * *.po: Update for 0.159. + +2014-01-03 Mark Wielaard + + * *.po: Update for 0.158. + +2013-07-30 Mark Wielaard + + * *.po: Update for 0.157. + +2013-07-25 Jan Kratochvil + + * *.po: Update for 0.156. + +2013-04-24 Mark Wielaard + + * Makefile.in.in: Upgrade to gettext-0.18.2. + +2012-08-27 Mark Wielaard + + * *.po: Update for 0.155. + +2012-06-22 Mark Wielaard + + * *.po: Update for 0.154. + +2012-02-23 Mark Wielaard + + * *.po: Update for 0.153. + +2010-04-21 Ulrich Drepper + + * LINGUAS: Remove fr.po, it.po, nl.po, ru.po, zh_CN. The files + contain no translations at all. + +2010-04-14 Roland McGrath + + * POTFILES.in: Add libdwfl/libdwflP.h. + + * LINGUAS: New file. + * Makefile.in.in: Upgrade to gettext-0.17. + +2009-01-23 Ulrich Drepper + + * Makevars (XGETTEXT_OPTIONS): Add --flag option for argp_error. + + * POTFILES.in: Add more files with translatable strings. + +2007-06-05 Ulrich Drepper + + * Makefile.in.in: Update from gettext 0.16.1. + * Rules-quot: Likewise. + * Makevars: Add more XGGETEXT_OPTIONS. + + * remove-potcdata.sin: New file. + + * POTFILES.in: Also include messages from libelf. + +2007-04-18 Ulrich Drepper + + * Makefile.in.in: Remove MKINSTALLDIRS. + Define mkinstalldirs to mkdir -p. + +2006-04-04 Roland McGrath + + * POTFILES.in: Comment out lib/xstrdup.c, not distributed any more. + +2005-08-27 Ulrich Drepper + + * POTFILES.in: Add src/strings.c. + +2005-08-15 Ulrich Drepper + + * POTFILES.in: Add src/ranlib.c. + +2005-08-05 Ulrich Drepper + + * Makefile.in.in (XGETTEXT_OPTIONS): Move adding of --flag options + after magic Makevars line. Also look for ERROR from elflint. + +2005-07-21 Ulrich Drepper + + * Makefile.in.in: Add src/elfcmp. + +2005-05-07 Ulrich Drepper + + * Makefile.in.in (XGETTEXT_OPTIONS): Define. + +2005-02-05 Ulrich Drepper + + * POTFILES.in: Remove unnecessary entries. + +2004-01-18 Ulrich Drepper + + * POTFILES.in: Add files from libdw, libebl, and libasm. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 00000000..4adcc52a --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,5 @@ +# List of translations, i.e. .po files supplied by translators. +de es ja pl uk + +# These are automagically created, not real translations. +en@quot en@boldquot diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 00000000..6b25f0d9 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,510 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-2000 Ulrich Drepper +# Copyright (C) 2000-2020 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. This file is offered as-is, +# without any warranty. +# +# Origin: gettext-0.21 +GETTEXT_MACRO_VERSION = 0.20 + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +SED = @SED@ +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = @localedir@ +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# @install_sh@ does not start with $(SHELL), so we add it. +# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) @install_sh@ -d +install_sh = $(SHELL) @install_sh@ +MKDIR_P = @MKDIR_P@ +mkdir_p = @mkdir_p@ + +# When building gettext-tools, we prefer to use the built programs +# rather than installed programs. However, we can't do that when we +# are cross compiling. +CROSS_COMPILING = @CROSS_COMPILING@ + +GMSGFMT_ = @GMSGFMT@ +GMSGFMT_no = @GMSGFMT@ +GMSGFMT_yes = @GMSGFMT_015@ +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = @XGETTEXT@ +XGETTEXT_no = @XGETTEXT@ +XGETTEXT_yes = @XGETTEXT_015@ +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = @MSGMERGE@ +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +POFILESDEPS_ = $(srcdir)/$(DOMAIN).pot +POFILESDEPS_yes = $(POFILESDEPS_) +POFILESDEPS_no = +POFILESDEPS = $(POFILESDEPS_$(PO_DEPENDS_ON_POT)) + +DISTFILESDEPS_ = update-po +DISTFILESDEPS_yes = $(DISTFILESDEPS_) +DISTFILESDEPS_no = +DISTFILESDEPS = $(DISTFILESDEPS_$(DIST_DEPENDS_ON_UPDATE_PO)) + +# Makevars gets inserted here. (Don't remove this line!) + +all: all-@USE_NLS@ + + +.SUFFIXES: +.SUFFIXES: .po .gmo .sed .sin .nop .po-create .po-update + +# The .pot file, stamp-po, .po files, and .gmo files appear in release tarballs. +# The GNU Coding Standards say in +# : +# "GNU distributions usually contain some files which are not source files +# ... . Since these files normally appear in the source directory, they +# should always appear in the source directory, not in the build directory. +# So Makefile rules to update them should put the updated files in the +# source directory." +# Therefore we put these files in the source directory, not the build directory. + +# During .po -> .gmo conversion, take into account the most recent changes to +# the .pot file. This eliminates the need to update the .po files when the +# .pot file has changed, which would be troublesome if the .po files are put +# under version control. +$(GMOFILES): $(srcdir)/$(DOMAIN).pot +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.1po && rm -f $${lang}.1po"; \ + cd $(srcdir) && \ + rm -f $${lang}.gmo && \ + $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && \ + $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.1po && \ + mv t-$${lang}.gmo $${lang}.gmo && \ + rm -f $${lang}.1po + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all-yes: $(srcdir)/stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +CHECK_MACRO_VERSION = \ + test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, $(srcdir)/stamp-po is a nop (i.e. a phony target). + +# $(srcdir)/stamp-po is a timestamp denoting the last time at which the CATALOGS +# have been loosely updated. Its purpose is that when a developer or translator +# checks out the package from a version control system, and the $(DOMAIN).pot +# file is not under version control, "make" will update the $(DOMAIN).pot and +# the $(CATALOGS), but subsequent invocations of "make" will do nothing. This +# timestamp would not be necessary if updating the $(CATALOGS) would always +# touch them; however, the rule for $(POFILES) has been designed to not touch +# files that don't need to be changed. +$(srcdir)/stamp-po: $(srcdir)/$(DOMAIN).pot + @$(CHECK_MACRO_VERSION) + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch $(srcdir)/stamp-po" && \ + echo timestamp > $(srcdir)/stamp-poT && \ + mv $(srcdir)/stamp-poT $(srcdir)/stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +# The determination of whether the package xyz is a GNU one is based on the +# heuristic whether some file in the top level directory mentions "GNU xyz". +# If GNU 'find' is available, we avoid grepping through monster files. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + package_gnu="$(PACKAGE_GNU)"; \ + test -n "$$package_gnu" || { \ + if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ + LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep -i 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \ + else \ + LC_ALL=C grep -i 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \ + fi; \ + } | grep -v 'libtool:' >/dev/null; then \ + package_gnu=yes; \ + else \ + package_gnu=no; \ + fi; \ + }; \ + if test "$$package_gnu" = "yes"; then \ + package_prefix='GNU '; \ + else \ + package_prefix=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_prefix}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot-header; then \ + sed -e '1,/^#$$/d' < $(DOMAIN).po > $(DOMAIN).1po && \ + cat $(srcdir)/$(DOMAIN).pot-header $(DOMAIN).1po > $(DOMAIN).po && \ + rm -f $(DOMAIN).1po \ + || exit 1; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(POFILESDEPS) + @test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + 0.1[6-7] | 0.1[6-7].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --previous $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +install-dvi install-ps install-pdf install-html: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f $(srcdir)/stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(srcdir)/$(DOMAIN).pot $(srcdir)/stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + test -z "$(DISTFILESDEPS)" || $(MAKE) $(DISTFILESDEPS) + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: $(srcdir)/stamp-po $(DISTFILES) + @dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + else \ + case $(XGETTEXT) in \ + :) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because a suitable 'xgettext' program was not found in PATH." 1>&2;; \ + *) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because 'xgettext' found no strings to extract. Check the contents of the POTFILES.in file and the XGETTEXT_OPTIONS in the Makevars file." 1>&2;; \ + esac; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang --previous $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + 0.1[6-7] | 0.1[6-7].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use @SHELL@, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && @SHELL@ ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 00000000..692394cc --- /dev/null +++ b/po/Makevars @@ -0,0 +1,74 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ \ + --keyword=N_ \ + --keyword=sgettext:1g \ + --flag=_:1:pass-c-format \ + --flag=N_:1:pass-c-format \ + --flag=sgettext:1:pass-c-format \ + --flag=error:3:c-format \ + --flag=ERROR:1:c-format \ + --flag=argp_error:2:c-format \ + --add-comments + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = The elfutils developers + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = https://sourceware.org/bugzilla/ + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = + +# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' +# context. Possible values are "yes" and "no". Set this to yes if the +# package uses functions taking also a message context, like pgettext(), or +# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. +USE_MSGCTXT = no + +# These options get passed to msgmerge. +# Useful options are in particular: +# --previous to keep previous msgids of translated messages, +# --quiet to reduce the verbosity. +MSGMERGE_OPTIONS = + +# This tells whether or not to regenerate a PO file when $(DOMAIN).pot +# has changed. Possible values are "yes" and "no". Set this to no if +# the POT file is checked in the repository and the version control +# program ignores timestamps. +PO_DEPENDS_ON_POT = yes + +# This tells whether or not to forcibly update $(DOMAIN).pot and +# regenerate PO files on "make dist". Possible values are "yes" and +# "no". Set this to no if the POT file and PO files are maintained +# externally. +DIST_DEPENDS_ON_UPDATE_PO = yes diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 00000000..65a6cfeb --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,54 @@ +# List of files which containing translatable strings. +# Copyright (C) 2000-2010 Red Hat, Inc. + +# Files from the compatibility library +lib/color.c +lib/printversion.c +lib/xmalloc.c + +# Library sources +libasm/asm_error.c +libcpu/i386_lex.l +libcpu/i386_parse.y +libdw/dwarf_error.c +libdwfl/argp-std.c +libdwfl/libdwflP.h +libebl/eblbackendname.c +libebl/eblcorenotetypename.c +libebl/ebldynamictagname.c +libebl/eblobjnote.c +libebl/eblobjnotetypename.c +libebl/eblosabiname.c +libebl/eblsectionname.c +libebl/eblsectiontypename.c +libebl/eblsegmenttypename.c +libebl/eblsymbolbindingname.c +libebl/eblsymboltypename.c +libelf/elf_error.c + +# Program sources +src/addr2line.c +src/ar.c +src/arlib-argp.c +src/arlib.c +src/elfclassify.c +src/elfcmp.c +src/elfcompress.c +src/elflint.c +src/findtextrel.c +src/nm.c +src/objdump.c +src/ranlib.c +src/readelf.c +src/size.c +src/stack.c +src/strings.c +src/strip.c +src/unstrip.c + +# debuginfod sources +debuginfod/debuginfod-find.c + +# Tests +tests/backtrace.c +tests/dwflmodtest.c diff --git a/po/Rules-quot b/po/Rules-quot new file mode 100644 index 00000000..18c024bf --- /dev/null +++ b/po/Rules-quot @@ -0,0 +1,62 @@ +# Special Makefile rules for English message catalogs with quotation marks. +# +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# This file, Rules-quot, and its auxiliary files (listed under +# DISTFILES.common.extra1) are free software; the Free Software Foundation +# gives unlimited permission to use, copy, distribute, and modify them. + +DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot + +.SUFFIXES: .insert-header .po-update-en + +en@quot.po-create: + $(MAKE) en@quot.po-update +en@boldquot.po-create: + $(MAKE) en@boldquot.po-update + +en@quot.po-update: en@quot.po-update-en +en@boldquot.po-update: en@boldquot.po-update-en + +.insert-header.po-update-en: + @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + ll=`echo $$lang | sed -e 's/@.*//'`; \ + LC_ALL=C; export LC_ALL; \ + cd $(srcdir); \ + if $(MSGINIT) $(MSGINIT_OPTIONS) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null \ + | $(SED) -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | \ + { case `$(MSGFILTER) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-8] | 0.1[0-8].*) \ + $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed \ + ;; \ + *) \ + $(MSGFILTER) `echo $$lang | sed -e 's/.*@//'` \ + ;; \ + esac } 2>/dev/null > $$tmpdir/$$lang.new.po \ + ; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "creation of $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +en@quot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header + +en@boldquot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header + +mostlyclean: mostlyclean-quot +mostlyclean-quot: + rm -f *.insert-header diff --git a/po/boldquot.sed b/po/boldquot.sed new file mode 100644 index 00000000..4b937aa5 --- /dev/null +++ b/po/boldquot.sed @@ -0,0 +1,10 @@ +s/"\([^"]*\)"/“\1”/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“”/""/g +s/“/“/g +s/”/”/g +s/‘/‘/g +s/’/’/g diff --git a/po/de.gmo b/po/de.gmo new file mode 100644 index 0000000000000000000000000000000000000000..7f84b59dacc44d8f23b5312435d3a3e1e407c856 GIT binary patch literal 17890 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 literal 0 HcmV?d00001 diff --git a/po/de.po b/po/de.po new file mode 100644 index 00000000..d7437c53 --- /dev/null +++ b/po/de.po @@ -0,0 +1,7004 @@ +# German translation of elfutils. +# Copyright (C) 2009 THE elfutils'S COPYRIGHT HOLDER +# This file is distributed under the same license as the elfutils package. +# , fuzzy +# +# +# Thomas Spura , 2009. +# Cornelius Neckenig , 2009. +# Michael Münch , 2009. +msgid "" +msgstr "" +"Project-Id-Version: elfutils VERSION\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2009-06-29 15:15+0200\n" +"Last-Translator: Michael Münch \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 0.3\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" + +#: lib/color.c:194 src/objdump.c:728 +#, fuzzy, c-format +msgid "cannot allocate memory" +msgstr "konnte Verzeichnis nicht erstellen: %s" + +#: lib/printversion.c:40 +#, fuzzy, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"Copyright (C) %s Red Hat, Inc.\n" +"Dies ist freie Software, siehe Quellcode für Kopierbedingungen. KEINE " +"GARANTIE,\n" +"auch nicht für Marktgängigkeit oder Eignung für einen Bestimmten Zweck.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "Kein Speicher mehr verfügbar" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "kein Fehler" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "nicht genügend Speicher" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "Ausgangsdatei konnte nicht erstellt werden" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "ungültiger Parameter" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "konnte Modus der Ausgabedatei nicht ändern" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "Ausgangsdatei konnte nicht umbenannt werden" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "Symbol doppelt vorhanden" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "ungültiger Abschnittstyp für Operation" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "Fehler bei Datenausgabe" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "keine Backend-Unterstützung verfügbar" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "unbekannter Fehler" + +#: libcpu/i386_lex.l:122 +#, c-format +msgid "invalid character '%c' at line %d; ignored" +msgstr "" + +#: libcpu/i386_lex.l:123 +#, c-format +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "" + +#: libcpu/i386_parse.y:554 +#, c-format +msgid "while reading i386 CPU description: %s at line %d" +msgstr "" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "Ungültiger Zugriff" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "Keine reguläre Date" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "I/O Fehler" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "Ungültige ELF Datei" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "keine DWARF Information" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "keine ELF Datei" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "ELF Kopf konnte nicht ausgelesen werden" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "Nicht implementiert" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "Ungültiger Befehl" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "Ungültige Version" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "Ungültige Datei" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "Keine Einträge gefunden" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "DWARF ungültig" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "" + +#: libdw/dwarf_error.c:75 +#, fuzzy +msgid ".debug_str section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:76 +#, fuzzy +msgid ".debug_line_str section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:77 +#, fuzzy +msgid ".debug_str_offsets section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "Kein Adress-Wert" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "Kein Konstanten-Wert" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "Kein Referenz-Wert" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "Ungültiger Referenz-Wert" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "ungültige .debug_line Sektion" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "Debug Information zu groß" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "Ungültige DWARF Version" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "ungültiger Verzeichnisindex" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "Außerhalb des Adressbereiches" + +#: libdw/dwarf_error.c:88 +#, fuzzy +msgid ".debug_loc section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:89 +#, fuzzy +msgid ".debug_loclists section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:90 +#, fuzzy +msgid "not a location list value" +msgstr "Kein Konstanten-Wert" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "Ungültiger Zeilenindex" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "Ungültiger Adressbereichs Index" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "Kein passender Adressbereich" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "ungültiger Offset" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr "" + +#: libdw/dwarf_error.c:98 +#, fuzzy +msgid ".debug_rnglists section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdw/dwarf_error.c:99 +#, fuzzy +msgid "invalid CFI section" +msgstr "ungültiger Abschnitt" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "" + +#: libdw/dwarf_error.c:101 +#, fuzzy +msgid "invalid opcode" +msgstr "ungültiger Operand" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "" + +#: libdw/dwarf_error.c:103 +#, fuzzy +msgid "unknown language code" +msgstr "unbekannter Typ" + +#: libdw/dwarf_error.c:104 +#, fuzzy +msgid ".debug_addr section missing" +msgstr ".debug_line Sektion fehlt" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "Eingabeauswahloptionen:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "Finde Adressen in FILE" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "Finde Adressen von Signatur aus COREFILE" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "Finde Adressen im laufenden Kernel" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "Kernel mit allen Modulen" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "Dateisuchpfad für separate Debug-Informationen" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "Nur eine Option von -e, -p, -k, -K, oder --core erlaubt" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "Konnte Kernel Symbole nicht laden" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "Konnte Kernel Module nicht finden" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "Konnte Kernel oder Module nicht finden" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "Konnte ELF Kerndatei %s nicht lesen" + +#: libdwfl/argp-std.c:317 +#, fuzzy +msgid "Not enough memory" +msgstr "nicht genügend Speicher" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "Keine Module in der Kerndatei gefunden" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:61 +msgid "zstd decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "Offset ausserhalb des Bereichs" + +#: libdwfl/libdwflP.h:67 +#, fuzzy +msgid "relocation refers to undefined symbol" +msgstr "Zeige Grösse der definierten Symbole" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "" + +#: libdwfl/libdwflP.h:69 +#, fuzzy +msgid "No DWARF information found" +msgstr "keine DWARF Information" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "" + +#: libdwfl/libdwflP.h:71 +#, fuzzy +msgid "No ELF program headers" +msgstr "Programm-Köpfe anzeigen" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "" + +#: libdwfl/libdwflP.h:76 +#, fuzzy +msgid "ELF file opened" +msgstr "keine ELF Datei" + +#: libdwfl/libdwflP.h:77 +#, fuzzy +msgid "not a valid ELF file" +msgstr "Ungültige ELF Datei" + +#: libdwfl/libdwflP.h:78 +#, fuzzy +msgid "cannot handle DWARF type description" +msgstr "konnte Elf-Deskriptor nicht erzeugen: %s" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "" + +#: libdwfl/libdwflP.h:80 +#, fuzzy +msgid "corrupt .gnu.prelink_undo section data" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "" + +#: libdwfl/libdwflP.h:83 +#, fuzzy +msgid "Invalid register" +msgstr "ungültiger Parameter" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "" + +#: libdwfl/libdwflP.h:87 +#, fuzzy +msgid "Invalid DWARF" +msgstr "DWARF ungültig" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "" + +#: libdwfl/libdwflP.h:93 +#, fuzzy +msgid "Invalid argument" +msgstr "ungültiger Parameter" + +#: libdwfl/libdwflP.h:94 +#, fuzzy +msgid "Not an ET_CORE ELF file" +msgstr "Ungültige ELF Datei" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "Kein Backend" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr ": %#" + +#: libebl/eblobjnote.c:58 +#, fuzzy, c-format +msgid "unknown SDT version %u\n" +msgstr "unbekannte Version" + +#: libebl/eblobjnote.c:76 +#, fuzzy, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "ungültiger Datei-Deskriptor" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr "" + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr "" + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr "" + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr "" + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr "" + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr "" + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " Build ID: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr "" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " OS: %s, ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr ": %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "unbekannte Version" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "unbekannter Typ" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "ungültiges `Elf'-Handle" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "ungültige Grösse des Quell-Operanden" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "ungültige Grösse des Ziel-Operanden" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "ungültige Kodierung" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "ungültiger Datei-Deskriptor" + +#: libelf/elf_error.c:99 +#, fuzzy +msgid "invalid ELF file data" +msgstr "Ungültige ELF Datei" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "ungültige Operation" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "ELF-Version nicht gesetzt" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "ungültiges fmag-Feld im Archivheader" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "Ungültige Archiv-Datei" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "kein Index verfügbar" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "Daten aus der Datei konnten nicht gelesen werden" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "Daten konnten nicht in die Datei geschrieben werden" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "ungültige Binärklasse" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "ungültiger Abschnittsindex" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "ungültiger Operand" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "ungültiger Abschnitt" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "ausführbarer Header wurde nicht zuerst erstellt" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "Datei-Deskriptor deaktiviert" + +#: libelf/elf_error.c:171 +#, fuzzy +msgid "archive/member file descriptor mismatch" +msgstr "Datei-Deskriptor deaktiviert" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "" + +#: libelf/elf_error.c:183 +#, fuzzy +msgid "data/scn mismatch" +msgstr "data/scn Unterschied" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "ungültiger Abschnitts-Header" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "Ungültige Daten" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "Unbekannte Datenkodierung" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "Abschnitt `sh_size' zu klein für Daten" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "ungültige Abschnittsausrichtung" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "Datei nicht gefunden" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "Datei hat keinen Programm-Kopf" + +#: libelf/elf_error.c:241 +#, fuzzy +msgid "invalid section type" +msgstr "ungültiger Abschnitt" + +#: libelf/elf_error.c:246 +#, fuzzy +msgid "invalid section flags" +msgstr "ungültiger Abschnitt" + +#: libelf/elf_error.c:251 +msgid "section does not contain compressed data" +msgstr "" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "" + +#: libelf/elf_error.c:261 +#, fuzzy +msgid "unknown compression type" +msgstr "unbekannter Typ" + +#: libelf/elf_error.c:266 +#, fuzzy +msgid "cannot compress data" +msgstr "konnte Abschnittsdaten nicht kopieren: %s" + +#: libelf/elf_error.c:271 +#, fuzzy +msgid "cannot decompress data" +msgstr "konnte Abschnittsdaten nicht kopieren: %s" + +#: src/addr2line.c:57 +#, fuzzy +msgid "Input format options:" +msgstr "Eingabeauswahloptionen:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "" + +#: src/addr2line.c:61 +#, fuzzy +msgid "Output format options:" +msgstr "Ausgabeformat:" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "Verschiedenes:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "" + +#: src/addr2line.c:519 +#, fuzzy, c-format +msgid "Section syntax requires exactly one module" +msgstr "Abschnitt syntax benötigt genau ein Modul" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "Konnte Symbol '%s' nicht finden" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "Befehle:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "Dateien aus dem Archiv löschen." + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "Dateien zum Archiv hinzufügen." + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "Packe Dateien in Archiv" + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "Hänge Dateien an ein Archiv" + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "Ersetze existierende oder füge neue Datei in das Archiv ein." + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "Zeige Archivinhalt an." + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "Entpacke Dateien aus dem Archiv" + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "Erhalte ursprüngliche Daten." + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "" + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "Ersetze existierende Dateien nicht mit entpackten Dateien" + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "Erlaube angehängte Dateinamen, wenn nötig" + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "Zeige detaillierte Ausgabe." + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "Erzwinge Regenerierung der Symboltabelle." + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "Füge Datei nach [MEMBER] ein." + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "Füge Datei vor [MEMBER] ein." + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "Genau wie -b." + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "Unterdrücke Nachricht wenn Bibliothek erstellt werden muss." + +#: src/ar.c:91 +#, fuzzy +msgid "Use full path for file matching." +msgstr "Vollständigen Pfad für Dateiabgleich verwenden." + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "Nur ältere Datein im Archiv aktualisieren" + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "Erstelle, ändere, extrahiere von Archiven" + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[MEMBER] [COUNT] ARCHIVE [FILE...]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "'a', 'b', und 'i' nur zusammen mit 'm' and 'r Optionen" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "'N' ist nur mit den Optionen 'x' und 'd' von Bedeutung." + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "COUNT Parameter erforderlich" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "Ungültiger COUNT Parameter %s" + +#: src/ar.c:225 +#, fuzzy, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "'%' ist nur mit der Option 'x' von Bedeutung" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "Archivname erforderlich" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "Mehr als eine Operation angegeben" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "Konnte Archiv '%s' nicht öffnen" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "Konnte Archiv '%s': %s nicht öffnen" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: Keine Archiv-Datei" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "Kein Eintrag %s in Archiv\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "Konnte Hash-Tabelle nicht erstellen" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "Konnte nicht in Hash-Tabelle einfügen" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "Konnte Inhalt von %s: %s nicht lesen" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "Konnte %.*s nicht öffnen" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "Konnte %s nicht schreiben" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "Konnte Bearbeitungszeit von %s nicht ändern" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "Konnte temporäre Datei nicht in %.*s umbenennen" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "neue Datei konnte nicht angelegt werden" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: Kein Eintrag %s in dem Archiv!\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "Konnte %s nicht öffnen" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "%s ist keine reguläre Datei" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "Konnte %s: %s nicht lesen" + +#: src/ar.c:1483 +#, fuzzy, c-format +msgid "cannot represent ar_date" +msgstr "konnte Abschnittsdaten nicht kopieren: %s" + +#: src/ar.c:1489 +#, fuzzy, c-format +msgid "cannot represent ar_uid" +msgstr "konnte Abschnittsdaten nicht kopieren: %s" + +#: src/ar.c:1495 +#, fuzzy, c-format +msgid "cannot represent ar_gid" +msgstr "konnte Abschnittsdaten nicht kopieren: %s" + +#: src/ar.c:1501 +#, fuzzy, c-format +msgid "cannot represent ar_mode" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/ar.c:1507 +#, fuzzy, c-format +msgid "cannot represent ar_size" +msgstr "Konnte %s nicht öffnen" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "Das Archiv '%s' ist zu groß" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "\"Konnte ELF-Kopf von %s(%s): %s nicht lesen" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "" + +#: src/elfclassify.c:245 +#, fuzzy +#| msgid "cannot get ELF header" +msgid "ELF header" +msgstr "ELF Kopf konnte nicht ausgelesen werden" + +#: src/elfclassify.c:256 +#, fuzzy +#| msgid "Program Headers:" +msgid "program headers" +msgstr "Programm-Köpfe:" + +#: src/elfclassify.c:265 +#, fuzzy +#| msgid "Program Headers:" +msgid "program header" +msgstr "Programm-Köpfe:" + +#: src/elfclassify.c:285 +#, fuzzy +#| msgid "invalid section header" +msgid "section headers" +msgstr "ungültiger Abschnitts-Header" + +#: src/elfclassify.c:296 +#, fuzzy +msgid "section header string table index" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfclassify.c:310 +#, fuzzy +msgid "could not obtain section header" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfclassify.c:316 +#, fuzzy +msgid "could not obtain section name" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "" + +#: src/elfclassify.c:877 +#, fuzzy +#| msgid "Input selection options:" +msgid "Classification options" +msgstr "Eingabeauswahloptionen:" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "" + +#: src/elfclassify.c:907 +#, fuzzy +#| msgid "cannot find kernel modules" +msgid "File is a linux kernel module" +msgstr "Konnte Kernel Module nicht finden" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "" + +#: src/elfclassify.c:956 +#, fuzzy +#| msgid "Output format:" +msgid "Output flags" +msgstr "Ausgabeformat:" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "" + +#: src/elfclassify.c:962 +#, fuzzy +#| msgid "More than one output file name given." +msgid "Do not output file names" +msgstr "Mehr als ein Name der Ausgabedatei angegeben." + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "DATEI..." + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +#, fuzzy +msgid "FILE1 FILE2" +msgstr "DATEI1 DATEI2" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "Ungültige Anzahl von Parametern.\n" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, fuzzy, c-format +msgid "cannot get section count of '%s': %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, fuzzy, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/elfcmp.c:233 +#, fuzzy, c-format +msgid "%s %s diff: program header count" +msgstr "Datei hat keinen Programm-Kopf" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, fuzzy, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "" + +#: src/elfcmp.c:330 +#, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "" + +#: src/elfcmp.c:353 +#, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "" + +#: src/elfcmp.c:451 +#, fuzzy, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "" + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "'%s' kann nicht geöffnet werden" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "" + +#: src/elfcompress.c:124 +#, fuzzy, c-format +msgid "-t option specified twice" +msgstr "Option -d zweimal angegeben" + +#: src/elfcompress.c:133 +#, fuzzy, c-format +msgid "unknown compression type '%s'" +msgstr "unbekannter Typ" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, fuzzy, c-format +msgid "No input file given" +msgstr "Eingabedatei '%s' ignoriert" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "" + +#: src/elfcompress.c:1307 +msgid "Place (de)compressed output into FILE" +msgstr "" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "" + +#: src/elfcompress.c:1325 +#, fuzzy +msgid "Be silent when a section cannot be compressed" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "" + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "" + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "Gebe nichts aus, wenn erfolgreich" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "" + +#: src/elflint.c:154 src/readelf.c:368 +#, fuzzy, c-format +msgid "cannot open input file '%s'" +msgstr "Kann Eingabedatei nicht öffnen" + +#: src/elflint.c:161 +#, fuzzy, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "kann Elf-Deskriptor nicht erzeugen: %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "Keine Fehler" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "Dateiname fehlt.\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr "" + +#. We cannot do anything. +#: src/elflint.c:292 +#, fuzzy, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "Keine ELF-Datei - sie hat die falschen Magic Bytes am Anfang\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "" + +#: src/elflint.c:380 +#, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] ist nicht null\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "" + +#: src/elflint.c:487 +#, fuzzy, c-format +msgid "invalid number of program header table entries\n" +msgstr "Ungültige Anzahl von Parametern.\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "" + +#: src/elflint.c:728 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" + +#: src/elflint.c:734 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "ungültiger Abschnittsindex" + +#: src/elflint.c:754 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:760 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:765 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" + +#: src/elflint.c:773 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" + +#: src/elflint.c:777 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" + +#: src/elflint.c:781 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" + +#: src/elflint.c:832 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:847 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" + +#: src/elflint.c:857 src/elflint.c:905 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:884 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" + +#: src/elflint.c:890 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" + +#: src/elflint.c:898 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:925 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" + +#: src/elflint.c:932 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" + +#: src/elflint.c:939 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" + +#: src/elflint.c:1063 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" + +#: src/elflint.c:1067 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:1105 +#, fuzzy, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "" + +#: src/elflint.c:1286 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "" + +#: src/elflint.c:1668 +#, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" + +#: src/elflint.c:1948 +#, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "" + +#: src/elflint.c:2140 +#, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "" + +#: src/elflint.c:2152 +#, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" + +#: src/elflint.c:2254 +#, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "" + +#: src/elflint.c:2330 +#, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "" + +#: src/elflint.c:2444 +#, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" + +#: src/elflint.c:2557 +#, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "" + +#: src/elflint.c:2664 +#, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "" + +#: src/elflint.c:2731 +#, fuzzy, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:2753 +#, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "" + +#: src/elflint.c:3974 +#, fuzzy, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:3979 +#, fuzzy, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr "" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "" + +#: src/elflint.c:4797 +#, fuzzy, c-format +msgid "cannot create backend for ELF file\n" +msgstr "neue Datei konnte nicht angelegt werden" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "" + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "" + +#: src/findtextrel.c:314 +#, fuzzy, c-format +msgid "cannot get program header count: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, fuzzy, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "Zeige nur definierte Symbole" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "Zeige dynamische Symbole anstelle normaler Symbole" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "Zeige nur externe Symbole" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "Zeige nur undefinierte Symbole" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "Ausgabeformat:" + +#: src/nm.c:79 +#, fuzzy +msgid "Print name of the input file before every symbol" +msgstr "Zeige Name der Eingabedatei vor jedem Symbol" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"Benutze das Ausgabeformat FORMAT. FORMAT kann `bsd', `sysv' or `posix' sein. " +"Der Standard ist `sysv'" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "Genau wie --format=bsd" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "Genau wie --format=posix" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "Benutze RADIX zur Ausgabe von Symbolwerten" + +#: src/nm.c:87 +#, fuzzy +msgid "Mark special symbols" +msgstr "Kennzeichne schwache Symbole" + +#: src/nm.c:89 +#, fuzzy +msgid "Print size of defined symbols" +msgstr "Zeige Grösse der definierten Symbole" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "Ausgabeoptionen:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "Symbole anhand der Adresse numerisch sortieren" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "Symbole nicht sortieren" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "Sortierreihenfolge umkehren" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "" + +#: src/nm.c:116 src/objdump.c:79 +#, fuzzy +msgid "Output formatting" +msgstr "Ausgabeformat:" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, fuzzy, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: INTERNER FEHLER %d (%s-%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "beim Schliessen von '%s'" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: Dateiformat nicht erkannt" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +#, fuzzy +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"Archiv-Index:" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "ungültiger Offset %zu für Symbol %s" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: Dateiformat nicht erkannt" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "Kann Suchbaum nicht erstellen" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"Symbole aus %s:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" + +#: src/nm.c:776 +msgctxt "sysv" +msgid "Name" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "" + +#: src/nm.c:1250 +#, fuzzy, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "%s: entry size in section `%s' is not what we expect" + +#: src/nm.c:1255 +#, fuzzy, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: entry size in section `%s' is not what we expect" + +#: src/nm.c:1336 +#, fuzzy, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "%s: entry size in section `%s' is not what we expect" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: Ungültige Operation" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: keine Symbole" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "" + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "" + +#: src/objdump.c:59 +#, fuzzy +msgid "Output content selection:" +msgstr "Eingabeauswahloptionen:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "" + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "" + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "Keine Operation angegeben.\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "OFFSET" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "Inhalt des Abschnitts %s:\n" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "Disassemblieren nicht möglich" + +#: src/objdump.c:760 +#, fuzzy, c-format +msgid "cannot create backend for elf file" +msgstr "neue Datei konnte nicht angelegt werden" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "Erstelle einen Index zur Beschleunigung des Zugriffs auf Archive." + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "ARCHIV" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "Archivname benötigt" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "'%s' ist kein Archiv" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "" + +#: src/readelf.c:97 +#, fuzzy +msgid "ELF input selection:" +msgstr "Eingabeauswahloptionen:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" + +#: src/readelf.c:104 +#, fuzzy +msgid "ELF output selection:" +msgstr "Eingabeauswahloptionen:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "Programm-Köpfe anzeigen" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "Relocations anzeigen" + +#: src/readelf.c:114 +#, fuzzy +msgid "Display the section groups" +msgstr "Programm-Köpfe anzeigen" + +#: src/readelf.c:115 +#, fuzzy +msgid "Display the sections' headers" +msgstr "Programm-Köpfe anzeigen" + +#: src/readelf.c:118 +#, fuzzy +msgid "Display the symbol table sections" +msgstr "Symboltabelle anzeigen" + +#: src/readelf.c:120 +#, fuzzy +msgid "Display (only) the dynamic symbol table" +msgstr "Zeige nur externe Symbole" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "Versionierungsinformationen anzeigen" + +#: src/readelf.c:122 +#, fuzzy +msgid "Display the ELF notes" +msgstr "Kernnotizen anzeigen" + +#: src/readelf.c:124 +#, fuzzy +msgid "Display architecture specific information, if any" +msgstr "Architekturspezifische Informationen anzeigen (falls vorhanden)" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "Abschnitte für Ausnahmebehandlung anzeigen" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "" + +#: src/readelf.c:130 +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "Symbolindex des Archivs anzeigen" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "Ausgabekontrolle:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "Keine symbolischen Namen für Adressen in DWARF-Daten suchen" + +#: src/readelf.c:145 +#, fuzzy +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "Keine symbolischen Namen für Adressen in DWARF-Daten suchen" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "Informationen aus der ELF-Datei in menschenlesbarer Form ausgeben." + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "ja" + +#: src/readelf.c:351 +msgid "no" +msgstr "nein" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "konnte Elf-Deskriptor nicht erzeugen: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "" + +#: src/readelf.c:663 +#, fuzzy, c-format +msgid "cannot get section name" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "" + +#: src/readelf.c:688 +#, fuzzy, c-format +msgid "cannot create temp file '%s'" +msgstr "neue Datei konnte nicht angelegt werden" + +#: src/readelf.c:697 +#, fuzzy, c-format +msgid "cannot write section data" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "" + +#: src/readelf.c:710 +#, fuzzy, c-format +msgid "error while rewinding file descriptor" +msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "Konnte '%s' nicht lesen: %s" + +#: src/readelf.c:881 +#, fuzzy, c-format +msgid "No such section '%s' in '%s'" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "" + +#: src/readelf.c:961 +#, fuzzy, c-format +msgid "cannot determine number of program headers: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/readelf.c:993 +#, fuzzy, c-format +msgid "cannot read ELF: %s" +msgstr "Konnte %s: %s nicht lesen" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" + +#: src/readelf.c:1084 +#, fuzzy, c-format +msgid " Data: %s\n" +msgstr " Daten: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr "" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(aktuell)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr "" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr "" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " Typ: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr "" + +#: src/readelf.c:1109 +#, fuzzy, c-format +msgid " Machine: : 0x%x\n" +msgstr " Daten: %s\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr "" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr "" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr "" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr "" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr "" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr "" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(Bytes)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr "" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr "" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr "" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr "" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr "" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr "" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr "" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr "" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, fuzzy, c-format +msgid "cannot get number of sections: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/readelf.c:1233 +#, fuzzy, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr " %s: %\n" + +#: src/readelf.c:1242 +#, fuzzy, c-format +msgid "cannot get section header string table index: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1335 +#, c-format +msgid "bad compression header for section %zd: %s" +msgstr "" + +#: src/readelf.c:1346 +#, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "Programm-Köpfe:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:1623 +msgid "" +msgstr "" + +#: src/readelf.c:1637 +msgid "" +msgstr "" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, fuzzy, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, fuzzy, c-format +msgid "invalid sh_link value in section %zu" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr "" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +msgstr[1] "" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr "" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr "" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr "" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr "" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr "" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr "" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "" + +#: src/readelf.c:2680 +msgid "none" +msgstr "keine" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| " + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2749 +#, fuzzy, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: Version: %hu Datei: %s Cnt: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: Name: %s Flags: %s Version: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr "" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr "" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *lokal* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *global* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr "" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "" + +#: src/readelf.c:3254 +#, fuzzy, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:3283 +#, fuzzy, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:3318 +#, fuzzy, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:3349 +#, fuzzy, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:3385 +#, fuzzy, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr "" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " File: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %, %s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, fuzzy, c-format +msgid "sprintf failure" +msgstr "mprotect fehlgeschlagen" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "" + +#: src/readelf.c:4800 +#, c-format +msgid "%*s[%2] %s \n" +msgstr "" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr "" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr "" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr "" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr "" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" + +#: src/readelf.c:5182 +#, fuzzy, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, fuzzy, c-format +msgid " Length: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, fuzzy, c-format +msgid " DWARF version: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, fuzzy, c-format +msgid " Address size: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, fuzzy, c-format +msgid " Segment size: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, fuzzy, c-format +msgid "Unknown version" +msgstr "unbekannte Version" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, fuzzy, c-format +msgid "unsupported address size" +msgstr "Kein Adress-Wert" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "" + +#: src/readelf.c:5511 +#, fuzzy, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr " %s: %\n" + +#: src/readelf.c:5523 +#, fuzzy, c-format +msgid " DWARF version: %6\n" +msgstr " %s: %\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "" + +#: src/readelf.c:5538 +#, fuzzy, c-format +msgid " CU offset: %6\n" +msgstr " %s: %\n" + +#: src/readelf.c:5544 +#, c-format +msgid " Address size: %6\n" +msgstr "" + +#: src/readelf.c:5555 +#, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr "" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr "" + +#: src/readelf.c:5654 +#, fuzzy, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, fuzzy, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr " %s: %\n" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, fuzzy, c-format +msgid " Offset entries: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr "" + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr "" + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr "" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, fuzzy, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " %s: %\n" + +#: src/readelf.c:5823 +#, fuzzy, c-format +msgid "invalid range list data" +msgstr "Ungültige Daten" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr "" + +#: src/readelf.c:6097 src/readelf.c:9719 +#, fuzzy +msgid "base address" +msgstr "Außerhalb des Adressbereiches" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, fuzzy, c-format +msgid " [%6tx] empty list\n" +msgstr " [%6tx] %s..%s\n" + +#: src/readelf.c:6367 +msgid " \n" +msgstr "" + +#: src/readelf.c:6624 +#, fuzzy, c-format +msgid "cannot get ELF: %s" +msgstr "ELF Kopf konnte nicht ausgelesen werden" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, fuzzy, c-format +msgid "invalid augmentation length" +msgstr "ungültige Abschnittsausrichtung" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "" + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "" + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr "" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr "" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr "" + +#: src/readelf.c:7053 +#, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "" + +#: src/readelf.c:7063 +#, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "" + +#: src/readelf.c:7085 +#, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "" + +#: src/readelf.c:7415 +#, fuzzy, c-format +msgid "invalid file (%): %s" +msgstr "Ungültige Datei" + +#: src/readelf.c:7419 +#, fuzzy, c-format +msgid "no srcfiles for CU [%]" +msgstr "unbekannte Form %" + +#: src/readelf.c:7423 +#, fuzzy, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "ELF Kopf konnte nicht ausgelesen werden" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" + +#: src/readelf.c:7788 +#, fuzzy, c-format +msgid "cannot get next unit: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:7808 +#, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr "" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "" + +#: src/readelf.c:7895 +#, fuzzy, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "" + +#: src/readelf.c:7985 +#, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" + +#: src/readelf.c:8037 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" + +#: src/readelf.c:8369 +#, fuzzy, c-format +msgid "unknown form: %s" +msgstr "unbekannte Form %" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" + +#: src/readelf.c:8524 +#, fuzzy, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "ungültige .debug_line Sektion" + +#: src/readelf.c:8532 +#, fuzzy, c-format +msgid "cannot handle address size: %u\n" +msgstr "Kein Adress-Wert" + +#: src/readelf.c:8540 +#, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, fuzzy, c-format +msgid " [" +msgstr " %s: %s\n" + +#: src/readelf.c:8653 +msgid "" +"\n" +"File name table:" +msgstr "" + +#: src/readelf.c:8714 +msgid " Entry Dir Time Size Name" +msgstr "" + +#: src/readelf.c:8753 +msgid "" +"\n" +"No line number statements." +msgstr "" + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "" + +#: src/readelf.c:8811 +#, c-format +msgid " special opcode %u: address+%u = " +msgstr "" + +#: src/readelf.c:8815 +#, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr "" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr "" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr "" + +#: src/readelf.c:8841 +msgid " end of sequence" +msgstr "" + +#: src/readelf.c:8859 +#, fuzzy, c-format +msgid " set address to " +msgstr "Außerhalb des Adressbereiches" + +#: src/readelf.c:8887 +#, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr "" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr "" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +#, fuzzy +msgid " unknown opcode" +msgstr "unbekannter Typ" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr "" + +#: src/readelf.c:8929 +#, c-format +msgid " advance address by %u to " +msgstr "" + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr "" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr "" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr "" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr "" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr "" + +#: src/readelf.c:8990 +#, c-format +msgid " advance address by constant %u to " +msgstr "" + +#: src/readelf.c:9010 +#, c-format +msgid " advance address by fixed value %u to \n" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr "" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr "" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:9084 +#, fuzzy, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "konnte Eintrag aus der Symboltabelle nicht holen: %s" + +#: src/readelf.c:9250 +#, c-format +msgid " \n" +msgstr "" + +#: src/readelf.c:9290 +#, fuzzy, c-format +msgid "invalid loclists data" +msgstr "Ungültige Daten" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr "" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "" + +#: src/readelf.c:9914 +#, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "" + +#: src/readelf.c:10015 +#, fuzzy, c-format +msgid " Offset: 0x%\n" +msgstr " %s: %\n" + +#: src/readelf.c:10027 +#, fuzzy, c-format +msgid " Version: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr "" + +#: src/readelf.c:10040 +#, fuzzy, c-format +msgid " Flag: 0x%" +msgstr " %s: %\n" + +#: src/readelf.c:10069 +#, c-format +msgid " Offset length: %\n" +msgstr "" + +#: src/readelf.c:10077 +#, c-format +msgid " .debug_line offset: 0x%\n" +msgstr "" + +#: src/readelf.c:10102 +#, c-format +msgid " extension opcode table, % items:\n" +msgstr "" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr "" + +#: src/readelf.c:10121 +#, c-format +msgid " % arguments:" +msgstr "" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr "" + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr "" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "" + +#: src/readelf.c:10396 +#, c-format +msgid " *** error, missing string terminator\n" +msgstr "" + +#: src/readelf.c:10425 +#, fuzzy, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:10524 +#, fuzzy, c-format +msgid " Length: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:10526 +#, fuzzy, c-format +msgid " Offset size: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:10540 +#, fuzzy, c-format +msgid " DWARF version: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:10549 +#, fuzzy, c-format +msgid " Padding: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr "" + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr "" + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr "" + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "" + +#: src/readelf.c:10882 +#, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" + +#: src/readelf.c:10911 +#, fuzzy, c-format +msgid " Version: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:10929 +#, c-format +msgid " CU offset: %#\n" +msgstr "" + +#: src/readelf.c:10936 +#, c-format +msgid " TU offset: %#\n" +msgstr "" + +#: src/readelf.c:10943 +#, c-format +msgid " address offset: %#\n" +msgstr "" + +#: src/readelf.c:10950 +#, c-format +msgid " symbol offset: %#\n" +msgstr "" + +#: src/readelf.c:10957 +#, c-format +msgid " constant offset: %#\n" +msgstr "" + +#: src/readelf.c:10971 +#, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" + +#: src/readelf.c:10996 +#, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" + +#: src/readelf.c:11025 +#, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" + +#: src/readelf.c:11057 +#, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr "" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr "" + +#: src/readelf.c:12518 +#, fuzzy, c-format +msgid "cannot get content of note: %s" +msgstr "Konnte Inhalt von %s: %s nicht lesen" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12622 +#, fuzzy, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, fuzzy, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:12654 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12659 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" + +#: src/readelf.c:12673 +#, fuzzy, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/readelf.c:12705 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12710 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" + +#: src/readelf.c:12853 +#, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" + +#: src/readelf.c:12871 +#, fuzzy, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "Genau wie `--format=sysv'" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "Genau wie `--format=bsd'" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "Genau wie `--radix=10'" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "Genau wie `--radix=8'" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "Genau wie `--radix=16'" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "" + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "Ungültiges Format: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr "" + +#: src/size.c:420 +#, fuzzy +#| msgid "invalid section" +msgctxt "sysv" +msgid "section" +msgstr "ungültiger Abschnitt" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "" + +#: src/size.c:482 +#, fuzzy, c-format +msgid "cannot get section header" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "" + +#: src/stack.c:493 +#, fuzzy, c-format +msgid "Cannot open core file '%s'" +msgstr "Konnte Archiv '%s' nicht öffnen" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "" + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "" + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "" + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "" + +#: src/stack.c:645 +#, fuzzy +msgid "Show stack of process PID" +msgstr "Kann Suchbaum nicht erstellen" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "" + +#: src/stack.c:652 +#, fuzzy +msgid "Output selection options:" +msgstr "Eingabeauswahloptionen:" + +#: src/stack.c:654 +msgid "Additionally show frame activation" +msgstr "" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "" + +#: src/stack.c:663 +msgid "Additionally show source file information" +msgstr "" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "" + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "" + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "" + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "Alias für --radix=o" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "" + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "" + +#: src/strings.c:585 +#, fuzzy, c-format +msgid "lseek failed" +msgstr "lseek64 fehlgeschlagen" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "re-mmap fehlgeschlagen" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "mprotect fehlgeschlagen" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "" + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "" + +#: src/strip.c:362 +#, c-format +msgid "cannot both keep and remove .comment section" +msgstr "" + +#: src/strip.c:481 +#, fuzzy, c-format +msgid "bad relocation" +msgstr "Relocations anzeigen" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, fuzzy, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: Kein Eintrag %s in dem Archiv!\n" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "" + +#: src/strip.c:1092 +#, fuzzy, c-format +msgid "cannot get number of phdrs" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/strip.c:1106 src/strip.c:1149 +#, fuzzy, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "neue Datei konnte nicht angelegt werden" + +#: src/strip.c:1116 src/strip.c:1159 +#, fuzzy, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "neue Datei konnte nicht angelegt werden" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "" + +#: src/strip.c:1250 +#, fuzzy, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/strip.c:1259 +#, fuzzy, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "Konnte Archiv '%s' nicht öffnen" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "" + +#: src/strip.c:1688 +#, fuzzy, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n" + +#: src/strip.c:1697 +#, fuzzy, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n" + +#: src/strip.c:1705 src/strip.c:2550 +#, fuzzy, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "" + +#: src/strip.c:1866 +#, c-format +msgid "no memory to create section header string table" +msgstr "" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "" + +#: src/strip.c:2599 src/strip.c:2619 +#, fuzzy, c-format +msgid "while writing '%s'" +msgstr "beim Schliessen von '%s'" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "Option -d zweimal angegeben" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "nur entweder -o oder -d erlaubt" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "-n kann nicht mit expliziten Dateien oder -o oder -d verwendet werden" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "Ausgabeverzeichnis '%s'" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "genau zwei Datei-Argumente werden benötigt" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "" + +#: src/unstrip.c:240 +#, fuzzy, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "" + +#: src/unstrip.c:254 +#, fuzzy, c-format +msgid "cannot get new zero section: %s" +msgstr "konnte Versionierungsabschnitt nicht erstellen: %s" + +#: src/unstrip.c:257 +#, fuzzy, c-format +msgid "cannot update new zero section: %s" +msgstr "konnte Versionierungsabschnitt nicht erstellen: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, fuzzy, c-format +msgid "cannot get number of program headers: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "konnte Programm-Kopf nicht kopieren: %s" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "konnte Abschnittsdaten nicht kopieren: %s" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "konnte Verzeichnis nicht erstellen: %s" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "konnte Eintrag aus der Symboltabelle nicht holen: %s" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "konnte Symboltabelle nicht aktualisieren: %s" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "" + +#: src/unstrip.c:848 +#, fuzzy, c-format +msgid "cannot get symbol section data: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:850 +#, fuzzy, c-format +msgid "cannot get string section data: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:867 +#, fuzzy, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "ungültiger Offset %zu für Symbol %s" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, fuzzy, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:1040 +#, fuzzy, c-format +msgid "bad sh_link for group section: %s" +msgstr "ungültige .debug_line Sektion" + +#: src/unstrip.c:1046 +#, fuzzy, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "konnte Versionierungsabschnitt nicht erstellen: %s" + +#: src/unstrip.c:1051 +#, fuzzy, c-format +msgid "bad data for group symbol section: %s" +msgstr "ungültige .debug_line Sektion" + +#: src/unstrip.c:1057 +#, fuzzy, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/unstrip.c:1062 +#, fuzzy, c-format +msgid "bad symbol name for group section: %s" +msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, fuzzy, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "" + +#: src/unstrip.c:1758 +#, fuzzy, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "ungültiger Abschnittsindex" + +#: src/unstrip.c:1790 +#, fuzzy, c-format +msgid "group has invalid section index [%zd]" +msgstr "ungültiger Abschnittsindex" + +#: src/unstrip.c:2065 +#, fuzzy, c-format +msgid "cannot read section data: %s" +msgstr "konnte Abschnittsdaten nicht holen: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "konnte Programm-Kopf nicht aktualisieren: %s" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "" + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr "" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "kein passendes Modul gefunden" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "mehr als ein passendes Modul" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "" + +#: tests/dwflmodtest.c:209 +msgid "Additionally show function names" +msgstr "" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "" + +#~ msgid "%s+%# <%s+%#>" +#~ msgstr "%s+%# <%s+%#>" + +#~ msgid "%s+%#0* <%s+%#>" +#~ msgstr "%s+%#0* <%s+%#>" + +#~ msgid "%# <%s+%#>" +#~ msgstr "%# <%s+%#>" + +#~ msgid "%#0* <%s+%#>" +#~ msgstr "%#0* <%s+%#>" + +#~ msgid "%s+%# <%s>" +#~ msgstr "%s+%# <%s>" + +#~ msgid "%s+%#0* <%s>" +#~ msgstr "%s+%#0* <%s>" + +#~ msgid "%# <%s>" +#~ msgstr "%# <%s>" + +#~ msgid "%#0* <%s>" +#~ msgstr "%#0* <%s>" + +#~ msgid "%s+%#" +#~ msgstr "%s+%#" + +#~ msgid "%s+%#0*" +#~ msgstr "%s+%#0*" + +#, fuzzy +#~ msgid " %s..%s (%)\n" +#~ msgstr " %s: %\n" + +#, fuzzy +#~ msgid " %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#~ msgid " [%6tx] %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#~ msgid " %s..%s\n" +#~ msgstr " %s..%s\n" + +#~ msgid " [%6tx] %s..%s" +#~ msgstr " [%6tx] %s..%s" + +#~ msgid " %s..%s" +#~ msgstr " %s..%s" + +#~ msgid "Written by %s.\n" +#~ msgstr "Geschrieben von %s.\n" + +#~ msgid "FILE" +#~ msgstr "DATEI" + +#~ msgid "Start a group." +#~ msgstr "Eine Gruppe starten." + +#~ msgid "End a group." +#~ msgstr "Eine Gruppe beenden." + +#~ msgid "PATH" +#~ msgstr "PFAD" + +#~ msgid "Same as --whole-archive." +#~ msgstr "Genau wie --whole-archive." + +#~ msgid "ADDRESS" +#~ msgstr "ADRESSE" + +#~ msgid "[FILE]..." +#~ msgstr "[DATEI]..." + +#~ msgid "At least one input file needed" +#~ msgstr "Mindestens eine Eingabedatei benötigt" + +#~ msgid "-( without matching -)" +#~ msgstr "-( ohne Übereinstimmung -)" + +#~ msgid "only one option of -G and -r is allowed" +#~ msgstr "nur eine Option aus -G und -r erlaubt" + +#~ msgid "-) without matching -(" +#~ msgstr "-) ohne Übereinstimmung -(" + +#~ msgid "unknown option '-%c %s'" +#~ msgstr "unbekannte Option '-%c %s'" + +#~ msgid "undefined symbol `%s' in %s" +#~ msgstr "undefiniertes Symbol `%s' in %s" + +#~ msgid "cannot create versioning data: %s" +#~ msgstr "konnte Versionierungsdaten nicht erstellen: %s" + +#~ msgid "cannot create program header: %s" +#~ msgstr "konnte Programm-Kopf nicht erstellen: %s" + +#~ msgid "default visibility set as local and global" +#~ msgstr "Standard-Sichtbarkeit auf lokal und global gesetzt" + +#, fuzzy +#~ msgid "cannot attach to core" +#~ msgstr "Kann Suchbaum nicht erstellen" + +#~ msgid "unknown tag %hx" +#~ msgstr "unbekannter Tag %hx" + +#~ msgid "unknown user tag %hx" +#~ msgstr "unbekannter Benutzer-Tag %hx" + +#~ msgid "unknown attribute %hx" +#~ msgstr "unbekanntes Attribut %hx" + +#~ msgid "unknown user attribute %hx" +#~ msgstr "unbekanntes Benutzer-Attribut %hx" + +#~ msgid "" +#~ "\n" +#~ "\n" +#~ "Symbols from %s[%s]:\n" +#~ "\n" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "Symbole aus %s[%s]:\n" +#~ "\n" + +#~ msgid "Equivalent to: -e -h -l" +#~ msgstr "Entspricht: -e -h -l" diff --git a/po/elfutils.pot b/po/elfutils.pot new file mode 100644 index 00000000..e4957cb0 --- /dev/null +++ b/po/elfutils.pot @@ -0,0 +1,6781 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The elfutils developers +# This file is distributed under the same license as the elfutils package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: elfutils 0.185\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" + +#: lib/color.c:194 src/objdump.c:728 +#, c-format +msgid "cannot allocate memory" +msgstr "" + +#: lib/printversion.c:40 +#, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "" + +#: libcpu/i386_lex.l:122 +#, c-format +msgid "invalid character '%c' at line %d; ignored" +msgstr "" + +#: libcpu/i386_lex.l:123 +#, c-format +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "" + +#: libcpu/i386_parse.y:554 +#, c-format +msgid "while reading i386 CPU description: %s at line %d" +msgstr "" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "" + +#: libdw/dwarf_error.c:75 +msgid ".debug_str section missing" +msgstr "" + +#: libdw/dwarf_error.c:76 +msgid ".debug_line_str section missing" +msgstr "" + +#: libdw/dwarf_error.c:77 +msgid ".debug_str_offsets section missing" +msgstr "" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr "" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "" + +#: libdw/dwarf_error.c:88 +msgid ".debug_loc section missing" +msgstr "" + +#: libdw/dwarf_error.c:89 +msgid ".debug_loclists section missing" +msgstr "" + +#: libdw/dwarf_error.c:90 +msgid "not a location list value" +msgstr "" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr "" + +#: libdw/dwarf_error.c:98 +msgid ".debug_rnglists section missing" +msgstr "" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "" + +#: libdw/dwarf_error.c:101 +msgid "invalid opcode" +msgstr "" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "" + +#: libdw/dwarf_error.c:103 +msgid "unknown language code" +msgstr "" + +#: libdw/dwarf_error.c:104 +msgid ".debug_addr section missing" +msgstr "" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "" + +#: libdwfl/argp-std.c:317 +msgid "Not enough memory" +msgstr "" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:61 +msgid "zstd decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "" + +#: libdwfl/libdwflP.h:67 +msgid "relocation refers to undefined symbol" +msgstr "" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "" + +#: libdwfl/libdwflP.h:69 +msgid "No DWARF information found" +msgstr "" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "" + +#: libdwfl/libdwflP.h:71 +msgid "No ELF program headers" +msgstr "" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "" + +#: libdwfl/libdwflP.h:76 +msgid "ELF file opened" +msgstr "" + +#: libdwfl/libdwflP.h:77 +msgid "not a valid ELF file" +msgstr "" + +#: libdwfl/libdwflP.h:78 +msgid "cannot handle DWARF type description" +msgstr "" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "" + +#: libdwfl/libdwflP.h:80 +msgid "corrupt .gnu.prelink_undo section data" +msgstr "" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "" + +#: libdwfl/libdwflP.h:83 +msgid "Invalid register" +msgstr "" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "" + +#: libdwfl/libdwflP.h:87 +msgid "Invalid DWARF" +msgstr "" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "" + +#: libdwfl/libdwflP.h:93 +msgid "Invalid argument" +msgstr "" + +#: libdwfl/libdwflP.h:94 +msgid "Not an ET_CORE ELF file" +msgstr "" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr "" + +#: libebl/eblobjnote.c:58 +#, c-format +msgid "unknown SDT version %u\n" +msgstr "" + +#: libebl/eblobjnote.c:76 +#, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr "" + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr "" + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr "" + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr "" + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr "" + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr "" + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr "" + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr "" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr "" + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr "" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "" + +#: libelf/elf_error.c:99 +msgid "invalid ELF file data" +msgstr "" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "" + +#: libelf/elf_error.c:171 +msgid "archive/member file descriptor mismatch" +msgstr "" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "" + +#: libelf/elf_error.c:241 +msgid "invalid section type" +msgstr "" + +#: libelf/elf_error.c:246 +msgid "invalid section flags" +msgstr "" + +#: libelf/elf_error.c:251 +msgid "section does not contain compressed data" +msgstr "" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "" + +#: libelf/elf_error.c:261 +msgid "unknown compression type" +msgstr "" + +#: libelf/elf_error.c:266 +msgid "cannot compress data" +msgstr "" + +#: libelf/elf_error.c:271 +msgid "cannot decompress data" +msgstr "" + +#: src/addr2line.c:57 +msgid "Input format options:" +msgstr "" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "" + +#: src/addr2line.c:61 +msgid "Output format options:" +msgstr "" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "" + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "" + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "" + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "" + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "" + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "" + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "" + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "" + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "" + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "" + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "" + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "" + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "" + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "" + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "" + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "" + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "" + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "" + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "" + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "" + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "" + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "" + +#: src/ar.c:1483 +#, c-format +msgid "cannot represent ar_date" +msgstr "" + +#: src/ar.c:1489 +#, c-format +msgid "cannot represent ar_uid" +msgstr "" + +#: src/ar.c:1495 +#, c-format +msgid "cannot represent ar_gid" +msgstr "" + +#: src/ar.c:1501 +#, c-format +msgid "cannot represent ar_mode" +msgstr "" + +#: src/ar.c:1507 +#, c-format +msgid "cannot represent ar_size" +msgstr "" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "" + +#: src/elfclassify.c:245 +msgid "ELF header" +msgstr "" + +#: src/elfclassify.c:256 +msgid "program headers" +msgstr "" + +#: src/elfclassify.c:265 +msgid "program header" +msgstr "" + +#: src/elfclassify.c:285 +msgid "section headers" +msgstr "" + +#: src/elfclassify.c:296 +msgid "section header string table index" +msgstr "" + +#: src/elfclassify.c:310 +msgid "could not obtain section header" +msgstr "" + +#: src/elfclassify.c:316 +msgid "could not obtain section name" +msgstr "" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "" + +#: src/elfclassify.c:877 +msgid "Classification options" +msgstr "" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "" + +#: src/elfclassify.c:907 +msgid "File is a linux kernel module" +msgstr "" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "" + +#: src/elfclassify.c:956 +msgid "Output flags" +msgstr "" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "" + +#: src/elfclassify.c:962 +msgid "Do not output file names" +msgstr "" + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "" + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, c-format +msgid "cannot get section count of '%s': %s" +msgstr "" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "" + +#: src/elfcmp.c:233 +#, c-format +msgid "%s %s diff: program header count" +msgstr "" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "" + +#: src/elfcmp.c:330 +#, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "" + +#: src/elfcmp.c:353 +#, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "" + +#: src/elfcmp.c:451 +#, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "" + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "" + +#: src/elfcompress.c:124 +#, c-format +msgid "-t option specified twice" +msgstr "" + +#: src/elfcompress.c:133 +#, c-format +msgid "unknown compression type '%s'" +msgstr "" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, c-format +msgid "No input file given" +msgstr "" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "" + +#: src/elfcompress.c:1307 +msgid "Place (de)compressed output into FILE" +msgstr "" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "" + +#: src/elfcompress.c:1325 +msgid "Be silent when a section cannot be compressed" +msgstr "" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "" + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "" + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "" + +#: src/elflint.c:154 src/readelf.c:368 +#, c-format +msgid "cannot open input file '%s'" +msgstr "" + +#: src/elflint.c:161 +#, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr "" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "" + +#: src/elflint.c:380 +#, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "" + +#: src/elflint.c:487 +#, c-format +msgid "invalid number of program header table entries\n" +msgstr "" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "" + +#: src/elflint.c:728 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" + +#: src/elflint.c:734 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "" + +#: src/elflint.c:754 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "" + +#: src/elflint.c:760 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "" + +#: src/elflint.c:765 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" + +#: src/elflint.c:773 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" + +#: src/elflint.c:777 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" + +#: src/elflint.c:781 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" + +#: src/elflint.c:832 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:847 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" + +#: src/elflint.c:857 src/elflint.c:905 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:884 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" + +#: src/elflint.c:890 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" + +#: src/elflint.c:898 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:925 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" + +#: src/elflint.c:932 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" + +#: src/elflint.c:939 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" + +#: src/elflint.c:1063 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" + +#: src/elflint.c:1067 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "" + +#: src/elflint.c:1105 +#, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "" + +#: src/elflint.c:1286 +#, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "" + +#: src/elflint.c:1668 +#, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" + +#: src/elflint.c:1948 +#, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "" + +#: src/elflint.c:2140 +#, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "" + +#: src/elflint.c:2152 +#, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" + +#: src/elflint.c:2254 +#, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "" + +#: src/elflint.c:2330 +#, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "" + +#: src/elflint.c:2444 +#, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" + +#: src/elflint.c:2557 +#, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "" + +#: src/elflint.c:2664 +#, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "" + +#: src/elflint.c:2731 +#, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:2753 +#, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "" + +#: src/elflint.c:3974 +#, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "" + +#: src/elflint.c:3979 +#, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr "" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "" + +#: src/elflint.c:4797 +#, c-format +msgid "cannot create backend for ELF file\n" +msgstr "" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "" + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "" + +#: src/findtextrel.c:314 +#, c-format +msgid "cannot get program header count: %s" +msgstr "" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "" + +#: src/nm.c:87 +msgid "Mark special symbols" +msgstr "" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "" + +#: src/nm.c:116 src/objdump.c:79 +msgid "Output formatting" +msgstr "" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +msgid "" +"\n" +"Archive index:\n" +msgstr "" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" + +#: src/nm.c:776 +msgctxt "sysv" +msgid "Name" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "" + +#: src/nm.c:1250 +#, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "" + +#: src/nm.c:1255 +#, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "" + +#: src/nm.c:1336 +#, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "" + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "" + +#: src/objdump.c:59 +msgid "Output content selection:" +msgstr "" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "" + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "" + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "" + +#: src/objdump.c:760 +#, c-format +msgid "cannot create backend for elf file" +msgstr "" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "" + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "" + +#: src/readelf.c:97 +msgid "ELF input selection:" +msgstr "" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" + +#: src/readelf.c:104 +msgid "ELF output selection:" +msgstr "" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "" + +#: src/readelf.c:114 +msgid "Display the section groups" +msgstr "" + +#: src/readelf.c:115 +msgid "Display the sections' headers" +msgstr "" + +#: src/readelf.c:118 +msgid "Display the symbol table sections" +msgstr "" + +#: src/readelf.c:120 +msgid "Display (only) the dynamic symbol table" +msgstr "" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "" + +#: src/readelf.c:122 +msgid "Display the ELF notes" +msgstr "" + +#: src/readelf.c:124 +msgid "Display architecture specific information, if any" +msgstr "" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "" + +#: src/readelf.c:130 +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "" + +#: src/readelf.c:145 +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "" + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "" + +#: src/readelf.c:351 +msgid "no" +msgstr "" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "" + +#: src/readelf.c:663 +#, c-format +msgid "cannot get section name" +msgstr "" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "" + +#: src/readelf.c:688 +#, c-format +msgid "cannot create temp file '%s'" +msgstr "" + +#: src/readelf.c:697 +#, c-format +msgid "cannot write section data" +msgstr "" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "" + +#: src/readelf.c:710 +#, c-format +msgid "error while rewinding file descriptor" +msgstr "" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "" + +#: src/readelf.c:881 +#, c-format +msgid "No such section '%s' in '%s'" +msgstr "" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "" + +#: src/readelf.c:961 +#, c-format +msgid "cannot determine number of program headers: %s" +msgstr "" + +#: src/readelf.c:993 +#, c-format +msgid "cannot read ELF: %s" +msgstr "" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr "" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr "" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr "" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr "" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr "" + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr "" + +#: src/readelf.c:1109 +#, c-format +msgid " Machine: : 0x%x\n" +msgstr "" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr "" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr "" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr "" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr "" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr "" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr "" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr "" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr "" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr "" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr "" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr "" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr "" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr "" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr "" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, c-format +msgid "cannot get number of sections: %s" +msgstr "" + +#: src/readelf.c:1233 +#, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" + +#: src/readelf.c:1242 +#, c-format +msgid "cannot get section header string table index: %s" +msgstr "" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1335 +#, c-format +msgid "bad compression header for section %zd: %s" +msgstr "" + +#: src/readelf.c:1346 +#, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:1623 +msgid "" +msgstr "" + +#: src/readelf.c:1637 +msgid "" +msgstr "" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, c-format +msgid "invalid sh_link value in section %zu" +msgstr "" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr "" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +msgstr[1] "" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr "" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr "" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr "" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr "" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr "" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr "" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "" + +#: src/readelf.c:2680 +msgid "none" +msgstr "" + +#: src/readelf.c:2697 +msgid "| " +msgstr "" + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr "" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr "" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr "" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr "" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr "" + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr "" + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr "" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr "" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "" + +#: src/readelf.c:3254 +#, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "" + +#: src/readelf.c:3283 +#, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "" + +#: src/readelf.c:3318 +#, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "" + +#: src/readelf.c:3349 +#, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "" + +#: src/readelf.c:3385 +#, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr "" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr "" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr "" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr "" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr "" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr "" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr "" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr "" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr "" + +#: src/readelf.c:3837 +#, c-format +msgid "sprintf failure" +msgstr "" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "" + +#: src/readelf.c:4800 +#, c-format +msgid "%*s[%2] %s \n" +msgstr "" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr "" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr "" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr "" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr "" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" + +#: src/readelf.c:5182 +#, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, c-format +msgid " Length: %8\n" +msgstr "" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, c-format +msgid " DWARF version: %8\n" +msgstr "" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, c-format +msgid " Address size: %8\n" +msgstr "" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, c-format +msgid " Segment size: %8\n" +msgstr "" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, c-format +msgid "Unknown version" +msgstr "" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, c-format +msgid "unsupported address size" +msgstr "" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr "" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "" + +#: src/readelf.c:5511 +#, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr "" + +#: src/readelf.c:5523 +#, c-format +msgid " DWARF version: %6\n" +msgstr "" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "" + +#: src/readelf.c:5538 +#, c-format +msgid " CU offset: %6\n" +msgstr "" + +#: src/readelf.c:5544 +#, c-format +msgid " Address size: %6\n" +msgstr "" + +#: src/readelf.c:5555 +#, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr "" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr "" + +#: src/readelf.c:5654 +#, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr "" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, c-format +msgid " Offset entries: %8\n" +msgstr "" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr "" + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr "" + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr "" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, c-format +msgid " Offsets starting at 0x%:\n" +msgstr "" + +#: src/readelf.c:5823 +#, c-format +msgid "invalid range list data" +msgstr "" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr "" + +#: src/readelf.c:6097 src/readelf.c:9719 +msgid "base address" +msgstr "" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, c-format +msgid " [%6tx] empty list\n" +msgstr "" + +#: src/readelf.c:6367 +msgid " \n" +msgstr "" + +#: src/readelf.c:6624 +#, c-format +msgid "cannot get ELF: %s" +msgstr "" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, c-format +msgid "invalid augmentation length" +msgstr "" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "" + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "" + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr "" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr "" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr "" + +#: src/readelf.c:7053 +#, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "" + +#: src/readelf.c:7063 +#, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "" + +#: src/readelf.c:7085 +#, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "" + +#: src/readelf.c:7415 +#, c-format +msgid "invalid file (%): %s" +msgstr "" + +#: src/readelf.c:7419 +#, c-format +msgid "no srcfiles for CU [%]" +msgstr "" + +#: src/readelf.c:7423 +#, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" + +#: src/readelf.c:7788 +#, c-format +msgid "cannot get next unit: %s" +msgstr "" + +#: src/readelf.c:7808 +#, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr "" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "" + +#: src/readelf.c:7895 +#, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "" + +#: src/readelf.c:7985 +#, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" + +#: src/readelf.c:8037 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" + +#: src/readelf.c:8369 +#, c-format +msgid "unknown form: %s" +msgstr "" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" + +#: src/readelf.c:8524 +#, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "" + +#: src/readelf.c:8532 +#, c-format +msgid "cannot handle address size: %u\n" +msgstr "" + +#: src/readelf.c:8540 +#, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, c-format +msgid " [" +msgstr "" + +#: src/readelf.c:8653 +msgid "" +"\n" +"File name table:" +msgstr "" + +#: src/readelf.c:8714 +msgid " Entry Dir Time Size Name" +msgstr "" + +#: src/readelf.c:8753 +msgid "" +"\n" +"No line number statements." +msgstr "" + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "" + +#: src/readelf.c:8811 +#, c-format +msgid " special opcode %u: address+%u = " +msgstr "" + +#: src/readelf.c:8815 +#, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr "" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr "" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr "" + +#: src/readelf.c:8841 +msgid " end of sequence" +msgstr "" + +#: src/readelf.c:8859 +#, c-format +msgid " set address to " +msgstr "" + +#: src/readelf.c:8887 +#, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr "" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr "" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +msgid " unknown opcode" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr "" + +#: src/readelf.c:8929 +#, c-format +msgid " advance address by %u to " +msgstr "" + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr "" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr "" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr "" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr "" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr "" + +#: src/readelf.c:8990 +#, c-format +msgid " advance address by constant %u to " +msgstr "" + +#: src/readelf.c:9010 +#, c-format +msgid " advance address by fixed value %u to \n" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr "" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr "" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr "" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] "" +msgstr[1] "" + +#: src/readelf.c:9084 +#, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "" + +#: src/readelf.c:9250 +#, c-format +msgid " \n" +msgstr "" + +#: src/readelf.c:9290 +#, c-format +msgid "invalid loclists data" +msgstr "" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr "" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "" + +#: src/readelf.c:9914 +#, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "" + +#: src/readelf.c:10015 +#, c-format +msgid " Offset: 0x%\n" +msgstr "" + +#: src/readelf.c:10027 +#, c-format +msgid " Version: %\n" +msgstr "" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr "" + +#: src/readelf.c:10040 +#, c-format +msgid " Flag: 0x%" +msgstr "" + +#: src/readelf.c:10069 +#, c-format +msgid " Offset length: %\n" +msgstr "" + +#: src/readelf.c:10077 +#, c-format +msgid " .debug_line offset: 0x%\n" +msgstr "" + +#: src/readelf.c:10102 +#, c-format +msgid " extension opcode table, % items:\n" +msgstr "" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr "" + +#: src/readelf.c:10121 +#, c-format +msgid " % arguments:" +msgstr "" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr "" + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr "" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "" + +#: src/readelf.c:10396 +#, c-format +msgid " *** error, missing string terminator\n" +msgstr "" + +#: src/readelf.c:10425 +#, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "" + +#: src/readelf.c:10524 +#, c-format +msgid " Length: %8\n" +msgstr "" + +#: src/readelf.c:10526 +#, c-format +msgid " Offset size: %8\n" +msgstr "" + +#: src/readelf.c:10540 +#, c-format +msgid " DWARF version: %8\n" +msgstr "" + +#: src/readelf.c:10549 +#, c-format +msgid " Padding: %8\n" +msgstr "" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr "" + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr "" + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr "" + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "" + +#: src/readelf.c:10882 +#, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" + +#: src/readelf.c:10911 +#, c-format +msgid " Version: %\n" +msgstr "" + +#: src/readelf.c:10929 +#, c-format +msgid " CU offset: %#\n" +msgstr "" + +#: src/readelf.c:10936 +#, c-format +msgid " TU offset: %#\n" +msgstr "" + +#: src/readelf.c:10943 +#, c-format +msgid " address offset: %#\n" +msgstr "" + +#: src/readelf.c:10950 +#, c-format +msgid " symbol offset: %#\n" +msgstr "" + +#: src/readelf.c:10957 +#, c-format +msgid " constant offset: %#\n" +msgstr "" + +#: src/readelf.c:10971 +#, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" + +#: src/readelf.c:10996 +#, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" + +#: src/readelf.c:11025 +#, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" + +#: src/readelf.c:11057 +#, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr "" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr "" + +#: src/readelf.c:12518 +#, c-format +msgid "cannot get content of note: %s" +msgstr "" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12622 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "" + +#: src/readelf.c:12654 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12659 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" + +#: src/readelf.c:12673 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" + +#: src/readelf.c:12705 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" + +#: src/readelf.c:12710 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" + +#: src/readelf.c:12853 +#, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" + +#: src/readelf.c:12871 +#, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "" + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr "" + +#: src/size.c:420 +msgctxt "sysv" +msgid "section" +msgstr "" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "" + +#: src/size.c:482 +#, c-format +msgid "cannot get section header" +msgstr "" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "" + +#: src/stack.c:493 +#, c-format +msgid "Cannot open core file '%s'" +msgstr "" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "" + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "" + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "" + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "" + +#: src/stack.c:645 +msgid "Show stack of process PID" +msgstr "" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "" + +#: src/stack.c:652 +msgid "Output selection options:" +msgstr "" + +#: src/stack.c:654 +msgid "Additionally show frame activation" +msgstr "" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "" + +#: src/stack.c:663 +msgid "Additionally show source file information" +msgstr "" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "" + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "" + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "" + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "" + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "" + +#: src/strings.c:585 +#, c-format +msgid "lseek failed" +msgstr "" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "" + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "" + +#: src/strip.c:362 +#, c-format +msgid "cannot both keep and remove .comment section" +msgstr "" + +#: src/strip.c:481 +#, c-format +msgid "bad relocation" +msgstr "" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, c-format +msgid "%s: no support for stripping archive" +msgstr "" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "" + +#: src/strip.c:1092 +#, c-format +msgid "cannot get number of phdrs" +msgstr "" + +#: src/strip.c:1106 src/strip.c:1149 +#, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "" + +#: src/strip.c:1116 src/strip.c:1159 +#, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "" + +#: src/strip.c:1250 +#, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "" + +#: src/strip.c:1259 +#, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "" + +#: src/strip.c:1688 +#, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "" + +#: src/strip.c:1697 +#, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "" + +#: src/strip.c:1705 src/strip.c:2550 +#, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "" + +#: src/strip.c:1866 +#, c-format +msgid "no memory to create section header string table" +msgstr "" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "" + +#: src/strip.c:2599 src/strip.c:2619 +#, c-format +msgid "while writing '%s'" +msgstr "" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "" + +#: src/unstrip.c:240 +#, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "" + +#: src/unstrip.c:254 +#, c-format +msgid "cannot get new zero section: %s" +msgstr "" + +#: src/unstrip.c:257 +#, c-format +msgid "cannot update new zero section: %s" +msgstr "" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, c-format +msgid "cannot get number of program headers: %s" +msgstr "" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "" + +#: src/unstrip.c:848 +#, c-format +msgid "cannot get symbol section data: %s" +msgstr "" + +#: src/unstrip.c:850 +#, c-format +msgid "cannot get string section data: %s" +msgstr "" + +#: src/unstrip.c:867 +#, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "" + +#: src/unstrip.c:1040 +#, c-format +msgid "bad sh_link for group section: %s" +msgstr "" + +#: src/unstrip.c:1046 +#, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "" + +#: src/unstrip.c:1051 +#, c-format +msgid "bad data for group symbol section: %s" +msgstr "" + +#: src/unstrip.c:1057 +#, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "" + +#: src/unstrip.c:1062 +#, c-format +msgid "bad symbol name for group section: %s" +msgstr "" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "" + +#: src/unstrip.c:1758 +#, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "" + +#: src/unstrip.c:1790 +#, c-format +msgid "group has invalid section index [%zd]" +msgstr "" + +#: src/unstrip.c:2065 +#, c-format +msgid "cannot read section data: %s" +msgstr "" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "" + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr "" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "" + +#: tests/dwflmodtest.c:209 +msgid "Additionally show function names" +msgstr "" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "" diff --git a/po/en@boldquot.gmo b/po/en@boldquot.gmo new file mode 100644 index 0000000000000000000000000000000000000000..109943385f3d7346d0def118592184604d5a4dcc GIT binary patch literal 156548 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ǪOn9)Nx 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 literal 0 HcmV?d00001 diff --git a/po/en@boldquot.header b/po/en@boldquot.header new file mode 100644 index 00000000..506ca9e9 --- /dev/null +++ b/po/en@boldquot.header @@ -0,0 +1,25 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# diff --git a/po/en@boldquot.po b/po/en@boldquot.po new file mode 100644 index 00000000..1de17dbf --- /dev/null +++ b/po/en@boldquot.po @@ -0,0 +1,7364 @@ +# English translations for elfutils package. +# Copyright (C) 2021 The elfutils developers +# This file is distributed under the same license as the elfutils package. +# Automatically generated, 2021. +# +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# +msgid "" +msgstr "" +"Project-Id-Version: elfutils 0.185\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2021-05-22 20:29+0200\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en@boldquot\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" +"colorize the output. WHEN defaults to ‘always’ or can be ‘auto’ " +"or ‘never’" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" +"%s: invalid argument ‘%s’ for ‘--color’\n" +"valid arguments are:\n" +" - 'always', 'yes', ‘force’\n" +" - 'never', 'no', ‘none’\n" +" - 'auto', 'tty', ‘if-tty’\n" + +#: lib/color.c:194 src/objdump.c:728 +#, c-format +msgid "cannot allocate memory" +msgstr "cannot allocate memory" + +#: lib/printversion.c:40 +#, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "memory exhausted" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "no error" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "out of memory" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "cannot create output file" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "invalid parameter" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "cannot change mode of output file" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "cannot rename output file" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "duplicate symbol" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "invalid section type for operation" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "error during output of data" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "no backend support available" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "unknown error" + +#: libcpu/i386_lex.l:122 +#, c-format +msgid "invalid character '%c' at line %d; ignored" +msgstr "invalid character ‘%c’ at line %d; ignored" + +#: libcpu/i386_lex.l:123 +#, c-format +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "invalid character ‘\\%o’ at line %d; ignored" + +#: libcpu/i386_parse.y:554 +#, c-format +msgid "while reading i386 CPU description: %s at line %d" +msgstr "while reading i386 CPU description: %s at line %d" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "invalid access" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "no regular file" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "I/O error" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "invalid ELF file" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "no DWARF information" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "cannot decompress DWARF" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "no ELF file" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "cannot get ELF header" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "not implemented" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "invalid command" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "invalid version" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "invalid file" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "no entries found" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "invalid DWARF" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "no string data" + +#: libdw/dwarf_error.c:75 +msgid ".debug_str section missing" +msgstr ".debug_str section missing" + +#: libdw/dwarf_error.c:76 +msgid ".debug_line_str section missing" +msgstr ".debug_line_str section missing" + +#: libdw/dwarf_error.c:77 +msgid ".debug_str_offsets section missing" +msgstr ".debug_str_offsets section missing" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "no address value" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "no constant value" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "no reference value" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "invalid reference value" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr ".debug_line section missing" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "invalid .debug_line section" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "debug information too big" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "invalid DWARF version" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "invalid directory index" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "address out of range" + +#: libdw/dwarf_error.c:88 +msgid ".debug_loc section missing" +msgstr ".debug_loc section missing" + +#: libdw/dwarf_error.c:89 +msgid ".debug_loclists section missing" +msgstr ".debug_loclists section missing" + +#: libdw/dwarf_error.c:90 +msgid "not a location list value" +msgstr "not a location list value" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "no block data" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "invalid line index" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "invalid address range index" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "no matching address range" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "no flag value" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "invalid offset" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr ".debug_ranges section missing" + +#: libdw/dwarf_error.c:98 +msgid ".debug_rnglists section missing" +msgstr ".debug_rnglists section missing" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "invalid CFI section" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "no alternative debug link found" + +#: libdw/dwarf_error.c:101 +msgid "invalid opcode" +msgstr "invalid opcode" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "not a CU (unit) DIE" + +#: libdw/dwarf_error.c:103 +msgid "unknown language code" +msgstr "unknown language code" + +#: libdw/dwarf_error.c:104 +msgid ".debug_addr section missing" +msgstr ".debug_addr section missing" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "Input selection options:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "Find addresses in FILE" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "Find addresses from signatures found in COREFILE" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "Find addresses in files mapped into process PID" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "Find addresses in the running kernel" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "Kernel with all modules" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "Search path for separate debuginfo files" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "only one of -e, -p, -k, -K, or --core allowed" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "cannot load kernel symbols" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "cannot find kernel modules" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "cannot find kernel or modules" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "cannot read ELF core file: %s" + +#: libdwfl/argp-std.c:317 +msgid "Not enough memory" +msgstr "Not enough memory" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "No modules recognized in core file" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "See errno" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "See elf_errno" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "See dwarf_errno" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "See ebl_errno (XXX missing)" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "gzip decompression failed" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "bzip2 decompression failed" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "LZMA decompression failed" + +#: libdwfl/libdwflP.h:61 +msgid "zstd decompression failed" +msgstr "zstd decompression failed" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "no support library found for machine" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "Callbacks missing for ET_REL file" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "Unsupported relocation type" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "r_offset is bogus" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "offset out of range" + +#: libdwfl/libdwflP.h:67 +msgid "relocation refers to undefined symbol" +msgstr "relocation refers to undefined symbol" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "Callback returned failure" + +#: libdwfl/libdwflP.h:69 +msgid "No DWARF information found" +msgstr "No DWARF information found" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "No symbol table found" + +#: libdwfl/libdwflP.h:71 +msgid "No ELF program headers" +msgstr "No ELF program headers" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "address range overlaps an existing module" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "image truncated" + +#: libdwfl/libdwflP.h:76 +msgid "ELF file opened" +msgstr "ELF file opened" + +#: libdwfl/libdwflP.h:77 +msgid "not a valid ELF file" +msgstr "not a valid ELF file" + +#: libdwfl/libdwflP.h:78 +msgid "cannot handle DWARF type description" +msgstr "cannot handle DWARF type description" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "ELF file does not match build ID" + +#: libdwfl/libdwflP.h:80 +msgid "corrupt .gnu.prelink_undo section data" +msgstr "corrupt .gnu.prelink_undo section data" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "Internal error due to ebl" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "Missing data in core file" + +#: libdwfl/libdwflP.h:83 +msgid "Invalid register" +msgstr "Invalid register" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "Error reading process memory" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "Couldn't find architecture of any ELF" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "Error parsing /proc filesystem" + +#: libdwfl/libdwflP.h:87 +msgid "Invalid DWARF" +msgstr "Invalid DWARF" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "Unsupported DWARF" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "Unable to find more threads" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "Dwfl already has attached state" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "Dwfl has no attached state" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "Unwinding not supported for this architecture" + +#: libdwfl/libdwflP.h:93 +msgid "Invalid argument" +msgstr "Invalid argument" + +#: libdwfl/libdwflP.h:94 +msgid "Not an ET_CORE ELF file" +msgstr "Not an ET_CORE ELF file" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "No backend" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr ": %#" + +#: libebl/eblobjnote.c:58 +#, c-format +msgid "unknown SDT version %u\n" +msgstr "unknown SDT version %u\n" + +#: libebl/eblobjnote.c:76 +#, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "invalid SDT probe descriptor\n" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr " PC: " + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr " Base: " + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr " Semaphore: " + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr " Provider: " + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr " Name: " + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr " Args: " + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " Build ID: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr " Linker version: %.*s\n" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " OS: %s, ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "Stand alone" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr ": %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "unknown version" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "unknown type" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "invalid ‘Elf’ handle" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "invalid size of source operand" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "invalid size of destination operand" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "invalid encoding" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "invalid file descriptor" + +#: libelf/elf_error.c:99 +msgid "invalid ELF file data" +msgstr "invalid ELF file data" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "invalid operation" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "ELF version not set" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "invalid fmag field in archive header" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "invalid archive file" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "descriptor is not for an archive" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "no index available" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "cannot read data from file" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "cannot write data to file" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "invalid binary class" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "invalid section index" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "invalid operand" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "invalid section" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "executable header not created first" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "file descriptor disabled" + +#: libelf/elf_error.c:171 +msgid "archive/member file descriptor mismatch" +msgstr "archive/member file descriptor mismatch" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "cannot manipulate null section" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "data/scn mismatch" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "invalid section header" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "invalid data" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "unknown data encoding" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "section ‘sh_size’ too small for data" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "invalid section alignment" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "invalid section entry size" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "update() for write on read-only file" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "no such file" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "only relocatable files can contain section groups" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" +"program header only allowed in executables, shared objects, and core files" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "file has no program header" + +#: libelf/elf_error.c:241 +msgid "invalid section type" +msgstr "invalid section type" + +#: libelf/elf_error.c:246 +msgid "invalid section flags" +msgstr "invalid section flags" + +#: libelf/elf_error.c:251 +msgid "section does not contain compressed data" +msgstr "section does not contain compressed data" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "section contains compressed data" + +#: libelf/elf_error.c:261 +msgid "unknown compression type" +msgstr "unknown compression type" + +#: libelf/elf_error.c:266 +msgid "cannot compress data" +msgstr "cannot compress data" + +#: libelf/elf_error.c:271 +msgid "cannot decompress data" +msgstr "cannot decompress data" + +#: src/addr2line.c:57 +msgid "Input format options:" +msgstr "Input format options:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "Treat addresses as offsets relative to NAME section." + +#: src/addr2line.c:61 +msgid "Output format options:" +msgstr "Output format options:" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "Print address before each entry" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "Show only base names of source files" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "Show absolute file names using compilation directory" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "Also show function names" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "Also show symbol or section names" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "Also show symbol and the section names" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "Also show line table flags" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "Show demangled symbols (ARG is always ignored)" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "Print all information on one line, and indent inlines" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "Miscellaneous:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" +"Locate source files and line information for ADDRs (in a.out by default)." + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "[ADDR...]" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "Section syntax requires exactly one module" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "offset %# lies outside section ‘%s’" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "cannot find symbol ‘%s’" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "offset %# lies outside contents of ‘%s’" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "Commands:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "Delete files from archive." + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "Move files in archive." + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "Print files in archive." + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "Quick append files to archive." + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "Replace existing or insert new file into archive." + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "Display content of archive." + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "Extract files from archive." + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "Command Modifiers:" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "Preserve original dates." + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "Use instance [COUNT] of name." + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "Do not replace existing files with extracted files." + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "Allow filename to be truncated if necessary." + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "Provide verbose output." + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "Force regeneration of symbol table." + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "Insert file after [MEMBER]." + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "Insert file before [MEMBER]." + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "Same as -b." + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "Suppress message when library has to be created." + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "Use full path for file matching." + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "Update only older files in archive." + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "Create, modify, and extract from archives." + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[MEMBER] [COUNT] ARCHIVE [FILE...]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "" +"'a', 'b', and ‘i’ are only allowed with the ‘m’ and ‘r’ " +"options" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "MEMBER parameter required for 'a', 'b', and ‘i’ modifiers" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "‘N’ is only meaningful with the ‘x’ and ‘d’ options" + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "COUNT parameter required" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "invalid COUNT parameter %s" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "‘%c’ is only meaningful with the ‘x’ option" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "archive name required" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "command option required" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "More than one operation specified" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "cannot open archive ‘%s’" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "cannot open archive '%s': %s" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: not an archive file" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "cannot stat archive ‘%s’" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "no entry %s in archive\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "cannot create hash table" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "cannot insert into hash table" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "cannot stat ‘%s’" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "cannot read content of %s: %s" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "cannot open %.*s" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "failed to write %s" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "cannot change mode of %s" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "cannot change modification time of %s" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "cannot rename temporary file to %.*s" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "cannot create new file" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "position member %s not found" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: no entry %s in archive!\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "cannot open %s" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "cannot stat %s" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "%s is no regular file" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "cannot get ELF descriptor for %s: %s\n" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "cannot read %s: %s" + +#: src/ar.c:1483 +#, c-format +msgid "cannot represent ar_date" +msgstr "cannot represent ar_date" + +#: src/ar.c:1489 +#, c-format +msgid "cannot represent ar_uid" +msgstr "cannot represent ar_uid" + +#: src/ar.c:1495 +#, c-format +msgid "cannot represent ar_gid" +msgstr "cannot represent ar_gid" + +#: src/ar.c:1501 +#, c-format +msgid "cannot represent ar_mode" +msgstr "cannot represent ar_mode" + +#: src/ar.c:1507 +#, c-format +msgid "cannot represent ar_size" +msgstr "cannot represent ar_size" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "Use zero for uid, gid, and date in archive members." + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "Use actual uid, gid, and date in archive members." + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "%s (default)" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "the archive ‘%s’ is too large" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "cannot read ELF header of %s(%s): %s" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "opening" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "reading" + +#: src/elfclassify.c:245 +msgid "ELF header" +msgstr "ELF header" + +#: src/elfclassify.c:256 +msgid "program headers" +msgstr "program headers" + +#: src/elfclassify.c:265 +msgid "program header" +msgstr "program header" + +#: src/elfclassify.c:285 +msgid "section headers" +msgstr "section headers" + +#: src/elfclassify.c:296 +msgid "section header string table index" +msgstr "section header string table index" + +#: src/elfclassify.c:310 +msgid "could not obtain section header" +msgstr "could not obtain section header" + +#: src/elfclassify.c:316 +msgid "could not obtain section name" +msgstr "could not obtain section name" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "writing to standard output" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "reading from standard input" + +#: src/elfclassify.c:877 +msgid "Classification options" +msgstr "Classification options" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "File looks like an ELF object or archive/static library (default)" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "File is an regular ELF object (not an archive/static library)" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "File is an ELF archive or static library" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "File is an ELF core dump file" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "File is (primarily) an ELF program executable (not primarily a DSO)" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "File is an ELF program executable (might also be a DSO)" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "File is an ELF shared object (DSO) (might also be an executable)" + +#: src/elfclassify.c:907 +msgid "File is a linux kernel module" +msgstr "File is a linux kernel module" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" +"File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "File is a loadable ELF object (program or shared object)" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "Input flags" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "Only classify regular (not symlink nor special device) files" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" +"Also read file names to process from standard input, separated by newlines" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "Do not read files from standard input (default)" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "Try to open compressed files or embedded (kernel) ELF images" + +#: src/elfclassify.c:956 +msgid "Output flags" +msgstr "Output flags" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "Output names of files, separated by newline" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "Output names of files, separated by ASCII NUL" + +#: src/elfclassify.c:962 +msgid "Do not output file names" +msgstr "Do not output file names" + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "If printing file names, print matching files (default)" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "If printing file names, print files that do not match" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "Additional flags" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "Output additional information (can be specified multiple times)" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "Suppress some error output (counterpart to --verbose)" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "FILE..." + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a “--not-" +"[0m” prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "Control options:" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "Output all differences, not just the first" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "Ignore permutation of buckets in SHT_HASH section" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "Ignore differences in build ID" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "Output nothing; yield exit status only" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "Compare relevant parts of two ELF files for equality." + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "FILE1 FILE2" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "Invalid number of parameters.\n" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "cannot get ELF header of '%s': %s" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "%s %s diff: ELF header" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, c-format +msgid "cannot get section count of '%s': %s" +msgstr "cannot get section count of '%s': %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "%s %s diff: section count" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "cannot get program header count of '%s': %s" + +#: src/elfcmp.c:233 +#, c-format +msgid "%s %s diff: program header count" +msgstr "%s %s diff: program header count" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "cannot get hdrstrndx of '%s': %s" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "%s %s diff: shdr string index" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "%s %s differ: section [%zu], [%zu] name" + +#: src/elfcmp.c:330 +#, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "%s %s differ: section [%zu] ‘%s’ header" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "cannot get content of section %zu in '%s': %s" + +#: src/elfcmp.c:353 +#, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "symbol table [%zu] in ‘%s’ has zero sh_entsize" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "cannot get symbol in '%s': %s" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "%s %s differ: symbol table [%zu]" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "%s %s differ: symbol table [%zu,%zu]" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "%s %s differ: section [%zu] ‘%s’ number of notes" + +#: src/elfcmp.c:451 +#, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "cannot read note section [%zu] ‘%s’ in '%s': %s" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "%s %s differ: section [%zu] ‘%s’ note name" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "%s %s differ: section [%zu] ‘%s’ note ‘%s’ type" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "%s %s differ: build ID length" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "%s %s differ: build ID content" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "%s %s differ: section [%zu] ‘%s’ note ‘%s’ content" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "%s %s differ: section [%zu] ‘%s’ content" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "%s %s differ: section [%zu,%zu] ‘%s’ content" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "%s %s differ: unequal amount of important sections" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "cannot load data of '%s': %s" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "cannot get program header entry %d of '%s': %s" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "%s %s differ: program header %d" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "%s %s differ: gap" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "Invalid value ‘%s’ for --gaps parameter." + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "cannot open ‘%s’" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "cannot create ELF descriptor for '%s': %s" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "cannot create EBL descriptor for ‘%s’" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "cannot get section header of section %zu: %s" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "cannot get content of section %zu: %s" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "cannot get relocation: %s" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "-o option specified twice" + +#: src/elfcompress.c:124 +#, c-format +msgid "-t option specified twice" +msgstr "-t option specified twice" + +#: src/elfcompress.c:133 +#, c-format +msgid "unknown compression type '%s'" +msgstr "unknown compression type ‘%s’" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, c-format +msgid "No input file given" +msgstr "No input file given" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "Only one input file allowed together with ‘-o’" + +#: src/elfcompress.c:1307 +msgid "Place (de)compressed output into FILE" +msgstr "Place (de)compressed output into FILE" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" +"What type of compression to apply. TYPE can be ‘none’ (decompress), " +"‘zlib’ (ELF ZLIB compression, the default, ‘zlib-gabi’ is an " +"alias) or ‘zlib-gnu’ (.zdebug GNU style compression, ‘gnu’ is an " +"alias)" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "Print a message for each section being (de)compressed" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "Relax a few rules to handle slightly broken ELF files" + +#: src/elfcompress.c:1325 +msgid "Be silent when a section cannot be compressed" +msgstr "Be silent when a section cannot be compressed" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "Compress or decompress sections in an ELF file." + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "Be extremely strict, flag level 2 features." + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "Do not print anything if successful" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "Binary is a separate debuginfo file" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "Pedantic checking of ELF files compliance with gABI/psABI spec." + +#: src/elflint.c:154 src/readelf.c:368 +#, c-format +msgid "cannot open input file '%s'" +msgstr "cannot open input file ‘%s’" + +#: src/elflint.c:161 +#, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "cannot generate Elf descriptor for '%s': %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "error while closing Elf descriptor: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "No errors" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "Missing file name.\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr " error while freeing sub-ELF descriptor: %s\n" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "Not an ELF file - it has the wrong magic bytes at the start\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "e_ident[%d] == %d is no known class\n" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "e_ident[%d] == %d is no known data encoding\n" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "unknown ELF header version number e_ident[%d] == %d\n" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "unsupported OS ABI e_ident[%d] == ‘%s’\n" + +#: src/elflint.c:380 +#, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "unsupported ABI version e_ident[%d] == %d\n" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] is not zero\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "unknown object file type %d\n" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "unknown machine type %d\n" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "unknown object file version\n" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "invalid program header offset\n" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "executables and DSOs cannot have zero program header offset\n" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "invalid number of program header entries\n" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "invalid section header table offset\n" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "section header table must be present\n" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "invalid number of section header table entries\n" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "invalid section header index\n" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "Can only check %u headers, shnum was %u\n" + +#: src/elflint.c:487 +#, c-format +msgid "invalid number of program header table entries\n" +msgstr "invalid number of program header table entries\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "Can only check %u headers, phnum was %u\n" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "invalid machine flags: %s\n" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "invalid ELF header size: %hd\n" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "invalid program header size: %hd\n" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "invalid program header position or size\n" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "invalid section header size: %hd\n" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "invalid section header position or size\n" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" +"section [%2d] '%s': section group [%2zu] ‘%s’ does not precede group " +"member\n" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "section [%2d] '%s': cannot get section data\n" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" +"section [%2d] '%s': referenced as string table for section [%2d] ‘%s’ " +"but type is not SHT_STRTAB\n" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" +"section [%2u] '%s': number of local entries in ‘st_info’ larger than " +"table size\n" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "section [%2d] '%s': cannot get symbol %d: %s\n" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "section [%2d] '%s': ‘%s’ in zeroth entry not zero\n" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "section [%2d] '%s': XINDEX for zeroth entry not zero\n" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "section [%2d] '%s': cannot get symbol %zu: %s\n" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "section [%2d] '%s': symbol %zu: invalid name value\n" + +#: src/elflint.c:728 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" + +#: src/elflint.c:734 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "section [%2d] '%s': symbol %zu (%s): invalid section index\n" + +#: src/elflint.c:754 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "section [%2d] '%s': symbol %zu (%s): unknown type\n" + +#: src/elflint.c:760 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" + +#: src/elflint.c:765 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" + +#: src/elflint.c:773 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" + +#: src/elflint.c:777 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" + +#: src/elflint.c:781 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" + +#: src/elflint.c:832 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] ‘%s’\n" + +#: src/elflint.c:847 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] ‘%s’ " +"does not have SHF_TLS flag set\n" + +#: src/elflint.c:857 src/elflint.c:905 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] ‘%s’\n" + +#: src/elflint.c:884 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" + +#: src/elflint.c:890 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" + +#: src/elflint.c:898 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] ‘%s’\n" + +#: src/elflint.c:925 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" + +#: src/elflint.c:932 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" + +#: src/elflint.c:939 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] ‘" +"%s’\n" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" + +#: src/elflint.c:1063 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" + +#: src/elflint.c:1067 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" + +#: src/elflint.c:1105 +#, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "section [%2d] '%s': cannot get section data.\n" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "section [%2d] '%s': invalid destination section index\n" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "section [%2d] '%s': invalid destination section type\n" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "section [%2d] '%s': sh_info should be zero\n" + +#: src/elflint.c:1286 +#, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "text relocation flag set but there is no read-only segment\n" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "section [%2d] '%s': relocation %zu: invalid type\n" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "section [%2d] '%s': relocation %zu: invalid symbol index\n" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" +"section [%2d] '%s': relocation %zu: only symbol " +"‘_GLOBAL_OFFSET_TABLE_’ can be used with %s\n" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "section [%2d] '%s': relocation %zu: offset out of bounds\n" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "section [%2d] '%s': relocations are against loaded and unloaded data\n" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "section [%2d] '%s': cannot get relocation %zu: %s\n" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "more than one dynamic section present\n" + +#: src/elflint.c:1668 +#, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" +"section [%2d]: referenced as string table for section [%2d] ‘%s’ but " +"section link value is invalid\n" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "section [%2d] '%s': sh_info not zero\n" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "section [%2d] '%s': entry %zu: unknown tag\n" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "section [%2d] '%s': entry %zu: level 2 tag %s used\n" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] ‘%s’ referenced by sh_link\n" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] ‘%s’\n" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "section [%2d] '%s': contains %s entry but not %s\n" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "section [%2d] '%s': mandatory tag %s not present\n" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "section [%2d] '%s': no hash section present\n" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "section [%2d] '%s': not all of %s, %s, and %s are present\n" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "section [%2d] '%s': %s tag missing in prelinked executable\n" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" +"section [%2d] '%s': only relocatable files can have extended section index\n" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" +"section [%2d] '%s': extended section index section not for symbol table\n" + +#: src/elflint.c:1948 +#, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "cannot get data for symbol section\n" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "section [%2d] '%s': entry size does not match Elf32_Word\n" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "section [%2d] '%s': extended index table too small for symbol table\n" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" +"section [%2d] '%s': extended section index in section [%2zu] ‘%s’ " +"refers to same symbol table\n" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "symbol 0 should have zero extended section index\n" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "cannot get data for symbol %zu\n" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "extended section index is % but symbol index is not XINDEX\n" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "section [%2d] '%s': chain array too large\n" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "section [%2d] '%s': hash bucket reference %zu out of bounds\n" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "section [%2d] '%s': hash chain reference %zu out of bounds\n" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "section [%2d] '%s': hash chain reference % out of bounds\n" + +#: src/elflint.c:2140 +#, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "section [%2d] '%s': not enough data\n" + +#: src/elflint.c:2152 +#, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "section [%2d] '%s': 2nd hash function shift too big: %u\n" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" + +#: src/elflint.c:2254 +#, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "section [%2d] '%s': bitmask does not match names in the hash table\n" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "section [%2d] '%s': relocatable files cannot have hash tables\n" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "section [%2d] '%s': hash table not for dynamic symbol table\n" + +#: src/elflint.c:2330 +#, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "section [%2d] '%s': hash table entry size incorrect\n" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "section [%2d] '%s': not marked to be allocated\n" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "" +"sh_link in hash sections [%2zu] ‘%s’ and [%2zu] ‘%s’ not " +"identical\n" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "hash section [%2zu] ‘%s’ does not contain enough data\n" + +#: src/elflint.c:2444 +#, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "hash section [%2zu] ‘%s’ has zero bit mask words\n" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "hash section [%2zu] ‘%s’ uses too much data\n" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" +"hash section [%2zu] ‘%s’ invalid symbol index % (max_nsyms: " +"%, nentries: %\n" + +#: src/elflint.c:2557 +#, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "hash section [%2zu] ‘%s’ invalid sh_entsize\n" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "section [%2zu] '%s': reference to symbol index 0\n" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" +"symbol %d referenced in new hash table in [%2zu] ‘%s’ but not in old " +"hash table in [%2zu] ‘%s’\n" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" +"symbol %d referenced in old hash table in [%2zu] ‘%s’ but not in new " +"hash table in [%2zu] ‘%s’\n" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "section [%2d] '%s': nonzero sh_%s for NULL section\n" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "section [%2d] '%s': cannot get symbol table: %s\n" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "section [%2d] '%s': section reference in sh_link is no symbol table\n" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "section [%2d] '%s': invalid symbol index in sh_info\n" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "section [%2d] '%s': sh_flags not zero\n" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "section [%2d] '%s': cannot get symbol for signature\n" + +#: src/elflint.c:2664 +#, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "section [%2d] '%s': cannot get symbol name for signature\n" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "section [%2d] '%s': signature symbol cannot be empty string\n" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "section [%2d] '%s': sh_flags not set correctly\n" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "section [%2d] '%s': cannot get data: %s\n" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "section [%2d] '%s': section group without flags word\n" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "section [%2d] '%s': section group without member\n" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "section [%2d] '%s': section group with only one member\n" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "section [%2d] '%s': unknown section group flags\n" + +#: src/elflint.c:2731 +#, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "section [%2d] '%s': section index %zu out of range\n" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "section [%2d] '%s': cannot get section header for element %zu: %s\n" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': section group contains another group [%2d] ‘%s’\n" + +#: src/elflint.c:2753 +#, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" +"section [%2d] '%s': element %zu references section [%2d] ‘%s’ without " +"SHF_GROUP flag set\n" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "section [%2d] ‘%s’ is contained in more than one section group\n" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" +"section [%2d] ‘%s’ refers in sh_link to section [%2d] ‘%s’ which " +"is no dynamic symbol table\n" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" +"section [%2d] ‘%s’ has different number of entries than symbol table " +"[%2d] ‘%s’\n" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "section [%2d] '%s': symbol %d: cannot read version data\n" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "section [%2d] '%s': symbol %d: local symbol with global scope\n" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "section [%2d] '%s': symbol %d: local symbol with version\n" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "section [%2d] '%s': symbol %d: invalid version index %d\n" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "more than one version reference section present\n" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "section [%2d] '%s': sh_link does not link to string table\n" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "section [%2d] '%s': entry %d has wrong version %d\n" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "section [%2d] '%s': entry %d has invalid file reference\n" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "section [%2d] '%s': entry %d references unknown dependency\n" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name ‘%s’\n" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "section [%2d] '%s': entry %d has invalid offset to next entry\n" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "more than one version definition section present\n" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "section [%2d] '%s': more than one BASE definition\n" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "section [%2d] '%s': entry %d has unknown flag\n" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "section [%2d] '%s': entry %d has invalid name reference\n" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "section [%2d] '%s': entry %d has duplicate version name ‘%s’\n" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "section [%2d] '%s': no BASE definition\n" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "section [%2d] '%s': unknown parent version ‘%s’\n" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "section [%2d] '%s': empty object attributes section\n" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "section [%2d] '%s': unrecognized attribute format\n" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "section [%2d] '%s': offset %zu: invalid length in attribute section\n" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "section [%2d] '%s': offset %zu: unterminated vendor name string\n" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "section [%2d] '%s': offset %zu: truncated attribute section\n" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "section [%2d] '%s': offset %zu: unterminated string in attribute\n" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "section [%2d] '%s': offset %zu: vendor ‘%s’ unknown\n" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "cannot get section header of zeroth section\n" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "zeroth section has nonzero name\n" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "zeroth section has nonzero type\n" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "zeroth section has nonzero flags\n" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "zeroth section has nonzero address\n" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "zeroth section has nonzero offset\n" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "zeroth section has nonzero align value\n" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "zeroth section has nonzero entry size value\n" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "cannot get section header for section [%2zu] '%s': %s\n" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "section [%2zu]: invalid name\n" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "section [%2d] ‘%s’ has wrong type: expected %s, is %s\n" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "section [%2zu] ‘%s’ has wrong flags: expected %s, is %s\n" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" +"section [%2zu] ‘%s’ has wrong flags: expected %s and possibly %s, is " +"%s\n" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "section [%2zu] ‘%s’ present in object file\n" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" +"section [%2zu] ‘%s’ has SHF_ALLOC flag set but there is no loadable " +"segment\n" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" +"section [%2zu] ‘%s’ has SHF_ALLOC flag not set but there are loadable " +"segments\n" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" +"section [%2zu] ‘%s’ is extension section index table in non-object " +"file\n" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "section [%2zu] '%s': size not multiple of entry size\n" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "cannot get section header\n" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "section [%2zu] ‘%s’ has unsupported type %d\n" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" +"section [%2zu] ‘%s’ contains invalid processor-specific flag(s) " +"%#\n" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "section [%2zu] ‘%s’ contains unknown flag(s) %#\n" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "section [%2zu] '%s': thread-local data sections address not zero\n" + +#: src/elflint.c:3974 +#, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "section [%2zu] '%s': allocated section cannot be compressed\n" + +#: src/elflint.c:3979 +#, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "section [%2zu] '%s': nobits section cannot be compressed\n" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "section [%2zu] '%s': invalid section reference in link value\n" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "section [%2zu] '%s': invalid section reference in info value\n" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "section [%2zu] '%s': strings flag set without merge flag\n" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "section [%2zu] '%s': merge flag set but entry size is zero\n" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "" +"section [%2zu] ‘%s’ has unexpected type %d for an executable section\n" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "section [%2zu] ‘%s’ must be of type NOBITS in debuginfo files\n" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "section [%2zu] ‘%s’ is both executable and writable\n" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" +"section [%2zu] ‘%s’ not fully contained in segment of program header " +"entry %d\n" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" +"section [%2zu] ‘%s’ has type NOBITS but is read from the file in " +"segment of program header entry %d\n" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" +"section [%2zu] ‘%s’ has type NOBITS but is read from the file in " +"segment of program header entry %d and file contents is non-zero\n" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" +"section [%2zu] ‘%s’ has not type NOBITS but is not read from the file " +"in segment of program header entry %d\n" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "section [%2zu] ‘%s’ is executable in nonexecutable segment %d\n" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "section [%2zu] ‘%s’ is writable in unwritable segment %d\n" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "more than one version symbol table present\n" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "INTERP program header entry but no .interp section\n" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" +"loadable segment [%u] is executable but contains no executable sections\n" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "loadable segment [%u] is writable but contains no writable sections\n" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "duplicate version index %d\n" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "phdr[%d]: unknown core file note type % at offset %\n" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" +"phdr[%d]: unknown object file note type % with owner name ‘%s’ " +"at offset %zu\n" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" +"section [%2d] '%s': unknown object file note type % with owner name " +"‘%s’ at offset %zu\n" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "phdr[%d]: no note entries defined for the type of file\n" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "phdr[%d]: cannot get content of note section: %s\n" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "phdr[%d]: extra % bytes after last note\n" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "section [%2d] '%s': no note entries defined for the type of file\n" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "section [%2d] '%s': cannot get content of note section\n" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "section [%2d] '%s': extra % bytes after last note\n" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" +"only executables, shared objects, and core files can have program headers\n" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "cannot get program header entry %d: %s\n" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" +"program header entry %d: unknown program header entry type %#\n" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "more than one INTERP entry in program header\n" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "more than one TLS entry in program header\n" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "static executable cannot have dynamic sections\n" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "dynamic section reference in program header has wrong offset\n" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "dynamic section size mismatch in program and section header\n" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "more than one GNU_RELRO entry in program header\n" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "loadable segment GNU_RELRO applies to is not writable\n" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "%s segment not contained in a loaded segment\n" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "program header offset in ELF header and PHDR entry do not match" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "call frame search table reference in program header has wrong offset\n" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "call frame search table size mismatch in program and section header\n" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "call frame search table must be allocated\n" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "section [%2zu] ‘%s’ must be allocated\n" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "call frame search table must not be writable\n" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "section [%2zu] ‘%s’ must not be writable\n" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "call frame search table must not be executable\n" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "section [%2zu] ‘%s’ must not be executable\n" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "program header entry %d: file size greater than memory size\n" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "program header entry %d: alignment not a power of 2\n" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "cannot read ELF header: %s\n" + +#: src/elflint.c:4797 +#, c-format +msgid "cannot create backend for ELF file\n" +msgstr "cannot create backend for ELF file\n" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "text relocation flag set but not needed\n" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "Input Selection:" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "Prepend PATH to all file names" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "Use PATH as root of debuginfo hierarchy" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "Locate source of text relocations in FILEs (a.out by default)." + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "[FILE...]" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "cannot get ELF header '%s': %s" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "‘%s’ is not a DSO or PIE" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "getting get section header of section %zu: %s" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "cannot read dynamic section: %s" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "no text relocations reported in ‘%s’" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "while reading ELF file" + +#: src/findtextrel.c:314 +#, c-format +msgid "cannot get program header count: %s" +msgstr "cannot get program header count: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "cannot get program header index at offset %zd: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "cannot get symbol table section %zu in '%s': %s" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "cannot get relocation at index %d in section %zu in '%s': %s" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "%s not compiled with -fpic/-fPIC\n" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"the file containing the function ‘%s’ is not compiled with -fpic/-" +"fPIC\n" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" +"the file containing the function ‘%s’ might not be compiled with -" +"fpic/-fPIC\n" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"either the file containing the function ‘%s’ or the file containing " +"the function ‘%s’ is not compiled with -fpic/-fPIC\n" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "Output selection:" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "Display debugger-only symbols" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "Display only defined symbols" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "Display dynamic symbols instead of normal symbols" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "Display only external symbols" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "Display only undefined symbols" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "Include index for symbols from archive members" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "Output format:" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "Print name of the input file before every symbol" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"Use the output format FORMAT. FORMAT can be ‘bsd’, ‘sysv’ or " +"‘posix’. The default is ‘sysv’" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "Same as --format=bsd" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "Same as --format=posix" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "Use RADIX for printing symbol values" + +#: src/nm.c:87 +msgid "Mark special symbols" +msgstr "Mark special symbols" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "Print size of defined symbols" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "Output options:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "Sort symbols numerically by address" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "Do not sort the symbols" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "Reverse the sense of the sort" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "Decode low-level symbol names into source code names" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "List symbols from FILEs (a.out by default)." + +#: src/nm.c:116 src/objdump.c:79 +msgid "Output formatting" +msgstr "Output formatting" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: INTERNAL ERROR %d (%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "while closing ‘%s’" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: File format not recognized" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"Archive index:\n" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "invalid offset %zu for symbol %s" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "%s in %s\n" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "cannot reset archive offset to beginning" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: file format not recognized" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "cannot create search tree" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "cannot get section header string table index" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" + +#: src/nm.c:776 +msgctxt "sysv" +msgid "Name" +msgstr "Name" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "Value" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "Size" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "Line" + +#: src/nm.c:1250 +#, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "%s: entry size in section %zd ‘%s’ is not what we expect" + +#: src/nm.c:1255 +#, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: size of section %zd ‘%s’ is not multiple of entry size" + +#: src/nm.c:1336 +#, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "%s: entries (%zd) in section %zd ‘%s’ is too large" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: Invalid operation" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: no symbols" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "Mode selection:" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "Display relocation information." + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "Display the full contents of all sections requested" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "Display assembler code of executable sections" + +#: src/objdump.c:59 +msgid "Output content selection:" +msgstr "Output content selection:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "Only display information for section NAME." + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "Show information from FILEs (a.out by default)." + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "No operation specified.\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "while close ‘%s’" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "INVALID SYMBOL" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "INVALID SECTION" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "OFFSET" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "Contents of section %s:\n" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "cannot disassemble" + +#: src/objdump.c:760 +#, c-format +msgid "cannot create backend for elf file" +msgstr "cannot create backend for elf file" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "Generate an index to speed access to archives." + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "ARCHIVE" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "Archive name required" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "‘%s’ is no archive" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "error while freeing sub-ELF descriptor: %s" + +#: src/readelf.c:97 +msgid "ELF input selection:" +msgstr "ELF input selection:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" + +#: src/readelf.c:104 +msgid "ELF output selection:" +msgstr "ELF output selection:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "All these plus -p .strtab -p .dynstr -p .comment" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "Display the dynamic segment" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "Display the ELF file header" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "Display histogram of bucket list lengths" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "Display the program headers" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "Display relocations" + +#: src/readelf.c:114 +msgid "Display the section groups" +msgstr "Display the section groups" + +#: src/readelf.c:115 +msgid "Display the sections' headers" +msgstr "Display the sections' headers" + +#: src/readelf.c:118 +msgid "Display the symbol table sections" +msgstr "Display the symbol table sections" + +#: src/readelf.c:120 +msgid "Display (only) the dynamic symbol table" +msgstr "Display (only) the dynamic symbol table" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "Display versioning information" + +#: src/readelf.c:122 +msgid "Display the ELF notes" +msgstr "Display the ELF notes" + +#: src/readelf.c:124 +msgid "Display architecture specific information, if any" +msgstr "Display architecture specific information, if any" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "Display sections for exception handling" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "Additional output selection:" + +#: src/readelf.c:130 +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "Dump the uninterpreted contents of SECTION, by number or name" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "Print string contents of sections" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "Display the symbol index of an archive" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "Output control:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "Do not find symbol names for addresses in DWARF data" + +#: src/readelf.c:145 +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "" +"Display just offsets instead of resolving values to addresses in DWARF data" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "Ignored for compatibility (lines always wide)" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "Print information from ELF file in human-readable form." + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "yes" + +#: src/readelf.c:351 +msgid "no" +msgstr "no" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "Unknown DWARF debug section ‘%s’.\n" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "cannot generate Elf descriptor: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "cannot determine number of sections: %s" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "cannot get section: %s" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "cannot get section header: %s" + +#: src/readelf.c:663 +#, c-format +msgid "cannot get section name" +msgstr "cannot get section name" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "cannot get %s content: %s" + +#: src/readelf.c:688 +#, c-format +msgid "cannot create temp file '%s'" +msgstr "cannot create temp file ‘%s’" + +#: src/readelf.c:697 +#, c-format +msgid "cannot write section data" +msgstr "cannot write section data" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "error while closing Elf descriptor: %s" + +#: src/readelf.c:710 +#, c-format +msgid "error while rewinding file descriptor" +msgstr "error while rewinding file descriptor" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "‘%s’ is not an archive, cannot print archive index" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "cannot stat input file" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "input file is empty" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "failed reading '%s': %s" + +#: src/readelf.c:881 +#, c-format +msgid "No such section '%s' in '%s'" +msgstr "No such section ‘%s’ in ‘%s’" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "cannot read ELF header: %s" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "cannot create EBL handle" + +#: src/readelf.c:961 +#, c-format +msgid "cannot determine number of program headers: %s" +msgstr "cannot determine number of program headers: %s" + +#: src/readelf.c:993 +#, c-format +msgid "cannot read ELF: %s" +msgstr "cannot read ELF: %s" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "NONE (None)" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "REL (Relocatable file)" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "EXEC (Executable file)" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "DYN (Shared object file)" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "CORE (Core file)" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "OS Specific: (%x)\n" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "Processor Specific: (%x)\n" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" +"ELF Header:\n" +" Magic: " + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" +"\n" +" Class: %s\n" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr " Data: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr " Ident Version: %hhd %s\n" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(current)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr " OS/ABI: %s\n" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr " ABI Version: %hhd\n" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " Type: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr " Machine: %s\n" + +#: src/readelf.c:1109 +#, c-format +msgid " Machine: : 0x%x\n" +msgstr " Machine: : 0x%x\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr " Version: %d %s\n" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr " Entry point address: %#\n" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr " Start of program headers: % %s\n" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "(bytes into file)" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr " Start of section headers: % %s\n" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr " Flags: %s\n" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr " Size of this header: % %s\n" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(bytes)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr " Size of program header entries: % %s\n" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr " Number of program headers entries: %" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr " (% in [0].sh_info)" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr " ([0] not available)" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr " Size of section header entries: % %s\n" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr " Number of section headers entries: %" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr " (% in [0].sh_size)" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr " (% in [0].sh_link)" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" +" Section header string table index: XINDEX%s\n" +"\n" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" +" Section header string table index: %\n" +"\n" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, c-format +msgid "cannot get number of sections: %s" +msgstr "cannot get number of sections: %s" + +#: src/readelf.c:1233 +#, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" +"There are %zd section headers, starting at offset %#:\n" +"\n" + +#: src/readelf.c:1242 +#, c-format +msgid "cannot get section header string table index: %s" +msgstr "cannot get section header string table index: %s" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "Section Headers:" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr " [Compression Size Al]" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr " [Compression Size Al]" + +#: src/readelf.c:1335 +#, c-format +msgid "bad compression header for section %zd: %s" +msgstr "bad compression header for section %zd: %s" + +#: src/readelf.c:1346 +#, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "bad gnu compressed size for section %zd: %s" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "Program Headers:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "\t[Requesting program interpreter: %s]\n" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "cannot get program header: %s" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"COMDAT section group [%2zu] ‘%s’ with signature ‘%s’ contains " +"%zu entry:\n" +msgstr[1] "" +"\n" +"COMDAT section group [%2zu] ‘%s’ with signature ‘%s’ contains " +"%zu entries:\n" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Section group [%2zu] ‘%s’ with signature ‘%s’ contains %zu " +"entry:\n" +msgstr[1] "" +"\n" +"Section group [%2zu] ‘%s’ with signature ‘%s’ contains %zu " +"entries:\n" + +#: src/readelf.c:1623 +msgid "" +msgstr "" + +#: src/readelf.c:1637 +msgid "" +msgstr "" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "Couldn't uncompress section" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "cannot get section [%zd] header: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, c-format +msgid "invalid sh_link value in section %zu" +msgstr "invalid sh_link value in section %zu" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" +msgstr[1] "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr " Type Value\n" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "Shared library: [%s]\n" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "Library soname: [%s]\n" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "Library rpath: [%s]\n" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "Library runpath: [%s]\n" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "% (bytes)\n" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" +"\n" +"Invalid symbol table at offset %#0\n" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +"\n" +"Relocation section [%2zu] ‘%s’ for section [%2u] ‘%s’ at offset " +"%#0 contains %d entry:\n" +msgstr[1] "" +"\n" +"Relocation section [%2zu] ‘%s’ for section [%2u] ‘%s’ at offset " +"%#0 contains %d entries:\n" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Relocation section [%2u] ‘%s’ at offset %#0 contains %d " +"entry:\n" +msgstr[1] "" +"\n" +"Relocation section [%2u] ‘%s’ at offset %#0 contains %d " +"entries:\n" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr " Offset Type Value Name\n" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr " Offset Type Value Name\n" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr " Offset Type Value Addend Name\n" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr "" +" Offset Type Value Addend Name\n" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +"\n" +"Symbol table [%2u] ‘%s’ contains %u entry:\n" +msgstr[1] "" +"\n" +"Symbol table [%2u] ‘%s’ contains %u entries:\n" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] " %lu local symbol String table: [%2u] ‘%s’\n" +msgstr[1] " %lu local symbols String table: [%2u] ‘%s’\n" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Num: Value Size Type Bind Vis Ndx Name\n" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Num: Value Size Type Bind Vis Ndx Name\n" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "%5u: %0* %6 %-7s %-6s %-9s %6s %s" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "bad dynamic symbol" + +#: src/readelf.c:2680 +msgid "none" +msgstr "none" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| " + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Version needs section [%2u] ‘%s’ contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" +msgstr[1] "" +"\n" +"Version needs section [%2u] ‘%s’ contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: Version: %hu File: %s Cnt: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: Name: %s Flags: %s Version: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Version definition section [%2u] ‘%s’ contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" +msgstr[1] "" +"\n" +"Version definition section [%2u] ‘%s’ contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr " %#06x: Parent %d: %s\n" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +"\n" +"Version symbols section [%2u] ‘%s’ contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’" +msgstr[1] "" +"\n" +"Version symbols section [%2u] ‘%s’ contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *local* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *global* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Histogram for bucket list length in section [%2u] ‘%s’ (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" +msgstr[1] "" +"\n" +"Histogram for bucket list length in section [%2u] ‘%s’ (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘" +"%s’\n" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr " Length Number % of total Coverage\n" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "cannot get data for section %d: %s" + +#: src/readelf.c:3254 +#, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "invalid data in sysv.hash section %d" + +#: src/readelf.c:3283 +#, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "invalid chain in sysv.hash section %d" + +#: src/readelf.c:3318 +#, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "invalid data in sysv.hash64 section %d" + +#: src/readelf.c:3349 +#, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "invalid chain in sysv.hash64 section %d" + +#: src/readelf.c:3385 +#, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "invalid data in gnu.hash section %d" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Library list section [%2zu] ‘%s’ at offset %#0 contains %d " +"entry:\n" +msgstr[1] "" +"\n" +"Library list section [%2zu] ‘%s’ at offset %#0 contains %d " +"entries:\n" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" +" Library Time Stamp Checksum Version " +"Flags" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" +"\n" +"Object attributes section [%2zu] ‘%s’ of % bytes at offset " +"%#0:\n" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr " Owner Size\n" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " File: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %, %s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, c-format +msgid "sprintf failure" +msgstr "sprintf failure" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "empty block" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "%zu byte block:" + +#: src/readelf.c:4800 +#, c-format +msgid "%*s[%2] %s \n" +msgstr "%*s[%2] %s \n" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "%s %# used with different address sizes" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "%s %# used with different offset sizes" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "%s %# used with different base addresses" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "%s %# used with different attribute %s and %s" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr " [%6tx] ... % bytes ...\n" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +" [ Code]\n" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" +"\n" +"Abbreviation section at offset %:\n" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr " *** error while reading abbreviation: %s\n" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr " [%5u] offset: %, children: %s, tag: %s\n" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" + +#: src/readelf.c:5182 +#, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "cannot get .debug_addr section data: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, c-format +msgid " Length: %8\n" +msgstr " Length: %8\n" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, c-format +msgid " DWARF version: %8\n" +msgstr " DWARF version: %8\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, c-format +msgid " Address size: %8\n" +msgstr " Address size: %8\n" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, c-format +msgid " Segment size: %8\n" +msgstr " Segment size: %8\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, c-format +msgid "Unknown version" +msgstr "Unknown version" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, c-format +msgid "unsupported address size" +msgstr "unsupported address size" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "unsupported segment size" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "cannot get .debug_aranges content: %s" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %# contains %zu entry:\n" +msgstr[1] "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %# contains %zu entries:\n" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" +"\n" +"Table at offset %zu:\n" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "invalid data in section [%zu] ‘%s’" + +#: src/readelf.c:5511 +#, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr "" +"\n" +" Length: %6\n" + +#: src/readelf.c:5523 +#, c-format +msgid " DWARF version: %6\n" +msgstr " DWARF version: %6\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "unsupported aranges version" + +#: src/readelf.c:5538 +#, c-format +msgid " CU offset: %6\n" +msgstr " CU offset: %6\n" + +#: src/readelf.c:5544 +#, c-format +msgid " Address size: %6\n" +msgstr " Address size: %6\n" + +#: src/readelf.c:5555 +#, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr "" +" Segment size: %6\n" +"\n" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr " %zu padding bytes\n" + +#: src/readelf.c:5654 +#, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "cannot get .debug_rnglists content: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr "" +"Table at Offset 0x%:\n" +"\n" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, c-format +msgid " Offset entries: %8\n" +msgstr " Offset entries: %8\n" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr " Unknown CU base: " + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr " CU [%6] base: " + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr " Not associated with a CU.\n" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "too many offset entries for unit length" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " Offsets starting at 0x%:\n" + +#: src/readelf.c:5823 +#, c-format +msgid "invalid range list data" +msgstr "invalid range list data" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" +" %zu padding bytes\n" +"\n" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "cannot get .debug_ranges content: %s" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" +"\n" +" Unknown CU base: " + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" +"\n" +" CU [%6] base: " + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:6097 src/readelf.c:9719 +msgid "base address" +msgstr "base address" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, c-format +msgid " [%6tx] empty list\n" +msgstr " [%6tx] empty list\n" + +#: src/readelf.c:6367 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:6624 +#, c-format +msgid "cannot get ELF: %s" +msgstr "cannot get ELF: %s" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Call frame information section [%2zu] ‘%s’ at offset %#:\n" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" +"\n" +" [%6tx] Zero terminator\n" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, c-format +msgid "invalid augmentation length" +msgstr "invalid augmentation length" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "FDE address encoding: " + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "LSDA pointer encoding: " + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr " (offset: %#)" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr " (end offset: %#)" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr " %-26sLSDA pointer: %#\n" + +#: src/readelf.c:7053 +#, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "DIE [%] cannot get attribute code: %s" + +#: src/readelf.c:7063 +#, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "DIE [%] cannot get attribute form: %s" + +#: src/readelf.c:7085 +#, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "DIE [%] cannot get attribute ‘%s’ (%s) value: %s" + +#: src/readelf.c:7415 +#, c-format +msgid "invalid file (%): %s" +msgstr "invalid file (%): %s" + +#: src/readelf.c:7419 +#, c-format +msgid "no srcfiles for CU [%]" +msgstr "no srcfiles for CU [%]" + +#: src/readelf.c:7423 +#, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "couldn't get DWARF CU: %s" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +" [Offset]\n" + +#: src/readelf.c:7788 +#, c-format +msgid "cannot get next unit: %s" +msgstr "cannot get next unit: %s" + +#: src/readelf.c:7808 +#, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr " Unit type: %s (%)" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "unknown version (%d) or unit type (%d)" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "cannot get DIE offset: %s" + +#: src/readelf.c:7895 +#, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "cannot get tag of DIE at offset [%] in section '%s': %s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "cannot get next DIE: %s\n" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "cannot get next DIE: %s" + +#: src/readelf.c:7985 +#, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" + +#: src/readelf.c:8037 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +"\n" + +#: src/readelf.c:8369 +#, c-format +msgid "unknown form: %s" +msgstr "unknown form: %s" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "cannot get line data section data: %s" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" + +#: src/readelf.c:8524 +#, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "cannot handle .debug_line version: %u\n" + +#: src/readelf.c:8532 +#, c-format +msgid "cannot handle address size: %u\n" +msgstr "cannot handle address size: %u\n" + +#: src/readelf.c:8540 +#, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "cannot handle segment selector size: %u\n" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "invalid data at offset %tu in section [%zu] ‘%s’" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] " [%*] %hhu argument\n" +msgstr[1] " [%*] %hhu arguments\n" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" +"\n" +"Directory table:" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, c-format +msgid " [" +msgstr " [" + +#: src/readelf.c:8653 +msgid "" +"\n" +"File name table:" +msgstr "" +"\n" +"File name table:" + +#: src/readelf.c:8714 +msgid " Entry Dir Time Size Name" +msgstr " Entry Dir Time Size Name" + +#: src/readelf.c:8753 +msgid "" +"\n" +"No line number statements." +msgstr "" +"\n" +"No line number statements." + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" +"\n" +"Line number statements:" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "invalid maximum operations per instruction is zero" + +#: src/readelf.c:8811 +#, c-format +msgid " special opcode %u: address+%u = " +msgstr " special opcode %u: address+%u = " + +#: src/readelf.c:8815 +#, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr ", op_index = %u, line%+d = %zu\n" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr ", line%+d = %zu\n" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr " extended opcode %u: " + +#: src/readelf.c:8841 +msgid " end of sequence" +msgstr " end of sequence" + +#: src/readelf.c:8859 +#, c-format +msgid " set address to " +msgstr " set address to " + +#: src/readelf.c:8887 +#, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr " define new file: dir=%u, mtime=%, length=%, name=%s\n" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr " set discriminator to %u\n" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +msgid " unknown opcode" +msgstr " unknown opcode" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr " copy" + +#: src/readelf.c:8929 +#, c-format +msgid " advance address by %u to " +msgstr " advance address by %u to " + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr ", op_index to %u" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr " advance line by constant %d to %\n" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr " set file to %\n" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr " set column to %\n" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr " set ‘%s’ to %\n" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr " set basic block flag" + +#: src/readelf.c:8990 +#, c-format +msgid " advance address by constant %u to " +msgstr " advance address by constant %u to " + +#: src/readelf.c:9010 +#, c-format +msgid " advance address by fixed value %u to \n" +msgstr " advance address by fixed value %u to \n" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr " set prologue end flag" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr " set epilogue begin flag" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr " set isa to %u\n" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] " unknown opcode with % parameter:" +msgstr[1] " unknown opcode with % parameters:" + +#: src/readelf.c:9084 +#, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "cannot get .debug_loclists content: %s" + +#: src/readelf.c:9250 +#, c-format +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9290 +#, c-format +msgid "invalid loclists data" +msgstr "invalid loclists data" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "cannot get .debug_loc content: %s" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "cannot get macro information section data: %s" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "%*s*** non-terminated string at end of section" + +#: src/readelf.c:9914 +#, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "%*s*** missing DW_MACINFO_start_file argument at end of section" + +#: src/readelf.c:10015 +#, c-format +msgid " Offset: 0x%\n" +msgstr " Offset: 0x%\n" + +#: src/readelf.c:10027 +#, c-format +msgid " Version: %\n" +msgstr " Version: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr " unknown version, cannot parse section\n" + +#: src/readelf.c:10040 +#, c-format +msgid " Flag: 0x%" +msgstr " Flag: 0x%" + +#: src/readelf.c:10069 +#, c-format +msgid " Offset length: %\n" +msgstr " Offset length: %\n" + +#: src/readelf.c:10077 +#, c-format +msgid " .debug_line offset: 0x%\n" +msgstr " .debug_line offset: 0x%\n" + +#: src/readelf.c:10102 +#, c-format +msgid " extension opcode table, % items:\n" +msgstr " extension opcode table, % items:\n" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr " [%]" + +#: src/readelf.c:10121 +#, c-format +msgid " % arguments:" +msgstr " % arguments:" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr " no arguments." + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +" %*s String\n" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "Offset" + +#: src/readelf.c:10396 +#, c-format +msgid " *** error, missing string terminator\n" +msgstr " *** error, missing string terminator\n" + +#: src/readelf.c:10425 +#, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "cannot get .debug_str_offsets section data: %s" + +#: src/readelf.c:10524 +#, c-format +msgid " Length: %8\n" +msgstr " Length: %8\n" + +#: src/readelf.c:10526 +#, c-format +msgid " Offset size: %8\n" +msgstr " Offset size: %8\n" + +#: src/readelf.c:10540 +#, c-format +msgid " DWARF version: %8\n" +msgstr " DWARF version: %8\n" + +#: src/readelf.c:10549 +#, c-format +msgid " Padding: %8\n" +msgstr " Padding: %8\n" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr " LPStart encoding: %#x " + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr " TType encoding: %#x " + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr " Call site encoding: %#x " + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" +"\n" +" Call site table:" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "invalid TType encoding" + +#: src/readelf.c:10882 +#, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" +"\n" +"GDB section [%2zu] ‘%s’ at offset %# contains % " +"bytes :\n" + +#: src/readelf.c:10911 +#, c-format +msgid " Version: %\n" +msgstr " Version: %\n" + +#: src/readelf.c:10929 +#, c-format +msgid " CU offset: %#\n" +msgstr " CU offset: %#\n" + +#: src/readelf.c:10936 +#, c-format +msgid " TU offset: %#\n" +msgstr " TU offset: %#\n" + +#: src/readelf.c:10943 +#, c-format +msgid " address offset: %#\n" +msgstr " address offset: %#\n" + +#: src/readelf.c:10950 +#, c-format +msgid " symbol offset: %#\n" +msgstr " symbol offset: %#\n" + +#: src/readelf.c:10957 +#, c-format +msgid " constant offset: %#\n" +msgstr " constant offset: %#\n" + +#: src/readelf.c:10971 +#, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" CU list at offset %# contains %zu entries:\n" + +#: src/readelf.c:10996 +#, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" TU list at offset %# contains %zu entries:\n" + +#: src/readelf.c:11025 +#, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Address list at offset %# contains %zu entries:\n" + +#: src/readelf.c:11057 +#, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "cannot get debug context descriptor: %s" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "cannot convert core note data: %s" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" +"\n" +"%*s... ..." + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr " Owner Data size Type\n" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr " %-13.*s %9 %s\n" + +#: src/readelf.c:12518 +#, c-format +msgid "cannot get content of note: %s" +msgstr "cannot get content of note: %s" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Note section [%2zu] ‘%s’ of % bytes at offset %#0:\n" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Note segment of % bytes at offset %#0:\n" + +#: src/readelf.c:12622 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" +"\n" +"Section [%zu] ‘%s’ has no data to dump.\n" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "cannot get data for section [%zu] '%s': %s" + +#: src/readelf.c:12654 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" + +#: src/readelf.c:12659 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" + +#: src/readelf.c:12673 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" +"\n" +"Section [%zu] ‘%s’ has no strings to dump.\n" + +#: src/readelf.c:12705 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" +"\n" +"String section [%zu] ‘%s’ contains % bytes at offset " +"%#0:\n" + +#: src/readelf.c:12710 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" +"\n" +"String section [%zu] ‘%s’ contains % bytes (%zd uncompressed) " +"at offset %#0:\n" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" +"\n" +"section [%lu] does not exist" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" +"\n" +"section ‘%s’ does not exist" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "cannot get symbol index of archive '%s': %s" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" +"\n" +"Archive ‘%s’ has no symbol index\n" + +#: src/readelf.c:12853 +#, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" +"\n" +"Index of archive ‘%s’ has %zu entries:\n" + +#: src/readelf.c:12871 +#, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "cannot extract member at offset %zu in '%s': %s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "Archive member ‘%s’ contains:\n" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" +"Use the output format FORMAT. FORMAT can be ‘bsd’ or ‘sysv’. " +"The default is ‘bsd’" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "Same as ‘--format=sysv’" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "Same as ‘--format=bsd’" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "Same as ‘--radix=10’" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "Same as ‘--radix=8’" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "Same as ‘--radix=16’" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "Similar to ‘--format=sysv’ output but in one line" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "Print size and permission flags for loadable segments" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "Display the total sizes (bsd only)" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "List section sizes of FILEs (a.out by default)." + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "Invalid format: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "Invalid radix: %s" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "%s: file format not recognized" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "text" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "data" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "bss" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "dec" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "hex" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "filename" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr " (ex %s)" + +#: src/size.c:420 +msgctxt "sysv" +msgid "section" +msgstr "section" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "size" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "addr" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "Total" + +#: src/size.c:482 +#, c-format +msgid "cannot get section header" +msgstr "cannot get section header" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "(TOTALS)\n" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "-p PID should be a positive process id." + +#: src/stack.c:493 +#, c-format +msgid "Cannot open core file '%s'" +msgstr "Cannot open core file ‘%s’" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "-n MAXFRAMES should be 0 or higher." + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "-e EXEC needs a core given by --core." + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "-1 needs a thread id given by -p." + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "One of -p PID or --core COREFILE should be given." + +#: src/stack.c:645 +msgid "Show stack of process PID" +msgstr "Show stack of process PID" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "Show stack found in COREFILE" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "(optional) EXECUTABLE that produced COREFILE" + +#: src/stack.c:652 +msgid "Output selection options:" +msgstr "Output selection options:" + +#: src/stack.c:654 +msgid "Additionally show frame activation" +msgstr "Additionally show frame activation" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "Additionally try to lookup DWARF debuginfo name for frame address" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "Additionally show module file information" + +#: src/stack.c:663 +msgid "Additionally show source file information" +msgstr "Additionally show source file information" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "Do not resolve address to function symbol name" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "Show raw function symbol names, do not try to demangle names" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "Show module build-id, load address and pc offset" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "Show the backtrace of only one thread" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "Show module memory map with build-id, elf and debug files detected" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "Couldn't show any frames." + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "Output Selection:" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "Scan entire file, not only loaded sections" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" +"Only NUL-terminated sequences of MIN-LEN characters or more are printed" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "Print name of the file before each string." + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "Print location of the string in base 8, 10, or 16 respectively." + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "Alias for --radix=o" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "Print the strings of printable characters in files." + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "invalid value ‘%s’ for %s parameter" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "invalid minimum length of matched string size" + +#: src/strings.c:585 +#, c-format +msgid "lseek failed" +msgstr "lseek failed" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "re-mmap failed" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "mprotect failed" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "Skipping section %zd ‘%s’ data outside file" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "Place stripped output into FILE" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "Extract the removed sections into FILE" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "Embed name FILE instead of -f argument" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "Remove all debugging symbols" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "Remove section headers (not recommended)" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "Copy modified/access timestamps to the output" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "Remove .comment section" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "Discard symbols from object files." + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "--reloc-debug-sections used without -f" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "Only one input file allowed together with ‘-o’ and ‘-f’" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "-f option specified twice" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "-F option specified twice" + +#: src/strip.c:362 +#, c-format +msgid "cannot both keep and remove .comment section" +msgstr "cannot both keep and remove .comment section" + +#: src/strip.c:481 +#, c-format +msgid "bad relocation" +msgstr "bad relocation" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "cannot stat input file ‘%s’" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "while opening ‘%s’" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "%s: cannot use -o or -f when stripping archive" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: no support for stripping archive" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "cannot open EBL backend" + +#: src/strip.c:1092 +#, c-format +msgid "cannot get number of phdrs" +msgstr "cannot get number of phdrs" + +#: src/strip.c:1106 src/strip.c:1149 +#, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "cannot create new ehdr for file '%s': %s" + +#: src/strip.c:1116 src/strip.c:1159 +#, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "cannot create new phdr for file '%s': %s" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "illformed file ‘%s’" + +#: src/strip.c:1250 +#, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "Cannot remove allocated section ‘%s’" + +#: src/strip.c:1259 +#, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "Cannot both keep and remove section ‘%s’" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "while generating output file: %s" + +#: src/strip.c:1688 +#, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "%s: error while updating ELF header: %s" + +#: src/strip.c:1697 +#, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "%s: error while getting shdrstrndx: %s" + +#: src/strip.c:1705 src/strip.c:2550 +#, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "%s: error updating shdrstrndx: %s" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "while preparing output for ‘%s’" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "while create section header section: %s" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "cannot allocate section data: %s" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "while create section header string table: %s" + +#: src/strip.c:1866 +#, c-format +msgid "no memory to create section header string table" +msgstr "no memory to create section header string table" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "Cannot remove symbol [%zd] from allocated symbol table [%zd]" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "while writing '%s': %s" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "while creating ‘%s’" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "while computing checksum for debug information" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "%s: error while creating ELF header: %s" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "%s: error while reading the file: %s" + +#: src/strip.c:2599 src/strip.c:2619 +#, c-format +msgid "while writing '%s'" +msgstr "while writing ‘%s’" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "error while finishing '%s': %s" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "cannot set access and modification date of ‘%s’" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "Match MODULE against file names, not module names" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "Silently skip unfindable files" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "Place output into FILE" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "Create multiple output files under DIRECTORY" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "Use module rather than file names" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "Create output for modules that have no separate debug information" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "Apply relocations to section contents in ET_REL files" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "Only list module and file names, build IDs" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "Force combining files even if some ELF headers don't seem to match" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "-d option specified twice" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "only one of -o or -d allowed" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "-n cannot be used with explicit files or -o or -d" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "output directory ‘%s’" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "exactly two file arguments are required" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "-m, -a, -R, and -i options not allowed with explicit files" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "-o or -d is required when using implicit files" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "cannot create ELF header: %s" + +#: src/unstrip.c:240 +#, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "cannot get shdrstrndx:%s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "cannot get ELF header: %s" + +#: src/unstrip.c:254 +#, c-format +msgid "cannot get new zero section: %s" +msgstr "cannot get new zero section: %s" + +#: src/unstrip.c:257 +#, c-format +msgid "cannot update new zero section: %s" +msgstr "cannot update new zero section: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "cannot copy ELF header: %s" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, c-format +msgid "cannot get number of program headers: %s" +msgstr "cannot get number of program headers: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "cannot create program headers: %s" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "cannot copy program header: %s" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "cannot copy section header: %s" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "cannot get section data: %s" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "cannot copy section data: %s" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "cannot create directory ‘%s’" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "cannot get symbol table entry: %s" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "cannot update symbol table: %s" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "cannot update section header: %s" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "cannot update relocation: %s" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "cannot get symbol version: %s" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "unexpected section type in [%zu] with sh_link to symtab" + +#: src/unstrip.c:848 +#, c-format +msgid "cannot get symbol section data: %s" +msgstr "cannot get symbol section data: %s" + +#: src/unstrip.c:850 +#, c-format +msgid "cannot get string section data: %s" +msgstr "cannot get string section data: %s" + +#: src/unstrip.c:867 +#, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "invalid string offset in symbol [%zu]" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "cannot read section [%zu] name: %s" + +#: src/unstrip.c:1040 +#, c-format +msgid "bad sh_link for group section: %s" +msgstr "bad sh_link for group section: %s" + +#: src/unstrip.c:1046 +#, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "couldn't get shdr for group section: %s" + +#: src/unstrip.c:1051 +#, c-format +msgid "bad data for group symbol section: %s" +msgstr "bad data for group symbol section: %s" + +#: src/unstrip.c:1057 +#, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "couldn't get symbol for group section: %s" + +#: src/unstrip.c:1062 +#, c-format +msgid "bad symbol name for group section: %s" +msgstr "bad symbol name for group section: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "cannot find matching section for [%zu] ‘%s’" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "cannot read ‘.gnu.prelink_undo’ section: %s" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "overflow with shnum = %zu in ‘%s’ section" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "invalid contents in ‘%s’ section" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "cannot add section name to string table: %s" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "cannot update section header string table data: %s" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "cannot get section header string table section index: %s" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "cannot get section count: %s" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "more sections in stripped file than debug file -- arguments reversed?" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "no sections in stripped file" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "cannot read section header string table: %s" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "cannot add new section: %s" + +#: src/unstrip.c:1758 +#, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "symbol [%zu] has invalid section index" + +#: src/unstrip.c:1790 +#, c-format +msgid "group has invalid section index [%zd]" +msgstr "group has invalid section index [%zd]" + +#: src/unstrip.c:2065 +#, c-format +msgid "cannot read section data: %s" +msgstr "cannot read section data: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "cannot update ELF header: %s" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "cannot update program header: %s" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "cannot write output file: %s" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "DWARF data not adjusted for prelinking bias; consider prelink -u" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"DWARF data in ‘%s’ not adjusted for prelinking bias; consider prelink -" +"u" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "cannot create ELF descriptor: %s" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "WARNING: " + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr ", use --force" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "ELF header identification (e_ident) different" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "ELF header type (e_type) different" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "ELF header machine type (e_machine) different" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "stripped program header (e_phnum) smaller than unstripped" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "cannot find stripped file for module '%s': %s" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "cannot open stripped file ‘%s’ for module '%s': %s" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "cannot find debug file for module '%s': %s" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "cannot open debug file ‘%s’ for module '%s': %s" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "module ‘%s’ file ‘%s’ is not stripped" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "cannot cache section addresses for module '%s': %s" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "no matching modules found" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "matched more than one module" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "Request debuginfo-related content from debuginfods listed in $" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "Run executable" + +#: tests/dwflmodtest.c:209 +msgid "Additionally show function names" +msgstr "Additionally show function names" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "Show instances of inlined functions" diff --git a/po/en@quot.gmo b/po/en@quot.gmo new file mode 100644 index 0000000000000000000000000000000000000000..7a57d1d21ef2ff5f3e230270e2f6d6f34480cd10 GIT binary patch literal 154720 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 UpH1`32A5m;X#3mG;ivt70I5O-jsO4v literal 0 HcmV?d00001 diff --git a/po/en@quot.header b/po/en@quot.header new file mode 100644 index 00000000..6522f0ce --- /dev/null +++ b/po/en@quot.header @@ -0,0 +1,22 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# diff --git a/po/en@quot.po b/po/en@quot.po new file mode 100644 index 00000000..b6e6e557 --- /dev/null +++ b/po/en@quot.po @@ -0,0 +1,7328 @@ +# English translations for elfutils package. +# Copyright (C) 2021 The elfutils developers +# This file is distributed under the same license as the elfutils package. +# Automatically generated, 2021. +# +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +msgid "" +msgstr "" +"Project-Id-Version: elfutils 0.185\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2021-05-22 20:29+0200\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en@quot\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" +"colorize the output. WHEN defaults to ‘always’ or can be ‘auto’ or ‘never’" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" +"%s: invalid argument ‘%s’ for ‘--color’\n" +"valid arguments are:\n" +" - 'always', 'yes', ‘force’\n" +" - 'never', 'no', ‘none’\n" +" - 'auto', 'tty', ‘if-tty’\n" + +#: lib/color.c:194 src/objdump.c:728 +#, c-format +msgid "cannot allocate memory" +msgstr "cannot allocate memory" + +#: lib/printversion.c:40 +#, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "memory exhausted" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "no error" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "out of memory" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "cannot create output file" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "invalid parameter" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "cannot change mode of output file" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "cannot rename output file" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "duplicate symbol" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "invalid section type for operation" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "error during output of data" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "no backend support available" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "unknown error" + +#: libcpu/i386_lex.l:122 +#, c-format +msgid "invalid character '%c' at line %d; ignored" +msgstr "invalid character ‘%c’ at line %d; ignored" + +#: libcpu/i386_lex.l:123 +#, c-format +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "invalid character ‘\\%o’ at line %d; ignored" + +#: libcpu/i386_parse.y:554 +#, c-format +msgid "while reading i386 CPU description: %s at line %d" +msgstr "while reading i386 CPU description: %s at line %d" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "invalid access" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "no regular file" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "I/O error" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "invalid ELF file" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "no DWARF information" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "cannot decompress DWARF" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "no ELF file" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "cannot get ELF header" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "not implemented" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "invalid command" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "invalid version" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "invalid file" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "no entries found" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "invalid DWARF" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "no string data" + +#: libdw/dwarf_error.c:75 +msgid ".debug_str section missing" +msgstr ".debug_str section missing" + +#: libdw/dwarf_error.c:76 +msgid ".debug_line_str section missing" +msgstr ".debug_line_str section missing" + +#: libdw/dwarf_error.c:77 +msgid ".debug_str_offsets section missing" +msgstr ".debug_str_offsets section missing" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "no address value" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "no constant value" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "no reference value" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "invalid reference value" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr ".debug_line section missing" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "invalid .debug_line section" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "debug information too big" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "invalid DWARF version" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "invalid directory index" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "address out of range" + +#: libdw/dwarf_error.c:88 +msgid ".debug_loc section missing" +msgstr ".debug_loc section missing" + +#: libdw/dwarf_error.c:89 +msgid ".debug_loclists section missing" +msgstr ".debug_loclists section missing" + +#: libdw/dwarf_error.c:90 +msgid "not a location list value" +msgstr "not a location list value" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "no block data" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "invalid line index" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "invalid address range index" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "no matching address range" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "no flag value" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "invalid offset" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr ".debug_ranges section missing" + +#: libdw/dwarf_error.c:98 +msgid ".debug_rnglists section missing" +msgstr ".debug_rnglists section missing" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "invalid CFI section" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "no alternative debug link found" + +#: libdw/dwarf_error.c:101 +msgid "invalid opcode" +msgstr "invalid opcode" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "not a CU (unit) DIE" + +#: libdw/dwarf_error.c:103 +msgid "unknown language code" +msgstr "unknown language code" + +#: libdw/dwarf_error.c:104 +msgid ".debug_addr section missing" +msgstr ".debug_addr section missing" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "Input selection options:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "Find addresses in FILE" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "Find addresses from signatures found in COREFILE" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "Find addresses in files mapped into process PID" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "Find addresses in the running kernel" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "Kernel with all modules" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "Search path for separate debuginfo files" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "only one of -e, -p, -k, -K, or --core allowed" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "cannot load kernel symbols" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "cannot find kernel modules" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "cannot find kernel or modules" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "cannot read ELF core file: %s" + +#: libdwfl/argp-std.c:317 +msgid "Not enough memory" +msgstr "Not enough memory" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "No modules recognized in core file" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "See errno" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "See elf_errno" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "See dwarf_errno" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "See ebl_errno (XXX missing)" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "gzip decompression failed" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "bzip2 decompression failed" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "LZMA decompression failed" + +#: libdwfl/libdwflP.h:61 +msgid "zstd decompression failed" +msgstr "zstd decompression failed" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "no support library found for machine" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "Callbacks missing for ET_REL file" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "Unsupported relocation type" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "r_offset is bogus" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "offset out of range" + +#: libdwfl/libdwflP.h:67 +msgid "relocation refers to undefined symbol" +msgstr "relocation refers to undefined symbol" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "Callback returned failure" + +#: libdwfl/libdwflP.h:69 +msgid "No DWARF information found" +msgstr "No DWARF information found" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "No symbol table found" + +#: libdwfl/libdwflP.h:71 +msgid "No ELF program headers" +msgstr "No ELF program headers" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "address range overlaps an existing module" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "image truncated" + +#: libdwfl/libdwflP.h:76 +msgid "ELF file opened" +msgstr "ELF file opened" + +#: libdwfl/libdwflP.h:77 +msgid "not a valid ELF file" +msgstr "not a valid ELF file" + +#: libdwfl/libdwflP.h:78 +msgid "cannot handle DWARF type description" +msgstr "cannot handle DWARF type description" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "ELF file does not match build ID" + +#: libdwfl/libdwflP.h:80 +msgid "corrupt .gnu.prelink_undo section data" +msgstr "corrupt .gnu.prelink_undo section data" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "Internal error due to ebl" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "Missing data in core file" + +#: libdwfl/libdwflP.h:83 +msgid "Invalid register" +msgstr "Invalid register" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "Error reading process memory" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "Couldn't find architecture of any ELF" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "Error parsing /proc filesystem" + +#: libdwfl/libdwflP.h:87 +msgid "Invalid DWARF" +msgstr "Invalid DWARF" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "Unsupported DWARF" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "Unable to find more threads" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "Dwfl already has attached state" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "Dwfl has no attached state" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "Unwinding not supported for this architecture" + +#: libdwfl/libdwflP.h:93 +msgid "Invalid argument" +msgstr "Invalid argument" + +#: libdwfl/libdwflP.h:94 +msgid "Not an ET_CORE ELF file" +msgstr "Not an ET_CORE ELF file" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "No backend" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr ": %#" + +#: libebl/eblobjnote.c:58 +#, c-format +msgid "unknown SDT version %u\n" +msgstr "unknown SDT version %u\n" + +#: libebl/eblobjnote.c:76 +#, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "invalid SDT probe descriptor\n" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr " PC: " + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr " Base: " + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr " Semaphore: " + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr " Provider: " + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr " Name: " + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr " Args: " + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " Build ID: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr " Linker version: %.*s\n" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " OS: %s, ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "Stand alone" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr ": %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "unknown version" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "unknown type" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "invalid ‘Elf’ handle" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "invalid size of source operand" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "invalid size of destination operand" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "invalid encoding" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "invalid file descriptor" + +#: libelf/elf_error.c:99 +msgid "invalid ELF file data" +msgstr "invalid ELF file data" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "invalid operation" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "ELF version not set" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "invalid fmag field in archive header" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "invalid archive file" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "descriptor is not for an archive" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "no index available" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "cannot read data from file" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "cannot write data to file" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "invalid binary class" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "invalid section index" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "invalid operand" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "invalid section" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "executable header not created first" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "file descriptor disabled" + +#: libelf/elf_error.c:171 +msgid "archive/member file descriptor mismatch" +msgstr "archive/member file descriptor mismatch" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "cannot manipulate null section" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "data/scn mismatch" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "invalid section header" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "invalid data" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "unknown data encoding" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "section ‘sh_size’ too small for data" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "invalid section alignment" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "invalid section entry size" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "update() for write on read-only file" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "no such file" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "only relocatable files can contain section groups" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" +"program header only allowed in executables, shared objects, and core files" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "file has no program header" + +#: libelf/elf_error.c:241 +msgid "invalid section type" +msgstr "invalid section type" + +#: libelf/elf_error.c:246 +msgid "invalid section flags" +msgstr "invalid section flags" + +#: libelf/elf_error.c:251 +msgid "section does not contain compressed data" +msgstr "section does not contain compressed data" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "section contains compressed data" + +#: libelf/elf_error.c:261 +msgid "unknown compression type" +msgstr "unknown compression type" + +#: libelf/elf_error.c:266 +msgid "cannot compress data" +msgstr "cannot compress data" + +#: libelf/elf_error.c:271 +msgid "cannot decompress data" +msgstr "cannot decompress data" + +#: src/addr2line.c:57 +msgid "Input format options:" +msgstr "Input format options:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "Treat addresses as offsets relative to NAME section." + +#: src/addr2line.c:61 +msgid "Output format options:" +msgstr "Output format options:" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "Print address before each entry" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "Show only base names of source files" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "Show absolute file names using compilation directory" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "Also show function names" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "Also show symbol or section names" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "Also show symbol and the section names" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "Also show line table flags" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "Show demangled symbols (ARG is always ignored)" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "Print all information on one line, and indent inlines" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "Miscellaneous:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" +"Locate source files and line information for ADDRs (in a.out by default)." + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "[ADDR...]" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "Section syntax requires exactly one module" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "offset %# lies outside section ‘%s’" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "cannot find symbol ‘%s’" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "offset %# lies outside contents of ‘%s’" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "Commands:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "Delete files from archive." + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "Move files in archive." + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "Print files in archive." + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "Quick append files to archive." + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "Replace existing or insert new file into archive." + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "Display content of archive." + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "Extract files from archive." + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "Command Modifiers:" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "Preserve original dates." + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "Use instance [COUNT] of name." + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "Do not replace existing files with extracted files." + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "Allow filename to be truncated if necessary." + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "Provide verbose output." + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "Force regeneration of symbol table." + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "Insert file after [MEMBER]." + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "Insert file before [MEMBER]." + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "Same as -b." + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "Suppress message when library has to be created." + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "Use full path for file matching." + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "Update only older files in archive." + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "Create, modify, and extract from archives." + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[MEMBER] [COUNT] ARCHIVE [FILE...]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "'a', 'b', and ‘i’ are only allowed with the ‘m’ and ‘r’ options" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "MEMBER parameter required for 'a', 'b', and ‘i’ modifiers" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "‘N’ is only meaningful with the ‘x’ and ‘d’ options" + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "COUNT parameter required" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "invalid COUNT parameter %s" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "‘%c’ is only meaningful with the ‘x’ option" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "archive name required" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "command option required" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "More than one operation specified" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "cannot open archive ‘%s’" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "cannot open archive '%s': %s" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: not an archive file" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "cannot stat archive ‘%s’" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "no entry %s in archive\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "cannot create hash table" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "cannot insert into hash table" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "cannot stat ‘%s’" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "cannot read content of %s: %s" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "cannot open %.*s" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "failed to write %s" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "cannot change mode of %s" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "cannot change modification time of %s" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "cannot rename temporary file to %.*s" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "cannot create new file" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "position member %s not found" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: no entry %s in archive!\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "cannot open %s" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "cannot stat %s" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "%s is no regular file" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "cannot get ELF descriptor for %s: %s\n" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "cannot read %s: %s" + +#: src/ar.c:1483 +#, c-format +msgid "cannot represent ar_date" +msgstr "cannot represent ar_date" + +#: src/ar.c:1489 +#, c-format +msgid "cannot represent ar_uid" +msgstr "cannot represent ar_uid" + +#: src/ar.c:1495 +#, c-format +msgid "cannot represent ar_gid" +msgstr "cannot represent ar_gid" + +#: src/ar.c:1501 +#, c-format +msgid "cannot represent ar_mode" +msgstr "cannot represent ar_mode" + +#: src/ar.c:1507 +#, c-format +msgid "cannot represent ar_size" +msgstr "cannot represent ar_size" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "Use zero for uid, gid, and date in archive members." + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "Use actual uid, gid, and date in archive members." + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "%s (default)" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "the archive ‘%s’ is too large" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "cannot read ELF header of %s(%s): %s" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "opening" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "reading" + +#: src/elfclassify.c:245 +msgid "ELF header" +msgstr "ELF header" + +#: src/elfclassify.c:256 +msgid "program headers" +msgstr "program headers" + +#: src/elfclassify.c:265 +msgid "program header" +msgstr "program header" + +#: src/elfclassify.c:285 +msgid "section headers" +msgstr "section headers" + +#: src/elfclassify.c:296 +msgid "section header string table index" +msgstr "section header string table index" + +#: src/elfclassify.c:310 +msgid "could not obtain section header" +msgstr "could not obtain section header" + +#: src/elfclassify.c:316 +msgid "could not obtain section name" +msgstr "could not obtain section name" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "writing to standard output" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "reading from standard input" + +#: src/elfclassify.c:877 +msgid "Classification options" +msgstr "Classification options" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "File looks like an ELF object or archive/static library (default)" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "File is an regular ELF object (not an archive/static library)" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "File is an ELF archive or static library" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "File is an ELF core dump file" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "File is (primarily) an ELF program executable (not primarily a DSO)" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "File is an ELF program executable (might also be a DSO)" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "File is an ELF shared object (DSO) (might also be an executable)" + +#: src/elfclassify.c:907 +msgid "File is a linux kernel module" +msgstr "File is a linux kernel module" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" +"File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "File is a loadable ELF object (program or shared object)" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "Input flags" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "Only classify regular (not symlink nor special device) files" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" +"Also read file names to process from standard input, separated by newlines" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "Do not read files from standard input (default)" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "Try to open compressed files or embedded (kernel) ELF images" + +#: src/elfclassify.c:956 +msgid "Output flags" +msgstr "Output flags" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "Output names of files, separated by newline" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "Output names of files, separated by ASCII NUL" + +#: src/elfclassify.c:962 +msgid "Do not output file names" +msgstr "Do not output file names" + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "If printing file names, print matching files (default)" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "If printing file names, print files that do not match" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "Additional flags" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "Output additional information (can be specified multiple times)" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "Suppress some error output (counterpart to --verbose)" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "FILE..." + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a “--not-” " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "Control options:" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "Output all differences, not just the first" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "Ignore permutation of buckets in SHT_HASH section" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "Ignore differences in build ID" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "Output nothing; yield exit status only" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "Compare relevant parts of two ELF files for equality." + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "FILE1 FILE2" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "Invalid number of parameters.\n" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "cannot get ELF header of '%s': %s" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "%s %s diff: ELF header" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, c-format +msgid "cannot get section count of '%s': %s" +msgstr "cannot get section count of '%s': %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "%s %s diff: section count" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "cannot get program header count of '%s': %s" + +#: src/elfcmp.c:233 +#, c-format +msgid "%s %s diff: program header count" +msgstr "%s %s diff: program header count" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "cannot get hdrstrndx of '%s': %s" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "%s %s diff: shdr string index" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "%s %s differ: section [%zu], [%zu] name" + +#: src/elfcmp.c:330 +#, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "%s %s differ: section [%zu] ‘%s’ header" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "cannot get content of section %zu in '%s': %s" + +#: src/elfcmp.c:353 +#, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "symbol table [%zu] in ‘%s’ has zero sh_entsize" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "cannot get symbol in '%s': %s" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "%s %s differ: symbol table [%zu]" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "%s %s differ: symbol table [%zu,%zu]" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "%s %s differ: section [%zu] ‘%s’ number of notes" + +#: src/elfcmp.c:451 +#, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "cannot read note section [%zu] ‘%s’ in '%s': %s" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "%s %s differ: section [%zu] ‘%s’ note name" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "%s %s differ: section [%zu] ‘%s’ note ‘%s’ type" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "%s %s differ: build ID length" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "%s %s differ: build ID content" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "%s %s differ: section [%zu] ‘%s’ note ‘%s’ content" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "%s %s differ: section [%zu] ‘%s’ content" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "%s %s differ: section [%zu,%zu] ‘%s’ content" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "%s %s differ: unequal amount of important sections" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "cannot load data of '%s': %s" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "cannot get program header entry %d of '%s': %s" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "%s %s differ: program header %d" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "%s %s differ: gap" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "Invalid value ‘%s’ for --gaps parameter." + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "cannot open ‘%s’" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "cannot create ELF descriptor for '%s': %s" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "cannot create EBL descriptor for ‘%s’" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "cannot get section header of section %zu: %s" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "cannot get content of section %zu: %s" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "cannot get relocation: %s" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "-o option specified twice" + +#: src/elfcompress.c:124 +#, c-format +msgid "-t option specified twice" +msgstr "-t option specified twice" + +#: src/elfcompress.c:133 +#, c-format +msgid "unknown compression type '%s'" +msgstr "unknown compression type ‘%s’" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, c-format +msgid "No input file given" +msgstr "No input file given" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "Only one input file allowed together with ‘-o’" + +#: src/elfcompress.c:1307 +msgid "Place (de)compressed output into FILE" +msgstr "Place (de)compressed output into FILE" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" +"What type of compression to apply. TYPE can be ‘none’ (decompress), " +"‘zlib’ (ELF ZLIB compression, the default, ‘zlib-gabi’ is an alias) or ‘zlib-" +"gnu’ (.zdebug GNU style compression, ‘gnu’ is an alias)" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "Print a message for each section being (de)compressed" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "Relax a few rules to handle slightly broken ELF files" + +#: src/elfcompress.c:1325 +msgid "Be silent when a section cannot be compressed" +msgstr "Be silent when a section cannot be compressed" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "Compress or decompress sections in an ELF file." + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "Be extremely strict, flag level 2 features." + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "Do not print anything if successful" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "Binary is a separate debuginfo file" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "Pedantic checking of ELF files compliance with gABI/psABI spec." + +#: src/elflint.c:154 src/readelf.c:368 +#, c-format +msgid "cannot open input file '%s'" +msgstr "cannot open input file ‘%s’" + +#: src/elflint.c:161 +#, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "cannot generate Elf descriptor for '%s': %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "error while closing Elf descriptor: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "No errors" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "Missing file name.\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr " error while freeing sub-ELF descriptor: %s\n" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "Not an ELF file - it has the wrong magic bytes at the start\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "e_ident[%d] == %d is no known class\n" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "e_ident[%d] == %d is no known data encoding\n" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "unknown ELF header version number e_ident[%d] == %d\n" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "unsupported OS ABI e_ident[%d] == ‘%s’\n" + +#: src/elflint.c:380 +#, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "unsupported ABI version e_ident[%d] == %d\n" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] is not zero\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "unknown object file type %d\n" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "unknown machine type %d\n" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "unknown object file version\n" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "invalid program header offset\n" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "executables and DSOs cannot have zero program header offset\n" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "invalid number of program header entries\n" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "invalid section header table offset\n" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "section header table must be present\n" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "invalid number of section header table entries\n" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "invalid section header index\n" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "Can only check %u headers, shnum was %u\n" + +#: src/elflint.c:487 +#, c-format +msgid "invalid number of program header table entries\n" +msgstr "invalid number of program header table entries\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "Can only check %u headers, phnum was %u\n" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "invalid machine flags: %s\n" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "invalid ELF header size: %hd\n" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "invalid program header size: %hd\n" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "invalid program header position or size\n" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "invalid section header size: %hd\n" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "invalid section header position or size\n" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" +"section [%2d] '%s': section group [%2zu] ‘%s’ does not precede group member\n" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "section [%2d] '%s': cannot get section data\n" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" +"section [%2d] '%s': referenced as string table for section [%2d] ‘%s’ but " +"type is not SHT_STRTAB\n" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" +"section [%2u] '%s': number of local entries in ‘st_info’ larger than table " +"size\n" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "section [%2d] '%s': cannot get symbol %d: %s\n" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "section [%2d] '%s': ‘%s’ in zeroth entry not zero\n" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "section [%2d] '%s': XINDEX for zeroth entry not zero\n" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "section [%2d] '%s': cannot get symbol %zu: %s\n" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "section [%2d] '%s': symbol %zu: invalid name value\n" + +#: src/elflint.c:728 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" + +#: src/elflint.c:734 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "section [%2d] '%s': symbol %zu (%s): invalid section index\n" + +#: src/elflint.c:754 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "section [%2d] '%s': symbol %zu (%s): unknown type\n" + +#: src/elflint.c:760 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" + +#: src/elflint.c:765 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" + +#: src/elflint.c:773 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" + +#: src/elflint.c:777 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" + +#: src/elflint.c:781 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" + +#: src/elflint.c:832 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] ‘%s’\n" + +#: src/elflint.c:847 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] ‘%s’ does not " +"have SHF_TLS flag set\n" + +#: src/elflint.c:857 src/elflint.c:905 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] ‘%s’\n" + +#: src/elflint.c:884 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" + +#: src/elflint.c:890 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" + +#: src/elflint.c:898 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] ‘%s’\n" + +#: src/elflint.c:925 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" + +#: src/elflint.c:932 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" + +#: src/elflint.c:939 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"‘%s’\n" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" + +#: src/elflint.c:1063 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" + +#: src/elflint.c:1067 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" + +#: src/elflint.c:1105 +#, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "section [%2d] '%s': cannot get section data.\n" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "section [%2d] '%s': invalid destination section index\n" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "section [%2d] '%s': invalid destination section type\n" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "section [%2d] '%s': sh_info should be zero\n" + +#: src/elflint.c:1286 +#, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "text relocation flag set but there is no read-only segment\n" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "section [%2d] '%s': relocation %zu: invalid type\n" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "section [%2d] '%s': relocation %zu: invalid symbol index\n" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" +"section [%2d] '%s': relocation %zu: only symbol ‘_GLOBAL_OFFSET_TABLE_’ can " +"be used with %s\n" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "section [%2d] '%s': relocation %zu: offset out of bounds\n" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "section [%2d] '%s': relocations are against loaded and unloaded data\n" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "section [%2d] '%s': cannot get relocation %zu: %s\n" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "more than one dynamic section present\n" + +#: src/elflint.c:1668 +#, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" +"section [%2d]: referenced as string table for section [%2d] ‘%s’ but section " +"link value is invalid\n" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "section [%2d] '%s': sh_info not zero\n" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "section [%2d] '%s': entry %zu: unknown tag\n" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "section [%2d] '%s': entry %zu: level 2 tag %s used\n" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] ‘%s’ referenced by sh_link\n" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] ‘%s’\n" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "section [%2d] '%s': contains %s entry but not %s\n" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "section [%2d] '%s': mandatory tag %s not present\n" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "section [%2d] '%s': no hash section present\n" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "section [%2d] '%s': not all of %s, %s, and %s are present\n" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "section [%2d] '%s': %s tag missing in prelinked executable\n" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" +"section [%2d] '%s': only relocatable files can have extended section index\n" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" +"section [%2d] '%s': extended section index section not for symbol table\n" + +#: src/elflint.c:1948 +#, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "cannot get data for symbol section\n" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "section [%2d] '%s': entry size does not match Elf32_Word\n" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "section [%2d] '%s': extended index table too small for symbol table\n" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" +"section [%2d] '%s': extended section index in section [%2zu] ‘%s’ refers to " +"same symbol table\n" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "symbol 0 should have zero extended section index\n" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "cannot get data for symbol %zu\n" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "extended section index is % but symbol index is not XINDEX\n" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "section [%2d] '%s': chain array too large\n" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "section [%2d] '%s': hash bucket reference %zu out of bounds\n" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "section [%2d] '%s': hash chain reference %zu out of bounds\n" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "section [%2d] '%s': hash chain reference % out of bounds\n" + +#: src/elflint.c:2140 +#, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "section [%2d] '%s': not enough data\n" + +#: src/elflint.c:2152 +#, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "section [%2d] '%s': 2nd hash function shift too big: %u\n" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" + +#: src/elflint.c:2254 +#, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "section [%2d] '%s': bitmask does not match names in the hash table\n" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "section [%2d] '%s': relocatable files cannot have hash tables\n" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "section [%2d] '%s': hash table not for dynamic symbol table\n" + +#: src/elflint.c:2330 +#, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "section [%2d] '%s': hash table entry size incorrect\n" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "section [%2d] '%s': not marked to be allocated\n" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "sh_link in hash sections [%2zu] ‘%s’ and [%2zu] ‘%s’ not identical\n" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "hash section [%2zu] ‘%s’ does not contain enough data\n" + +#: src/elflint.c:2444 +#, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "hash section [%2zu] ‘%s’ has zero bit mask words\n" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "hash section [%2zu] ‘%s’ uses too much data\n" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" +"hash section [%2zu] ‘%s’ invalid symbol index % (max_nsyms: " +"%, nentries: %\n" + +#: src/elflint.c:2557 +#, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "hash section [%2zu] ‘%s’ invalid sh_entsize\n" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "section [%2zu] '%s': reference to symbol index 0\n" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" +"symbol %d referenced in new hash table in [%2zu] ‘%s’ but not in old hash " +"table in [%2zu] ‘%s’\n" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" +"symbol %d referenced in old hash table in [%2zu] ‘%s’ but not in new hash " +"table in [%2zu] ‘%s’\n" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "section [%2d] '%s': nonzero sh_%s for NULL section\n" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "section [%2d] '%s': cannot get symbol table: %s\n" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "section [%2d] '%s': section reference in sh_link is no symbol table\n" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "section [%2d] '%s': invalid symbol index in sh_info\n" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "section [%2d] '%s': sh_flags not zero\n" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "section [%2d] '%s': cannot get symbol for signature\n" + +#: src/elflint.c:2664 +#, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "section [%2d] '%s': cannot get symbol name for signature\n" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "section [%2d] '%s': signature symbol cannot be empty string\n" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "section [%2d] '%s': sh_flags not set correctly\n" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "section [%2d] '%s': cannot get data: %s\n" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "section [%2d] '%s': section group without flags word\n" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "section [%2d] '%s': section group without member\n" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "section [%2d] '%s': section group with only one member\n" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "section [%2d] '%s': unknown section group flags\n" + +#: src/elflint.c:2731 +#, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "section [%2d] '%s': section index %zu out of range\n" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "section [%2d] '%s': cannot get section header for element %zu: %s\n" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "section [%2d] '%s': section group contains another group [%2d] ‘%s’\n" + +#: src/elflint.c:2753 +#, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" +"section [%2d] '%s': element %zu references section [%2d] ‘%s’ without " +"SHF_GROUP flag set\n" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "section [%2d] ‘%s’ is contained in more than one section group\n" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" +"section [%2d] ‘%s’ refers in sh_link to section [%2d] ‘%s’ which is no " +"dynamic symbol table\n" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" +"section [%2d] ‘%s’ has different number of entries than symbol table [%2d] " +"‘%s’\n" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "section [%2d] '%s': symbol %d: cannot read version data\n" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "section [%2d] '%s': symbol %d: local symbol with global scope\n" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "section [%2d] '%s': symbol %d: local symbol with version\n" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "section [%2d] '%s': symbol %d: invalid version index %d\n" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "more than one version reference section present\n" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "section [%2d] '%s': sh_link does not link to string table\n" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "section [%2d] '%s': entry %d has wrong version %d\n" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "section [%2d] '%s': entry %d has invalid file reference\n" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "section [%2d] '%s': entry %d references unknown dependency\n" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name ‘%s’\n" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "section [%2d] '%s': entry %d has invalid offset to next entry\n" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "more than one version definition section present\n" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "section [%2d] '%s': more than one BASE definition\n" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "section [%2d] '%s': entry %d has unknown flag\n" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "section [%2d] '%s': entry %d has invalid name reference\n" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "section [%2d] '%s': entry %d has duplicate version name ‘%s’\n" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "section [%2d] '%s': no BASE definition\n" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "section [%2d] '%s': unknown parent version ‘%s’\n" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "section [%2d] '%s': empty object attributes section\n" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "section [%2d] '%s': unrecognized attribute format\n" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "section [%2d] '%s': offset %zu: invalid length in attribute section\n" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "section [%2d] '%s': offset %zu: unterminated vendor name string\n" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "section [%2d] '%s': offset %zu: truncated attribute section\n" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "section [%2d] '%s': offset %zu: unterminated string in attribute\n" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "section [%2d] '%s': offset %zu: vendor ‘%s’ unknown\n" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "cannot get section header of zeroth section\n" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "zeroth section has nonzero name\n" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "zeroth section has nonzero type\n" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "zeroth section has nonzero flags\n" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "zeroth section has nonzero address\n" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "zeroth section has nonzero offset\n" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "zeroth section has nonzero align value\n" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "zeroth section has nonzero entry size value\n" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "cannot get section header for section [%2zu] '%s': %s\n" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "section [%2zu]: invalid name\n" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "section [%2d] ‘%s’ has wrong type: expected %s, is %s\n" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "section [%2zu] ‘%s’ has wrong flags: expected %s, is %s\n" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" +"section [%2zu] ‘%s’ has wrong flags: expected %s and possibly %s, is %s\n" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "section [%2zu] ‘%s’ present in object file\n" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" +"section [%2zu] ‘%s’ has SHF_ALLOC flag set but there is no loadable segment\n" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" +"section [%2zu] ‘%s’ has SHF_ALLOC flag not set but there are loadable " +"segments\n" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" +"section [%2zu] ‘%s’ is extension section index table in non-object file\n" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "section [%2zu] '%s': size not multiple of entry size\n" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "cannot get section header\n" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "section [%2zu] ‘%s’ has unsupported type %d\n" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" +"section [%2zu] ‘%s’ contains invalid processor-specific flag(s) %#\n" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "section [%2zu] ‘%s’ contains unknown flag(s) %#\n" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "section [%2zu] '%s': thread-local data sections address not zero\n" + +#: src/elflint.c:3974 +#, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "section [%2zu] '%s': allocated section cannot be compressed\n" + +#: src/elflint.c:3979 +#, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "section [%2zu] '%s': nobits section cannot be compressed\n" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "section [%2zu] '%s': invalid section reference in link value\n" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "section [%2zu] '%s': invalid section reference in info value\n" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "section [%2zu] '%s': strings flag set without merge flag\n" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "section [%2zu] '%s': merge flag set but entry size is zero\n" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "section [%2zu] ‘%s’ has unexpected type %d for an executable section\n" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "section [%2zu] ‘%s’ must be of type NOBITS in debuginfo files\n" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "section [%2zu] ‘%s’ is both executable and writable\n" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" +"section [%2zu] ‘%s’ not fully contained in segment of program header entry " +"%d\n" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" +"section [%2zu] ‘%s’ has type NOBITS but is read from the file in segment of " +"program header entry %d\n" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" +"section [%2zu] ‘%s’ has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" +"section [%2zu] ‘%s’ has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "section [%2zu] ‘%s’ is executable in nonexecutable segment %d\n" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "section [%2zu] ‘%s’ is writable in unwritable segment %d\n" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "more than one version symbol table present\n" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "INTERP program header entry but no .interp section\n" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" +"loadable segment [%u] is executable but contains no executable sections\n" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "loadable segment [%u] is writable but contains no writable sections\n" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "duplicate version index %d\n" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "phdr[%d]: unknown core file note type % at offset %\n" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" +"phdr[%d]: unknown object file note type % with owner name ‘%s’ at " +"offset %zu\n" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" +"section [%2d] '%s': unknown object file note type % with owner name " +"‘%s’ at offset %zu\n" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "phdr[%d]: no note entries defined for the type of file\n" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "phdr[%d]: cannot get content of note section: %s\n" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "phdr[%d]: extra % bytes after last note\n" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "section [%2d] '%s': no note entries defined for the type of file\n" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "section [%2d] '%s': cannot get content of note section\n" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "section [%2d] '%s': extra % bytes after last note\n" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" +"only executables, shared objects, and core files can have program headers\n" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "cannot get program header entry %d: %s\n" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" +"program header entry %d: unknown program header entry type %#\n" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "more than one INTERP entry in program header\n" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "more than one TLS entry in program header\n" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "static executable cannot have dynamic sections\n" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "dynamic section reference in program header has wrong offset\n" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "dynamic section size mismatch in program and section header\n" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "more than one GNU_RELRO entry in program header\n" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "loadable segment GNU_RELRO applies to is not writable\n" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "%s segment not contained in a loaded segment\n" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "program header offset in ELF header and PHDR entry do not match" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "call frame search table reference in program header has wrong offset\n" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "call frame search table size mismatch in program and section header\n" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "call frame search table must be allocated\n" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "section [%2zu] ‘%s’ must be allocated\n" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "call frame search table must not be writable\n" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "section [%2zu] ‘%s’ must not be writable\n" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "call frame search table must not be executable\n" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "section [%2zu] ‘%s’ must not be executable\n" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "program header entry %d: file size greater than memory size\n" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "program header entry %d: alignment not a power of 2\n" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "cannot read ELF header: %s\n" + +#: src/elflint.c:4797 +#, c-format +msgid "cannot create backend for ELF file\n" +msgstr "cannot create backend for ELF file\n" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "text relocation flag set but not needed\n" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "Input Selection:" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "Prepend PATH to all file names" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "Use PATH as root of debuginfo hierarchy" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "Locate source of text relocations in FILEs (a.out by default)." + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "[FILE...]" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "cannot get ELF header '%s': %s" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "‘%s’ is not a DSO or PIE" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "getting get section header of section %zu: %s" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "cannot read dynamic section: %s" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "no text relocations reported in ‘%s’" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "while reading ELF file" + +#: src/findtextrel.c:314 +#, c-format +msgid "cannot get program header count: %s" +msgstr "cannot get program header count: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "cannot get program header index at offset %zd: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "cannot get symbol table section %zu in '%s': %s" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "cannot get relocation at index %d in section %zu in '%s': %s" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "%s not compiled with -fpic/-fPIC\n" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"the file containing the function ‘%s’ is not compiled with -fpic/-fPIC\n" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" +"the file containing the function ‘%s’ might not be compiled with -fpic/-" +"fPIC\n" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"either the file containing the function ‘%s’ or the file containing the " +"function ‘%s’ is not compiled with -fpic/-fPIC\n" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "Output selection:" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "Display debugger-only symbols" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "Display only defined symbols" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "Display dynamic symbols instead of normal symbols" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "Display only external symbols" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "Display only undefined symbols" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "Include index for symbols from archive members" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "Output format:" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "Print name of the input file before every symbol" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"Use the output format FORMAT. FORMAT can be ‘bsd’, ‘sysv’ or ‘posix’. The " +"default is ‘sysv’" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "Same as --format=bsd" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "Same as --format=posix" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "Use RADIX for printing symbol values" + +#: src/nm.c:87 +msgid "Mark special symbols" +msgstr "Mark special symbols" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "Print size of defined symbols" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "Output options:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "Sort symbols numerically by address" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "Do not sort the symbols" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "Reverse the sense of the sort" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "Decode low-level symbol names into source code names" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "List symbols from FILEs (a.out by default)." + +#: src/nm.c:116 src/objdump.c:79 +msgid "Output formatting" +msgstr "Output formatting" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: INTERNAL ERROR %d (%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "while closing ‘%s’" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: File format not recognized" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"Archive index:\n" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "invalid offset %zu for symbol %s" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "%s in %s\n" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "cannot reset archive offset to beginning" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: file format not recognized" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "cannot create search tree" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "cannot get section header string table index" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" + +#: src/nm.c:776 +msgctxt "sysv" +msgid "Name" +msgstr "Name" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "Value" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "Size" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "Line" + +#: src/nm.c:1250 +#, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "%s: entry size in section %zd ‘%s’ is not what we expect" + +#: src/nm.c:1255 +#, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: size of section %zd ‘%s’ is not multiple of entry size" + +#: src/nm.c:1336 +#, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "%s: entries (%zd) in section %zd ‘%s’ is too large" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: Invalid operation" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: no symbols" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "Mode selection:" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "Display relocation information." + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "Display the full contents of all sections requested" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "Display assembler code of executable sections" + +#: src/objdump.c:59 +msgid "Output content selection:" +msgstr "Output content selection:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "Only display information for section NAME." + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "Show information from FILEs (a.out by default)." + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "No operation specified.\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "while close ‘%s’" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "INVALID SYMBOL" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "INVALID SECTION" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "OFFSET" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "Contents of section %s:\n" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "cannot disassemble" + +#: src/objdump.c:760 +#, c-format +msgid "cannot create backend for elf file" +msgstr "cannot create backend for elf file" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "Generate an index to speed access to archives." + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "ARCHIVE" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "Archive name required" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "‘%s’ is no archive" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "error while freeing sub-ELF descriptor: %s" + +#: src/readelf.c:97 +msgid "ELF input selection:" +msgstr "ELF input selection:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" + +#: src/readelf.c:104 +msgid "ELF output selection:" +msgstr "ELF output selection:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "All these plus -p .strtab -p .dynstr -p .comment" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "Display the dynamic segment" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "Display the ELF file header" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "Display histogram of bucket list lengths" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "Display the program headers" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "Display relocations" + +#: src/readelf.c:114 +msgid "Display the section groups" +msgstr "Display the section groups" + +#: src/readelf.c:115 +msgid "Display the sections' headers" +msgstr "Display the sections' headers" + +#: src/readelf.c:118 +msgid "Display the symbol table sections" +msgstr "Display the symbol table sections" + +#: src/readelf.c:120 +msgid "Display (only) the dynamic symbol table" +msgstr "Display (only) the dynamic symbol table" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "Display versioning information" + +#: src/readelf.c:122 +msgid "Display the ELF notes" +msgstr "Display the ELF notes" + +#: src/readelf.c:124 +msgid "Display architecture specific information, if any" +msgstr "Display architecture specific information, if any" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "Display sections for exception handling" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "Additional output selection:" + +#: src/readelf.c:130 +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "Dump the uninterpreted contents of SECTION, by number or name" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "Print string contents of sections" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "Display the symbol index of an archive" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "Output control:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "Do not find symbol names for addresses in DWARF data" + +#: src/readelf.c:145 +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "" +"Display just offsets instead of resolving values to addresses in DWARF data" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "Ignored for compatibility (lines always wide)" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "Print information from ELF file in human-readable form." + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "yes" + +#: src/readelf.c:351 +msgid "no" +msgstr "no" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "Unknown DWARF debug section ‘%s’.\n" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "cannot generate Elf descriptor: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "cannot determine number of sections: %s" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "cannot get section: %s" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "cannot get section header: %s" + +#: src/readelf.c:663 +#, c-format +msgid "cannot get section name" +msgstr "cannot get section name" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "cannot get %s content: %s" + +#: src/readelf.c:688 +#, c-format +msgid "cannot create temp file '%s'" +msgstr "cannot create temp file ‘%s’" + +#: src/readelf.c:697 +#, c-format +msgid "cannot write section data" +msgstr "cannot write section data" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "error while closing Elf descriptor: %s" + +#: src/readelf.c:710 +#, c-format +msgid "error while rewinding file descriptor" +msgstr "error while rewinding file descriptor" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "‘%s’ is not an archive, cannot print archive index" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "cannot stat input file" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "input file is empty" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "failed reading '%s': %s" + +#: src/readelf.c:881 +#, c-format +msgid "No such section '%s' in '%s'" +msgstr "No such section ‘%s’ in ‘%s’" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "cannot read ELF header: %s" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "cannot create EBL handle" + +#: src/readelf.c:961 +#, c-format +msgid "cannot determine number of program headers: %s" +msgstr "cannot determine number of program headers: %s" + +#: src/readelf.c:993 +#, c-format +msgid "cannot read ELF: %s" +msgstr "cannot read ELF: %s" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "NONE (None)" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "REL (Relocatable file)" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "EXEC (Executable file)" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "DYN (Shared object file)" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "CORE (Core file)" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "OS Specific: (%x)\n" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "Processor Specific: (%x)\n" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" +"ELF Header:\n" +" Magic: " + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" +"\n" +" Class: %s\n" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr " Data: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr " Ident Version: %hhd %s\n" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(current)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr " OS/ABI: %s\n" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr " ABI Version: %hhd\n" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " Type: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr " Machine: %s\n" + +#: src/readelf.c:1109 +#, c-format +msgid " Machine: : 0x%x\n" +msgstr " Machine: : 0x%x\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr " Version: %d %s\n" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr " Entry point address: %#\n" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr " Start of program headers: % %s\n" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "(bytes into file)" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr " Start of section headers: % %s\n" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr " Flags: %s\n" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr " Size of this header: % %s\n" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(bytes)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr " Size of program header entries: % %s\n" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr " Number of program headers entries: %" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr " (% in [0].sh_info)" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr " ([0] not available)" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr " Size of section header entries: % %s\n" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr " Number of section headers entries: %" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr " (% in [0].sh_size)" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr " (% in [0].sh_link)" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" +" Section header string table index: XINDEX%s\n" +"\n" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" +" Section header string table index: %\n" +"\n" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, c-format +msgid "cannot get number of sections: %s" +msgstr "cannot get number of sections: %s" + +#: src/readelf.c:1233 +#, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" +"There are %zd section headers, starting at offset %#:\n" +"\n" + +#: src/readelf.c:1242 +#, c-format +msgid "cannot get section header string table index: %s" +msgstr "cannot get section header string table index: %s" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "Section Headers:" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr " [Compression Size Al]" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr " [Compression Size Al]" + +#: src/readelf.c:1335 +#, c-format +msgid "bad compression header for section %zd: %s" +msgstr "bad compression header for section %zd: %s" + +#: src/readelf.c:1346 +#, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "bad gnu compressed size for section %zd: %s" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "Program Headers:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "\t[Requesting program interpreter: %s]\n" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "cannot get program header: %s" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"COMDAT section group [%2zu] ‘%s’ with signature ‘%s’ contains %zu entry:\n" +msgstr[1] "" +"\n" +"COMDAT section group [%2zu] ‘%s’ with signature ‘%s’ contains %zu entries:\n" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Section group [%2zu] ‘%s’ with signature ‘%s’ contains %zu entry:\n" +msgstr[1] "" +"\n" +"Section group [%2zu] ‘%s’ with signature ‘%s’ contains %zu entries:\n" + +#: src/readelf.c:1623 +msgid "" +msgstr "" + +#: src/readelf.c:1637 +msgid "" +msgstr "" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "Couldn't uncompress section" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "cannot get section [%zd] header: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, c-format +msgid "invalid sh_link value in section %zu" +msgstr "invalid sh_link value in section %zu" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" +msgstr[1] "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr " Type Value\n" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "Shared library: [%s]\n" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "Library soname: [%s]\n" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "Library rpath: [%s]\n" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "Library runpath: [%s]\n" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "% (bytes)\n" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" +"\n" +"Invalid symbol table at offset %#0\n" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +"\n" +"Relocation section [%2zu] ‘%s’ for section [%2u] ‘%s’ at offset %#0 " +"contains %d entry:\n" +msgstr[1] "" +"\n" +"Relocation section [%2zu] ‘%s’ for section [%2u] ‘%s’ at offset %#0 " +"contains %d entries:\n" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Relocation section [%2u] ‘%s’ at offset %#0 contains %d entry:\n" +msgstr[1] "" +"\n" +"Relocation section [%2u] ‘%s’ at offset %#0 contains %d entries:\n" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr " Offset Type Value Name\n" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr " Offset Type Value Name\n" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr " Offset Type Value Addend Name\n" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr "" +" Offset Type Value Addend Name\n" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +"\n" +"Symbol table [%2u] ‘%s’ contains %u entry:\n" +msgstr[1] "" +"\n" +"Symbol table [%2u] ‘%s’ contains %u entries:\n" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] " %lu local symbol String table: [%2u] ‘%s’\n" +msgstr[1] " %lu local symbols String table: [%2u] ‘%s’\n" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Num: Value Size Type Bind Vis Ndx Name\n" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Num: Value Size Type Bind Vis Ndx Name\n" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "%5u: %0* %6 %-7s %-6s %-9s %6s %s" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "bad dynamic symbol" + +#: src/readelf.c:2680 +msgid "none" +msgstr "none" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| " + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Version needs section [%2u] ‘%s’ contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" +msgstr[1] "" +"\n" +"Version needs section [%2u] ‘%s’ contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: Version: %hu File: %s Cnt: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: Name: %s Flags: %s Version: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Version definition section [%2u] ‘%s’ contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" +msgstr[1] "" +"\n" +"Version definition section [%2u] ‘%s’ contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr " %#06x: Parent %d: %s\n" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +"\n" +"Version symbols section [%2u] ‘%s’ contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’" +msgstr[1] "" +"\n" +"Version symbols section [%2u] ‘%s’ contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *local* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *global* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Histogram for bucket list length in section [%2u] ‘%s’ (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" +msgstr[1] "" +"\n" +"Histogram for bucket list length in section [%2u] ‘%s’ (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] ‘%s’\n" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr " Length Number % of total Coverage\n" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "cannot get data for section %d: %s" + +#: src/readelf.c:3254 +#, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "invalid data in sysv.hash section %d" + +#: src/readelf.c:3283 +#, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "invalid chain in sysv.hash section %d" + +#: src/readelf.c:3318 +#, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "invalid data in sysv.hash64 section %d" + +#: src/readelf.c:3349 +#, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "invalid chain in sysv.hash64 section %d" + +#: src/readelf.c:3385 +#, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "invalid data in gnu.hash section %d" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Library list section [%2zu] ‘%s’ at offset %#0 contains %d entry:\n" +msgstr[1] "" +"\n" +"Library list section [%2zu] ‘%s’ at offset %#0 contains %d entries:\n" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" +" Library Time Stamp Checksum Version " +"Flags" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" +"\n" +"Object attributes section [%2zu] ‘%s’ of % bytes at offset " +"%#0:\n" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr " Owner Size\n" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " File: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %, %s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, c-format +msgid "sprintf failure" +msgstr "sprintf failure" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "empty block" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "%zu byte block:" + +#: src/readelf.c:4800 +#, c-format +msgid "%*s[%2] %s \n" +msgstr "%*s[%2] %s \n" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "%s %# used with different address sizes" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "%s %# used with different offset sizes" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "%s %# used with different base addresses" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "%s %# used with different attribute %s and %s" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr " [%6tx] ... % bytes ...\n" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +" [ Code]\n" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" +"\n" +"Abbreviation section at offset %:\n" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr " *** error while reading abbreviation: %s\n" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr " [%5u] offset: %, children: %s, tag: %s\n" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" + +#: src/readelf.c:5182 +#, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "cannot get .debug_addr section data: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, c-format +msgid " Length: %8\n" +msgstr " Length: %8\n" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, c-format +msgid " DWARF version: %8\n" +msgstr " DWARF version: %8\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, c-format +msgid " Address size: %8\n" +msgstr " Address size: %8\n" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, c-format +msgid " Segment size: %8\n" +msgstr " Segment size: %8\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, c-format +msgid "Unknown version" +msgstr "Unknown version" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, c-format +msgid "unsupported address size" +msgstr "unsupported address size" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "unsupported segment size" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "cannot get .debug_aranges content: %s" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %# contains %zu entry:\n" +msgstr[1] "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %# contains %zu entries:\n" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" +"\n" +"Table at offset %zu:\n" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "invalid data in section [%zu] ‘%s’" + +#: src/readelf.c:5511 +#, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr "" +"\n" +" Length: %6\n" + +#: src/readelf.c:5523 +#, c-format +msgid " DWARF version: %6\n" +msgstr " DWARF version: %6\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "unsupported aranges version" + +#: src/readelf.c:5538 +#, c-format +msgid " CU offset: %6\n" +msgstr " CU offset: %6\n" + +#: src/readelf.c:5544 +#, c-format +msgid " Address size: %6\n" +msgstr " Address size: %6\n" + +#: src/readelf.c:5555 +#, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr "" +" Segment size: %6\n" +"\n" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr " %zu padding bytes\n" + +#: src/readelf.c:5654 +#, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "cannot get .debug_rnglists content: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr "" +"Table at Offset 0x%:\n" +"\n" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, c-format +msgid " Offset entries: %8\n" +msgstr " Offset entries: %8\n" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr " Unknown CU base: " + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr " CU [%6] base: " + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr " Not associated with a CU.\n" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "too many offset entries for unit length" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " Offsets starting at 0x%:\n" + +#: src/readelf.c:5823 +#, c-format +msgid "invalid range list data" +msgstr "invalid range list data" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" +" %zu padding bytes\n" +"\n" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "cannot get .debug_ranges content: %s" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" +"\n" +" Unknown CU base: " + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" +"\n" +" CU [%6] base: " + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:6097 src/readelf.c:9719 +msgid "base address" +msgstr "base address" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, c-format +msgid " [%6tx] empty list\n" +msgstr " [%6tx] empty list\n" + +#: src/readelf.c:6367 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:6624 +#, c-format +msgid "cannot get ELF: %s" +msgstr "cannot get ELF: %s" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Call frame information section [%2zu] ‘%s’ at offset %#:\n" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" +"\n" +" [%6tx] Zero terminator\n" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, c-format +msgid "invalid augmentation length" +msgstr "invalid augmentation length" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "FDE address encoding: " + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "LSDA pointer encoding: " + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr " (offset: %#)" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr " (end offset: %#)" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr " %-26sLSDA pointer: %#\n" + +#: src/readelf.c:7053 +#, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "DIE [%] cannot get attribute code: %s" + +#: src/readelf.c:7063 +#, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "DIE [%] cannot get attribute form: %s" + +#: src/readelf.c:7085 +#, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "DIE [%] cannot get attribute ‘%s’ (%s) value: %s" + +#: src/readelf.c:7415 +#, c-format +msgid "invalid file (%): %s" +msgstr "invalid file (%): %s" + +#: src/readelf.c:7419 +#, c-format +msgid "no srcfiles for CU [%]" +msgstr "no srcfiles for CU [%]" + +#: src/readelf.c:7423 +#, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "couldn't get DWARF CU: %s" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +" [Offset]\n" + +#: src/readelf.c:7788 +#, c-format +msgid "cannot get next unit: %s" +msgstr "cannot get next unit: %s" + +#: src/readelf.c:7808 +#, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr " Unit type: %s (%)" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "unknown version (%d) or unit type (%d)" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "cannot get DIE offset: %s" + +#: src/readelf.c:7895 +#, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "cannot get tag of DIE at offset [%] in section '%s': %s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "cannot get next DIE: %s\n" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "cannot get next DIE: %s" + +#: src/readelf.c:7985 +#, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" + +#: src/readelf.c:8037 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +"\n" + +#: src/readelf.c:8369 +#, c-format +msgid "unknown form: %s" +msgstr "unknown form: %s" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "cannot get line data section data: %s" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" + +#: src/readelf.c:8524 +#, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "cannot handle .debug_line version: %u\n" + +#: src/readelf.c:8532 +#, c-format +msgid "cannot handle address size: %u\n" +msgstr "cannot handle address size: %u\n" + +#: src/readelf.c:8540 +#, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "cannot handle segment selector size: %u\n" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "invalid data at offset %tu in section [%zu] ‘%s’" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] " [%*] %hhu argument\n" +msgstr[1] " [%*] %hhu arguments\n" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" +"\n" +"Directory table:" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, c-format +msgid " [" +msgstr " [" + +#: src/readelf.c:8653 +msgid "" +"\n" +"File name table:" +msgstr "" +"\n" +"File name table:" + +#: src/readelf.c:8714 +msgid " Entry Dir Time Size Name" +msgstr " Entry Dir Time Size Name" + +#: src/readelf.c:8753 +msgid "" +"\n" +"No line number statements." +msgstr "" +"\n" +"No line number statements." + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" +"\n" +"Line number statements:" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "invalid maximum operations per instruction is zero" + +#: src/readelf.c:8811 +#, c-format +msgid " special opcode %u: address+%u = " +msgstr " special opcode %u: address+%u = " + +#: src/readelf.c:8815 +#, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr ", op_index = %u, line%+d = %zu\n" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr ", line%+d = %zu\n" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr " extended opcode %u: " + +#: src/readelf.c:8841 +msgid " end of sequence" +msgstr " end of sequence" + +#: src/readelf.c:8859 +#, c-format +msgid " set address to " +msgstr " set address to " + +#: src/readelf.c:8887 +#, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr " define new file: dir=%u, mtime=%, length=%, name=%s\n" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr " set discriminator to %u\n" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +msgid " unknown opcode" +msgstr " unknown opcode" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr " copy" + +#: src/readelf.c:8929 +#, c-format +msgid " advance address by %u to " +msgstr " advance address by %u to " + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr ", op_index to %u" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr " advance line by constant %d to %\n" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr " set file to %\n" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr " set column to %\n" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr " set ‘%s’ to %\n" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr " set basic block flag" + +#: src/readelf.c:8990 +#, c-format +msgid " advance address by constant %u to " +msgstr " advance address by constant %u to " + +#: src/readelf.c:9010 +#, c-format +msgid " advance address by fixed value %u to \n" +msgstr " advance address by fixed value %u to \n" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr " set prologue end flag" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr " set epilogue begin flag" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr " set isa to %u\n" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] " unknown opcode with % parameter:" +msgstr[1] " unknown opcode with % parameters:" + +#: src/readelf.c:9084 +#, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "cannot get .debug_loclists content: %s" + +#: src/readelf.c:9250 +#, c-format +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9290 +#, c-format +msgid "invalid loclists data" +msgstr "invalid loclists data" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "cannot get .debug_loc content: %s" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "cannot get macro information section data: %s" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "%*s*** non-terminated string at end of section" + +#: src/readelf.c:9914 +#, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "%*s*** missing DW_MACINFO_start_file argument at end of section" + +#: src/readelf.c:10015 +#, c-format +msgid " Offset: 0x%\n" +msgstr " Offset: 0x%\n" + +#: src/readelf.c:10027 +#, c-format +msgid " Version: %\n" +msgstr " Version: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr " unknown version, cannot parse section\n" + +#: src/readelf.c:10040 +#, c-format +msgid " Flag: 0x%" +msgstr " Flag: 0x%" + +#: src/readelf.c:10069 +#, c-format +msgid " Offset length: %\n" +msgstr " Offset length: %\n" + +#: src/readelf.c:10077 +#, c-format +msgid " .debug_line offset: 0x%\n" +msgstr " .debug_line offset: 0x%\n" + +#: src/readelf.c:10102 +#, c-format +msgid " extension opcode table, % items:\n" +msgstr " extension opcode table, % items:\n" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr " [%]" + +#: src/readelf.c:10121 +#, c-format +msgid " % arguments:" +msgstr " % arguments:" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr " no arguments." + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" +"\n" +"DWARF section [%2zu] ‘%s’ at offset %#:\n" +" %*s String\n" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "Offset" + +#: src/readelf.c:10396 +#, c-format +msgid " *** error, missing string terminator\n" +msgstr " *** error, missing string terminator\n" + +#: src/readelf.c:10425 +#, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "cannot get .debug_str_offsets section data: %s" + +#: src/readelf.c:10524 +#, c-format +msgid " Length: %8\n" +msgstr " Length: %8\n" + +#: src/readelf.c:10526 +#, c-format +msgid " Offset size: %8\n" +msgstr " Offset size: %8\n" + +#: src/readelf.c:10540 +#, c-format +msgid " DWARF version: %8\n" +msgstr " DWARF version: %8\n" + +#: src/readelf.c:10549 +#, c-format +msgid " Padding: %8\n" +msgstr " Padding: %8\n" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr " LPStart encoding: %#x " + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr " TType encoding: %#x " + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr " Call site encoding: %#x " + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" +"\n" +" Call site table:" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "invalid TType encoding" + +#: src/readelf.c:10882 +#, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" +"\n" +"GDB section [%2zu] ‘%s’ at offset %# contains % bytes :\n" + +#: src/readelf.c:10911 +#, c-format +msgid " Version: %\n" +msgstr " Version: %\n" + +#: src/readelf.c:10929 +#, c-format +msgid " CU offset: %#\n" +msgstr " CU offset: %#\n" + +#: src/readelf.c:10936 +#, c-format +msgid " TU offset: %#\n" +msgstr " TU offset: %#\n" + +#: src/readelf.c:10943 +#, c-format +msgid " address offset: %#\n" +msgstr " address offset: %#\n" + +#: src/readelf.c:10950 +#, c-format +msgid " symbol offset: %#\n" +msgstr " symbol offset: %#\n" + +#: src/readelf.c:10957 +#, c-format +msgid " constant offset: %#\n" +msgstr " constant offset: %#\n" + +#: src/readelf.c:10971 +#, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" CU list at offset %# contains %zu entries:\n" + +#: src/readelf.c:10996 +#, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" TU list at offset %# contains %zu entries:\n" + +#: src/readelf.c:11025 +#, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Address list at offset %# contains %zu entries:\n" + +#: src/readelf.c:11057 +#, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "cannot get debug context descriptor: %s" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "cannot convert core note data: %s" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" +"\n" +"%*s... ..." + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr " Owner Data size Type\n" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr " %-13.*s %9 %s\n" + +#: src/readelf.c:12518 +#, c-format +msgid "cannot get content of note: %s" +msgstr "cannot get content of note: %s" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Note section [%2zu] ‘%s’ of % bytes at offset %#0:\n" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Note segment of % bytes at offset %#0:\n" + +#: src/readelf.c:12622 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" +"\n" +"Section [%zu] ‘%s’ has no data to dump.\n" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "cannot get data for section [%zu] '%s': %s" + +#: src/readelf.c:12654 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" + +#: src/readelf.c:12659 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" + +#: src/readelf.c:12673 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" +"\n" +"Section [%zu] ‘%s’ has no strings to dump.\n" + +#: src/readelf.c:12705 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" +"\n" +"String section [%zu] ‘%s’ contains % bytes at offset %#0:\n" + +#: src/readelf.c:12710 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" +"\n" +"String section [%zu] ‘%s’ contains % bytes (%zd uncompressed) at " +"offset %#0:\n" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" +"\n" +"section [%lu] does not exist" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" +"\n" +"section ‘%s’ does not exist" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "cannot get symbol index of archive '%s': %s" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" +"\n" +"Archive ‘%s’ has no symbol index\n" + +#: src/readelf.c:12853 +#, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" +"\n" +"Index of archive ‘%s’ has %zu entries:\n" + +#: src/readelf.c:12871 +#, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "cannot extract member at offset %zu in '%s': %s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "Archive member ‘%s’ contains:\n" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" +"Use the output format FORMAT. FORMAT can be ‘bsd’ or ‘sysv’. The default " +"is ‘bsd’" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "Same as ‘--format=sysv’" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "Same as ‘--format=bsd’" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "Same as ‘--radix=10’" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "Same as ‘--radix=8’" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "Same as ‘--radix=16’" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "Similar to ‘--format=sysv’ output but in one line" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "Print size and permission flags for loadable segments" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "Display the total sizes (bsd only)" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "List section sizes of FILEs (a.out by default)." + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "Invalid format: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "Invalid radix: %s" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "%s: file format not recognized" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "text" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "data" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "bss" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "dec" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "hex" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "filename" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr " (ex %s)" + +#: src/size.c:420 +msgctxt "sysv" +msgid "section" +msgstr "section" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "size" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "addr" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "Total" + +#: src/size.c:482 +#, c-format +msgid "cannot get section header" +msgstr "cannot get section header" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "(TOTALS)\n" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "-p PID should be a positive process id." + +#: src/stack.c:493 +#, c-format +msgid "Cannot open core file '%s'" +msgstr "Cannot open core file ‘%s’" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "-n MAXFRAMES should be 0 or higher." + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "-e EXEC needs a core given by --core." + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "-1 needs a thread id given by -p." + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "One of -p PID or --core COREFILE should be given." + +#: src/stack.c:645 +msgid "Show stack of process PID" +msgstr "Show stack of process PID" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "Show stack found in COREFILE" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "(optional) EXECUTABLE that produced COREFILE" + +#: src/stack.c:652 +msgid "Output selection options:" +msgstr "Output selection options:" + +#: src/stack.c:654 +msgid "Additionally show frame activation" +msgstr "Additionally show frame activation" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "Additionally try to lookup DWARF debuginfo name for frame address" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "Additionally show module file information" + +#: src/stack.c:663 +msgid "Additionally show source file information" +msgstr "Additionally show source file information" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "Do not resolve address to function symbol name" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "Show raw function symbol names, do not try to demangle names" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "Show module build-id, load address and pc offset" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "Show the backtrace of only one thread" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "Show module memory map with build-id, elf and debug files detected" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "Couldn't show any frames." + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "Output Selection:" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "Scan entire file, not only loaded sections" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" +"Only NUL-terminated sequences of MIN-LEN characters or more are printed" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "Print name of the file before each string." + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "Print location of the string in base 8, 10, or 16 respectively." + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "Alias for --radix=o" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "Print the strings of printable characters in files." + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "invalid value ‘%s’ for %s parameter" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "invalid minimum length of matched string size" + +#: src/strings.c:585 +#, c-format +msgid "lseek failed" +msgstr "lseek failed" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "re-mmap failed" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "mprotect failed" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "Skipping section %zd ‘%s’ data outside file" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "Place stripped output into FILE" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "Extract the removed sections into FILE" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "Embed name FILE instead of -f argument" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "Remove all debugging symbols" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "Remove section headers (not recommended)" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "Copy modified/access timestamps to the output" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "Remove .comment section" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "Discard symbols from object files." + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "--reloc-debug-sections used without -f" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "Only one input file allowed together with ‘-o’ and ‘-f’" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "-f option specified twice" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "-F option specified twice" + +#: src/strip.c:362 +#, c-format +msgid "cannot both keep and remove .comment section" +msgstr "cannot both keep and remove .comment section" + +#: src/strip.c:481 +#, c-format +msgid "bad relocation" +msgstr "bad relocation" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "cannot stat input file ‘%s’" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "while opening ‘%s’" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "%s: cannot use -o or -f when stripping archive" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: no support for stripping archive" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "cannot open EBL backend" + +#: src/strip.c:1092 +#, c-format +msgid "cannot get number of phdrs" +msgstr "cannot get number of phdrs" + +#: src/strip.c:1106 src/strip.c:1149 +#, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "cannot create new ehdr for file '%s': %s" + +#: src/strip.c:1116 src/strip.c:1159 +#, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "cannot create new phdr for file '%s': %s" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "illformed file ‘%s’" + +#: src/strip.c:1250 +#, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "Cannot remove allocated section ‘%s’" + +#: src/strip.c:1259 +#, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "Cannot both keep and remove section ‘%s’" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "while generating output file: %s" + +#: src/strip.c:1688 +#, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "%s: error while updating ELF header: %s" + +#: src/strip.c:1697 +#, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "%s: error while getting shdrstrndx: %s" + +#: src/strip.c:1705 src/strip.c:2550 +#, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "%s: error updating shdrstrndx: %s" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "while preparing output for ‘%s’" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "while create section header section: %s" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "cannot allocate section data: %s" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "while create section header string table: %s" + +#: src/strip.c:1866 +#, c-format +msgid "no memory to create section header string table" +msgstr "no memory to create section header string table" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "Cannot remove symbol [%zd] from allocated symbol table [%zd]" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "while writing '%s': %s" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "while creating ‘%s’" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "while computing checksum for debug information" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "%s: error while creating ELF header: %s" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "%s: error while reading the file: %s" + +#: src/strip.c:2599 src/strip.c:2619 +#, c-format +msgid "while writing '%s'" +msgstr "while writing ‘%s’" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "error while finishing '%s': %s" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "cannot set access and modification date of ‘%s’" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "Match MODULE against file names, not module names" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "Silently skip unfindable files" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "Place output into FILE" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "Create multiple output files under DIRECTORY" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "Use module rather than file names" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "Create output for modules that have no separate debug information" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "Apply relocations to section contents in ET_REL files" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "Only list module and file names, build IDs" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "Force combining files even if some ELF headers don't seem to match" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "-d option specified twice" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "only one of -o or -d allowed" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "-n cannot be used with explicit files or -o or -d" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "output directory ‘%s’" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "exactly two file arguments are required" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "-m, -a, -R, and -i options not allowed with explicit files" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "-o or -d is required when using implicit files" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "cannot create ELF header: %s" + +#: src/unstrip.c:240 +#, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "cannot get shdrstrndx:%s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "cannot get ELF header: %s" + +#: src/unstrip.c:254 +#, c-format +msgid "cannot get new zero section: %s" +msgstr "cannot get new zero section: %s" + +#: src/unstrip.c:257 +#, c-format +msgid "cannot update new zero section: %s" +msgstr "cannot update new zero section: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "cannot copy ELF header: %s" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, c-format +msgid "cannot get number of program headers: %s" +msgstr "cannot get number of program headers: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "cannot create program headers: %s" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "cannot copy program header: %s" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "cannot copy section header: %s" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "cannot get section data: %s" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "cannot copy section data: %s" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "cannot create directory ‘%s’" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "cannot get symbol table entry: %s" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "cannot update symbol table: %s" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "cannot update section header: %s" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "cannot update relocation: %s" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "cannot get symbol version: %s" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "unexpected section type in [%zu] with sh_link to symtab" + +#: src/unstrip.c:848 +#, c-format +msgid "cannot get symbol section data: %s" +msgstr "cannot get symbol section data: %s" + +#: src/unstrip.c:850 +#, c-format +msgid "cannot get string section data: %s" +msgstr "cannot get string section data: %s" + +#: src/unstrip.c:867 +#, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "invalid string offset in symbol [%zu]" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "cannot read section [%zu] name: %s" + +#: src/unstrip.c:1040 +#, c-format +msgid "bad sh_link for group section: %s" +msgstr "bad sh_link for group section: %s" + +#: src/unstrip.c:1046 +#, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "couldn't get shdr for group section: %s" + +#: src/unstrip.c:1051 +#, c-format +msgid "bad data for group symbol section: %s" +msgstr "bad data for group symbol section: %s" + +#: src/unstrip.c:1057 +#, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "couldn't get symbol for group section: %s" + +#: src/unstrip.c:1062 +#, c-format +msgid "bad symbol name for group section: %s" +msgstr "bad symbol name for group section: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "cannot find matching section for [%zu] ‘%s’" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "cannot read ‘.gnu.prelink_undo’ section: %s" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "overflow with shnum = %zu in ‘%s’ section" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "invalid contents in ‘%s’ section" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "cannot add section name to string table: %s" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "cannot update section header string table data: %s" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "cannot get section header string table section index: %s" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "cannot get section count: %s" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "more sections in stripped file than debug file -- arguments reversed?" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "no sections in stripped file" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "cannot read section header string table: %s" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "cannot add new section: %s" + +#: src/unstrip.c:1758 +#, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "symbol [%zu] has invalid section index" + +#: src/unstrip.c:1790 +#, c-format +msgid "group has invalid section index [%zd]" +msgstr "group has invalid section index [%zd]" + +#: src/unstrip.c:2065 +#, c-format +msgid "cannot read section data: %s" +msgstr "cannot read section data: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "cannot update ELF header: %s" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "cannot update program header: %s" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "cannot write output file: %s" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "DWARF data not adjusted for prelinking bias; consider prelink -u" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"DWARF data in ‘%s’ not adjusted for prelinking bias; consider prelink -u" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "cannot create ELF descriptor: %s" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "WARNING: " + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr ", use --force" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "ELF header identification (e_ident) different" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "ELF header type (e_type) different" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "ELF header machine type (e_machine) different" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "stripped program header (e_phnum) smaller than unstripped" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "cannot find stripped file for module '%s': %s" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "cannot open stripped file ‘%s’ for module '%s': %s" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "cannot find debug file for module '%s': %s" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "cannot open debug file ‘%s’ for module '%s': %s" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "module ‘%s’ file ‘%s’ is not stripped" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "cannot cache section addresses for module '%s': %s" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "no matching modules found" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "matched more than one module" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "Request debuginfo-related content from debuginfods listed in $" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "Run executable" + +#: tests/dwflmodtest.c:209 +msgid "Additionally show function names" +msgstr "Additionally show function names" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "Show instances of inlined functions" diff --git a/po/es.gmo b/po/es.gmo new file mode 100644 index 0000000000000000000000000000000000000000..1a85cc9584a17c548afde63d6232b9fc5aa14b70 GIT binary patch literal 107373 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, 2009. +# Gladys Guerrero Lozano , 2009. +# Héctor Daniel Cabrera , 2009, 2010. +# Claudio Rodrigo Pereyra Diaz , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: elfutils.master.es\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2011-01-10 15:17-0300\n" +"Last-Translator: Claudio Rodrigo Pereyra Diaz \n" +"Language-Team: Fedora Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Spanish\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Country: ARGENTINA\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" + +#: lib/color.c:194 src/objdump.c:728 +#, fuzzy, c-format +msgid "cannot allocate memory" +msgstr "No se puede asignar sección PLT: %s" + +#: lib/printversion.c:40 +#, fuzzy, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"Copyright (C) %s Red Hat, Inc.\n" +"El siguiente es un software libre; consulte el código para conocer las " +"condiciones de copiado. NO tiene\n" +"garantía, ni siquiera para SU COMERCIALIZACIÓN o PARA SER USADO CON UN FIN " +"DETERMINADO.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "memoria agotada" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "ningún error" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "memoria agotada" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "no se puede crear el archivo de salida" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "Parámetro inválido" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "no sepuede cambiar modo de archivo de salida" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "no se puede renombrar el archivo de salida" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "Duplicar símbolo" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "tipo de sección inválido para operación" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "error durante salida de datos" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "No hay soporte de segundo plano" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "error desconocido" + +#: libcpu/i386_lex.l:122 +#, fuzzy, c-format +#| msgid "invalid page size value '%s': ignored" +msgid "invalid character '%c' at line %d; ignored" +msgstr "Valor de tamaño de página'%s': ignorado" + +#: libcpu/i386_lex.l:123 +#, fuzzy, c-format +#| msgid "invalid page size value '%s': ignored" +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "Valor de tamaño de página'%s': ignorado" + +#: libcpu/i386_parse.y:554 +#, fuzzy, c-format +#| msgid "while reading linker script '%s': %s at line %d" +msgid "while reading i386 CPU description: %s at line %d" +msgstr "al leer script de enlace '%s': %s en línea %d" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "Acceso inválido" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "no es un archivo regular" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "Error de E/S" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "Archivo ELF inválido" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "Sin información de DWARF" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "No hay archivo ELF" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "no se puede obtener el encabezamiento ELF" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "sin implementar" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "comando inválido" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "versión inválida" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "Archivo inválido" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "No se hallaron entradas" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "DWARF inválido" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "no hay datos de cadena" + +#: libdw/dwarf_error.c:75 +#, fuzzy +msgid ".debug_str section missing" +msgstr ".debug_ranges section faltante" + +#: libdw/dwarf_error.c:76 +#, fuzzy +msgid ".debug_line_str section missing" +msgstr ".debug_line section faltante" + +#: libdw/dwarf_error.c:77 +#, fuzzy +msgid ".debug_str_offsets section missing" +msgstr ".debug_ranges section faltante" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "no hay valor de dirección" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "no hay valor constante" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "no hay valor de referencia" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "valor de la referencia inválido" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr ".debug_line section faltante" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr ".debug_line section inválida" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "información de depuración muy grande" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "versión DWARF inválida" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "Índice de directorio inválido" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "dirección fuera de rango" + +#: libdw/dwarf_error.c:88 +#, fuzzy +msgid ".debug_loc section missing" +msgstr ".debug_line section faltante" + +#: libdw/dwarf_error.c:89 +#, fuzzy +msgid ".debug_loclists section missing" +msgstr ".debug_line section faltante" + +#: libdw/dwarf_error.c:90 +#, fuzzy +msgid "not a location list value" +msgstr "valor de lista sin ubicación" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "sin datos de bloque " + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "Índice de línea inválido" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "Índice de dirección de rango inválido" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "dirección de rango no coincidente" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "sin valor de bandera" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "desplazamiento inválido" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr ".debug_ranges section faltante" + +#: libdw/dwarf_error.c:98 +#, fuzzy +msgid ".debug_rnglists section missing" +msgstr ".debug_ranges section faltante" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "sección CFI inválida" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "" + +#: libdw/dwarf_error.c:101 +#, fuzzy +msgid "invalid opcode" +msgstr "operando inválido" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "" + +#: libdw/dwarf_error.c:103 +#, fuzzy +msgid "unknown language code" +msgstr "código operativo desconocido " + +#: libdw/dwarf_error.c:104 +#, fuzzy +msgid ".debug_addr section missing" +msgstr ".debug_ranges section faltante" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "Opciones de selección de entrada:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "Hallar direcciones en FICHERO" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "Buscar direcciones desde firmas encontradas en COREFILE" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "Busca direcciones en archivos mapeados sobre procesos PID" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" +"Busca direcciones en archivos asignados como leídos desde FILE en formato " +"Linux /proc/PID/maps" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "Busca direcciones en el kernel que está ejecutándose" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "Kernel con todos los módulos" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "Ruta de búsqueda para archivos debugingfo independientes" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "Sólo uno de -e, -p, -k, -K, ó --core está permitido" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "No se pueden cargar símbolos de kernel" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "no se pueden hallar módulos de kernel" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "imposible encontrar kernel o módulos" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "No se puede leer archivo core ELF: %s" + +#: libdwfl/argp-std.c:317 +#, fuzzy +msgid "Not enough memory" +msgstr "memoria agotada" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "No hay módulos reconocidos en el archivo core" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "Ve errno" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "Ver elf_errno" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "Ver dwarf_errno" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "Ver ebl_errno (no se encuentra XXX)" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "falló la descompresión gzip" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "falló la descompresión bzip2" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "falló la descompresión LZMA" + +#: libdwfl/libdwflP.h:61 +#, fuzzy +msgid "zstd decompression failed" +msgstr "falló la descompresión gzip" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "no se ha encontrado una biblioteca de soporte para la máquina" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "No se encuentran rellamadas para el archivo ET_REL" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "Tipo de reubicación no soportada" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "r_offset se encuentra inutilizable" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "desplazamiento fuera de rango" + +#: libdwfl/libdwflP.h:67 +msgid "relocation refers to undefined symbol" +msgstr "la reubicación hace referencia a un símbolo no definido" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "La rellamada devolvió un fallo" + +#: libdwfl/libdwflP.h:69 +msgid "No DWARF information found" +msgstr "No se ha encontrado una información DWARF" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "No se ha encontrado una tabla simbólica" + +#: libdwfl/libdwflP.h:71 +msgid "No ELF program headers" +msgstr "No existen encabezados de programa ELF" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "el rango de dirección se superpone con un módulo existente" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "imagen truncada" + +#: libdwfl/libdwflP.h:76 +msgid "ELF file opened" +msgstr "Archivo ELF abierto" + +#: libdwfl/libdwflP.h:77 +msgid "not a valid ELF file" +msgstr "no es un archivo ELF válido" + +#: libdwfl/libdwflP.h:78 +msgid "cannot handle DWARF type description" +msgstr "no es posible manipular tipo de descripción DWARF" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "El archivo ELF no coincide con el ID construido" + +#: libdwfl/libdwflP.h:80 +#, fuzzy +msgid "corrupt .gnu.prelink_undo section data" +msgstr "no se puede leer sección '.gnu.prelink_undo': %s" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "" + +#: libdwfl/libdwflP.h:83 +#, fuzzy +msgid "Invalid register" +msgstr "Parámetro inválido" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "" + +#: libdwfl/libdwflP.h:87 +#, fuzzy +msgid "Invalid DWARF" +msgstr "DWARF inválido" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "" + +#: libdwfl/libdwflP.h:93 +#, fuzzy +msgid "Invalid argument" +msgstr "Parámetro inválido" + +#: libdwfl/libdwflP.h:94 +#, fuzzy +msgid "Not an ET_CORE ELF file" +msgstr "no es un archivo ELF válido" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "No hay segundo plano (Backend)" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr ": %#" + +#: libebl/eblobjnote.c:58 +#, fuzzy, c-format +msgid "unknown SDT version %u\n" +msgstr "versión desconocida" + +#: libebl/eblobjnote.c:76 +#, fuzzy, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "descriptor de archivo inválido" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr "" + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr "" + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr "" + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr "" + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr "" + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr "" + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " Build ID: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr " Versión del Enlazador: %.*s\n" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " OS: %s, ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "Autónomo" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr ": %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "versión desconocida" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "tipo desconocido" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "manejo`ELF' inválido" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "tamaño inválido del operando fuente" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "tamaño inválido del operando destino" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "codificación inválida" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "descriptor de archivo inválido" + +#: libelf/elf_error.c:99 +#, fuzzy +msgid "invalid ELF file data" +msgstr "Archivo ELF inválido" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "operación inválida" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "no se estableció la versión de ELF" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "campo fmag no válido en el encabezamiento del archivo" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "fichero de archivo inválido" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "el descriptor no es de un archivo" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "no hay índice disponible" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "no se pueden leer los datos del archivo" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "no se puede escribir los datos al archivo" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "clase de binario inválida" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "índice de sección inválido" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "operando inválido" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "sección inválida" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "no se ha creado primero el encabezamiento ejecutable" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "descriptor de archivo inhabilitada" + +#: libelf/elf_error.c:171 +msgid "archive/member file descriptor mismatch" +msgstr "archivo/miembro no coincide el descriptor de archivos" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "no se pudo manipular una sección nula" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "no coinciden los datos/scn" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "encabezamiento de sección inválida" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "datos inválidos" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "codificación de caracteres desconocida" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "el tamaño de la sección `sh_size' es demasiado pequeño para los datos " + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "alineación de la sección inválida" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "tamaño de la entrada de la sección inválida" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "update() para escribir sobre archivo de sólo lectura" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "no hay tal archivo" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "solo los archivos reubicables pueden contener grupos de sección" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" +"los encabezamientos de los programas solo son permitidos en archivos " +"ejecutables, archivos principales, u objetos compartidos" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "el archivo no tiene encabezamiento de programa" + +#: libelf/elf_error.c:241 +#, fuzzy +msgid "invalid section type" +msgstr "sección inválida" + +#: libelf/elf_error.c:246 +#, fuzzy +msgid "invalid section flags" +msgstr "sección inválida" + +#: libelf/elf_error.c:251 +#, fuzzy +msgid "section does not contain compressed data" +msgstr "sección [%2zu] '%s' no debe ser ejecutable\n" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "" + +#: libelf/elf_error.c:261 +#, fuzzy +msgid "unknown compression type" +msgstr "tipo desconocido" + +#: libelf/elf_error.c:266 +#, fuzzy +msgid "cannot compress data" +msgstr "no pueden copiar datos de sección: %s" + +#: libelf/elf_error.c:271 +#, fuzzy +msgid "cannot decompress data" +msgstr "no pueden copiar datos de sección: %s" + +#: src/addr2line.c:57 +#, fuzzy +msgid "Input format options:" +msgstr "Opciones de selección de entrada:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "Manejar direcciones como compensaciones relativas a sección de NOMBRE." + +#: src/addr2line.c:61 +#, fuzzy +msgid "Output format options:" +msgstr "Formato de salida:" + +#: src/addr2line.c:62 +#, fuzzy +msgid "Print address before each entry" +msgstr "Imprimir nombre de archivo antes de cada cadena." + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "Mostrar sólo nombres de base de ficheros fuente" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "" +"Mostrar nombres de fichero absolutos mediante directorio de compilación" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "También mostrar nombres de función" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "También mostrar símbolo o nombres de sección" + +#: src/addr2line.c:68 +#, fuzzy +msgid "Also show symbol and the section names" +msgstr "También mostrar símbolo o nombres de sección" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "También mostrar marcas de líneas de tabla" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "Misceláneos:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" +"Localizar archivos fuente e información de línea para DIRECCIONES (en a.out " +"por defecto)." + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "[DIREC...]" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "Sintaxis de sección requiere exactamente un módulo" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "Compensación %# se encuentra fuera de sección '%s'" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "no se puede encontrar símbolo '%s'" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "compensación %# se encuentra fuera de contenido de '%s'" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "Comandos:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "Borrar archivos de un archivo" + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "Desplazar ficheros en archivo." + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "Imprimir ficheros en archivo." + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "Adición rápida de ficheros para archivar" + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "Remplazar fichero existente o insertar uno nuevo en el archivo." + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "Mostrar contenido de archivo" + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "extraer ficheros de un archivo" + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "Modificadores de comandos:" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "Preservar fechas originales." + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "Usar instancia [COUNT] de nombre." + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "No remplazar los archivos existentes por los archivos extractados." + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "Permitir truncamiento del nombre de archivo de ser necesario." + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "Proporcionar salida detallada" + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "Forzar regeneración de tabla de símbolos." + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "Insertar archivo después de [MIEMBRO]." + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "Introducir fichero antes de [MIEMBRO]." + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "Igual que -b." + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "Suprimir mensaje cuando se tenga que crear la biblioteca." + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "Usar la ruta total para fichero coincidente." + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "Actualizar sólo ficheros antiguos en archivo." + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "Crear, modificar, y extraer de archivos." + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[MIEMBRO] [CONTAR] ARCHIVO [FICHERO...]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "'a', 'b', é 'i' sólo se permiten con las opciones 'm' y 'r'." + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "Parámetro MIEMBRO requerido para modificadores 'a', 'b', e 'i'" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "'N' sólo es significativa con las opciones `x' y `d'." + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "Parámetro CONTAR requerido" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "Parámetro CONTAR inválido %s" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "'%c' es sólo significativo con la opción 'x'" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "nombre de archivo requerido" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "Más de una operación especificada" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "Imposible abrir el archivo '%s'" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "Imposible abrir el archivo '%s': %s" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: no es un fichero de archivo" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "no sepuede stat el archivo '%s'" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "no hay entrada %s en archivo\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "Falló al crear la tabla de dispersión" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "no sepuede insertar en tabla de dispersión" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "no se puede stat '%s'" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "no se puede leer el contenido de %s: %s" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr " Imposible abrir %.*s" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "Falló al escribir %s" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "No se puede cambiar el modo de %s" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "No puede cambiar tiempo de modificación de %s" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "no sepuede renombrar fichero temporal para %.*s" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "no sepuede crear fichero nuevo" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "no se encuentra miembro de posición %s " + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: ¡no hay entrada %s en archive!\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "no sepuede abrir %s" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "no sepuede efectuar stat %s" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr " %s no es un fichero ordinario " + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "no sepuede obtener descriptor ELF para %s: %s\n" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "no sepuede leer %s: %s" + +#: src/ar.c:1483 +#, fuzzy, c-format +msgid "cannot represent ar_date" +msgstr "no pueden copiar datos de sección: %s" + +#: src/ar.c:1489 +#, fuzzy, c-format +msgid "cannot represent ar_uid" +msgstr "no pueden copiar datos de sección: %s" + +#: src/ar.c:1495 +#, fuzzy, c-format +msgid "cannot represent ar_gid" +msgstr "no pueden copiar datos de sección: %s" + +#: src/ar.c:1501 +#, fuzzy, c-format +msgid "cannot represent ar_mode" +msgstr "no se puede obtener encabezamiento de sección\n" + +#: src/ar.c:1507 +#, fuzzy, c-format +msgid "cannot represent ar_size" +msgstr "no sepuede abrir %s" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr " El archivo '%s' es demasiado grande" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "no se puede leer el encabezamiento ELF de %s(%s): %s" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "" + +#: src/elfclassify.c:245 +#, fuzzy +#| msgid "cannot get ELF header" +msgid "ELF header" +msgstr "no se puede obtener el encabezamiento ELF" + +#: src/elfclassify.c:256 +#, fuzzy +#| msgid "Program Headers:" +msgid "program headers" +msgstr "encabezamientos de programa:" + +#: src/elfclassify.c:265 +#, fuzzy +#| msgid "Program Headers:" +msgid "program header" +msgstr "encabezamientos de programa:" + +#: src/elfclassify.c:285 +#, fuzzy +#| msgid "Section Headers:" +msgid "section headers" +msgstr "encabezamientos de sección:" + +#: src/elfclassify.c:296 +#, fuzzy +#| msgid "cannot get section header string table index" +msgid "section header string table index" +msgstr "no se puede obtener índice de cadena de encabezamiento de sección" + +#: src/elfclassify.c:310 +#, fuzzy +msgid "could not obtain section header" +msgstr "no se puede obtener encabezamiento de sección\n" + +#: src/elfclassify.c:316 +#, fuzzy +msgid "could not obtain section name" +msgstr "no se puede obtener encabezamiento de sección\n" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "" + +#: src/elfclassify.c:877 +#, fuzzy +#| msgid "Input selection options:" +msgid "Classification options" +msgstr "Opciones de selección de entrada:" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "" + +#: src/elfclassify.c:907 +#, fuzzy +#| msgid "cannot find kernel modules" +msgid "File is a linux kernel module" +msgstr "no se pueden hallar módulos de kernel" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "" + +#: src/elfclassify.c:956 +#, fuzzy +#| msgid "Output format:" +msgid "Output flags" +msgstr "Formato de salida:" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "" + +#: src/elfclassify.c:962 +#, fuzzy +#| msgid "More than one output file name given." +msgid "Do not output file names" +msgstr "Se ha dado más de un nombre de archivo de salida." + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "FICHERO..." + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "Opciones de control:" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" +"Tratamiento de control de brechas en segmento cargables [ignorar|" +"coincidencia] (por defecto: ignorar)" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "Ignorar permutación de cubetas en sección SHT_HASH" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "Nada de salida; producir estado de salida únicamente" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "Comparar partes relevantes de dos ficheros ELF para igualdad." + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "FICHERO1 FICHERO2" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "Número inválido de parámetros.\n" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "no se puede obtener encabezamiento de '%s': %s" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "%s %s diff: encabezamiento ELF" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, c-format +msgid "cannot get section count of '%s': %s" +msgstr "no se puede obtener un conteo de sección en '%s': %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "%s %s diff: conteo de sección" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "no se puede obtener un conteo de encabezado de programa de '%s': %s" + +#: src/elfcmp.c:233 +#, c-format +msgid "%s %s diff: program header count" +msgstr "%s %s diff: encabezado de programa" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, fuzzy, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "no se puede obtener encabezamiento de '%s': %s" + +#: src/elfcmp.c:249 +#, fuzzy, c-format +msgid "%s %s diff: shdr string index" +msgstr "%s %s diff: conteo de sección" + +#: src/elfcmp.c:307 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "%s %s differ: sección [%zu,%zu] contenido '%s'" + +#: src/elfcmp.c:330 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "No se puede obtener contenido de sección %zu en '%s': %s" + +#: src/elfcmp.c:353 +#, fuzzy, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "" +"\n" +"La tabla de símbolos [%2u] '%s' contiene entrada %u:\n" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "No se puede obtener símbolo en '%s': %s" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "%s %s differ: tabla de símbolos [%zu]" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "%s %s differ: tabla de símbolos [%zu,%zu]" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:451 +#, fuzzy, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "No se puede obtener contenido de sección %zu en '%s': %s" + +#: src/elfcmp.c:462 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:470 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:485 +#, fuzzy, c-format +msgid "%s %s differ: build ID length" +msgstr "%s %s differ: brecha" + +#: src/elfcmp.c:493 +#, fuzzy, c-format +msgid "%s %s differ: build ID content" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:502 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "%s %s differ: sección [%zu] contenido '%s'" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "%s %s differ: sección [%zu,%zu] contenido '%s'" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "%s %s differ: cantidad desigual de secciones importantes" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "no se pueden cargar los datos de '%s': %s" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "" +"no se puede obtener entrada de encabezamiento de programa %d de '%s': %s" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "%s %s differ: encabezamiento de programa %d" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "%s %s differ: brecha" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "Valor inválido '%s' para parámetro --gaps" + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "Imposible abrir '%s'" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "No puede crear descriptor ELF para '%s': %s" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "no se puede crear el descriptor EBL para '%s'" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "No se puede obtener el encabezamiento de sección %zu: %s" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "No se puede obtener contenido de sección %zu: %s" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "No se puede obtener reubicación: %s" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "opción -o especificada dos veces" + +#: src/elfcompress.c:124 +#, fuzzy, c-format +msgid "-t option specified twice" +msgstr "opción -f especificada dos veces" + +#: src/elfcompress.c:133 +#, fuzzy, c-format +msgid "unknown compression type '%s'" +msgstr "tipo desconocido" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, fuzzy, c-format +msgid "No input file given" +msgstr "archivo de entrada vacío" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, fuzzy, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "Sólo se permite ingresar un archivo junto con '-o' y '-f'" + +#: src/elfcompress.c:1307 +#, fuzzy +msgid "Place (de)compressed output into FILE" +msgstr "Colocar la salida obtenida en FICHERO" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "Relaja algunas reglas para manejar ficheros ELF rotos" + +#: src/elfcompress.c:1325 +#, fuzzy +msgid "Be silent when a section cannot be compressed" +msgstr "" +"Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "" + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "Sea extremadamente estricto, característica de marca de nivel 2." + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "No imprime nada si está correcto" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "Binario es un archivo debuginfo independiente" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" +"Binario ha sido creado con GNU Id y por lo tanto se sabe que puede estar " +"roto de alguna forma" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "Chequeo minucioso de ficheros ELF de acuerdo con gABI/psABI " + +#: src/elflint.c:154 src/readelf.c:368 +#, fuzzy, c-format +msgid "cannot open input file '%s'" +msgstr "no se puede abrir el fichero de entrada" + +#: src/elflint.c:161 +#, fuzzy, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "no se puede crear descriptor ELF: %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "error al cerrar el descriptor ELF: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "No hay errores" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "Falta el nombre de archivo.\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr " error al liberar descriptor sub-ELF: %s\n" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "No es un fichero ELF - tiene los bytes mágicos errados en el inicio\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "e_ident[%d] == %d es una clase desconocida\n" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "e_ident[%d] == %d es una codificación de datos desconocida\n" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "" +"número de versión de encabezamiento ELF desconocido e_ident[%d] == %d\n" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "Sistema operativo OS ABI e_ident[%d] == '%s' incompatible\n" + +#: src/elflint.c:380 +#, fuzzy, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "Versión incompatible ABI e_ident[%d] == %d\n" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] no es cero\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "tipo de fichero objeto desconocido %d\n" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "tipo de máquina desconocido %d\n" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "versión de fichero objeto desconocido\n" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "Compensación de encabezamiento de programa inválida\n" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "" +"tanto los ejecutables como los DSO no pueden tener compensación de " +"encabezamiento de programa cero\n" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "cantidad no válida de entradas del encabezamiento del programa\n" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "compensación de sección de tabla de encabezamiento inválida\n" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "tabla de encabezamiento de sección debe estar presente\n" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "" +"cantidad no válida de entradas en la tabla del encabezamiento de sección\n" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "Índice de sección de encabezamiento inválido\n" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "" + +#: src/elflint.c:487 +#, c-format +msgid "invalid number of program header table entries\n" +msgstr "cantidad no válida de entradas de tabla de encabezado del programa\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "Indicadores de máquina inválidos: %s\n" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "tamaño inválido del encabezamiento ELF: %hd\n" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "tamaño inválido del encabezamiento del programa: %hd\n" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "tamaño o posición inválidos del encabezamiento del programa\n" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "tamaño inválido del encabezamiento de sección: %hd\n" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "tamaño o posición no válidos del encabezamiento de sección\n" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" +"sección [%2d] '%s': sección con la bandera SHF_GROUP no es parte de una " +"sección de grupo\n" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" +"sección [%2d] '%s': el grupo de sección [%2zu] '%s' no precede al miembro de " +"grupo\n" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "Sección [%2d] '%s': No se pueden obtener datos de sección\n" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" +"sección [%2d] '%s': nombrado como una tabla de cadena para la sección [%2d] " +"'%s' pero el tipo no es SHT_STRTAB\n" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" +"sección [%2d] '%s': la tabla de símbolo no puede tener más de una sección de " +"índice extendido\n" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "" +"sección [%2u] '%s': el tamaño de la entrada no coincide con ElfXX_Sym\n" + +#: src/elflint.c:662 +#, fuzzy, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" +"Sección [%2d] '%s': no hay entradas de nota definidas para el tipo de " +"archivo\n" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "Sección [%2d] '%s': no se puede obtener símbolo %d: %s\n" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "Sección [%2d] '%s': '%s' en la entrada zeroth no es cero\n" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "sección [%2d] '%s': XINDEX en la entrada zeroth no es cero\n" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "sección [%2d] '%s': no es posible obtener el símbolo %zu: %s\n" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "sección [%2d] '%s': símbolo %zu: valor de nombre inválido\n" + +#: src/elflint.c:728 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: el índice de sección es demasiado extenso, " +"pero no la sección extendida de la sección de índice\n" + +#: src/elflint.c:734 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: XINDEX es utilizado para índice que pueda " +"caber en st_shndx (%)\n" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "sección [%2d] '%s': símbolo %zu: índice de sección inválido\n" + +#: src/elflint.c:754 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "sección [%2d] '%s': símbolo %zu: tipo desconocido\n" + +#: src/elflint.c:760 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "sección [%2d] '%s': símbolo %zu: asociación de símbolo desconocida\n" + +#: src/elflint.c:765 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "Sección [%2d] '%s': símbolo %zu: símbolo único no de tipo de objeto\n" + +#: src/elflint.c:773 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" +"sección [%2d] '%s': símbolo %zu: COMMON solo es permitido en archivos " +"realojables\n" + +#: src/elflint.c:777 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: símbolos locales COMMON no tienen sentido\n" + +#: src/elflint.c:781 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: función en sección COMMON no tiene sentido\n" + +#: src/elflint.c:832 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "sección [%2d] '%s': símbolo %zu: st_value fuera de límites\n" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu no se ajusta totalmente en la sección [%2d] " +"'%s'\n" + +#: src/elflint.c:847 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: sección de referencia [%2d] '%s' no tiene " +"establecida bandera SHF_TLS\n" + +#: src/elflint.c:857 src/elflint.c:905 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: st_value fuera de límites de sección de " +"referencia [%2d] '%s'\n" + +#: src/elflint.c:884 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: símbolo TLS, pero no hay entrada de " +"programa TLS\n" + +#: src/elflint.c:890 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: símbolo TLS, pero no hay entrada de " +"programa TLS\n" + +#: src/elflint.c:898 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: st_value falta sección de referencia [%2d] " +"'%s'\n" + +#: src/elflint.c:925 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: símbolo local fuera del rango descrito en " +"sh_info\n" + +#: src/elflint.c:932 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: símbolo non-local fuera del rango descrito " +"en sh_info\n" + +#: src/elflint.c:939 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "Sección [%2d] '%s': símbolo %zu: símbolo de sección non-local\n" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" +"Sección [%2d] '%s': símbolo _GLOBAL_OFFSET_TABLE_ se refiere a sección " +"errada [%2d]\n" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" +"Sección [%2d] '%s': símbolo _GLOBAL_OFFSET_TABLE_ se refiere a sección [%2d] " +"'%s'\n" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" +"Sección [%2d] '%s': valor del símbolo _GLOBAL_OFFSET_TABLE_ %# no " +"coincide con dirección de sección %s %#\n" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" +"Sección [%2d] '%s': tamaño de símbolo _GLOBAL_OFFSET_TABLE_ % no " +"coincide con tamaño de sección %s %\n" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" +"Sección [%2d] '%s': símbolo _GLOBAL_OFFSET_TABLE_ presente, pero no. sección " +"got\n" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" +"sección [%2d] '%s': Valor de símbolo _DYNAMIC_ %# no coincide con la " +"dirección de segmento%#\n" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" +"Sección [%2d] '%s': tamaño de símbolo _DYNAMIC % no coincide con " +"tamaño de segmento %\n" + +#: src/elflint.c:1063 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: símbolo en tabla de símbolos dinámicos sin " +"visibilidad predeterminada\n" + +#: src/elflint.c:1067 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "" +"Sección [%2d] '%s': símbolo %zu: bit desconocido establecido en st_other\n" + +#: src/elflint.c:1105 +#, fuzzy, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "Sección [%2d] '%s': No se pueden obtener datos de sección\n" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "Sección [%2d] '%s': DT_RELCOUNT utilizada para esta sección RELA\n" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "" +"Sección [%2d] '%s': valor DT_RELCOUNT %d demasiado alto para esta sección\n" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" +"Sección [%2d] '%s': reubicaciones relativas después de que el %d de índice " +"haya sido especificado por DT_RELCOUNT\n" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" +"Sección [%2d] '%s': reubicación no-relativa en %zu de índice; DT_RELCOUNT " +"especificado %d reubicaciones relativas\n" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "sección [%2d] '%s': DT_RELACOUNT utilizado para esta sección REL\n" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "Sección [%2d] '%s': índice de sección de destino inválido\n" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "Sección [%2d] '%s': tipo de sección de destino inválido\n" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "Sección [%2d] '%s': sh_info debe ser cero\n" + +#: src/elflint.c:1286 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" +"Sección [%2d] '%s': no reubicaciones para secciones de fusión posibles\n" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "" +"Sección [%2d] '%s': tamaño de entrada de sección no coincide con ElfXX_Rela\n" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "Reubicación de bandera pero no hay segmento de sólo lectura\n" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "Sección [%2d] '%s': reubicación %zu: tipo inválido\n" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" +"Sección [%2d] '%s': reubicación %zu: tipo de reubicación inválido para el " +"tipo de archivo\n" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "Sección [%2d] '%s': reubicación %zu: índice de símbolo inválido\n" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" +"Sección [%2d] '%s': reubicación %zu: sólo el símbolo '_GLOBAL_OFFSET_TABLE_' " +"puede utilizarse con %s\n" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "Sección [%2d] '%s': reubicación %zu: compensación fuera de límites\n" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" +"Sección [%2d] '%s': reubicación %zu: reubicación de copia con símbolo de " +"tipo %s\n" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" +"Sección [%2d] '%s': reubicación %zu: sección de sólo-lectura modificada, " +"pero no se estableció bandera de reubicación\n" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "" +"Sección [%2d] '%s': las reubicaciones se hacen con datos cargados y " +"descargados\n" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "Sección [%2d] '%s': no puede obtener reubicación %zu: %s\n" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "más de una sección dinámica presente\n" + +#: src/elflint.c:1668 +#, fuzzy, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" +"sección [%2d] '%s': nombrado como una tabla de cadena para la sección [%2d] " +"'%s' pero el tipo no es SHT_STRTAB\n" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "" +"Sección [%2d] '%s': tamaño de entrada de sección no coincide con ElfXX_Dyn\n" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "Sección [%2d] '%s': sh_info no es cero\n" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "" +"Sección [%2d] '%s': no puede obtener entrada de sección dinámica %zu: %s\n" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "Sección [%2d] '%s': entradas non-DT_NULL siguen a la entrada DT_NULL\n" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "Sección [%2d] '%s': entrada %zu: etiqueta desconocida\n" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "Sección [%2d] '%s': entrada %zu: más de una entrada con etiqueta %s\n" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "Sección [%2d] '%s': entrada %zu: nivel 2 etiqueta %s utilizada\n" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" +"Sección [%2d] '%s': entrada %zu: el valor DT_PLTREL debe ser DT_REL or " +"DT_RELA\n" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" +"Sección [%2d] '%s': entrada %zu: puntero no coincide con dirección de " +"sección [%2d] '%s' al que hace referencia sh_link\n" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" +"Sección [%2d] '%s': entrada %zu: valor %s debe apuntar en segmento cargado\n" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" +"sección [%2d] '%s': entrada %zu: valor %s debe ser compensación válida en " +"sección [%2d] '%s'\n" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "Sección [%2d] '%s': contiene entrada %s pero no %s\n" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "Sección [%2d] '%s': etiqueta obligatoria %s no está presente\n" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "Sección [%2d] '%s': no hay sección de dispersión presente\n" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "Sección [%2d] '%s': no todas las %s, %s, y %s están presentes\n" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "" +"Sección [%2d] '%s': etiqueta %s faltante en DSO marcada durante el pre-" +"enlace\n" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "" +"Sección [%2d] '%s': archivo no-DSO marcado como dependencia durante el pre-" +"enlace\n" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "Sección [%2d] '%s': etiqueta %s faltante en pre-enlace ejecutable\n" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" +"Sección [%2d] '%s': sólo los archivos reubicables pueden tener índice de " +"sección extendido\n" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" +"Sección [%2d] '%s': índice de sección extendido no para tabla de símbolos\n" + +#: src/elflint.c:1948 +#, fuzzy, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "" +"Sección [%2d] '%s': índice de sección extendido no para tabla de símbolos\n" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "no se puede obtener sección para símbolos\n" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "Sección [%2d] '%s': tamaño de entrada no coincide con Elf32_Word\n" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "" +"Sección [%2d] '%s': tabla de índice extendida demasiado pequeña para tabla " +"de símbolos\n" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" +"Sección [%2d] '%s': índice de sección extendida en sección [%2zu] '%s' se " +"refiere a la misma tabla de símbolos\n" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "símbolo 0 debe tener índice de sección extendida cero\n" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "no puede obtener datos para símbolo %zu\n" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "" +"índice de sección extendida es % pero índice de símbolo no es " +"XINDEX\n" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" +"Sección [%2d] '%s': sección de tabla de dispersión es demasiado pequeña (es " +"%ld, se espera %ld)\n" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "Sección [%2d] '%s': índice de la cadena es demasiado grande\n" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "" +"Sección [%2d] '%s': referencia de cubetas de dispersión %zu fuera de " +"límites\n" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "" +"Sección [%2d] '%s': referencia de cadena de dispersión %zu fuera de límites\n" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "" +"Sección [%2d] '%s': referencia de cadena de dispersión % fuera de " +"límites\n" + +#: src/elflint.c:2140 +#, fuzzy, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "Sección [%2d] '%s': no puede obtener datos: %s\n" + +#: src/elflint.c:2152 +#, fuzzy, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "Sección [%2d] '%s': tamaño de bitmask no es potencia de 2: %u\n" + +#: src/elflint.c:2168 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" +"Sección [%2d] '%s': sección de tabla de dispersión es demasiado pequeña (es " +"%ld, se espera al menos least%ld)\n" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "" +"Sección [%2d] '%s': segundo cambio de función de dispersión demasiado " +"grande: %u\n" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" +"Sección [%2d] '%s': cadena de dispersión para cubetas %zu inferior a " +"polarización de índice de símbolo\n" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" +"Sección [%2d] '%s': el símbolo %u al que se hace referencia en cadena para " +"cubeta %zu es indefinido\n" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"Sección [%2d] '%s': valor de dispersión para símbolo %u en cadena para " +"cubeta %zu está errado\n" + +#: src/elflint.c:2254 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"Sección [%2d] '%s': valor de dispersión para símbolo %u en cadena para " +"cubeta %zu está errado\n" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "" +"Sección [%2d] '%s': cadena de dispersión para cubeta %zu fuera de limites\n" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" +"Sección [%2d] '%s': referencia de símbolo en cadena para cubeta %zu fuera de " +"límites\n" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "" +"Sección [%2d] '%s': bitmask no coincide con nombres en la tabla de " +"dispersión\n" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "" +"Sección [%2d] '%s': archivos reubicables no pueden tener tablas de " +"dispersión\n" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "" +"Sección [%2d] '%s': tabla de dispersión no para tabla de símbolos dinámicos\n" + +#: src/elflint.c:2330 +#, fuzzy, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "Sección [%2d] '%s': índice de sección de destino inválido\n" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "" +"Sección [%2d] '%s': tamaño incorrecto de entrada de tabla de dispersión\n" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "Sección [%2d] '%s': no marcada para ser asignada\n" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" +"Sección [%2d] '%s': tabla de dispersión no tiene ni siquiera espacio para " +"entradas administrativas iniciales\n" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "" +"sh_link en secciones de dispersión [%2zu] '%s' y [%2zu] '%s' no son " +"idénticas\n" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "sección [%2zu] '%s' no debe ser ejecutable\n" + +#: src/elflint.c:2444 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "Sección [%2d] '%s': grupo de sección sin palabra de banderas\n" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "sección [%2zu] '%s' debe ser asignada\n" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" + +#: src/elflint.c:2557 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "Sección [%2zu]: nombre inválido\n" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "Sección [%2zu] '%s': referencia al índice de símbolo 0\n" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" +"Símbolo %d nombrado en nueva tabla de dispersión en [%2zu] '%s' pero no en " +"la tabla de dispersión anterior en [%2zu] '%s'\n" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" +"Símbolo %d nombrado en la tabla de dispersión anterior en [%2zu] '%s' pero " +"no en la nueva tabla de dispersión en [%2zu] '%s'\n" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "Sección [%2d] '%s': nonzero sh_%s para sección NULL\n" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" +"Sección [%2d] '%s': grupos de sección sólo permitidos en archivos de objeto " +"reubicables\n" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "Sección [%2d] '%s': no puede obtener tabla de símbolos: %s\n" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "" +"Sección [%2d] '%s': referencia de sección en sh_link no es una tabla de " +"símbolos\n" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "Sección [%2d] '%s': índice de símbolo inválido en sh_info\n" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "Sección [%2d] '%s': sh_flags no cero\n" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "Sección [%2d] '%s': no puede obtener símbolo para firma\n" + +#: src/elflint.c:2664 +#, fuzzy, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "Sección [%2d] '%s': no puede obtener símbolo para firma\n" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "" +"sección [%2d] '%s': el símbolo de firma no puede ser una cadena vacía\n" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "Sección [%2d] '%s': sh_flags no establecida correctamente\n" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "Sección [%2d] '%s': no puede obtener datos: %s\n" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "" +"Sección [%2d] '%s': tamaño de sección no es múltiplo de tamaño de " +"(Elf32_Word)\n" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "Sección [%2d] '%s': grupo de sección sin palabra de banderas\n" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "Sección [%2d] '%s': grupo de sección sin miembro\n" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "Sección [%2d] '%s': grupo de sección con sólo un miembro\n" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "Sección [%2d] '%s': banderas de grupo de sección desconocido\n" + +#: src/elflint.c:2731 +#, fuzzy, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "Sección [%2d] '%s': índice de sección %Zu fuera de rango\n" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "" +"Sección [%2d] '%s': no se puede obtener encabezamiento de sección para " +"elemento %zu: %s\n" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "Sección [%2d] '%s': grupo de sección contiene otro grupo [%2d] '%s'\n" + +#: src/elflint.c:2753 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" +"Sección [%2d] '%s': elemento %Zu hace referencia a sección [%2d] '%s' sin " +"establecer bandera SHF_GROUP\n" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "Sección [%2d] '%s' está contenida en más de un grupo de sección\n" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" +"Sección [%2d] '%s' se refiere en sh_link a la sección [%2d] '%s' la cual no " +"es una tabla de símbolos dinámicos\n" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" +"Sección [%2d] '%s' tiene un número diferente de entradas a la de la tabla de " +"símbolos [%2d] '%s'\n" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "" +"Sección [%2d] '%s': el símbolo %d: no se pueden leer datos de versión\n" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "" +"Sección [%2d] '%s': el símbolo %d: el símbolo local con alcance mundial\n" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "Sección [%2d] '%s': símbolo %d: símbolo local con versión\n" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "Sección [%2d] '%s': símbolo %d: índice de versión inválida %d\n" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" +"Sección [%2d] '%s': símbolo %d: índice de versión %d es para versión " +"definida\n" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" +"Sección [%2d] '%s': símbolo %d: índice de versión %d es para la versión " +"solicitada\n" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "Más de una sección de referencia de versión presente\n" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "Sección [%2d] '%s': sh_link no se enlaza a la tabla de cadenas\n" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "Sección [%2d] '%s': entrada %d tiene versión %d errada\n" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "" +"Sección [%2d] '%s': entrada %d tiene compensación errada de datos " +"auxiliares\n" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "Sección [%2d] '%s': entrada %d tiene referencia de archivo inválida\n" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "Sección [%2d] '%s': %d hace referencia a dependencia desconocida\n" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "" +"sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene bandera " +"desconocida\n" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" +"Sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene referencia de " +"nombre inválida\n" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" +"Sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene valor de " +"dispersión: %#x, esperado %#x\n" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" +"sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene nombre duplicado " +"'%s'\n" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" +"sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene próximo campo " +"errado\n" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "" +"sección [%2d] '%s': entrada %d tiene compensación inválida para próxima " +"entrada\n" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" +"sección [%2d] '%s': entrada %d tiene compensación inválida para próxima " +"entrada\n" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "más de una definición de versión presente de sección\n" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "Sección [%2d] '%s': más de una definición de BASE\n" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "" +"Sección [%2d] '%s': definición de BASE debe tener índice VER_NDX_GLOBAL\n" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "Sección [%2d] '%s': entrada %d tiene bandera desconocida\n" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "Sección [%2d] '%s': entrada %d tiene referencia de nombre inválida\n" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "" +"Sección [%2d] '%s': entrada %d tiene valor de dispersión errado: %#x, " +"esperado %#x\n" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "" +"Sección [%2d] '%s': entrada %d tiene nombre de versión duplicado '%s'\n" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" +"Sección [%2d] '%s': entrada %d tiene referencia de nombre inválida en datos " +"auxiliares\n" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "" +"Sección [%2d] '%s': entrada %d tiene próximo campo errado en datos " +"auxiliares\n" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "Sección [%2d] '%s': no hay definición de BASE\n" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "Sección [%2d] '%s': desconocida versión principal '%s'\n" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "Sección [%2d] '%s': sección de atributos de objeto vacío\n" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "Sección[%2d] '%s': formato de atributo no reconocido\n" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" +"Sección[%2d] '%s': compensación %zu: campo de longitud cero en sección de " +"atributo\n" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "" +"Sección[%2d] '%s': compensación %zu: longitud inválida en sección de " +"atributo\n" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "" +"Sección[%2d] '%s': compensación %zu: cadena de nombre de proveedor sin " +"terminar\n" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: sin fin ULEB128 en etiqueta de sub-" +"sección de atributo\n" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "Sección [%2d] '%s': compensación %zu: sección de atributo truncado\n" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: campo de longitud cero length en sub-" +"sección de atributo\n" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: longitud inválida en sub-sección de " +"atributo\n" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" +"Sección[%2d] '%s': compensación %zu: sub-sección de atributo tiene etiqueta " +"inesperada %u\n" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "" +"Sección[%2d] '%s': compensación %zu: sin fin ULEB128 en etiqueta de " +"atributo\n" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: cadena sin terminar en atributo\n" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: etiqueta de atributo no reconocida %u\n" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: no reconocido %s valor de atributo " +"%\n" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "Sección [%2d] '%s': compensación %zu: proveedor '%s' desconocido\n" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" +"Sección [%2d] '%s': compensación %zu: extra bytes después de la última " +"sección de atributo\n" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "no puede obtener encabezamiento de sección de sección zeroth\n" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "Sección zeroth tiene nombre nonzero\n" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "Sección zeroth tiene tipo nonzero\n" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "Sección zeroth tiene banderas nonzero\n" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "Sección zeroth tiene dirección nonzero\n" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "Sección zeroth tiene compensación nonzero\n" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "Sección zeroth tiene valor de alineación nonzero\n" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "Sección zeroth tiene valor de tamaño de entrada nonzero\n" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" +"Sección zeroth tiene valor de tamaño nonzero mientras que el encabezamiento " +"ELF tiene valor shnum nonzero\n" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" +"Sección zeroth tiene valor de enlace nonzero mientras que el encabezamiento " +"ELF no señala sobreflujo en shstrndx\n" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" +"la sección zeroth tiene un valor de enlace distinto a cero mientras que el " +"encabezamiento ELF no señala desbordamiento en phnum\n" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "No se puede obtener encabezamiento para sección [%2zu] '%s': %s\n" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "Sección [%2zu]: nombre inválido\n" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "Sección [%2d] '%s' tiene tipo errado: %s esperado, es %s\n" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "Sección [%2zu] '%s' tiene banderas erradas: %s esperado, es %s\n" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" +"Sección [%2zu] '%s' tiene banderas erradas: %s esperado y posiblemente %s, " +"es %s\n" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "Sección [%2zu] '%s' presente en archivo objeto\n" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" +"Sección [%2zu] '%s' tiene bandera SHF_ALLOC establecida pero no es un " +"segmento cargable\n" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" +"Sección [%2zu] '%s' no tiene bandera SHF_ALLOC establecida pero hay " +"segmentos cargables\n" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" +"Sección [%2zu] '%s' es tabla de índice de sección de extensión en archivo no-" +"objeto\n" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "Sección [%2zu] '%s': tamaño no es múltiplo de tamaño de entrada\n" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "no se puede obtener encabezamiento de sección\n" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "sección [%2zu] '%s' tiene tipo %d incompatible \n" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" +"Sección [%2zu] '%s' contiene bandera(s) de procesador-específico inválidas " +"%#\n" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "Sección [%2zu] '%s' contiene bandera(s) desconocidas %#\n" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "" +"Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n" + +#: src/elflint.c:3974 +#, fuzzy, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "" +"Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n" + +#: src/elflint.c:3979 +#, fuzzy, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "Sección [%2d] '%s': no hay sección de dispersión presente\n" + +#: src/elflint.c:3985 +#, fuzzy, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "Sección [%2d] '%s': grupo de sección con sólo un miembro\n" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "" +"Sección [%2zu] '%s': referencia de sección inválida en valor de enlace\n" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "" +"Sección [%2zu] '%s': referencia de sección inválida en valor de información\n" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "" +"Sección [%2zu] '%s': bandera de cadenas establecida sin bandera de fusión\n" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "" +"Sección [%2zu] '%s': bandera de fusión establecida pero tamaño de entrada es " +"cero\n" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "" +"Sección [%2zu] '%s' tiene un tipo %d inesperado para una sección ejecutable\n" + +#: src/elflint.c:4036 +#, fuzzy, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "sección [%2zu] '%s' no debe tener permiso de escritura\n" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "Sección [%2zu] '%s' es tanto de ejecución como de escritura\n" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" +"Sección [%2zu] '%s' no contenida totalmente en segmento de entrada de " +"encabezamiento de programa %d\n" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" +"Sección [%2zu] '%s' no tiene tipo NOBITS pero es leída desde el archivo en " +"segmento de entrada de encabezamiento de programa %d\n" + +#: src/elflint.c:4110 +#, fuzzy, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" +"Sección [%2zu] '%s' no tiene tipo NOBITS pero es leída desde el archivo en " +"segmento de entrada de encabezamiento de programa %d\n" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" +"Sección [%2zu] '%s' no tiene tipo NOBITS pero no es leída desde el fichero " +"en segmento de entrada de encabezamiento de programa %d\n" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "Sección [%2zu] '%s' es ejecutable en segmento no ejecutable %d\n" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "" +"Sección [%2zu] '%s' es de escritura en segmento que no es de escritura %d\n" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" +"Sección [%2zu] '%s': asignación de bandera establecida pero sección no en " +"ningún segmento cargado\n" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" +"Sección [%2zu] '%s': encabezamiento ELF dice esta es la tabla de cadena de " +"encabezamiento de sección, pero el tipo no es SHT_TYPE\n" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" +"sección [%2zu] '%s': ficheros reubicables no pueden tener tablas de símbolos " +"dinámicos\n" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "Más de una tabla de símbolos presente\n" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "" +"Entrada de encabezamiento de programa INTERP pero no la sección .interp\n" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" +"segmento cargable [%u] es ejecutable pero no contiene secciones ejecutables\n" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "" +"segmento cargable [%u] es de escritura pero contiene secciones protegidas " +"contra escritura\n" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" +"Sección no .gnu.versym presente, pero la sección .gnu.versym_d o la sección ." +"gnu.versym_r existen\n" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "Duplicar índice de versión %d\n" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr "" +"Sección .gnu.versym presente sin las secciones .gnu.versym_d o .gnu." +"versym_r\n" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "" +"phdr[%d]: tipo de nota de fichero core desconocido % en compensación " +"%\n" + +#: src/elflint.c:4348 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" +"Sección [%2d] '%s': tipo de nota de fichero core desconocido % en " +"compensación %Zu\n" + +#: src/elflint.c:4397 +#, fuzzy, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" +"phdr[%d]: tipo de nota de fichero objeto desconocido % en " +"compensación %Zu\n" + +#: src/elflint.c:4402 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" +"Sección [%2d] '%s': tipo de nota de fichero objeto desconocido % en " +"compensación %Zu\n" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "phdr[%d]: no hay entradas de nota definidas para el tipo de archivo\n" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "phdr[%d]: no puede obtener contenido de sección de nota: %s\n" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "phdr[%d]: extra % bytes después de la última nota\n" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "" +"Sección [%2d] '%s': no hay entradas de nota definidas para el tipo de " +"archivo\n" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "" +"Sección[%2d] '%s': no se puede obtener el contenido de sección de nota\n" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "Sección[%2d] '%s': extra % bytes después de la última nota\n" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" +"Sólo ejecutables, objetos compartidos y ficheros core pueden tener " +"encabezamientos de programas\n" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "no se puede obtener entrada de encabezamiento %d: %s\n" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" +"entrada de encabezamiento de programa %d: tipo %# de entrada de " +"encabezamiento de programa desconocido\n" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "Más de una entrada INTERP en encabezamiento de programa\n" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "más de una entrada TLS en encabezamiento de programa\n" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "ejecutable estático no puede tener secciones dinámicas\n" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "" +"Referencia de sección dinámica en encabezamiento de programa tiene " +"compensación errada\n" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "" +"No coinciden tamaño de sección dinámica en programa y encabezamiento de " +"sección\n" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "Más de una entrada GNU_RELRO en encabezamiento de programa\n" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "Segmento cargable GNU_RELRO que se aplica no es de escritura\n" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "" +"Banderas de segmento cargable [%u] no coinciden con banderas GNU_RELRO [%u]\n" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "Segmento %s no contenido en un segmento cargable\n" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "" +"Compensación de encabezamiento de programa en encabezamiento ELF y entrada " +"PHDR no coinciden" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "" +"Referencia de tabla de búsqueda de marco de llamada en encabezamiento de " +"programa tiene una compensación errada\n" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "" +"Tamaño de tabla de búsqueda de marco de llamada no coincide con programa y " +"encabezamiento de sección\n" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "PT_GNU_EH_FRAME presente pero no la sección.eh_frame_hdr\n" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "tabla de búsqueda de marco de llamada debe ser asignada\n" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "sección [%2zu] '%s' debe ser asignada\n" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "" +"tabla de búsqueda de marco de llamada no debe tener permiso de escritura\n" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "sección [%2zu] '%s' no debe tener permiso de escritura\n" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "tabla de búsqueda de marco de llamada no debe ser ejecutable\n" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "sección [%2zu] '%s' no debe ser ejecutable\n" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "" +"entrada de encabezamiento de programa %d: tamaño de fichero mayor que el " +"tamaño de memoria\n" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "" +"entrada de encabezamiento de programa %d: alineamiento no es potencia de 2\n" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" +"entrada de encabezamiento de programa %d: compensación de fichero y " +"dirección virtual no módulo de alineación\n" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" +"ejecutable/DSO con sección .eh_frame_hdr no tiene una entrada de " +"encabezamiento de programa PT_GNU_EH_FRAME" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "No se puede leer encabezamiento ELF: %s\n" + +#: src/elflint.c:4797 +#, fuzzy, c-format +msgid "cannot create backend for ELF file\n" +msgstr "no sepuede crear fichero nuevo" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "Bandera de reubicación de texto establecida pero no necesaria\n" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "Selección de entrada:" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "Agregar RUTA a todos los nombres de ficheros" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "Usar RUTA como root de jerarquía de debuginfo" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "" +"Localizar origen de reubicaciones de texto en FICHEROS (a.out por defecto)." + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "[FICHERO...]" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "No se puede obtener encabezamiento ELF '%s': %s" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "'%s' es no un DSO o PIE" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "obtener encabezamiento de sección get de sección %zu: %s" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "No se puede leer sección dinámica: %s" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "no hay reubicaciones de texto reportado en '%s'" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "Error al leer fichero ELF" + +#: src/findtextrel.c:314 +#, fuzzy, c-format +msgid "cannot get program header count: %s" +msgstr "no se puede obtener memoria para encabezamiento del programa: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, fuzzy, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "" +"Nos se puede obtener el índice de encabezamiento de programa en compensación " +"%d: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "No se puede obtener tabla de símbolos %zu en '%s': %s" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "" +"No se puede obtener reubicación en índice %d en sección %zu en '%s': %s" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "%s no compilado con -fpic/-fPIC\n" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"El archivo que contiene la función '%s' no está compilado con -fpic/-fPIC\n" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" +"el fichero que contiene la función '%s' podría no estar compilado con -fpic/-" +"fPIC\n" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"Tanto el fichero que contiene la función '%s' como el fichero que contiene " +"la función '%s' no están compilados con -fpic/-fPIC\n" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" +"Una reubicación modifica memoria en compensación %llu en un segmento " +"protegido contra escritura\n" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "Selección de salida:" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "Mostrar sólo símbolos del depurador" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "Mostrar sólo símbolos definidos" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "Mostrar símbolos dinámicos en lugar de símbolos normales" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "Mostrar sólo símbolos externos" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "Mostrar sólo símbolos indefinidos" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "Incluir índices para símbolos de miembros de archivo" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "Formato de salida:" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "Imprimir nombre de archivo de entrada antes de cada símbolo" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"Usar el formato de salida FORMATO. FORMATO puede ser o bien `bsd', o " +"`sysv', o `posix'. El establecido por defecto es `sysv'" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "lo mismo que --format=bsd" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "lo mismo que --format=posix" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "Utilizar RADIX para imprimir valores de símbolo" + +#: src/nm.c:87 +#, fuzzy +msgid "Mark special symbols" +msgstr "Marcar símbolos débiles" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "Tamaño de impresión de símbolos definidos" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "Opciones de salida:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "Ordenar los símbolos numéricos por dirección" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "No ordenar los símbolos" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "Invertir el orden" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "Listar símbolos de FICHEROS (a.out por defecto)." + +#: src/nm.c:116 src/objdump.c:79 +#, fuzzy +msgid "Output formatting" +msgstr "Formato de salida:" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, fuzzy, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: ERROR INTERNO %d (%s-%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "error al cerrar '%s'" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: No se reconoce el formato del fichero" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +#, fuzzy +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"Índice de archivo:" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "Compensación %zu inválida para símbolo %s" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "%s en %s\n" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "imposible restablecer compensación de archivo al inicio" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: no se reconoció el formato de fichero" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "No se puede crear el árbol de búsqueda" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "no se puede obtener índice de cadena de encabezamiento de sección" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"Símbolos de %s:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" +"%*s%-*s %-*s Clase Tipo %-*s %*s Sección\n" +"\n" + +#: src/nm.c:776 +msgctxt "sysv" +msgid "Name" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "" + +#: src/nm.c:1250 +#, fuzzy, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "" +"%s: el tamaño de la entrada en la sección `%s' no es el que esperábamos " + +#: src/nm.c:1255 +#, fuzzy, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: Tamaño de sección `%s' no es múltiplo de tamaño de entrada" + +#: src/nm.c:1336 +#, fuzzy, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "" +"%s: el tamaño de la entrada en la sección `%s' no es el que esperábamos " + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: Operación inválida" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: No hay símbolos" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "Selección de modo:" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "Mostrar la reubicación de información." + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "Mostrar el contenido total de todas las secciones solicitadas" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "Mostrar código de ensamblador de secciones ejecutables" + +#: src/objdump.c:59 +#, fuzzy +msgid "Output content selection:" +msgstr "Selección de opción de salida:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "Sólo muestra información para NOMBRE de sección." + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "Muestra información de FICHEROS (a.out por defecto)." + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "No se especificó una operación.\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "mientras cierra `%s'" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "SÍMBOLO INVÁLIDO" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "SECCIÓN INVÁLIDA" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" +"\n" +"REUBICACIÓN DE REGISTROS PARA [%s]:\n" +"%-*s TIPO VALOR\n" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "COMPENSACIÓN" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "Contenido de la sección %s:\n" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "No se puede desensamblar" + +#: src/objdump.c:760 +#, fuzzy, c-format +msgid "cannot create backend for elf file" +msgstr "no sepuede crear fichero nuevo" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr " Generar un índice para acelerar el acceso a los archivos." + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "ARCHIVO " + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "Se requiere nombre de archivo" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "%s: no es un archivo" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "error al liberar descriptor sub-ELF: %s" + +#: src/readelf.c:97 +#, fuzzy +msgid "ELF input selection:" +msgstr "Selección de salida de ELF:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" + +#: src/readelf.c:104 +msgid "ELF output selection:" +msgstr "Selección de salida de ELF:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "Todo esto mas -p .strtab -p .dynstr -p .comment" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "Mostrar el segmento dinámico" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "Mostrar el encabezamiento del fichero ELF" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "Mostrar histograma de las longitudes de las listas de cubetas" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "Mostrar encabezamientos de programa" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "Mostrar reubicaciones" + +#: src/readelf.c:114 +#, fuzzy +msgid "Display the section groups" +msgstr "Mostrar los encabezados de las secciones" + +#: src/readelf.c:115 +msgid "Display the sections' headers" +msgstr "Mostrar los encabezados de las secciones" + +#: src/readelf.c:118 +#, fuzzy +msgid "Display the symbol table sections" +msgstr "Mostrar la tabla de símbolos" + +#: src/readelf.c:120 +#, fuzzy +msgid "Display (only) the dynamic symbol table" +msgstr "Mostrar sólo símbolos externos" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "Mostrar información de versión" + +#: src/readelf.c:122 +msgid "Display the ELF notes" +msgstr "Mostrar las notas ELF" + +#: src/readelf.c:124 +msgid "Display architecture specific information, if any" +msgstr "Mostrar información específica de la arquitectura (si es que la hay)" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "Muestra secciones para manejo de excepciones" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "Selección de salida adicional:" + +#: src/readelf.c:130 +#, fuzzy +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" +"Mostrar el contenido de la sección DWARF. SECCIÓN puede ser algo de lo " +"siguiente: abbrev, aranges, frame, info, loc, line, ranges, pubnames, str, " +"macinfo, o exception" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "Vuelca los contenidos no interpretados de SECCIÓN, por número o nombre" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "Imprime contenido de cadena de secciones" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "Muestra el índice de símbolos de un archivo" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "Control de salida:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "" +"No se encuentran los nombres de símbolos para direcciones en datos DWARF" + +#: src/readelf.c:145 +#, fuzzy +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "" +"No se encuentran los nombres de símbolos para direcciones en datos DWARF" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "" +"Imprimir información del fichero ELF en una forma comprensible para los " +"seres humanos." + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "sí" + +#: src/readelf.c:351 +msgid "no" +msgstr "no" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "Sección de depuración DWARF desconocida `%s'.\n" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "no se puede crear descriptor ELF: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "no se pudieron determinar el número de secciones: %s" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "No se puede encontrar la sección: %s" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "No se puede obtener encabezamiento de sección: %s" + +#: src/readelf.c:663 +#, fuzzy, c-format +msgid "cannot get section name" +msgstr "no se puede obtener encabezamiento de sección\n" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "No se puede obtener el contenido %s: %s" + +#: src/readelf.c:688 +#, fuzzy, c-format +msgid "cannot create temp file '%s'" +msgstr "no se puede crear fichero nuevo '%s': %s" + +#: src/readelf.c:697 +#, fuzzy, c-format +msgid "cannot write section data" +msgstr "no se puede leer la sección de datos: %s" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "error al cerrar el descriptor ELF: %s" + +#: src/readelf.c:710 +#, fuzzy, c-format +msgid "error while rewinding file descriptor" +msgstr "error al cerrar el descriptor ELF: %s" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "'%s' no es un archivo, no se puede imprimir índice de archivo" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "no sepudo stat archivo de entrada" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "archivo de entrada vacío" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "Falló lectura de '%s': %s" + +#: src/readelf.c:881 +#, fuzzy, c-format +msgid "No such section '%s' in '%s'" +msgstr "No se puede obtener contenido de sección %zu en '%s': %s" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "no se pudo leer encabezamiento ELF: %s" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "no se puede crear EBL" + +#: src/readelf.c:961 +#, c-format +msgid "cannot determine number of program headers: %s" +msgstr "no se pudo determinar la cantidad de encabezados de programa: %s" + +#: src/readelf.c:993 +#, fuzzy, c-format +msgid "cannot read ELF: %s" +msgstr "no sepuede leer %s: %s" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "NONE (Ninguno)" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "REL (Fichero reubicable)" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "EXEC (Fichero ejecutable)" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "DYN (Fichero objeto compartido)" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "CORE (Fichero núcleo)" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "OS Specific: (%x)\n" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "Específico del procesador: (%x)\n" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" +"Encabezamiento ELF:\n" +" Mágico: " + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" +"\n" +" Clase: %s\n" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr " Datos: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr " Versión ident: %hhd %s\n" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(actual)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr " OS/ABI: %s\n" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr " Versión ABI: %hhd\n" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " Tipo: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr " Máquina: %s\n" + +#: src/readelf.c:1109 +#, fuzzy, c-format +msgid " Machine: : 0x%x\n" +msgstr " Máquina: %s\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr " Versión: %d %s\n" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr " Dirección de punto de entrada: %#\n" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr " Inicio de encabezamientos de programa: % %s\n" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr " (bytes en el archivo)" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr " Inicio de encabezamientos de sección: % %s\n" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr " Indicadores: %s\n" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr " Tamaño de este encabezamiento: % %s\n" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(bytes)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr "" +" Tamaño de las entradas en encabezamiento del programa: % %s\n" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr " Cantidad de entradas de encabezados de programa: %" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr " (% in [0].sh_info)" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr " ([0] no disponible)" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr "" +" Tamaño de las entradas en el encabezamiento de sección: % %s\n" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr " Cantidad de entradas en los encabezamientos de sección: %" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr " (% en [0].sh_size)" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr " (% en [0].sh_link)" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" +" Índice de tabla de cadenas de sección de encabezamiento de : XINDEX%s\n" +"\n" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr " Índice de tabla de cadenas de sección de encabezamiento: %\n" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, fuzzy, c-format +msgid "cannot get number of sections: %s" +msgstr "no se pudieron determinar el número de secciones: %s" + +#: src/readelf.c:1233 +#, fuzzy, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" +"Hay %d encabezamientos de sección, comenzando en compensación %#:\n" +"\n" + +#: src/readelf.c:1242 +#, fuzzy, c-format +msgid "cannot get section header string table index: %s" +msgstr "no se puede obtener índice de cadena de encabezamiento de sección" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "encabezamientos de sección:" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" +"[Nr] Nombre Tipo Dirección Off Tamaño Inf Al " +"Enlace banderas ES" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1335 +#, fuzzy, c-format +msgid "bad compression header for section %zd: %s" +msgstr "No se puede obtener el encabezamiento de sección %zu: %s" + +#: src/readelf.c:1346 +#, fuzzy, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "No se pueden obtener datos para la sección %d: %s" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "encabezamientos de programa:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" +" Tipo Compensación Dirección Virtual Dirección " +"Física Tamaño de Fichero Tamaño de Memoria Alineación de bandera" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" +" Tipo Compensación Dirección Virtual Dirección " +"Física Tamaño de Fichero Tamaño de Memoria Alineación de bandera" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "\t[Solicitando intérprete de programa: %s]\n" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" +"\n" +" Sección para asignación de segmento:\n" +" Secciones de segmento..." + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "no se puede obtener memoria para encabezamiento del programa: %s" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Grupo de sección COMDAT [%2zu] '%s' con firma '%s' contiene entrada %zu:\n" +msgstr[1] "" +"\n" +"Grupo de sección COMDAT [%2zu] '%s' con firma '%s' contiene entradas %zu:\n" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Grupo de sección [%2zu] '%s' con firma '%s' contiene entrada %zu:\n" +msgstr[1] "" +"\n" +"Grupo de sección [%2zu] '%s' con firma '%s' contiene entradas %zu:\n" + +#: src/readelf.c:1623 +msgid "" +msgstr "" + +#: src/readelf.c:1637 +msgid "" +msgstr "" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, fuzzy, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "No se puede obtener encabezamiento de sección: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, fuzzy, c-format +msgid "invalid sh_link value in section %zu" +msgstr ".debug_line section inválida" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Segmento dinámico contiene entrada %lu:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" +msgstr[1] "" +"\n" +"Segmento dinámico contiene entradas %lu:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr " Tipo Valor\n" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "Biblioteca compartida: [%s]\n" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "Nombre-so de la biblioteca: [%s]\n" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "Rpath de la biblioteca: [%s]\n" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "Ruta de ejecución de la biblioteca: [%s]\n" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "% (bytes)\n" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" +"\n" +"Tabla de símbolos inválida en compensación %#0\n" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +"\n" +"Sección de reubicación [%2zu] '%s' para sección [%2u] '%s' en compensación " +"%#0 contiene entrada %d:\n" +msgstr[1] "" +"\n" +"Sección de reubicación [%2zu] '%s' para sección [%2u] '%s' en compensación " +"%#0 contiene entradas %d:\n" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Sección de reubicación[%2u] '%s' en compensación %#0 contiene " +"entrada %d:\n" +msgstr[1] "" +"\n" +"Sección de reubicación [%2u] '%s' en compensación %#0 contiene " +"entradas %d:\n" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr " Compensación Tipo Valor Nombre\n" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr " Compensación Tipo Valor Nombre\n" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr " Compensación Tipo Valor Nombre Adend\n" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr " Compensación Tipo Valor Nombre Adend\n" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +"\n" +"La tabla de símbolos [%2u] '%s' contiene entrada %u:\n" +msgstr[1] "" +"\n" +"La tabla de símbolos [%2u] '%s' contiene entradas %u:\n" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] "símbolos locales %lu Tabla de cadena: [%2u] '%s'\n" +msgstr[1] " Símbolos locales %lu Tabla de cadenas: [%2u] '%s'\n" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Núm: Valor Tamaño Tipo Unión Vis Nombre Ndx\n" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Num: Valor Tamaño Tipo Unión Vis Nombre Ndx\n" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "%5u: %0* %6 %-7s %-6s %-9s %6s %s" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "símbolo dinámico erróneo" + +#: src/readelf.c:2680 +msgid "none" +msgstr "nada" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| " + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Sección de versión necesita [%2u] '%s' contiene entrada %d entry:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" +msgstr[1] "" +"\n" +"Versión necesita sección [%2u] '%s' contiene entrada %d:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: Versión: %hu Fichero: %s Conteo: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: Nombre: %s Banderas: %s Versión: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Sección de definición de versión [%2u] '%s' contiene entrada %d:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" +msgstr[1] "" +"\n" +"Sección de definición de versión [%2u] '%s' contiene %d entrada:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr "" +" %#06x: Versión: %hd Banderas: %s Índice: %hd Conteo: %hd Nombre: %s\n" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr " %#06x: Principal %d: %s\n" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +"\n" +"Sección de versión de símbolos [%2u] '%s' contiene %d entrada:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'" +msgstr[1] "" +"\n" +"Sección de versión de símbolos [%2u] '%s' contiene entradas %d:\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *local* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *global* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Histograma para longitud de lista de cubeta en sección [%2u] '%s' (total de " +"cubetas %d):\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" +msgstr[1] "" +"\n" +"Histograma para longitud de lista de cubeta en sección [%2u] '%s' (total de " +"cubetas %d):\n" +" Dirección: %#0* Compensación: %#08 Enlace a sección: " +"[%2u] '%s'\n" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr " Longitud Número % of total Cobertura\n" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" +" Número promedio de pruebas: búsqueda exitosa: %f\n" +" búsqueda sin éxito: %f\n" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "No se pueden obtener datos para la sección %d: %s" + +#: src/readelf.c:3254 +#, fuzzy, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "Datos inválidos en sección [%zu] '%s'" + +#: src/readelf.c:3283 +#, fuzzy, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "Datos inválidos en sección [%zu] '%s'" + +#: src/readelf.c:3318 +#, fuzzy, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "Datos inválidos en sección [%zu] '%s'" + +#: src/readelf.c:3349 +#, fuzzy, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "Datos inválidos en sección [%zu] '%s'" + +#: src/readelf.c:3385 +#, fuzzy, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "Datos inválidos en sección [%zu] '%s'" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" +" Polarización de símbolo: %u\n" +" Tamaño de Bitmask: %zu bytes %%% bits establecen segundo " +"cambio de dispersión: %u\n" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Sección de lista de biblioteca [%2zu] '%s' en compensación %#0 " +"contiene entrada %d:\n" +msgstr[1] "" +"\n" +"Sección de lista de biblioteca [%2zu] '%s' en compensación %#0 " +"contiene entradas %d:\n" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" +" Biblioteca Marca de tiempo Indicadores " +"de versión de suma de verificación" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" +"\n" +"Sección de atributos de objeto [%2zu] '%s' de % bytes con " +"desplazamiento %#0:\n" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr " Propietario Tamaño\n" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " File: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %, %s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, fuzzy, c-format +msgid "sprintf failure" +msgstr "mprotect falló" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "bloque vacío" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "bloque de byte %zu:" + +#: src/readelf.c:4800 +#, fuzzy, c-format +msgid "%*s[%2] %s \n" +msgstr "%*s[%4] %s \n" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "%s %# utilizado con direcciones de diferente tamaño" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "%s %# utilizado con offsetr de diferente tamaño" + +#: src/readelf.c:4881 +#, fuzzy, c-format +msgid "%s %# used with different base addresses" +msgstr "%s %# utilizado con direcciones de diferente tamaño" + +#: src/readelf.c:4888 +#, fuzzy, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "%s %# utilizado con direcciones de diferente tamaño" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr " [%6tx] ... % bytes ...\n" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %#:\n" +" [ Código]\n" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" +"\n" +"Sección de abreviatura en compensación %:\n" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr " *** error en lectura de abreviatura: %s\n" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr " [%5u] compensación: %, hijos: %s, etiqueta: %s\n" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %#:\n" + +#: src/readelf.c:5182 +#, fuzzy, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "no se pueden obtener datos de sección: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, fuzzy, c-format +msgid " Length: %8\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, fuzzy, c-format +msgid " DWARF version: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, fuzzy, c-format +msgid " Address size: %8\n" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, fuzzy, c-format +msgid " Segment size: %8\n" +msgstr " establecer archivo a %\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, fuzzy, c-format +msgid "Unknown version" +msgstr "versión desconocida" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, fuzzy, c-format +msgid "unsupported address size" +msgstr "no hay valor de dirección" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "no se ha podido obtener contenido de .debug_aranges: %s" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %# contiene entrada %zu:\n" +msgstr[1] "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %# contiene entradas %zu:\n" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" +" Inicio [%*zu]: %0#*, longitud: %5, compensación CU DIE: " +"%6\n" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, fuzzy, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" +"\n" +"Tabla en compensación %Zu:\n" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "Datos inválidos en sección [%zu] '%s'" + +#: src/readelf.c:5511 +#, fuzzy, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:5523 +#, fuzzy, c-format +msgid " DWARF version: %6\n" +msgstr " %s: %\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "" + +#: src/readelf.c:5538 +#, fuzzy, c-format +msgid " CU offset: %6\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:5544 +#, fuzzy, c-format +msgid " Address size: %6\n" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:5555 +#, fuzzy, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr " establecer archivo a %\n" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr "" + +#: src/readelf.c:5654 +#, fuzzy, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "no se ha podido obtener contenido de .debug_ranges: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, fuzzy, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, fuzzy, c-format +msgid " Offset entries: %8\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr "" + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr "" + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr "" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, fuzzy, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " Propietario Tamaño\n" + +#: src/readelf.c:5823 +#, fuzzy, c-format +msgid "invalid range list data" +msgstr "datos inválidos" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "no se ha podido obtener contenido de .debug_ranges: %s" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:6097 src/readelf.c:9719 +#, fuzzy +msgid "base address" +msgstr "Establecer dirección a %s\n" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, fuzzy, c-format +msgid " [%6tx] empty list\n" +msgstr " [%6tx] lista vacía\n" + +#: src/readelf.c:6367 +#, fuzzy +msgid " \n" +msgstr " \n" + +#: src/readelf.c:6624 +#, fuzzy, c-format +msgid "cannot get ELF: %s" +msgstr "no se puede leer encabezamiento ELF: %s" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Sección de información de marco de llamada [%2zu] '%s' en compensación " +"%#:\n" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" +"\n" +" [%6tx] Terminator cero\n" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, c-format +msgid "invalid augmentation length" +msgstr "longitud de aumento inválida" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "Codificación de dirección FDE:" + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "Codificación de puntero LSDA:" + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr " (compensación: %#)" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr "Puntero %-26sLSDA: %#\n" + +#: src/readelf.c:7053 +#, fuzzy, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "No se puede obtener código de atributo: %s" + +#: src/readelf.c:7063 +#, fuzzy, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "No se puede obtener forma de atributo: %s" + +#: src/readelf.c:7085 +#, fuzzy, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "No se puede obtener valor: %s" + +#: src/readelf.c:7415 +#, fuzzy, c-format +msgid "invalid file (%): %s" +msgstr "Archivo inválido" + +#: src/readelf.c:7419 +#, fuzzy, c-format +msgid "no srcfiles for CU [%]" +msgstr " establecer archivo a %\n" + +#: src/readelf.c:7423 +#, fuzzy, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "no se puede leer encabezamiento ELF: %s" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %#:\n" +" [Offset]\n" + +#: src/readelf.c:7788 +#, fuzzy, c-format +msgid "cannot get next unit: %s" +msgstr "No se puede obtener próximo DIE: %s" + +#: src/readelf.c:7808 +#, fuzzy, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" +"Tipo de unidad al compensar %:\n" +" Versión: %, Abreviación de sección de compensación: %, " +"Tamaño de dirección: %, Tamaño de compensación: %\n" +" Tipo de firma: %#, Tipo de compensación: %#\n" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +"Unidad de compilación en compensación %:\n" +" Versión: %, Compensación de sección de abreviatura: %, " +"Tamaño de dirección: %, Tamaño de compensación: %\n" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr "" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "no se puede obtener DIE en compensación: %s" + +#: src/readelf.c:7895 +#, fuzzy, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "" +"no se ha podido obtener etiqueta de DIE en compensación% en sección " +"'%s': %s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "No se puede obtener próximo DIE: %s\n" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "No se puede obtener próximo DIE: %s" + +#: src/readelf.c:7985 +#, fuzzy, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +"Unidad de compilación en compensación %:\n" +" Versión: %, Compensación de sección de abreviatura: %, " +"Tamaño de dirección: %, Tamaño de compensación: %\n" + +#: src/readelf.c:8037 +#, fuzzy, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %#:\n" + +#: src/readelf.c:8369 +#, fuzzy, c-format +msgid "unknown form: %s" +msgstr "Forma % desconocida" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "No se puede obtener sección de datos de línea: %s" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, fuzzy, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" +"\n" +" Longitud: %\n" +" Versión DWARF: %\n" +" Longitud de prólogo: %\n" +" Longitud de instrucción mínima: %\n" +" Máximo operaciones por instrucción: %\n" +" Valor inicial si '%s': %\n" +" Base de línea: %\n" +" Rango de línea: %\n" +" Base de código operativo: %\n" +"\n" +"Códigos operativos:\n" + +#: src/readelf.c:8524 +#, fuzzy, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "no se puede obtener versión de símbolo: %s" + +#: src/readelf.c:8532 +#, fuzzy, c-format +msgid "cannot handle address size: %u\n" +msgstr "no hay valor de dirección" + +#: src/readelf.c:8540 +#, fuzzy, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "No se puede encontrar la sección: %s" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "datos inválidos en compensación %tu en sección [%zu] '%s'" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] " [%*] argumento %hhu \n" +msgstr[1] " [%*] argumento %hhu\n" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" +"\n" +"Tabla de Directorio:" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, fuzzy, c-format +msgid " [" +msgstr " %s: %s\n" + +#: src/readelf.c:8653 +#, fuzzy +msgid "" +"\n" +"File name table:" +msgstr "" +"\n" +" Tabla de sitio de llamada:" + +#: src/readelf.c:8714 +#, fuzzy +msgid " Entry Dir Time Size Name" +msgstr "" +"\n" +"Tabla de nombre de archivo:\n" +" Directorio de entrada Tiempo Tamaño Nombre" + +#: src/readelf.c:8753 +#, fuzzy +msgid "" +"\n" +"No line number statements." +msgstr "" +"\n" +" Declaraciones de número de Línea:" + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" +"\n" +" Declaraciones de número de Línea:" + +#: src/readelf.c:8777 +#, fuzzy, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "longitud mínima inválida de tamaño de cadena coincidente" + +#: src/readelf.c:8811 +#, fuzzy, c-format +msgid " special opcode %u: address+%u = " +msgstr " opcode especial %u: dirección+%u = %s, línea%+d = %zu\n" + +#: src/readelf.c:8815 +#, fuzzy, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr "" +" opcode especial %u: dirección+%u = %s, op_index = %u, línea%+d = %zu\n" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr "" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr " Código operativo extendido %u: " + +#: src/readelf.c:8841 +#, fuzzy +msgid " end of sequence" +msgstr "Fin de secuencia" + +#: src/readelf.c:8859 +#, fuzzy, c-format +msgid " set address to " +msgstr "Establecer dirección a %s\n" + +#: src/readelf.c:8887 +#, fuzzy, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr "" +"definir nuevo archivo: dir=%u, mtime=%, longitud=%, nombre=" +"%s\n" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr " establecer discriminador a %u\n" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +#, fuzzy +msgid " unknown opcode" +msgstr "código operativo desconocido " + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr "Copiar" + +#: src/readelf.c:8929 +#, fuzzy, c-format +msgid " advance address by %u to " +msgstr "Dirección de avance por %u a %s\n" + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr "" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr " línea de avance por la constante %d a %\n" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr " establecer archivo a %\n" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr " Establecer columna a %\n" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr "Establecer '%s' a %\n" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr "Establecer bandera de bloque básico" + +#: src/readelf.c:8990 +#, fuzzy, c-format +msgid " advance address by constant %u to " +msgstr "Dirección de avance por constante %u a %s\n" + +#: src/readelf.c:9010 +#, fuzzy, c-format +msgid " advance address by fixed value %u to \n" +msgstr "dirección de avance por valor corregido %u a %s\n" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr " Establecer bandera prologue_end" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr " Establecer bandera epilogue_begin" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr " establecer isa para %u\n" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] " opcódigo con parámetro % desconocido:" +msgstr[1] " opcódigo con parámetros % desconocido:" + +#: src/readelf.c:9084 +#, fuzzy, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "no es posible obtener contenido de .debug_loc: %s" + +#: src/readelf.c:9250 +#, fuzzy, c-format +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9290 +#, fuzzy, c-format +msgid "invalid loclists data" +msgstr "datos inválidos" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "no es posible obtener contenido de .debug_loc: %s" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "no es posible obtener datos de la sección de macro información: %s" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "%*s*** cadena no finalizada al final de la sección" + +#: src/readelf.c:9914 +#, fuzzy, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "%*s*** cadena no finalizada al final de la sección" + +#: src/readelf.c:10015 +#, fuzzy, c-format +msgid " Offset: 0x%\n" +msgstr " Propietario Tamaño\n" + +#: src/readelf.c:10027 +#, fuzzy, c-format +msgid " Version: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr "" + +#: src/readelf.c:10040 +#, fuzzy, c-format +msgid " Flag: 0x%" +msgstr " Dirección de punto de entrada: %#\n" + +#: src/readelf.c:10069 +#, fuzzy, c-format +msgid " Offset length: %\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10077 +#, fuzzy, c-format +msgid " .debug_line offset: 0x%\n" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:10102 +#, fuzzy, c-format +msgid " extension opcode table, % items:\n" +msgstr " opcódigo con parámetro % desconocido:" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr "" + +#: src/readelf.c:10121 +#, fuzzy, c-format +msgid " % arguments:" +msgstr " [%*] argumento %hhu \n" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr "" + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr "" +" Compensación [%5d] DIE: %6, Compensación CU DIE: %6, " +"nombre: %s\n" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %#:\n" +" %*s String\n" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "" + +#: src/readelf.c:10396 +#, fuzzy, c-format +msgid " *** error, missing string terminator\n" +msgstr " *** error en lectura de cadenas: %s\n" + +#: src/readelf.c:10425 +#, fuzzy, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "no se pueden obtener datos de sección: %s" + +#: src/readelf.c:10524 +#, fuzzy, c-format +msgid " Length: %8\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10526 +#, fuzzy, c-format +msgid " Offset size: %8\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10540 +#, fuzzy, c-format +msgid " DWARF version: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:10549 +#, fuzzy, c-format +msgid " Padding: %8\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" +"\n" +"Sección de tabla de búsqueda de marco de llamada [%2zu] '.eh_frame_hdr':\n" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" +"\n" +"Excepción en el manejo de la sección de tabla [%2zu] '.gcc_except_table':\n" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr "Codificación LPStart: %#x " + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr "Codificación TType: %#x " + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr "Codificación de sitio de llamada: %#x " + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" +"\n" +" Tabla de sitio de llamada:" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "Codificación TType inválida" + +#: src/readelf.c:10882 +#, fuzzy, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %# contiene entrada %zu:\n" + +#: src/readelf.c:10911 +#, fuzzy, c-format +msgid " Version: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:10929 +#, fuzzy, c-format +msgid " CU offset: %#\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10936 +#, fuzzy, c-format +msgid " TU offset: %#\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10943 +#, fuzzy, c-format +msgid " address offset: %#\n" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:10950 +#, fuzzy, c-format +msgid " symbol offset: %#\n" +msgstr " (compensación: %#)" + +#: src/readelf.c:10957 +#, fuzzy, c-format +msgid " constant offset: %#\n" +msgstr " (fin de compensación: %#)" + +#: src/readelf.c:10971 +#, fuzzy, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %# contiene entrada %zu:\n" + +#: src/readelf.c:10996 +#, fuzzy, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %# contiene entrada %zu:\n" + +#: src/readelf.c:11025 +#, fuzzy, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +"Sección DWARF [%2zu] '%s' en compensación %# contiene entrada %zu:\n" + +#: src/readelf.c:11057 +#, fuzzy, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" +"\n" +"Tabla de símbolos inválida en compensación %#0\n" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "no se puede depurar descriptor de contexto: %s" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "no es posible convertir datos de la nota principal: %s" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" +"\n" +"%*s... ..." + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr " Owner Data size Type\n" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr " %-13.*s %9 %s\n" + +#: src/readelf.c:12518 +#, fuzzy, c-format +msgid "cannot get content of note: %s" +msgstr "no se puede obtener el contenido de sección de nota: %s" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Sección de nota [%2zu] '%s' de % bytes en compensación %#0:\n" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Segmento de nota de % bytes en compensación %#0:\n" + +#: src/readelf.c:12622 +#, fuzzy, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" +"\n" +"Sección [%Zu] '%s' no tiene datos para volcar.\n" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, fuzzy, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "no se pueden obtener datos para sección [%Zu] '%s': %s" + +#: src/readelf.c:12654 +#, fuzzy, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" +"\n" +"Volcado Hex de sección [%Zu] '%s', % bytes en compensación " +"%#0:\n" + +#: src/readelf.c:12659 +#, fuzzy, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" +"\n" +"Volcado Hex de sección [%Zu] '%s', % bytes en compensación " +"%#0:\n" + +#: src/readelf.c:12673 +#, fuzzy, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" +"\n" +"Sección [%Zu] '%s' no tiene datos para volcar.\n" + +#: src/readelf.c:12705 +#, fuzzy, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" +"\n" +"Sección de cadena [%Zu] '%s' contiene % bytes en compensación " +"%#0:\n" + +#: src/readelf.c:12710 +#, fuzzy, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" +"\n" +"Sección de cadena [%Zu] '%s' contiene % bytes en compensación " +"%#0:\n" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" +"\n" +"sección [%lu] no existe" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" +"\n" +"sección '%s' no existe" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "no se puede obtener el índice de símbolo de archivo '%s': %s" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" +"\n" +"Archivo '%s' no tiene índice de símbolo\n" + +#: src/readelf.c:12853 +#, fuzzy, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" +"\n" +"Índice de archivo '%s' tiene %Zu entradas:\n" + +#: src/readelf.c:12871 +#, fuzzy, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "no es posible extraer miembro en compensación %Zu en '%s': %s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "Miembro de archivo contiene '%s':\n" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" +"Utilice el formato de salida FORMAT. FORMAT puede ser tanto `bsd' como " +"`sysv'. El establecido por defecto es `bsd'" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "lo mismo que `--format=sysv'" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "lo mismo que `--format=bsd'" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "lo mismo que `--radix=10'" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "lo mismo que `--radix=8'" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "lo mismo que`--radix=16'" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "Similar a la salida `--format=sysv' pero en una sola línea" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "" +"Imprime el tamaño y las marcas de permiso para los segmentos que pueden ser " +"cargados" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "Muestra el tamaño total (bsd solamente)" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "Lista los tamaños de sección de FICHEROS (por defecto a.out). " + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "Formato de archivo inválido: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "Radical inválido: %s" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "%s: No se reconoce el formato del fichero" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr " (ex %s)" + +#: src/size.c:420 +#, fuzzy +#| msgid "invalid section" +msgctxt "sysv" +msgid "section" +msgstr "sección inválida" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "" + +#: src/size.c:482 +#, fuzzy, c-format +msgid "cannot get section header" +msgstr "no se puede obtener encabezamiento de sección\n" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "(TOTALES)\n" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "" + +#: src/stack.c:493 +#, fuzzy, c-format +msgid "Cannot open core file '%s'" +msgstr "Imposible abrir el archivo '%s'" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "" + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "" + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "" + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "" + +#: src/stack.c:645 +#, fuzzy +msgid "Show stack of process PID" +msgstr "No se puede crear el árbol de búsqueda" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "" + +#: src/stack.c:652 +msgid "Output selection options:" +msgstr "Opciones de selección de salida:" + +#: src/stack.c:654 +#, fuzzy +msgid "Additionally show frame activation" +msgstr "Selección de salida adicional:" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "" + +#: src/stack.c:663 +#, fuzzy +msgid "Additionally show source file information" +msgstr "Selección de salida adicional:" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "" + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "Selección de salida:" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "Explorar todo el archivo, no sólo las secciones cargadas" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "Sólo secuencias NUL-terminated de caracteres MIN-LEN o más se imprimen" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" +"Seleccionar tamaño de caracter y Endianess: s = 7-bit, S = 8-bit, {b,l} = 16-" +"bit, {B,L} = 32-bit" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "Imprimir nombre de archivo antes de cada cadena." + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "Imprimir ubicación de la cadena en base 8, 10, o 16 respectivamente." + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "Alias para --radix=o" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "Imprimir las cadenas de caracteres imprimibles en archivos." + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "Valor inválido '%s' para parámetro %s" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "longitud mínima inválida de tamaño de cadena coincidente" + +#: src/strings.c:585 +#, fuzzy, c-format +msgid "lseek failed" +msgstr "lseek64 falló" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "re-mmap falló" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "mprotect falló" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "Colocar la salida obtenida en FICHERO" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "Extraer secciones eliminadas en FICHERO" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "Incorporar nombre FILE en lugar de argumento -f" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "Elimina todos los símbolos de depuración" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "Quitar sección de cabeceras (no recomendado)" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "Copiar marcas de tiempo modificadas/acceso a la salida" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "Quitar sección de comentario" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "Descarta símbolos de archivos objeto." + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "Sólo se permite ingresar un archivo junto con '-o' y '-f'" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "opción -f especificada dos veces" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "opción -F especificada dos veces" + +#: src/strip.c:362 +#, fuzzy, c-format +msgid "cannot both keep and remove .comment section" +msgstr "Quitar sección de comentario" + +#: src/strip.c:481 +#, fuzzy, c-format +msgid "bad relocation" +msgstr "Mostrar reubicaciones" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "no sepuede stat fichero de entrada '%s'" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "mientras se abría '%s'" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "%s: no puede utilizarse -o o -f cuando se extrae un archivo" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, fuzzy, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: no puede utilizarse -o o -f cuando se extrae un archivo" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "No se puede abrir el segundo plano EBL" + +#: src/strip.c:1092 +#, fuzzy, c-format +msgid "cannot get number of phdrs" +msgstr "no se pudo determinar la cantidad de encabezados de programa: %s" + +#: src/strip.c:1106 src/strip.c:1149 +#, fuzzy, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "no se puede crear fichero nuevo '%s': %s" + +#: src/strip.c:1116 src/strip.c:1159 +#, fuzzy, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "no se puede crear fichero nuevo '%s': %s" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "Fichero illformed '%s'" + +#: src/strip.c:1250 +#, fuzzy, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "No se puede asignar sección PLT: %s" + +#: src/strip.c:1259 +#, fuzzy, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "No se puede añadir nueva sección: %s" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "al generar fichero de salida: %s" + +#: src/strip.c:1688 +#, fuzzy, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "%s: error al crear encabezamiento ELF: %s" + +#: src/strip.c:1697 +#, fuzzy, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "%s: error al crear encabezamiento ELF: %s" + +#: src/strip.c:1705 src/strip.c:2550 +#, fuzzy, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "%s: error al crear encabezamiento ELF: %s" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "al preparar salida para '%s'" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "al crear sección de encabezamiento de sección: %s" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "no se puede asignar espacio para los datos: %s" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "al crear tabla de cadenas de encabezamiento de sección: %s" + +#: src/strip.c:1866 +#, fuzzy, c-format +msgid "no memory to create section header string table" +msgstr "al crear tabla de cadenas de encabezamiento de sección: %s" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "al escribir '%s': %s" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "al crear '%s'" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "al computar la suma de verificación para información de depuración" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "%s: error al crear encabezamiento ELF: %s" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "%s: error al leer el fichero: %s" + +#: src/strip.c:2599 src/strip.c:2619 +#, c-format +msgid "while writing '%s'" +msgstr "al escribir '%s'" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "Error al terminar '%s': %s" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "no es posible establecer acceso y fecha de modificación de '%s'" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "Coincidir MODULO con nombres de archivo, no con nombres de módulo" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "Omitir silenciosamente los archivos perdidos" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "Colocar salida en FICHERO" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "Crear archivos de salida múltiple bajo DIRECTORIO" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "Usar módulo en lugar de nombres de archivo" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "" +"Crear salida para módulos que no tienen información de depuración " +"independiente" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "Aplicar reubicaciones a contenido de sección en archivos ET_REL" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "Solamente listar módulo y nombres de archivo, crear los ID" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "opción -d especificada dos veces" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "Sólo se permite usar -o ó -d " + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "-n no puede utilizarse con archivos explícitos o con -o ó -d" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "Directorio de salida '%s'" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "dos argumentos de archivos se requieren exactamente" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "No se permiten las opciones -m, -a, -R, ni -i con archivos explícitos" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "se requiere -o ó -d cuando se utilizan archivos implícitos" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "no se puede crear el encabezamiento ELF: %s" + +#: src/unstrip.c:240 +#, fuzzy, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "No se puede encontrar la sección: %s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "no se puede leer encabezamiento ELF: %s" + +#: src/unstrip.c:254 +#, fuzzy, c-format +msgid "cannot get new zero section: %s" +msgstr "No se puede encontrar la sección: %s" + +#: src/unstrip.c:257 +#, fuzzy, c-format +msgid "cannot update new zero section: %s" +msgstr "no se puede actualizar reubicación: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "no se puede copiar encabezamiento ELF: %s" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, fuzzy, c-format +msgid "cannot get number of program headers: %s" +msgstr "no se pudo determinar la cantidad de encabezados de programa: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "No pueden crear encabezamientos de programa: %s" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "no puede copiar encabezamiento de programa: %s" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "no se puede copiar encabezamiento de sección: %s" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "no se pueden obtener datos de sección: %s" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "no pueden copiar datos de sección: %s" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "no se puede crear el directorio '%s'" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "no se puede obtener entrada de tabla de símbolos: %s" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "no se puede actualizar tabla de símbolos: %s" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "no se puede actualizar encabezamiento de sección: %s" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "no se puede actualizar reubicación: %s" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "no se puede obtener versión de símbolo: %s" + +#: src/unstrip.c:593 +#, fuzzy, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "tipo de sección inesperado en [%Zu] con sh_link para symtab" + +#: src/unstrip.c:848 +#, fuzzy, c-format +msgid "cannot get symbol section data: %s" +msgstr "no se pueden obtener datos de sección: %s" + +#: src/unstrip.c:850 +#, fuzzy, c-format +msgid "cannot get string section data: %s" +msgstr "no se pueden obtener datos de sección: %s" + +#: src/unstrip.c:867 +#, fuzzy, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "compensación de cadena inválida en símbolo [%Zu]" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, fuzzy, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "no se puede leer nombre [%Zu]: %s" + +#: src/unstrip.c:1040 +#, fuzzy, c-format +msgid "bad sh_link for group section: %s" +msgstr ".debug_line section inválida" + +#: src/unstrip.c:1046 +#, fuzzy, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "No se puede obtener encabezamiento de sección 0th: %s" + +#: src/unstrip.c:1051 +#, fuzzy, c-format +msgid "bad data for group symbol section: %s" +msgstr "no se puede obtener sección para símbolos\n" + +#: src/unstrip.c:1057 +#, fuzzy, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "no se puede obtener versión de símbolo: %s" + +#: src/unstrip.c:1062 +#, fuzzy, c-format +msgid "bad symbol name for group section: %s" +msgstr "No se puede obtener el encabezamiento de sección %zu: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, fuzzy, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "no se puede hallar sección coincidente para [%Zu] '%s'" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "no se puede leer sección '.gnu.prelink_undo': %s" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "contenido inválido en sección '%s'" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "no se puede añadir nombre de sección a tabla de cadenas: %s" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "" +"no se pueden actualizar datos de tabla de cadenas de encabezamiento de " +"sección: %s" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "" +"no se puede obtener índice de sección de tabla de cadenas de encabezamiento " +"de sección: %s" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "No se puede obtener cuenta de sección: %s" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "" +"más secciones en el archivo despojado que en el archivo de depuración -- " +"¿argumentos invertidos?" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "no se puede obtener tabla de cadenas de encabezamiento de sección: %s" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "No se puede añadir nueva sección: %s" + +#: src/unstrip.c:1758 +#, fuzzy, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "símbolo [%Zu] tiene índice de sección inválido" + +#: src/unstrip.c:1790 +#, fuzzy, c-format +msgid "group has invalid section index [%zd]" +msgstr "símbolo [%Zu] tiene índice de sección inválido" + +#: src/unstrip.c:2065 +#, c-format +msgid "cannot read section data: %s" +msgstr "no se puede leer la sección de datos: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "No se puede actualizar encabezamiento ELF: %s" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "no se puede actualizar encabezamiento de programa: %s" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "no se puede escribir al archivo de salida: %s" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"datos DWARF no se ajustan para polarización de pre-enlace; considere prelink " +"-u" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"Datos DWARF en '%s' no se ajustan a polarización de pre-enlace; considere " +"prelink -u" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "no se puede crear un descriptor ELF: %s" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "" + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr "" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "no se puede hallar archivo obtenido para módulo '%s': %s " + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "No se puede abrir el archivo '%s' obtenido para módulo '%s': %s" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "no puede hallar archivo de depuración para módulo '%s': %su" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "No puede abrir archivo de depuración '%s' para módulo '%s': %s" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "No se obtuvo el archivo '%s' de módulo '%s' " + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "" +"No puede almacenar en cache direcciones de sección para módulo '%s': %s" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "No se encontraron módulos coincidentes" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "coincidió con más de un módulo" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" + +#: src/unstrip.c:2561 +#, fuzzy +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "" + +#: tests/dwflmodtest.c:209 +#, fuzzy +msgid "Additionally show function names" +msgstr "También mostrar nombres de función" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "" + +#, fuzzy +#~ msgid "" +#~ " [%6tx] base address\n" +#~ " " +#~ msgstr " [%6tx] (dirección base) %s\n" + +#, fuzzy +#~ msgid "%s: error getting zero section: %s" +#~ msgstr "%s: error al leer el fichero: %s" + +#, fuzzy +#~ msgid "%s: error while updating zero section: %s" +#~ msgstr "%s: error al leer el fichero: %s" + +#~ msgid "%s+%# <%s+%#>" +#~ msgstr "%s+%# <%s+%#>" + +#~ msgid "%s+%#0* <%s+%#>" +#~ msgstr "%s+%#0* <%s+%#>" + +#~ msgid "%# <%s+%#>" +#~ msgstr "%# <%s+%#>" + +#~ msgid "%#0* <%s+%#>" +#~ msgstr "%#0* <%s+%#>" + +#~ msgid "%s+%# <%s>" +#~ msgstr "%s+%# <%s>" + +#~ msgid "%s+%#0* <%s>" +#~ msgstr "%s+%#0* <%s>" + +#~ msgid "%# <%s>" +#~ msgstr "%# <%s>" + +#~ msgid "%#0* <%s>" +#~ msgstr "%#0* <%s>" + +#~ msgid "%s+%#" +#~ msgstr "%s+%#" + +#~ msgid "%s+%#0*" +#~ msgstr "%s+%#0*" + +#, fuzzy +#~ msgid " %s..%s (%)\n" +#~ msgstr " %s: %\n" + +#, fuzzy +#~ msgid " %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#, fuzzy +#~ msgid " advance address by %u to %s, op_index to %u\n" +#~ msgstr "dirección avanzada por %u a %s, op_index a %u\n" + +#, fuzzy +#~ msgid " advance address by constant %u to %s, op_index to %u\n" +#~ msgstr "dirección avanzada por constante %u a %s, op_index a %u\n" + +#~ msgid " [%6tx] %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#~ msgid " %s..%s\n" +#~ msgstr " %s..%s\n" + +#~ msgid "cannot get DIE at offset % in section '%s': %s" +#~ msgstr "" +#~ "no se puede obtener DIE en compensación % en sección '%s': %s" + +#~ msgid " [%6tx] %s..%s" +#~ msgstr " [%6tx] %s..%s" + +#~ msgid " %s..%s" +#~ msgstr " %s..%s" + +#~ msgid "-R option supports only .comment section" +#~ msgstr "la opción -R soporta únicamente. sección de comentario" + +#~ msgid "Written by %s.\n" +#~ msgstr "Escrito por %s.\n" + +#~ msgid "cannot allocate PLTREL section: %s" +#~ msgstr "No se puede asignar sección PLTREL: %s" + +#~ msgid "cannot allocate GOT section: %s" +#~ msgstr "No se puede asignar sección GOT: %s" + +#~ msgid "cannot allocate GOTPLT section: %s" +#~ msgstr "No se puede asignar sección GOTPLT: %s" + +#~ msgid "initial-executable TLS relocation cannot be used " +#~ msgstr "Reubicación TLS ejecutable-inicial no se puede utilizar" + +#~ msgid "Input File Control:" +#~ msgstr "Control de fichero de entrada:" + +#~ msgid "Include whole archives in the output from now on." +#~ msgstr "A partir de ahora incluye archivos completos en la salida." + +#~ msgid "Stop including the whole archives in the output." +#~ msgstr "Deja de incluir archivos completos en la salida." + +#~ msgid "FILE" +#~ msgstr "FICHERO" + +#~ msgid "Start a group." +#~ msgstr "Inicia un grupo" + +#~ msgid "End a group." +#~ msgstr "Termina un grupo." + +#~ msgid "PATH" +#~ msgstr "RUTA" + +#~ msgid "Add PATH to list of directories files are searched in." +#~ msgstr "" +#~ "Agrega RUTA a la lista de los directorios en los que se realiza la " +#~ "búsqueda." + +#~ msgid "Only set DT_NEEDED for following dynamic libs if actually used" +#~ msgstr "" +#~ "Sólo se define DT_NEEDED para las siguientes bibliotecas dinámicas, si " +#~ "están siendo utilizadas" + +#~ msgid "Always set DT_NEEDED for following dynamic libs" +#~ msgstr "" +#~ "Siempre establece DT_NEEDED para las siguientes bibliotecas dinámicas" + +#~ msgid "Ignore LD_LIBRARY_PATH environment variable." +#~ msgstr "Ignora la variable de entorno LD_LIBRARY_PATH." + +#~ msgid "Output File Control:" +#~ msgstr "Control de fichero de salida:" + +#~ msgid "Place output in FILE." +#~ msgstr "Coloca salida en FICHERO." + +#~ msgid "Object is marked to not use default search path at runtime." +#~ msgstr "" +#~ "Objeto está marcado para no usar ruta de búsqueda predeterminada en " +#~ "tiempo de ejecución." + +#~ msgid "Same as --whole-archive." +#~ msgstr "Lo mismo que --whole-archive." + +#~ msgid "" +#~ "Default rules of extracting from archive; weak references are not enough." +#~ msgstr "" +#~ "Reglas establecidas por defecto para extraer desde el archivo; las " +#~ "referencias débiles no son suficientes." + +#~ msgid "Weak references cause extraction from archive." +#~ msgstr "Referencias débiles causan extracción del archivo." + +#~ msgid "Allow multiple definitions; first is used." +#~ msgstr "Permite definiciones múltiples; se utiliza la primera." + +#~ msgid "Disallow/allow undefined symbols in DSOs." +#~ msgstr "Habilita/inhabilita símbolos indefinidos en los DSO." + +#~ msgid "Object requires immediate handling of $ORIGIN." +#~ msgstr "Los objetos requieren manipulación inmediata de $ORIGIN." + +#~ msgid "Relocation will not be processed lazily." +#~ msgstr "La reubicación no se procesará de forma perezosa." + +#~ msgid "Object cannot be unloaded at runtime." +#~ msgstr "El objeto no se puede descargar en tiempo de ejecución." + +#~ msgid "Mark object to be initialized first." +#~ msgstr "Marcar objeto a ser inicializado primero." + +#~ msgid "Enable/disable lazy-loading flag for following dependencies." +#~ msgstr "" +#~ "Activar/desactivar marca lazy-loading para las siguientes dependencias." + +#~ msgid "Mark object as not loadable with 'dlopen'." +#~ msgstr "Marcar el objeto como no cargable con 'dlopen'" + +#~ msgid "Ignore/record dependencies on unused DSOs." +#~ msgstr "Ignorar/registrar dependencias sobre DSO no utilizados." + +#~ msgid "Generated DSO will be a system library." +#~ msgstr "El DSO generado será una biblioteca del sistema." + +#~ msgid "ADDRESS" +#~ msgstr "DIRECCIÓN" + +#~ msgid "Set entry point address." +#~ msgstr "Establecer dirección de entrada de punto" + +#~ msgid "Do not link against shared libraries." +#~ msgstr "No enlazar con bibliotecas compartidas." + +#~ msgid "Prefer linking against shared libraries." +#~ msgstr "No enlazar con bibliotecas compartidas." + +#~ msgid "Export all dynamic symbols." +#~ msgstr "Exportar todos los símbolos dinámicos." + +#~ msgid "Strip all symbols." +#~ msgstr "Descartar todos los símbolos." + +#~ msgid "Strip debugging symbols." +#~ msgstr "Descartar los símbolos de depuración." + +#~ msgid "Assume pagesize for the target system to be SIZE." +#~ msgstr "Asumir que pagesize para el sistema de destino sea SIZE." + +#~ msgid "Set runtime DSO search path." +#~ msgstr "Establecer la ruta de búsqueda tiempo de ejecución DSO." + +#~ msgid "Set link time DSO search path." +#~ msgstr "Establecer ruta de tiempo de enlace DSO." + +#~ msgid "Generate dynamic shared object." +#~ msgstr "Generar objeto compartido dinámico." + +#~ msgid "Generate relocatable object." +#~ msgstr "Generar objeto reubicable" + +#~ msgid "Causes symbol not assigned to a version be reduced to local." +#~ msgstr "" +#~ "Hacer que un símbolo no asignado a una versión sea reducido a local." + +#~ msgid "Remove unused sections." +#~ msgstr "Eliminar las secciones no utilizadas." + +#~ msgid "Don't remove unused sections." +#~ msgstr "No eliminar las secciones no utilizadas." + +#~ msgid "Set soname of shared object." +#~ msgstr "Establecer soname de objeto compartido." + +#~ msgid "Set the dynamic linker name." +#~ msgstr "Establecer el nombre de enlazador dinámico." + +#~ msgid "Add/suppress addition indentifying link-editor to .comment section." +#~ msgstr "" +#~ "Añadir/suprimir adición identificando enlace-editor para .sección de " +#~ "comentario." + +#~ msgid "Create .eh_frame_hdr section" +#~ msgstr "Crear una sección .eh_frame_hdr" + +#~ msgid "Set hash style to sysv, gnu or both." +#~ msgstr "Establecer el estilo de dispersión un sysv, gnu o ambos." + +#~ msgid "Generate build ID note (md5, sha1 (default), uuid)." +#~ msgstr "" +#~ "Crear una nota del ID de compilación (md5, sha1 (por defecto), uuid)." + +#~ msgid "Linker Operation Control:" +#~ msgstr "Control de volumen desconocido:" + +#~ msgid "Verbose messages." +#~ msgstr "Mensajes explicativos." + +#~ msgid "Trace file opens." +#~ msgstr "Rastrear apertura de ficheros." + +#~ msgid "Trade speed for less memory usage" +#~ msgstr "Intercambiar velocidad por menor utilización de memoria" + +#~ msgid "LEVEL" +#~ msgstr "NIVEL" + +#~ msgid "Set optimization level to LEVEL." +#~ msgstr "Establecer el nivel de optimización a LEVEL." + +#~ msgid "Use linker script in FILE." +#~ msgstr "Usar script enlazador en FICHERO." + +#~ msgid "Select to get parser debug information" +#~ msgstr "Seleccionar para obtener análisis de información de depuración" + +#~ msgid "Read version information from FILE." +#~ msgstr "Leer información de versión de FICHERO." + +#~ msgid "Set emulation to NAME." +#~ msgstr "Establecer emulación a NOMBRE." + +#~ msgid "Combine object and archive files." +#~ msgstr "Combinar objeto y archivos de almacenamiento." + +#~ msgid "[FILE]..." +#~ msgstr "[FICHERO]..." + +#~ msgid "At least one input file needed" +#~ msgstr "Se necesita al menos un fichero de entrada" + +#~ msgid "error while preparing linking" +#~ msgstr "Error al preparar vinculación" + +#~ msgid "cannot open linker script '%s'" +#~ msgstr "no se puede abrir script enlazador '%s'" + +#~ msgid "-( without matching -)" +#~ msgstr "-( sin coincidir -)" + +#~ msgid "only one option of -G and -r is allowed" +#~ msgstr "Solamente una opción de -G y -r es permitida" + +#~ msgid "more than one '-m' parameter" +#~ msgstr "más de un parámetro '-m'" + +#~ msgid "unknown option `-%c %s'" +#~ msgstr "opción desconocida `-%c %s'" + +#~ msgid "invalid hash style '%s'" +#~ msgstr "estilo de dispersión inválido '%s'" + +#~ msgid "invalid build-ID style '%s'" +#~ msgstr "estilo de cuerpo-ID inválido '%s'" + +#~ msgid "Invalid optimization level `%s'" +#~ msgstr "Nivel de optimización inválido `%s'" + +#~ msgid "nested -( -) groups are not allowed" +#~ msgstr "no se permiten grupos -( -) en nido" + +#~ msgid "-) without matching -(" +#~ msgstr "-) sin coincidir -(" + +#~ msgid "unknown option '-%c %s'" +#~ msgstr "Opción desconocida '-%c %s'" + +#~ msgid "could not find input file to determine output file format" +#~ msgstr "" +#~ "no se pudo encontrar un archivo de entrada que determine el formato del " +#~ "archivo de salida" + +#~ msgid "try again with an appropriate '-m' parameter" +#~ msgstr "Inténtelo con una parámetro '-m' apropiado" + +#~ msgid "cannot read version script '%s'" +#~ msgstr "No se puede leer script de versión '%s'" + +#~ msgid "duplicate definition of '%s' in linker script" +#~ msgstr "Duplicar definición de '%s' en script enlazador" + +#~ msgid "cannot create string table" +#~ msgstr "no puede crear tabla de cadenas" + +#~ msgid "cannot load ld backend library '%s': %s" +#~ msgstr "no se puede cargar biblioteca ID de segundo plano '%s': %s" + +#~ msgid "cannot find init function in ld backend library '%s': %s" +#~ msgstr "" +#~ "no se pudo encontrar la función init en la biblioteca ld de segundo plano " +#~ "'%s': %s" + +#~ msgid "%s listed more than once as input" +#~ msgstr "%s listado más de una vez como entrada" + +#~ msgid "%s (for -l%s)\n" +#~ msgstr "%s (para -l%s)\n" + +#~ msgid "%s (for DT_NEEDED %s)\n" +#~ msgstr "%s (para DT_NEEDED %s)\n" + +#~ msgid "Warning: type of `%s' changed from %s in %s to %s in %s" +#~ msgstr "Advertencia: el tipo de `%s' cambió de %s en %s a %s en %s" + +#~ msgid "" +#~ "Warning: size of `%s' changed from % in %s to % in %s" +#~ msgstr "" +#~ "Advertencia: el tamaño de `%s' cambió de % en %s a % en %s" + +#~ msgid "(%s+%#): multiple definition of %s `%s'\n" +#~ msgstr "(%s+%#): definición múltiplo de %s `%s'\n" + +#~ msgid "(%s+%#): first defined here\n" +#~ msgstr "(%s+%#): se definió primero aquí\n" + +#~ msgid "%s: cannot get section group data: %s" +#~ msgstr "%s: no se pueden obtener datos de sección de grupo: %s" + +#~ msgid "%s: section '%s' with group flag set does not belong to any group" +#~ msgstr "" +#~ "%s: la sección '%s' con bandera de grupo establecida no pertenece a " +#~ "ningún grupo" + +#~ msgid "%s: section [%2d] '%s' is not in the correct section group" +#~ msgstr "" +#~ "%s: la sección [%2d] '%s' no se encuentra en el grupo de sección correcto" + +#~ msgid "%s: invalid ELF file (%s:%d)\n" +#~ msgstr "%s: fichero ELF inválido (%s:%d)\n" + +#~ msgid "%s: only files of type ET_REL might contain section groups" +#~ msgstr "%s: solo archivos de tipo ET_REL pueden contener grupos de sección" + +#~ msgid "%s: cannot determine signature of section group [%2zd] '%s': %s" +#~ msgstr "" +#~ "%s: no es posible determinar la firma del grupo de sección [%2zd] '%s': " +#~ "%s " + +#~ msgid "%s: cannot get content of section group [%2zd] '%s': %s'" +#~ msgstr "" +#~ "%s: no es posible obtener el contenido de la sección del grupo [%2zd] " +#~ "'%s': %s'" + +#~ msgid "" +#~ "%s: group member %zu of section group [%2zd] '%s' has too high index: " +#~ "%" +#~ msgstr "" +#~ "%s el miembro del grupo %zu del grupo de sección [%2zd] '%s' posee el " +#~ "índice demasiado alto: %" + +#~ msgid "%s: section '%s' has unknown type: %d" +#~ msgstr "%s: sección '%s' tiene tipo desconocido: %d" + +#~ msgid "cannot get descriptor for ELF file (%s:%d): %s\n" +#~ msgstr "no es posible obtener descriptor para el archivo ELF (%s:%d): %s\n" + +#~ msgid "cannot read archive `%s': %s" +#~ msgstr "no se puede leer archivo `%s': %s" + +#~ msgid "file of type %s cannot be linked in\n" +#~ msgstr "archivo de tipo %s no puede ser enlazado en\n" + +#~ msgid "%s: input file incompatible with ELF machine type %s\n" +#~ msgstr "" +#~ "%s: el archivo ingresado es incompatible con una máquina ELF tipo %s\n" + +#~ msgid "%s: cannot get section header string table index: %s\n" +#~ msgstr "" +#~ "%s: no se ha podido obtener un índice para la tabla de la cadena del " +#~ "encabezamiento de la sección: %s\n" + +#~ msgid "cannot use DSO '%s' when generating relocatable object file" +#~ msgstr "" +#~ "no es posible utilizar DSO '%s' al general un archivo de objeto realojable" + +#~ msgid "input file '%s' ignored" +#~ msgstr "archivo de entrada '%s' ignorado" + +#~ msgid "undefined symbol `%s' in %s" +#~ msgstr "símbolo indefinido `%s' en %s" + +#~ msgid "cannot create ELF descriptor for output file: %s" +#~ msgstr "no es posible crear un descriptor ELF para el archivo de salida: %s" + +#~ msgid "could not create ELF header for output file: %s" +#~ msgstr "" +#~ "no es posible crear un encabezamiento ELF para el archivo de salida: %s" + +#~ msgid "cannot create section for output file: %s" +#~ msgstr "no se puede crear sección para archivo de salida: %s" + +#~ msgid "address computation expression contains variable '%s'" +#~ msgstr "la expresión de computación contiene la variable '%s'" + +#~ msgid "" +#~ "argument '%' of ALIGN in address computation expression is no " +#~ "power of two" +#~ msgstr "" +#~ "el argumento '%' de ALIGN en expresión de dirección de " +#~ "computación no es potencia de dos" + +#~ msgid "cannot find entry symbol '%s': defaulting to %#0*" +#~ msgstr "" +#~ "no se puede encontrar símbolo de entrada '%s': predeterminada para " +#~ "%#0*" + +#~ msgid "no entry symbol specified: defaulting to %#0*" +#~ msgstr "" +#~ "no se ha especificado una entrada de símbolo: estableciendo por defecto a " +#~ "%#0*" + +#~ msgid "cannot create GNU hash table section for output file: %s" +#~ msgstr "" +#~ "no se puede crear una tabla de dispersión GNU para archivo de salida: %s" + +#~ msgid "cannot create hash table section for output file: %s" +#~ msgstr "" +#~ "no es posible crear una sección para la tabla de dispersión del archivo " +#~ "de salida: %s" + +#~ msgid "cannot create build ID section: %s" +#~ msgstr "no se puede crear sección de creación de ID: %s" + +#~ msgid "cannot convert section data to file format: %s" +#~ msgstr "" +#~ "no es posible convertir los datos de la sección en formato de archivo: %s" + +#~ msgid "cannot convert section data to memory format: %s" +#~ msgstr "" +#~ "no es posible convertir datos de la sección en formato de memoria: %s" + +#~ msgid "cannot read enough data for UUID" +#~ msgstr "no es posible leer suficientes datos para el UUID" + +#~ msgid "cannot create symbol table for output file: %s" +#~ msgstr "no es posible crear tabla de símbolo para el comando de salida: %s" + +#~ msgid "section index too large in dynamic symbol table" +#~ msgstr "" +#~ "el índice de la sección es demasiado extenso en la tabla de símbolos " +#~ "dinámicos" + +#~ msgid "cannot create versioning section: %s" +#~ msgstr "no se puede crear sección de versión: %s" + +#~ msgid "cannot create dynamic symbol table for output file: %s" +#~ msgstr "" +#~ "no es posible crear tabla de símbolos dinámicos para el archivo de " +#~ "salida: %s" + +#~ msgid "cannot create versioning data: %s" +#~ msgstr "no se pueden crear datos de versión: %s" + +#~ msgid "cannot create section header string section: %s" +#~ msgstr "" +#~ "no se puede crear sección de cadenas de encabezamiento de sección: %s" + +#~ msgid "cannot create section header string section" +#~ msgstr "no se puede crear sección de cadenas de encabezamiento de sección" + +#~ msgid "cannot create program header: %s" +#~ msgstr "no se puede crear encabezamiento de programa: %s" + +#~ msgid "while determining file layout: %s" +#~ msgstr "al determinar diseño de fichero: %s" + +#~ msgid "internal error: non-nobits section follows nobits section" +#~ msgstr "error interno: sección non-nobits sigue a sección nobits" + +#~ msgid "linker backend didn't specify function to relocate section" +#~ msgstr "" +#~ "enlazador de segundo plano no especificó función para reubicar sección" + +#~ msgid "while writing output file: %s" +#~ msgstr "Ocurrió un error de fichero de salida: %s" + +#~ msgid "while finishing output file: %s" +#~ msgstr "error al cerrar el fichero de salida: %s" + +#~ msgid "cannot stat output file" +#~ msgstr "no se puede generar stat de fichero de salida" + +#~ msgid "WARNING: temporary output file overwritten before linking finished" +#~ msgstr "" +#~ "ADVERTENCIA: archivo de salida temporal sobreescrito antes que haya " +#~ "concluido el enlazamiento" + +#~ msgid "no machine specific '%s' implementation" +#~ msgstr "no hay máquina específica de implementación '%s'" + +#~ msgid "mode for segment invalid\n" +#~ msgstr "modo para segmento inválido\n" + +#~ msgid "while reading version script '%s': %s at line %d" +#~ msgstr "al leer script de versión '%s': %s en línea %d" + +#, fuzzy +#~ msgid "" +#~ "symbol '%s' is declared both local and global for unnamed version '%s'" +#~ msgstr "" +#~ "el símbolo '%s' es declarado tanto local como global para la versión sin " +#~ "nombre" + +#~ msgid "symbol '%s' is declared both local and global for version '%s'" +#~ msgstr "" +#~ "el símbolo '%s' es declarado tanto local como global para la versión '%s'" + +#~ msgid "default visibility set as local and global" +#~ msgstr "" +#~ "la visibilidad establecida por defecto establecida como local y global" + +#~ msgid "cannot get section header of section %Zu: %s" +#~ msgstr "No se puede obtener encabezamiento de sección %Zu: %s" + +#, fuzzy +#~ msgid "cannot attach to core" +#~ msgstr "No se puede crear el árbol de búsqueda" + +#~ msgid "'%s' and '%s' do not seem to match" +#~ msgstr "Al parecer '%s' y '%s'no coinciden" + +#~ msgid "unknown tag %hx" +#~ msgstr "etiqueta %hx desconocida" + +#~ msgid "unknown user tag %hx" +#~ msgstr "Usuario de etiqueta %hx desconocido " + +#~ msgid "unknown attribute %hx" +#~ msgstr "atributo de sección %hx desconocido" + +#~ msgid "unknown user attribute %hx" +#~ msgstr "Atributo de usuario desconocido %hx" + +#~ msgid "" +#~ "\n" +#~ "\n" +#~ "Symbols from %s[%s]:\n" +#~ "\n" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "Símbolos de %s[%s]:\n" +#~ "\n" + +#~ msgid "%s %s differ: section header" +#~ msgstr "%s %s differ: encabezamiento de sección" + +#~ msgid "Equivalent to: -e -h -l" +#~ msgstr "Equivalente a: -e -h -l" + +#~ msgid "zeroth section has nonzero info field\n" +#~ msgstr "Sección zeroth tiene campo de información nonzero\n" + +#~ msgid " Version String: " +#~ msgstr "Cadena versión:" + +#~ msgid "" +#~ "\n" +#~ "Section [%Zu] '%s' is empty.\n" +#~ msgstr "" +#~ "\n" +#~ "Sección [%Zu] '%s' está vacía.\n" diff --git a/po/insert-header.sin b/po/insert-header.sin new file mode 100644 index 00000000..ceeebb93 --- /dev/null +++ b/po/insert-header.sin @@ -0,0 +1,28 @@ +# Sed script that inserts the file called HEADER before the header entry. +# +# Copyright (C) 2001 Free Software Foundation, Inc. +# Written by Bruno Haible , 2001. +# This file is free software; the Free Software Foundation gives +# unlimited permission to use, copy, distribute, and modify it. +# +# At each occurrence of a line starting with "msgid ", we execute the following +# commands. At the first occurrence, insert the file. At the following +# occurrences, do nothing. The distinction between the first and the following +# occurrences is achieved by looking at the hold space. +/^msgid /{ +x +# Test if the hold space is empty. +s/m/m/ +ta +# Yes it was empty. First occurrence. Read the file. +r HEADER +# Output the file's contents by reading the next line. But don't lose the +# current line while doing this. +g +N +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/po/ja.gmo b/po/ja.gmo new file mode 100644 index 0000000000000000000000000000000000000000..d52ea8a96c62813568af9a27344134a4b4621b67 GIT binary patch literal 57859 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, 2009. +# Hyu_gabaru Ryu_ichi , 2009. +msgid "" +msgstr "" +"Project-Id-Version: ja\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2009-09-20 15:32+0900\n" +"Last-Translator: Hyu_gabaru Ryu_ichi \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" + +#: lib/color.c:194 src/objdump.c:728 +#, fuzzy, c-format +msgid "cannot allocate memory" +msgstr "PLT セクションを割り当てられません: %s" + +#: lib/printversion.c:40 +#, fuzzy, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"Copyright (C) %s Red Hat, Inc.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "メモリー消費済み" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "エラー無し" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "メモリー不足" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "出力ファイルを作成できません" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "不当なパラメーター" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "出力ファイルのモードを変更できません" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "出力ファイルの名前を変更できません" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "重複シンボル" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "操作に不当なセクションタイプ" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "データの出力中にエラー" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "バックエンドサポートが利用できません" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "不明なエラー" + +#: libcpu/i386_lex.l:122 +#, fuzzy, c-format +#| msgid "invalid page size value '%s': ignored" +msgid "invalid character '%c' at line %d; ignored" +msgstr "不当なページサイズ値 '%s': 無視しました" + +#: libcpu/i386_lex.l:123 +#, fuzzy, c-format +#| msgid "invalid page size value '%s': ignored" +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "不当なページサイズ値 '%s': 無視しました" + +#: libcpu/i386_parse.y:554 +#, fuzzy, c-format +#| msgid "while reading linker script '%s': %s at line %d" +msgid "while reading i386 CPU description: %s at line %d" +msgstr "リンカースクリプト '%1$s' 読込み中: %3$d 行目の %2$s" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "不当なアクセス" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "一般ファイルではありません" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "I/O エラー" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "不当な ELF ファイル" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "DWARF 情報がありません" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "ELF ファイルがありません" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "ELF ヘッダーを得られません" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "未実装" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "不当なコマンド" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "不当なバージョン" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "不当なファイル" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "項目が見つかりません" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "不当な DWARF" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "文字データがありません" + +#: libdw/dwarf_error.c:75 +#, fuzzy +msgid ".debug_str section missing" +msgstr ".debug_ranges セクションがありません" + +#: libdw/dwarf_error.c:76 +#, fuzzy +msgid ".debug_line_str section missing" +msgstr ".debug_line セクションがありません" + +#: libdw/dwarf_error.c:77 +#, fuzzy +msgid ".debug_str_offsets section missing" +msgstr ".debug_ranges セクションがありません" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "アドレス値ではありません" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "固定値ではありません" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "参照値がありません" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "不当な参照値" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr ".debug_line セクションがありません" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "不当な .debug_line セクション" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "デバッグ情報が大きすぎます" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "不当な DWARF バージョン" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "不当なディレクトリー索引" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "アドレスが範囲外です" + +#: libdw/dwarf_error.c:88 +#, fuzzy +msgid ".debug_loc section missing" +msgstr ".debug_line セクションがありません" + +#: libdw/dwarf_error.c:89 +#, fuzzy +msgid ".debug_loclists section missing" +msgstr ".debug_line セクションがありません" + +#: libdw/dwarf_error.c:90 +#, fuzzy +msgid "not a location list value" +msgstr "ロケーションリスト値ではありません" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "ブロックデータではありません" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "不当な行索引" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "不当なアドレス範囲索引" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "アドレス範囲に対応しません" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "フラグ値がありません" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "不当なオフセット" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr ".debug_ranges セクションがありません" + +#: libdw/dwarf_error.c:98 +#, fuzzy +msgid ".debug_rnglists section missing" +msgstr ".debug_ranges セクションがありません" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "不当な CFI セクション" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "" + +#: libdw/dwarf_error.c:101 +#, fuzzy +msgid "invalid opcode" +msgstr "不当なオペランド" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "" + +#: libdw/dwarf_error.c:103 +#, fuzzy +msgid "unknown language code" +msgstr "不明な命令コード" + +#: libdw/dwarf_error.c:104 +#, fuzzy +msgid ".debug_addr section missing" +msgstr ".debug_ranges セクションがありません" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "選択オプションを入力してください:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "ふぁいる 中のアドレスを探す" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "COREFILE 中で見つかった署名からアドレスを探す" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "プロセス PID に対応するファイル中のアドレスを探す" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" +"Linux の /proc/PID/maps 形式の ふぁいる から読み込んだものに対応するファイル" +"のアドレスを探す" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "実行中のカーネルのアドレスを探す" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "全てのモジュール付きのカーネル" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "分離した debuginfo ファイルべきパスを探す" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "-e か、-p、-k、-K、--core のひとつだけが認められます" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "カーネルシンボルをロードできません" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "カーネルモジュールを見つけられません" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "カーネルかモジュールを見つけられません" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "ELF コアファイルを読めません: %s" + +#: libdwfl/argp-std.c:317 +#, fuzzy +msgid "Not enough memory" +msgstr "メモリー不足" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "コアファイルの中にモジュールを認識できません" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:61 +msgid "zstd decompression failed" +msgstr "" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "オフセットが範囲を越えている" + +#: libdwfl/libdwflP.h:67 +#, fuzzy +msgid "relocation refers to undefined symbol" +msgstr "定義されたシンボルの印刷サイズ" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "" + +#: libdwfl/libdwflP.h:69 +#, fuzzy +msgid "No DWARF information found" +msgstr "DWARF 情報がありません" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "" + +#: libdwfl/libdwflP.h:71 +#, fuzzy +msgid "No ELF program headers" +msgstr "プログラムヘッダーを得られません: %s" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "" + +#: libdwfl/libdwflP.h:76 +#, fuzzy +msgid "ELF file opened" +msgstr "ファイルのオープンを追跡します。" + +#: libdwfl/libdwflP.h:77 +#, fuzzy +msgid "not a valid ELF file" +msgstr "不当な ELF ファイル" + +#: libdwfl/libdwflP.h:78 +#, fuzzy +msgid "cannot handle DWARF type description" +msgstr "Elf 記述子を生成できません: %s" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "" + +#: libdwfl/libdwflP.h:80 +#, fuzzy +msgid "corrupt .gnu.prelink_undo section data" +msgstr "ラインデータセクションデータを得られません: %s" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "" + +#: libdwfl/libdwflP.h:83 +#, fuzzy +msgid "Invalid register" +msgstr "不当なパラメーター" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "" + +#: libdwfl/libdwflP.h:87 +#, fuzzy +msgid "Invalid DWARF" +msgstr "不当な DWARF" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "" + +#: libdwfl/libdwflP.h:93 +#, fuzzy +msgid "Invalid argument" +msgstr "不当なパラメーター" + +#: libdwfl/libdwflP.h:94 +#, fuzzy +msgid "Not an ET_CORE ELF file" +msgstr "不当な ELF ファイル" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "バックエンドがありません" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "<不明>" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr "<不明>: %#" + +#: libebl/eblobjnote.c:58 +#, fuzzy, c-format +msgid "unknown SDT version %u\n" +msgstr "不明なバージョン" + +#: libebl/eblobjnote.c:76 +#, fuzzy, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "不当なファイル記述子" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr "" + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr "" + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr "" + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr "" + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr "" + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr "" + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " ビルト ID: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr "" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " OS: %s、ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "スタンドアローン" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr "<不明>: %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "不明なバージョン" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "不明なタイプ" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "無効な `Elf' の処理" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "ソース演算子の大きさが無効" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "宛先演算子の大きさが無効" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "無効なエンコード" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "不当なファイル記述子" + +#: libelf/elf_error.c:99 +#, fuzzy +msgid "invalid ELF file data" +msgstr "不当な ELF ファイル" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "不当な操作" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "ELF のバージョンが設定されていない" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "アーカイブヘッダーの不当な fmag 領域" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "不当なアーカイブファイル" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "記述子はアーカイブ用ではありません" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "索引が使えません" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "ファイルからデータを読みません" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "ファイルへデータを書けません" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "不当なバイナリークラス" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "不当なセクション索引" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "不当なオペランド" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "不当なセクション" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "エクゼキュータブルヘッダーが最初に作られていません" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "ファイル記述子が機能しません" + +#: libelf/elf_error.c:171 +#, fuzzy +msgid "archive/member file descriptor mismatch" +msgstr "アーカイブ/メンバー領域が不整合です" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "null セクションを操作できません" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "データ/scnが不整合です" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "不当なセクションヘッダー" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "不当なデータ" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "不明なデータエンコード" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "`sh_size' セクションがデータには小さすぎます" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "不当なセクション調整" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "不当なセクション項目の大きさ" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "読込み専用ファイルでの書込みのための update()" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "そのようなファイルはありません" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "リロケータブルファイルのみセクショングループを含むことができます" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" +"プログラムヘッダーはエクゼキュータブルか、共用オブジェクト、コアファイルにの" +"み認められています" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "ファイルにプログラムヘッダーがありません" + +#: libelf/elf_error.c:241 +#, fuzzy +msgid "invalid section type" +msgstr "不当なセクション" + +#: libelf/elf_error.c:246 +#, fuzzy +msgid "invalid section flags" +msgstr "不当なセクション" + +#: libelf/elf_error.c:251 +#, fuzzy +msgid "section does not contain compressed data" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "" + +#: libelf/elf_error.c:261 +#, fuzzy +msgid "unknown compression type" +msgstr "不明なタイプ" + +#: libelf/elf_error.c:266 +#, fuzzy +msgid "cannot compress data" +msgstr "セクションデータを割り当てられません: %s" + +#: libelf/elf_error.c:271 +#, fuzzy +msgid "cannot decompress data" +msgstr "セクションデータを割り当てられません: %s" + +#: src/addr2line.c:57 +#, fuzzy +msgid "Input format options:" +msgstr "選択オプションを入力してください:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "" + +#: src/addr2line.c:61 +#, fuzzy +msgid "Output format options:" +msgstr "出力形式:" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "雑則:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "コマンド:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "アーカイブからファイルを削除。" + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "アーカイブ内のファイルを移動。" + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "アーカイブ内のファイルを印刷。" + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "アーカイブへの即座のファイル追加。" + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "アーカイブへの既存のファイルの置き換えか、新しいファイルの挿入。" + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "アーカイブの内容の表示" + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "アーカイブからのファイルの取出し" + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "コマンド修飾子:" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "元データの保存。" + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "名前のインスタンス [COUNT] の使用。" + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "既存のファイルを抽出したファイルで置き換えない。" + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "必要ならばファイル名の切り捨てを認める。" + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "饒舌な出力を提供する。" + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "シンボルテーブルの再生成を強制する。" + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "[MEMBER]の後にファイルを挿入する。" + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "[MEMBER]の前にファイルを挿入する。" + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "-b と同じ。" + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "ライブラリーを生成しなければならない時にメッセージを抑止する。" + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "ファイル照合にフルパスを使う。" + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "アーカイブの古いファイルのみ更新する。" + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "アーカイブから作成や、修正、抽出する。" + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[メンバー] [合計] アーカイブ [ファイル...]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "'a'や、'b'、'i'は、'm' や 'r' オプションと一緒にしか指定できません" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "'a'や、'b'、'i' 修飾子には MEMBER パラメーターが必要です" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "'N' は 'x' や 'd' オプションと一緒の時のみ意味を持ちます" + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "COUNT パラメーターが必要です" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "不当な COUNT パラメーター %s" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "'%c' は 'x' オプションと一緒の時のみ意味を持ちます" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "アーカイブ名が必要です" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "1つを越える操作が指定されました" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "アーカイブ '%s' を開くことができません" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "アーカイブ '%s' を開けません: %s" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: アーカイブファイルではありません" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "アーカイブに stat できません: '%s'" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "アーカイブに項目 %s がありません\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "ハッシュテーブルを生成できません" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "ハッシュに挿入できません" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "'%s' に stat できません" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "%s の内容を読むことができません: %s" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "%.*s を開けません" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "%s への書込みに失敗しました" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "%s のモードを変更できません" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "%s の更新時間を変更できません" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "一時ファイルを %.*s に名前変更できません" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "新しいファイルを生成できません" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "位置メンバー %s が見つかりません" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: 項目 %s がアーカイブにありません!\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "%s を開けません" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "%s を stat できません" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "%s は一般ファイルではありません" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "%s の ELF 記述子を得られません: %s\n" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "%s を読みません: %s" + +#: src/ar.c:1483 +#, fuzzy, c-format +msgid "cannot represent ar_date" +msgstr "セクションデータを割り当てられません: %s" + +#: src/ar.c:1489 +#, fuzzy, c-format +msgid "cannot represent ar_uid" +msgstr "セクションデータを割り当てられません: %s" + +#: src/ar.c:1495 +#, fuzzy, c-format +msgid "cannot represent ar_gid" +msgstr "セクションデータを割り当てられません: %s" + +#: src/ar.c:1501 +#, fuzzy, c-format +msgid "cannot represent ar_mode" +msgstr "セクションを得られません: %s" + +#: src/ar.c:1507 +#, fuzzy, c-format +msgid "cannot represent ar_size" +msgstr "%s を開けません" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "" + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "アーカイブ '%s' は大きすぎます" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "%s(%s) の ELF ヘッダーを読めません: %s" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "" + +#: src/elfclassify.c:245 +#, fuzzy +#| msgid "cannot get ELF header" +msgid "ELF header" +msgstr "ELF ヘッダーを得られません" + +#: src/elfclassify.c:256 +#, fuzzy +#| msgid "Program Headers:" +msgid "program headers" +msgstr "プログラムヘッダー:" + +#: src/elfclassify.c:265 +#, fuzzy +#| msgid "Program Headers:" +msgid "program header" +msgstr "プログラムヘッダー:" + +#: src/elfclassify.c:285 +#, fuzzy +#| msgid "Section Headers:" +msgid "section headers" +msgstr "セクションヘッダー:" + +#: src/elfclassify.c:296 +#, fuzzy +#| msgid "cannot get section header string table index" +msgid "section header string table index" +msgstr "セクションヘッダー文字列テーブル索引が得られません" + +#: src/elfclassify.c:310 +#, fuzzy +msgid "could not obtain section header" +msgstr "セクションヘッダーを得られません: %s" + +#: src/elfclassify.c:316 +#, fuzzy +msgid "could not obtain section name" +msgstr "セクションを得られません: %s" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "" + +#: src/elfclassify.c:877 +#, fuzzy +#| msgid "Input selection options:" +msgid "Classification options" +msgstr "選択オプションを入力してください:" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "" + +#: src/elfclassify.c:907 +#, fuzzy +#| msgid "cannot find kernel modules" +msgid "File is a linux kernel module" +msgstr "カーネルモジュールを見つけられません" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "" + +#: src/elfclassify.c:956 +#, fuzzy +#| msgid "Output format:" +msgid "Output flags" +msgstr "出力形式:" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "" + +#: src/elfclassify.c:962 +#, fuzzy +#| msgid "More than one output file name given." +msgid "Do not output file names" +msgstr "ひとつを越える出力ファイル名が与えられました。" + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "ふぁいる..." + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, fuzzy, c-format +msgid "cannot get section count of '%s': %s" +msgstr "セクションを得られません: %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, fuzzy, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "プログラムヘッダーを得られません: %s" + +#: src/elfcmp.c:233 +#, fuzzy, c-format +msgid "%s %s diff: program header count" +msgstr "ファイルにプログラムヘッダーがありません" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, fuzzy, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "セクションを得られません: %s" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "" + +#: src/elfcmp.c:330 +#, fuzzy, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "" + +#: src/elfcmp.c:353 +#, fuzzy, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "" +"\n" +"シンボルテーブル [%2u] '%s' には %u 個の項目があります:\n" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "" + +#: src/elfcmp.c:451 +#, fuzzy, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "セクション [%Zu] '%s' からデータが得られません: %s" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "" + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "'%s' を開けません" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "-o オプションが 2 回指定されています" + +#: src/elfcompress.c:124 +#, fuzzy, c-format +msgid "-t option specified twice" +msgstr "-f オプションが 2 回指定されています" + +#: src/elfcompress.c:133 +#, fuzzy, c-format +msgid "unknown compression type '%s'" +msgstr "不明なタイプ" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, fuzzy, c-format +msgid "No input file given" +msgstr "入力ファイルが空です" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, fuzzy, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "'-o' と '-f' と一緒の場合は入力ファイルは 1 つしか認められません" + +#: src/elfcompress.c:1307 +#, fuzzy +msgid "Place (de)compressed output into FILE" +msgstr "はぎ取った出力を ふぁいる に置く" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "少し壊れた ELF ファイルを取り扱うためにルールを少し緩和する" + +#: src/elfcompress.c:1325 +#, fuzzy +msgid "Be silent when a section cannot be compressed" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "" + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "非常に厳密にやってください、フラグレベル 2 機能。" + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "成功したら何も印刷しない" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "バイナリーは別の debuginfo ファイルです" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" +"バイナリーは GNU ld で作成され、従ってある方法で壊れているのが知られている" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "ELF ファイルが gABI/psABI 仕様へ準拠しているかの厳密なチェック。" + +#: src/elflint.c:154 src/readelf.c:368 +#, fuzzy, c-format +msgid "cannot open input file '%s'" +msgstr "入力ファイルを開けません" + +#: src/elflint.c:161 +#, fuzzy, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "Elf 記述子を生成できません: %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "Elf 記述子を閉じている時にエラー: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "エラーはありません" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "ファイル名がありません。\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr "副-ELF 記述子を解放している時にエラー: %s\n" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "ELF ファイルではありません - 最初に誤ったマジックバイトがあります\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "e_ident[%d] == %d は既知のクラスではありません\n" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "e_ident[%d] == %d は既知のデータエンコードではありません\n" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "不明な ELF ヘッダーバージョン数 e_ident[%d] == %d\n" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "不明な OS ABI e_ident[%d] == '%s'\n" + +#: src/elflint.c:380 +#, fuzzy, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "不明な ABI バージョン e_ident[%d] == %d\n" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] がゼロではありません\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "不明なオブジェクトファイルタイプ %d\n" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "不明なマシンタイプ %d\n" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "不明なオブジェクトファイルバージョン\n" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "不当なプログラムヘッダーオフセット\n" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "" +"実行ファイルと DSO はプログラムヘッダーオフセットが 0 であってはいけません\n" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "プログラムヘッダー項目数として不当な数\n" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "不当なセクションヘッダーテーブルオフセット\n" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "セクションヘッダーテーブルがなければなりません\n" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "セクションヘッダーテーブル項目数として不当な数\n" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "不当なセクションヘッダーインデックス\n" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "" + +#: src/elflint.c:487 +#, fuzzy, c-format +msgid "invalid number of program header table entries\n" +msgstr "プログラムヘッダー項目数として不当な数\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "不当なマシンフラグ: %s\n" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "不当な ELF ヘッダーサイズ: %hd\n" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "不当なプログラムヘッダーサイズ: %hd\n" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "不当なプログラムヘッダー位置かサイズ\n" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "不当なセクションヘッダーサイズ: %hd\n" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "不当なセクションヘッダー位置かサイズ\n" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" +"セクション [%2d] '%s': SHF_GROUP フラグのあるセクションにセクショングループの" +"一部分が設定されていません\n" + +#: src/elflint.c:594 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" +"セクション [%2d] '%s': セクショングループ [%2zu] '%s' がグループメンバーを継" +"続していません\n" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" +"セクション [%2d] '%s': セクション [%2d] '%s' 用の文字列テーブルとして参照され" +"ていますが、タイプが SHT_STRTAB ではありません\n" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" +"セクション [%2d] '%s': シンボルテーブルは 1 個を越える拡張インデックスセク" +"ションを持てません\n" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "セクション [%2u] '%s': 項目サイズが ElfXX_Sym と一致しません\n" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "セクション [%2d] '%s': シンボル %d を得られません: %s\n" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "セクション [%2d] '%s': 0番目の項目にある '%s' ゼロではありません\n" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "セクション [%2d] '%s': 0番目の項目用の XINDEX がゼロではありません\n" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "セクション [%2d] '%s': シンボル %zu を得られません: %s\n" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "セクション [%2d] '%s': シンボル %zu: 不当な名前の値\n" + +#: src/elflint.c:728 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: 大きすぎるセクションインデックスだが、拡" +"張セクションインデックスセクションがありません\n" + +#: src/elflint.c:734 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: st_shndx (%) に適合するインデッ" +"クス用に使われる XINDEX\n" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "セクション [%2d] '%s': シンボル %zu: 不当なセクションインデックス\n" + +#: src/elflint.c:754 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "セクション [%2d] '%s': シンボル %zu: 不明なタイプ\n" + +#: src/elflint.c:760 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "セクション [%2d] '%s': シンボル %zu: 不明なシンボルバインディング\n" + +#: src/elflint.c:765 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: オブジェクトタイプと異なる固有のシンボ" +"ル\n" + +#: src/elflint.c:773 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: COMMON はリロケータブルファイル内のみで" +"許されます\n" + +#: src/elflint.c:777 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: ローカルな COMMON シンボルは意味がありま" +"せん\n" + +#: src/elflint.c:781 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: COMMON セクションの機能は意味がありませ" +"ん\n" + +#: src/elflint.c:832 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "セクション [%2d] '%s': シンボル %zu: st_value 境界外\n" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu は参照されるセクション [%2d] '%s' とは完" +"全に一致しません\n" + +#: src/elflint.c:847 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: 参照されるセクション [%2d] '%s' は " +"SHF_TLS フラグが設定されていません\n" + +#: src/elflint.c:857 src/elflint.c:905 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: st_value 参照されるセクション [%2d] " +"'%s' の境界外\n" + +#: src/elflint.c:884 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: TLS プログラムヘッダー項目がない TLS シ" +"ンボル\n" + +#: src/elflint.c:890 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: TLS プログラムヘッダー項目がない TLS シ" +"ンボル\n" + +#: src/elflint.c:898 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: 参照されるセクション [%2d] '%s' の" +"st_value 不足\n" + +#: src/elflint.c:925 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: sh_info に記述された範囲外のローカルシン" +"ボル\n" + +#: src/elflint.c:932 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: sh_info に記述された範囲外の非ローカルシ" +"ンボル\n" + +#: src/elflint.c:939 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "セクション [%2d] '%s': シンボル %zu: 非ローカルセクションシンボル\n" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" +"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルが間違ったセクション " +"[%2d] を参照しています\n" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" +"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルはセクション [%2d] '%s' " +"を参照しています\n" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" +"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボル値 %# は %s のセ" +"クションアドレス %# と一致しません\n" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" +"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルサイズ % は %s " +"のセクションサイズ % と一致しません\n" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" +"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルはありますが、.got セク" +"ションがありません\n" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" +"セクション [%2d] '%s': _DYNAMIC_ シンボル値 %# は動的セグメントアドレ" +"ス %# と一致しません\n" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" +"セクション [%2d] '%s': _DYNAMIC シンボルサイズ % は動的セグメントサイ" +"ズ % と一致しません\n" + +#: src/elflint.c:1063 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: 省略以外の可視性を持った動的シンボルテー" +"ブル中のシンボル\n" + +#: src/elflint.c:1067 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: st_other 中に設定された不明なビット\n" + +#: src/elflint.c:1105 +#, fuzzy, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "セクション [%2d] '%s': この RELA セクション用に使われる DT_RELCOUNT\n" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "" +"セクション [%2d] '%s': このセクション用には高すぎる DT_RELCOUNT 値 %d\n" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" +"セクション [%2d] '%s': UT_RELOCOUNT で指定されたインデックス %d 後の相対リロ" +"ケーション\n" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" +"セクション [%2d] '%s': インデックス %zu での非相対リロケーション; %d 相対リ" +"ロケーションで指定された DT_RELCOUNT\n" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "セクション [%2d] '%s': この REL セクション用に使われる DT_RELACOUNT\n" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "セクション [%2d] '%s': 不当な宛先セクションインデックス\n" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "セクション [%2d] '%s': 不当な宛先セクションタイプ\n" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "セクション [%2d] '%s': sh_info はゼロでなければなりません\n" + +#: src/elflint.c:1286 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" +"セクション [%2d] '%s': マージできるセクションのリロケーションは不可能です\n" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "" +"セクション [%2d] '%s': セクション項目サイズが ElfXX_Rela と一致しません\n" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "" +"テキストリロケーションフラグが設定されていますが、読込み専用セグメントがあり" +"ません\n" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "セクション [%2d] '%s': リロケーション %zu: 不当なタイプ\n" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" +"セクション [%2d] '%s': リロケーション %zu: このファイル用のリロケーションタイ" +"プは不当です\n" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "" +"セクション [%2d] '%s': リロケーション %zu: 不当なシンボルインデックス\n" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" +"セクション [%2d] '%s': リロケーション %zu: シンボル '_GLOBAL_OFFSET_TABLE_' " +"のみが %s と一緒に使用できます\n" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "セクション [%2d] '%s': リロケーション %zu: オフセット境界外\n" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" +"セクション [%2d] '%s': リロケーション %zu: タイプ %s のシンボルに対するコピー" +"リロケーション\n" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" +"セクション [%2d] '%s': リロケーション %zu: 読込み専用セクションが変更されまし" +"たが、テキストリロケーションフラグが設定されていません\n" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "" +"セクション [%2d] '%s': リロケーションがロードされたデータとロードされなかった" +"データに対してです\n" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "" + +#: src/elflint.c:1668 +#, fuzzy, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" +"セクション [%2d] '%s': セクション [%2d] '%s' 用の文字列テーブルとして参照され" +"ていますが、タイプが SHT_STRTAB ではありません\n" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" + +#: src/elflint.c:1948 +#, fuzzy, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "セクション [%2d] '%s': 不当な宛先セクションインデックス\n" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "" + +#: src/elflint.c:2140 +#, fuzzy, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:2152 +#, fuzzy, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "セクション [%2d] '%s': 0番目の項目にある '%s' ゼロではありません\n" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" + +#: src/elflint.c:2254 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "" + +#: src/elflint.c:2330 +#, fuzzy, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "セクション [%2d] '%s': 不当な宛先セクションインデックス\n" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:2444 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "" +"\n" +"セクション [%Zu] '%s' にはダンプすべきデータがありません。\n" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" + +#: src/elflint.c:2557 +#, fuzzy, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "セクション [%2d] '%s': 不当な宛先セクションタイプ\n" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "" + +#: src/elflint.c:2664 +#, fuzzy, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "セクション [%2d] '%s': シンボル %d を得られません: %s\n" + +#: src/elflint.c:2669 +#, fuzzy, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "" + +#: src/elflint.c:2731 +#, fuzzy, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "セクション [%2d] '%s': リロケーション %zu: オフセット境界外\n" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "" + +#: src/elflint.c:2753 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" +"セクション [%2d] '%s': シンボル %zu: 参照されるセクション [%2d] '%s' は " +"SHF_TLS フラグが設定されていません\n" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "" + +#: src/elflint.c:3974 +#, fuzzy, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:3979 +#, fuzzy, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "セクション [%2d] '%s': セクションデータを得られません\n" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr "" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "" + +#: src/elflint.c:4797 +#, fuzzy, c-format +msgid "cannot create backend for ELF file\n" +msgstr "新しいファイルを生成できません" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "" + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "[ふぁいる...]" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "" + +#: src/findtextrel.c:314 +#, fuzzy, c-format +msgid "cannot get program header count: %s" +msgstr "プログラムヘッダーを得られません: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, fuzzy, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "プログラムヘッダーを得られません: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "出力選択:" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "デバッガー専用シンボルを表示" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "定義されたシンボルのみを表示" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "通常シンボルの代わりに動的シンボルを表示" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "外部シンボルのみを表示" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "未定義シンボルのみを表示" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "アーカイブメンバーからのシンボルの索引を含める" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "出力形式:" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "全てのシンボルの前に入力ファイル名を印刷" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"出力形式として FORMATを使う。FORMAT は `bsd'か、`sysv'、`posix' のどれか。省" +"略値は `sysv'" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "--format=bsd と同じ" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "--format=posix と同じ" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "シンボル値を印刷するために RADIX を使う" + +#: src/nm.c:87 +#, fuzzy +msgid "Mark special symbols" +msgstr "弱いシンボルに印を点ける" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "定義されたシンボルの印刷サイズ" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "出力オプション:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "シンボルをアドレスにより数値的に並べ替える" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "シンボルを並べ替えない" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "並べ替えの意味を逆にする" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "ふぁいる からシンボルを表示 (デフォルトではa.out)。" + +#: src/nm.c:116 src/objdump.c:79 +#, fuzzy +msgid "Output formatting" +msgstr "出力形式:" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, fuzzy, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: 内部エラー %d (%s-%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "'%s' を閉じている最中" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: ファイル形式を認識できませんでした" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +#, fuzzy +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"アーカイブ索引:" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "シンボル %2$sの不正なオフセット %1$zu " + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "%2$s の中の %1$s\n" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "アーカイブのオフセットを最初にリセットできません" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: ファイル形式を認識できません" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "検索ツリーを生成できません" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "セクションヘッダー文字列テーブル索引が得られません" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"%s からのシンボル:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" +"%*s%-*s %-*s クラス タイプ %-*s %*s セクション\n" +"\n" + +#: src/nm.c:776 +msgctxt "sysv" +msgid "Name" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "" + +#: src/nm.c:1250 +#, fuzzy, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "%s: セクションの項目の大きさ `%s' は予期したものとは異なります" + +#: src/nm.c:1255 +#, fuzzy, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: セクション `%s' の大きさは項目の大きさの整数倍ではありません" + +#: src/nm.c:1336 +#, fuzzy, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "%s: セクションの項目の大きさ `%s' は予期したものとは異なります" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: 不当な操作" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: シンボルがありません" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "" + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "" + +#: src/objdump.c:59 +#, fuzzy +msgid "Output content selection:" +msgstr "出力選択:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "" + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "" + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "操作が指定されていません。\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "不当なシンボル" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "不当なセクション" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "" + +#: src/objdump.c:760 +#, fuzzy, c-format +msgid "cannot create backend for elf file" +msgstr "新しいファイルを生成できません" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "" + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "" + +#: src/readelf.c:97 +#, fuzzy +msgid "ELF input selection:" +msgstr "出力選択:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" + +#: src/readelf.c:104 +#, fuzzy +msgid "ELF output selection:" +msgstr "出力選択:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "動的セグメントを表示" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "ELF ファイルヘッダーを表示" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "バケットリスト長の柱状図を表示" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "プログラムヘッダーを表示" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "リロケーションを表示" + +#: src/readelf.c:114 +#, fuzzy +msgid "Display the section groups" +msgstr "セクションのヘッダーを表示" + +#: src/readelf.c:115 +#, fuzzy +msgid "Display the sections' headers" +msgstr "セクションのヘッダーを表示" + +#: src/readelf.c:118 +#, fuzzy +msgid "Display the symbol table sections" +msgstr "シンボルテーブルを表示" + +#: src/readelf.c:120 +#, fuzzy +msgid "Display (only) the dynamic symbol table" +msgstr "外部シンボルのみを表示" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "バージョニング情報の表示" + +#: src/readelf.c:122 +#, fuzzy +msgid "Display the ELF notes" +msgstr "コアノートを表示" + +#: src/readelf.c:124 +#, fuzzy +msgid "Display architecture specific information, if any" +msgstr "(もしあれば)アーキテクチャー固有の情報を表示" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "例外を取り扱うためのセクションを表示" + +#: src/readelf.c:128 +#, fuzzy +msgid "Additional output selection:" +msgstr "出力選択:" + +#: src/readelf.c:130 +#, fuzzy +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" +"DWARF セクションの内容を表示。SECTION は addrevか、aranges、frame、info、" +"loc、ranges、pubnames、str、macinfo、exception のいずれかです" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "数字か名前で解釈できないセクションの内容をダンプする" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "セクションの文字列内容を印刷する" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "アーカイブのシンボル索引を表示" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "出力制御:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "DWARFデータ中のアドレスのためのシンボル名を探さない" + +#: src/readelf.c:145 +#, fuzzy +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "DWARFデータ中のアドレスのためのシンボル名を探さない" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "ELF ファイルから人間が読める形で情報を印刷する。" + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "はい" + +#: src/readelf.c:351 +msgid "no" +msgstr "いいえ" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "不明な DWARF デバッグセクション `%s'.\n" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "Elf 記述子を生成できません: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "セクション数を決定できません: %s" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "セクションを得られません: %s" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "セクションヘッダーを得られません: %s" + +#: src/readelf.c:663 +#, fuzzy, c-format +msgid "cannot get section name" +msgstr "セクションを得られません: %s" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "%s の内容を得られません: %s" + +#: src/readelf.c:688 +#, fuzzy, c-format +msgid "cannot create temp file '%s'" +msgstr "新しいファイル '%s' を生成できません: %s" + +#: src/readelf.c:697 +#, fuzzy, c-format +msgid "cannot write section data" +msgstr "セクションデータを割り当てられません: %s" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "Elf 記述子を閉じている時にエラー: %s" + +#: src/readelf.c:710 +#, fuzzy, c-format +msgid "error while rewinding file descriptor" +msgstr "Elf 記述子を閉じている時にエラー: %s" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "'%s' はアーカイブではなく、アーカイブ索引を印刷できません" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "入力ファイルを stat できません" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "入力ファイルが空です" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "'%s' の読込みに失敗: %s" + +#: src/readelf.c:881 +#, fuzzy, c-format +msgid "No such section '%s' in '%s'" +msgstr "セクション [%Zu] '%s' からデータが得られません: %s" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "ELF ヘッダーが読めません: %s" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "EBL ヘッダーを生成できません" + +#: src/readelf.c:961 +#, fuzzy, c-format +msgid "cannot determine number of program headers: %s" +msgstr "セクション数を決定できません: %s" + +#: src/readelf.c:993 +#, fuzzy, c-format +msgid "cannot read ELF: %s" +msgstr "%s を読みません: %s" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "なし (なし)" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "REL (リロケータブルファイル)" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "(EXEC (実行ファイル)" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "DYN (共用オブジェクトファイル)" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "CORE (コアファイル)" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "OS 固有: (%x)\n" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "プロセッサー固有: (%x)\n" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" +"ELF ヘッダー:\n" +" マジック: " + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" +"\n" +" クラス: %s\n" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr " データ: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr " 識別バージョン: %hhd %s\n" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(現在)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr " OS/ABI: %s\n" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr " ABI バージョン: %hhd\n" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " タイプ: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr " マシン : %s\n" + +#: src/readelf.c:1109 +#, fuzzy, c-format +msgid " Machine: : 0x%x\n" +msgstr " マシン : %s\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr " バージョン: %d %s\n" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr " 入口点アドレス : %#\n" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr " プログラムヘッダーの開始: % %s\n" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "(ファイルへのバイト数)" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr " セクションヘッダーの開始: % %s\n" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr " フラグ: %s\n" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr " このヘッダーの大きさ: % %s\n" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(バイト)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr " プログラムヘッダー項目の大きさ:% %s\n" + +#: src/readelf.c:1134 +#, fuzzy, c-format +msgid " Number of program headers entries: %" +msgstr " プログラムヘッダー項目の数 : %\n" + +#: src/readelf.c:1141 +#, fuzzy, c-format +msgid " (% in [0].sh_info)" +msgstr "([0].sh_link の %)" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr "([0]は使えません)" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr " セクションヘッダー項目の大きさ:% %s\n" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr " セクションヘッダー項目の数 : %" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr " ([0].sh_size の %)" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr "([0].sh_link の %)" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" +" セクションヘッダー文字列テーブル索引: XINDEX%s\n" +"\n" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" +" セクションヘッダー文字列テーブル索引: %\n" +"\n" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, fuzzy, c-format +msgid "cannot get number of sections: %s" +msgstr "セクション数を決定できません: %s" + +#: src/readelf.c:1233 +#, fuzzy, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" +"オフセット %2$# から始まる %1$d 個のセクションヘッダーがあります:\n" +"\n" + +#: src/readelf.c:1242 +#, fuzzy, c-format +msgid "cannot get section header string table index: %s" +msgstr "セクションヘッダー文字列テーブル索引が得られません" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "セクションヘッダー:" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" +"[番] 名前 タイプ アドレス オフセ 大きさ ES フラグLk " +"Inf Al" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" +"[番] 名前 タイプ アドレス オフセ 大きさ ES " +"フラグLk Inf Al" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr "" + +#: src/readelf.c:1335 +#, fuzzy, c-format +msgid "bad compression header for section %zd: %s" +msgstr "セクションヘッダー文字列セクションを生成できません: %s" + +#: src/readelf.c:1346 +#, fuzzy, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "セクションからデータを得られません %d: %s" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "プログラムヘッダー:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" +" タイプ オフセ 仮アドレス 物アドレス ファイ量 メモ量 Flg 調整 " + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" +" タイプ オフセ 仮想アドレス 物理アドレス ファイル量メモ" +"量 Flg 調整 " + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "\t[プログラム割込みを要求: %s]\n" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" +"\n" +" セクションからセグメントへのマッビング:\n" +" セグメント セクション..." + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "プログラムヘッダーを得られません: %s" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"署名 '%3$s' を持つ COMDAT セクショングループ [%1$2zu] '%2$s' には %4$zu 個の" +"項目があります:\n" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"署名 '%3$s' を持つセクショングループ [%1$2zu] '%2$s' には %4$zu 個の項目があ" +"ります:\n" + +#: src/readelf.c:1623 +msgid "" +msgstr "<不当なシンボル>" + +#: src/readelf.c:1637 +msgid "" +msgstr "<不当なセクション>" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, fuzzy, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "セクションヘッダーを得られません: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, fuzzy, c-format +msgid "invalid sh_link value in section %zu" +msgstr "不当な .debug_line セクション" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"動的セグメントには %lu 個の項目があります:\n" +" アドレス: %#0* オフセット: %#08 セクションへのリンク: " +"[%2u] '%s'\n" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr " タイプ 値\n" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "共用ライブラリー: [%s]\n" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "ライブラリー so 名: [%s]\n" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "ライブラリー rパス: [%s]\n" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "ライブラリー run パス: [%s]\n" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "% (バイト)\n" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" +"\n" +"オフセット %#0 に不当なシンボルテーブル\n" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +"\n" +"オフセット %5$#0 のセクション [%3$2u] '%4$s' 用のリロケーションセク" +"ション [%1$2zu] '%2$s' には %6$d 個の項目があります:\n" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"オフセット %3$#0 のリロケーションセクション [%1$2u] '%2$s' には %4$d " +"個の項目があります:\n" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr " オフセット タイプ 値 名前\n" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr " オフセット タイプ 値 名前\n" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "<不当なRELOC>" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr " オフセット タイプ 値 付加名\n" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr " オフセット タイプ 値 付加名\n" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +"\n" +"シンボルテーブル [%2u] '%s' には %u 個の項目があります:\n" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] " %lu ローカルシンボル文字列テーブル: [%2u] '%s'\n" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " 数 : 値 大き タイプ Bind Vis Ndx 名前\n" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " 数 : 値 大き タイプ Bind Vis Ndx 名前\n" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "%5u: %0* %6 %-7s %-6s %-9s %6s %s" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "不正な動的シンボル" + +#: src/readelf.c:2680 +msgid "none" +msgstr "なし" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| <不明>" + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"セクション [%2u] '%s' を必要とするバージョンには %d 個の項目があります:\n" +" アドレス: %#0* オフセット: %#08 セクションへのリンク: " +"[%2u] '%s'\n" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: バージョン: %hu ファイル: %s 数: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: 名前: %s フラグ: %s バージョン: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"バージョン定義セクション [%2u] '%s' には %d 個の項目があります:\n" +" アドレス: %#0* オフセット: %#08 セクションへのリンク: " +"[%2u] '%s'\n" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr " %#06x: バージョン: %hd フラグ: %s 索引: %hd 数: %hd 名前: %s\n" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr " %#06x: 親 %d: %s\n" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +"\n" +"バージョンシンボルセクション [%2u] '%s' には %d 個の項目があります:\n" +" アドレス: %#0* オフセット: %#08 セクションへのリンク: " +"[%2u] '%s'" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *ローカル* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *グローバル* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"セクション [%2u] '%s' のバケット一覧の長さの柱状図(合計 %d バケット):\n" +" アドレス: %#0* オフセット: %#08 セクションへのリンク: " +"[%2u] '%s'\n" + +#: src/readelf.c:3206 +#, fuzzy, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr " 長さ 数 全体の% 範囲 \n" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, fuzzy, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" +" テストの平均数: 検索成功: %f\n" +" 検索失敗: %f\n" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "セクションからデータを得られません %d: %s" + +#: src/readelf.c:3254 +#, fuzzy, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/readelf.c:3283 +#, fuzzy, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/readelf.c:3318 +#, fuzzy, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/readelf.c:3349 +#, fuzzy, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/readelf.c:3385 +#, fuzzy, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" +" シンボルの偏り: %u\n" +" ビットマスクの大きさ: %zu バイト %%% ビット設定 第2ハッシュシフ" +"ト: %u\n" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"オフセット %3$#0 のライブラリー一覧セクション [%1$2zu] '%2$s' には " +"%4$d 個の項目があります:\n" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" +" ライブラリー タイムスタンプ チェックサム バー" +"ジョン フラグ" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" +"\n" +"オフセット %4$#0 の %3$ バイトのオブジェクト属性セクション " +"[%1$2zu] '%2$s':\n" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr " 所有者 大きさ\n" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " ファイル: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %、%s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, c-format +msgid "sprintf failure" +msgstr "" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "空ブロック" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "%zu バイトのブロック:" + +#: src/readelf.c:4800 +#, fuzzy, c-format +msgid "%*s[%2] %s \n" +msgstr "%*s[%4] %s \n" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr "" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr "" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s':\n" +" [ コード]\n" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" +"\n" +"オフセット % の略語セクション:\n" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr " *** 略語を読んでいる間にエラー: %s\n" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr " [%5u] オフセット: %、子: %s、タグ: %s\n" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s':\n" + +#: src/readelf.c:5182 +#, fuzzy, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "セクションデータを割り当てられません: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, fuzzy, c-format +msgid " Length: %8\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, fuzzy, c-format +msgid " DWARF version: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, fuzzy, c-format +msgid " Address size: %8\n" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, fuzzy, c-format +msgid " Segment size: %8\n" +msgstr " ファイルを % に設定する\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, fuzzy, c-format +msgid "Unknown version" +msgstr "不明なバージョン" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, fuzzy, c-format +msgid "unsupported address size" +msgstr "アドレス値ではありません" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr ".debug_aragnes の内容を得られません: %s" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項" +"目があります:\n" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" +" [%*zu] 開始: %0#*、長さ: %5、CU DIE オフセット: %6\n" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, fuzzy, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" +"\n" +"オフセット %Zu のテーブル:\n" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/readelf.c:5511 +#, fuzzy, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:5523 +#, fuzzy, c-format +msgid " DWARF version: %6\n" +msgstr " %s: %\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "" + +#: src/readelf.c:5538 +#, fuzzy, c-format +msgid " CU offset: %6\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:5544 +#, fuzzy, c-format +msgid " Address size: %6\n" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:5555 +#, fuzzy, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr " ファイルを % に設定する\n" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr "" + +#: src/readelf.c:5654 +#, fuzzy, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr ".degub_ranges の内容を得られません: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, fuzzy, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, fuzzy, c-format +msgid " Offset entries: %8\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr "" + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr "" + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr "" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, fuzzy, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " 所有者 大きさ\n" + +#: src/readelf.c:5823 +#, fuzzy, c-format +msgid "invalid range list data" +msgstr "不当なデータ" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr ".degub_ranges の内容を得られません: %s" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] <不当なデータ>\n" + +#: src/readelf.c:6097 src/readelf.c:9719 +#, fuzzy +msgid "base address" +msgstr "アドレスを %s に設定する\n" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, fuzzy, c-format +msgid " [%6tx] empty list\n" +msgstr "" +"\n" +" [%6tx] ゼロ終端\n" + +#: src/readelf.c:6367 +#, fuzzy +msgid " \n" +msgstr " [%6tx] <不当なデータ>\n" + +#: src/readelf.c:6624 +#, fuzzy, c-format +msgid "cannot get ELF: %s" +msgstr "次の DIE を得られません: %s" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"オフセット %3$# の フレーム情報呼出しセクション [%1$2zu] '%2$s':\n" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" +"\n" +" [%6tx] ゼロ終端\n" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, fuzzy, c-format +msgid "invalid augmentation length" +msgstr "不当な拡大エンコード" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "FDE アドレスエンコード" + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "LSDA ポインターエンコード:" + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr " (オフセット: %#)" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr " %-26sLSDA ポインター: %#\n" + +#: src/readelf.c:7053 +#, fuzzy, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "属性コードを得られません: %s" + +#: src/readelf.c:7063 +#, fuzzy, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "属性様式を得られません: %s" + +#: src/readelf.c:7085 +#, fuzzy, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "属性値を得られません: %s" + +#: src/readelf.c:7415 +#, fuzzy, c-format +msgid "invalid file (%): %s" +msgstr "不当なファイル" + +#: src/readelf.c:7419 +#, fuzzy, c-format +msgid "no srcfiles for CU [%]" +msgstr " ファイルを % に設定する\n" + +#: src/readelf.c:7423 +#, fuzzy, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "次の DIE を得られません: %s" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s':\n" +" [オフセット]\n" + +#: src/readelf.c:7788 +#, fuzzy, c-format +msgid "cannot get next unit: %s" +msgstr "次の DIE を得られません: %s" + +#: src/readelf.c:7808 +#, fuzzy, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" +" オフセット %1$ のコンパイル単位:\n" +" バージョン: %2$、略語セクションオフセット: %3$、アドレスの大" +"きさ: %4$、オフセットの大きさ: %5$\n" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" オフセット %1$ のコンパイル単位:\n" +" バージョン: %2$、略語セクションオフセット: %3$、アドレスの大" +"きさ: %4$、オフセットの大きさ: %5$\n" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr "" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "DIE オフセットを得られません: %s" + +#: src/readelf.c:7895 +#, fuzzy, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "" +"セクション '%2$s' 中のオフセット %1$ の DIE のタグを得られません: " +"%3$s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "次の DIE を得られません: %s\n" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "次の DIE を得られません: %s" + +#: src/readelf.c:7985 +#, fuzzy, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" オフセット %1$ のコンパイル単位:\n" +" バージョン: %2$、略語セクションオフセット: %3$、アドレスの大" +"きさ: %4$、オフセットの大きさ: %5$\n" + +#: src/readelf.c:8037 +#, fuzzy, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s':\n" + +#: src/readelf.c:8369 +#, fuzzy, c-format +msgid "unknown form: %s" +msgstr "不明な様式 %" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "ラインデータセクションデータを得られません: %s" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, fuzzy, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" +"\n" +" 長さ: %\n" +" DWARF バージョン: %\n" +" プロローグ長: %\n" +" 最小命令長: %\n" +" もし '%s' なら初期値: %\n" +" 行ベース: %\n" +" 行範囲: %\n" +" 命令コードベース: %\n" +"\n" +"命令コード:\n" + +#: src/readelf.c:8524 +#, fuzzy, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr ".degub_ranges の内容を得られません: %s" + +#: src/readelf.c:8532 +#, fuzzy, c-format +msgid "cannot handle address size: %u\n" +msgstr "アドレス値ではありません" + +#: src/readelf.c:8540 +#, fuzzy, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "セクションを得られません: %s" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "セクション [%2$zu] '%3$s' 中のオフセット %1$tu に不当なデータ" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] " [%*] %hhu パラメーター\n" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" +"\n" +"ディレクトリーテーブル:" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, fuzzy, c-format +msgid " [" +msgstr " %s: %s\n" + +#: src/readelf.c:8653 +#, fuzzy +msgid "" +"\n" +"File name table:" +msgstr "" +"\n" +" 呼出しサイトテーブル:" + +#: src/readelf.c:8714 +#, fuzzy +msgid " Entry Dir Time Size Name" +msgstr "" +"\n" +"ファイル名テーブル:\n" +" Entry Dir 時刻 大きさ 名前" + +#: src/readelf.c:8753 +#, fuzzy +msgid "" +"\n" +"No line number statements." +msgstr "" +"\n" +"行 番号 文:" + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" +"\n" +"行 番号 文:" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "" + +#: src/readelf.c:8811 +#, fuzzy, c-format +msgid " special opcode %u: address+%u = " +msgstr " 特殊命令コード %u: アドレス+%u = %s, 行%+d = %zu\n" + +#: src/readelf.c:8815 +#, fuzzy, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr " 特殊命令コード %u: アドレス+%u = %s, 行%+d = %zu\n" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr "" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr " 拡張命令コード %u: " + +#: src/readelf.c:8841 +#, fuzzy +msgid " end of sequence" +msgstr "列の終わり" + +#: src/readelf.c:8859 +#, fuzzy, c-format +msgid " set address to " +msgstr "アドレスを %s に設定する\n" + +#: src/readelf.c:8887 +#, fuzzy, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr "" +"新ファイルを定義する: dir=%u、mtime=%、長さh=%、名前=%s\n" + +#: src/readelf.c:8901 +#, fuzzy, c-format +msgid " set discriminator to %u\n" +msgstr "カラムを % に設定する\n" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +#, fuzzy +msgid " unknown opcode" +msgstr "不明な命令コード" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr "複写" + +#: src/readelf.c:8929 +#, fuzzy, c-format +msgid " advance address by %u to " +msgstr "アドレスを %u だけ進めて %s にする\n" + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr "" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr "行を定数 %d だけ進めて % にする\n" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr " ファイルを % に設定する\n" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr "カラムを % に設定する\n" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr " '%s' を % に設定する\n" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr "基本ブロックフラグを設定する" + +#: src/readelf.c:8990 +#, fuzzy, c-format +msgid " advance address by constant %u to " +msgstr "アドレスを定数 %u だけ済めて %s にする\n" + +#: src/readelf.c:9010 +#, fuzzy, c-format +msgid " advance address by fixed value %u to \n" +msgstr "アドレスを固定値 %u だけ進めて %s にする\n" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr "プロローグ終了フラグを設定する" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr "エピローグ開始フラグを設定する" + +#: src/readelf.c:9035 +#, fuzzy, c-format +msgid " set isa to %u\n" +msgstr " ファイルを % に設定する\n" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] " % 個のパラメーターのある不明な命令コード:" + +#: src/readelf.c:9084 +#, fuzzy, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr ".debug_loc の内容を得られません: %s" + +#: src/readelf.c:9250 +#, fuzzy, c-format +msgid " \n" +msgstr " [%6tx] <不当なデータ>\n" + +#: src/readelf.c:9290 +#, fuzzy, c-format +msgid "invalid loclists data" +msgstr "不当なデータ" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr ".debug_loc の内容を得られません: %s" + +#: src/readelf.c:9756 src/readelf.c:10800 +#, fuzzy +msgid " \n" +msgstr " [%6tx] <不当なデータ>\n" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "マクロ情報セクションのデータを得られません: %s" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "%*s*** 最後のセクションの終端していない文字列" + +#: src/readelf.c:9914 +#, fuzzy, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "%*s*** 最後のセクションの終端していない文字列" + +#: src/readelf.c:10015 +#, fuzzy, c-format +msgid " Offset: 0x%\n" +msgstr " 所有者 大きさ\n" + +#: src/readelf.c:10027 +#, fuzzy, c-format +msgid " Version: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr "" + +#: src/readelf.c:10040 +#, fuzzy, c-format +msgid " Flag: 0x%" +msgstr " 入口点アドレス : %#\n" + +#: src/readelf.c:10069 +#, fuzzy, c-format +msgid " Offset length: %\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10077 +#, fuzzy, c-format +msgid " .debug_line offset: 0x%\n" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:10102 +#, fuzzy, c-format +msgid " extension opcode table, % items:\n" +msgstr " % 個のパラメーターのある不明な命令コード:" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr "" + +#: src/readelf.c:10121 +#, fuzzy, c-format +msgid " % arguments:" +msgstr " [%*] %hhu パラメーター\n" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr "" + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr "" +" [%5d] DIE オフセット: %6, CU DIE オフセット: %6, 名前: %s\n" + +# # "オフセット %3$# の DWARF セクション [%1$2zu] '%2$s':\n" +# # " %4$*s 文字列\n" がエラーになるのは何故? 取り敢えず fuzzy扱い +#: src/readelf.c:10381 +#, fuzzy, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s':\n" +" %4$*s 文字列\n" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "" + +#: src/readelf.c:10396 +#, fuzzy, c-format +msgid " *** error, missing string terminator\n" +msgstr " *** 文字列の読込み中にエラー: %s\n" + +#: src/readelf.c:10425 +#, fuzzy, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr ".degub_ranges の内容を得られません: %s" + +#: src/readelf.c:10524 +#, fuzzy, c-format +msgid " Length: %8\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10526 +#, fuzzy, c-format +msgid " Offset size: %8\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10540 +#, fuzzy, c-format +msgid " DWARF version: %8\n" +msgstr " %s: %\n" + +#: src/readelf.c:10549 +#, fuzzy, c-format +msgid " Padding: %8\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" +"\n" +"呼出しフレーム検索テーブルセクション [%2zu] '.eh_frame_hdr':\n" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" +"\n" +"例外取扱いテーブルセクション [%2zu] '.gcc_except_table':\n" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr " LPStart コード化: %#x " + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr "TType コード化: %#x " + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr "呼出しサイトコード化: %#x " + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" +"\n" +" 呼出しサイトテーブル:" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" +" [%4u] 呼出しサイト開始 : %#\n" +" 呼出しサイト長: %\n" +" 離着陸場: %#\n" +" 行動: %u\n" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "不当な TType コード化" + +#: src/readelf.c:10882 +#, fuzzy, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項" +"目があります:\n" + +#: src/readelf.c:10911 +#, fuzzy, c-format +msgid " Version: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:10929 +#, fuzzy, c-format +msgid " CU offset: %#\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10936 +#, fuzzy, c-format +msgid " TU offset: %#\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10943 +#, fuzzy, c-format +msgid " address offset: %#\n" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:10950 +#, fuzzy, c-format +msgid " symbol offset: %#\n" +msgstr " (オフセット: %#)" + +#: src/readelf.c:10957 +#, fuzzy, c-format +msgid " constant offset: %#\n" +msgstr " (終了オフセット: %#)" + +#: src/readelf.c:10971 +#, fuzzy, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項" +"目があります:\n" + +#: src/readelf.c:10996 +#, fuzzy, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項" +"目があります:\n" + +#: src/readelf.c:11025 +#, fuzzy, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +"オフセット %3$# の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項" +"目があります:\n" + +#: src/readelf.c:11057 +#, fuzzy, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" +"\n" +"オフセット %#0 に不当なシンボルテーブル\n" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "デバッグ内容記述子を得られません: %s" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "コアノートデータの変換ができません: %s" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" +"\n" +"%*s... < %u 回の繰返し> ..." + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr " 所有者 データ大きさタイプ\n" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr " %-13.*s %9 %s\n" + +#: src/readelf.c:12518 +#, fuzzy, c-format +msgid "cannot get content of note: %s" +msgstr "ノートセクションの内容を得られません: %s" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" +"\n" +"オフセット %4$#0 の %3$ バイトのノートセクション [%1$2zu] " +"'%2$s':\n" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" +"\n" +"オフセット %2$#0 の %1$ バイトのノートセグメント:\n" + +#: src/readelf.c:12622 +#, fuzzy, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" +"\n" +"セクション [%Zu] '%s' にはダンプすべきデータがありません。\n" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, fuzzy, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "セクション [%Zu] '%s' からデータが得られません: %s" + +#: src/readelf.c:12654 +#, fuzzy, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" +"\n" +"オフセット %4$#0 のセクション [%1$Zu] '%2$s' の16進ダン" +"プ、%3$ バイト:\n" + +#: src/readelf.c:12659 +#, fuzzy, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" +"\n" +"オフセット %4$#0 のセクション [%1$Zu] '%2$s' の16進ダン" +"プ、%3$ バイト:\n" + +#: src/readelf.c:12673 +#, fuzzy, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" +"\n" +"セクション [%Zu] '%s' にはダンプすべきデータがありません。\n" + +#: src/readelf.c:12705 +#, fuzzy, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" +"\n" +"オフセット %4$#0 文字列セクション [%1$Zu] '%2$s' には %3$ バ" +"イトあります:\n" + +#: src/readelf.c:12710 +#, fuzzy, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" +"\n" +"オフセット %4$#0 文字列セクション [%1$Zu] '%2$s' には %3$ バ" +"イトあります:\n" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" +"\n" +"セクション [%lu] がありません" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" +"\n" +"セクション '%s' がありません" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "アーカイブのシンボル索引 '%s' を得られません: %s" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" +"\n" +"アーカイブ '%s' にはシンボル索引がありません\n" + +#: src/readelf.c:12853 +#, fuzzy, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" +"\n" +"アーカイブ '%s' の索引には %Zu 項目あります:\n" + +#: src/readelf.c:12871 +#, fuzzy, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "'%2$s' の オフセット %1$Zu のメンバーを抽出できません: %3$s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "アーカイブメンバー '%s' には以下があります:\n" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" +"出力形式として FORMAT を使ってください。FORMAT は `bsd'か、`sysv' のどちらか" +"です。省略値は `bsd'です" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "`--format=sysv' と同じ" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "`--format=bsd' と同じ" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "`--radix=10' と同じ" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "`--radix=8' と同じ" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "`--radix=16' と同じ" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "`--format=sysv' の出力と似ていますが、1行です" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "ロード可能セグメントのための印刷の大きさと許可フラグ" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "合計の大きさを表示 (bsd のみ)" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "ふぁいる のセクションの大きさの一覧 (省略値は a.out)" + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "不当な形式: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "不当な基数: %s" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "%s: ファイル形式を認識できません" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr " (ex %s)" + +#: src/size.c:420 +#, fuzzy +#| msgid "invalid section" +msgctxt "sysv" +msgid "section" +msgstr "不当なセクション" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "" + +#: src/size.c:482 +#, fuzzy, c-format +msgid "cannot get section header" +msgstr "セクションヘッダーを得られません: %s" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "(合計)\n" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "" + +#: src/stack.c:493 +#, fuzzy, c-format +msgid "Cannot open core file '%s'" +msgstr "アーカイブ '%s' を開くことができません" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "" + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "" + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "" + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "" + +#: src/stack.c:645 +#, fuzzy +msgid "Show stack of process PID" +msgstr "検索ツリーを生成できません" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "" + +#: src/stack.c:652 +#, fuzzy +msgid "Output selection options:" +msgstr "選択オプションを入力してください:" + +#: src/stack.c:654 +#, fuzzy +msgid "Additionally show frame activation" +msgstr "出力選択:" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "" + +#: src/stack.c:663 +#, fuzzy +msgid "Additionally show source file information" +msgstr "出力選択:" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "" + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "" + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "" + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "" + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "" + +#: src/strings.c:585 +#, c-format +msgid "lseek failed" +msgstr "" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "はぎ取った出力を ふぁいる に置く" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "抽出した取り除いたセクションを ふぁいる に置く" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "-f パラメーターの代わりに 名前 ふぁいる を有効にする" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "デバッグ用のシンボルを全て取り除く" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "修正/アクセスタイムスタンプを出力へ複写する" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr ".comment セクションを取り除く" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "オブジェクトファイルからシンボルを破棄する" + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "'-o' と '-f' と一緒の場合は入力ファイルは 1 つしか認められません" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "-f オプションが 2 回指定されています" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "-F オプションが 2 回指定されています" + +#: src/strip.c:362 +#, fuzzy, c-format +msgid "cannot both keep and remove .comment section" +msgstr ".comment セクションを取り除く" + +#: src/strip.c:481 +#, fuzzy, c-format +msgid "bad relocation" +msgstr "リロケーションを表示" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "入力ファイル '%s' を stat できません" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "'%s' を開いている間" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "%s: アーカイブから抜き出している時は -o や -f は使えません" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, fuzzy, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: アーカイブから抜き出している時は -o や -f は使えません" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "EBL バックエンドを開けません" + +#: src/strip.c:1092 +#, fuzzy, c-format +msgid "cannot get number of phdrs" +msgstr "セクション数を決定できません: %s" + +#: src/strip.c:1106 src/strip.c:1149 +#, fuzzy, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "新しいファイル '%s' を生成できません: %s" + +#: src/strip.c:1116 src/strip.c:1159 +#, fuzzy, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "新しいファイル '%s' を生成できません: %s" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "不適格なファイル '%s'" + +#: src/strip.c:1250 +#, fuzzy, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "PLT セクションを割り当てられません: %s" + +#: src/strip.c:1259 +#, fuzzy, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "0番目のセクションのヘッダーを得られません: %s" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "出力ファイルを生成している間: %s" + +#: src/strip.c:1688 +#, fuzzy, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "%s: ELF ヘッダーを生成している間にエラー: %s" + +#: src/strip.c:1697 +#, fuzzy, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "%s: ELF ヘッダーを生成している間にエラー: %s" + +#: src/strip.c:1705 src/strip.c:2550 +#, fuzzy, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "%s: ELF ヘッダーを生成している間にエラー: %s" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "'%s' のための出力を準備している間" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "セクションヘッダーセクションを生成している間: %s" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "セクションデータを割り当てられません: %s" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "セクションヘッダー文字列テーブルを生成中: %s" + +#: src/strip.c:1866 +#, fuzzy, c-format +msgid "no memory to create section header string table" +msgstr "セクションヘッダー文字列テーブルを生成中: %s" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "'%s' を書込み中: %s" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "'%s' を生成中" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "デバッグ情報のチェックサムを計算中" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "%s: ELF ヘッダーを生成している間にエラー: %s" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "%s: ファイルを読込み中にエラー: %s" + +#: src/strip.c:2599 src/strip.c:2619 +#, fuzzy, c-format +msgid "while writing '%s'" +msgstr "'%s' を書込み中: %s" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "'%s' の終了中にエラー: %s" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "'%s' のアクセスと変更日付を設定できません" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "" + +#: src/unstrip.c:240 +#, fuzzy, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "セクションを得られません: %s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "" + +#: src/unstrip.c:254 +#, fuzzy, c-format +msgid "cannot get new zero section: %s" +msgstr "セクションを得られません: %s" + +#: src/unstrip.c:257 +#, fuzzy, c-format +msgid "cannot update new zero section: %s" +msgstr "セクション数を決定できません: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, fuzzy, c-format +msgid "cannot get number of program headers: %s" +msgstr "セクション数を決定できません: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "" + +#: src/unstrip.c:848 +#, fuzzy, c-format +msgid "cannot get symbol section data: %s" +msgstr "ラインデータセクションデータを得られません: %s" + +#: src/unstrip.c:850 +#, fuzzy, c-format +msgid "cannot get string section data: %s" +msgstr "ラインデータセクションデータを得られません: %s" + +#: src/unstrip.c:867 +#, fuzzy, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "シンボル %2$sの不正なオフセット %1$zu " + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, fuzzy, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "セクションデータを割り当てられません: %s" + +#: src/unstrip.c:1040 +#, fuzzy, c-format +msgid "bad sh_link for group section: %s" +msgstr "不当な .debug_line セクション" + +#: src/unstrip.c:1046 +#, fuzzy, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "セクションからデータを得られません %d: %s" + +#: src/unstrip.c:1051 +#, fuzzy, c-format +msgid "bad data for group symbol section: %s" +msgstr "セクションからデータを得られません %d: %s" + +#: src/unstrip.c:1057 +#, fuzzy, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "セクション数を決定できません: %s" + +#: src/unstrip.c:1062 +#, fuzzy, c-format +msgid "bad symbol name for group section: %s" +msgstr "セクションヘッダー文字列セクションを生成できません: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, fuzzy, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "セクション [%zu] '%s' の不当なデータ" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "" + +#: src/unstrip.c:1758 +#, fuzzy, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "不当なセクション索引" + +#: src/unstrip.c:1790 +#, fuzzy, c-format +msgid "group has invalid section index [%zd]" +msgstr "不当なセクション索引" + +#: src/unstrip.c:2065 +#, fuzzy, c-format +msgid "cannot read section data: %s" +msgstr "セクションデータを割り当てられません: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "ELF ヘッダーを更新できません: %s" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "" + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr "" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "" + +#: tests/dwflmodtest.c:209 +#, fuzzy +msgid "Additionally show function names" +msgstr "出力選択:" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "" + +#, fuzzy +#~ msgid "" +#~ " [%6tx] base address\n" +#~ " " +#~ msgstr " [%6tx] ベースアドレス %s\n" + +#, fuzzy +#~ msgid "%s: error getting zero section: %s" +#~ msgstr "%s: ファイルを読込み中にエラー: %s" + +#, fuzzy +#~ msgid "%s: error while updating zero section: %s" +#~ msgstr "%s: ファイルを読込み中にエラー: %s" + +#~ msgid "%s+%# <%s+%#>" +#~ msgstr "%s+%# <%s+%#>" + +#~ msgid "%s+%#0* <%s+%#>" +#~ msgstr "%s+%#0* <%s+%#>" + +#~ msgid "%# <%s+%#>" +#~ msgstr "%# <%s+%#>" + +#~ msgid "%#0* <%s+%#>" +#~ msgstr "%#0* <%s+%#>" + +#~ msgid "%s+%# <%s>" +#~ msgstr "%s+%# <%s>" + +#~ msgid "%s+%#0* <%s>" +#~ msgstr "%s+%#0* <%s>" + +#~ msgid "%# <%s>" +#~ msgstr "%# <%s>" + +#~ msgid "%#0* <%s>" +#~ msgstr "%#0* <%s>" + +#~ msgid "%s+%#" +#~ msgstr "%s+%#" + +#~ msgid "%s+%#0*" +#~ msgstr "%s+%#0*" + +#, fuzzy +#~ msgid " %s..%s (%)\n" +#~ msgstr " %s: %\n" + +#, fuzzy +#~ msgid " %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#, fuzzy +#~ msgid " advance address by %u to %s, op_index to %u\n" +#~ msgstr "アドレスを %u だけ進めて %s にする\n" + +#, fuzzy +#~ msgid " advance address by constant %u to %s, op_index to %u\n" +#~ msgstr "アドレスを定数 %u だけ済めて %s にする\n" + +#~ msgid " [%6tx] %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#~ msgid " %s..%s\n" +#~ msgstr " %s..%s\n" + +#~ msgid "cannot get DIE at offset % in section '%s': %s" +#~ msgstr "" +#~ "セクション '%2$s' の オフセット %1$ の DIE を得られません: %3$s" + +#~ msgid " [%6tx] %s..%s" +#~ msgstr " [%6tx] %s..%s" + +#~ msgid " %s..%s" +#~ msgstr " %s..%s" + +#~ msgid "-R option supports only .comment section" +#~ msgstr "-R オプションは .comment セクションのみをサポートします" + +#~ msgid "Written by %s.\n" +#~ msgstr "%s によって書かれました。\n" + +#~ msgid "cannot allocate PLTREL section: %s" +#~ msgstr "PLTREL セクションを割り当てられません: %s" + +#~ msgid "cannot allocate GOT section: %s" +#~ msgstr "GOT セクションを割り当てられません: %s" + +#~ msgid "cannot allocate GOTPLT section: %s" +#~ msgstr "GOTPLT セクションを割り当てられません: %s" + +#~ msgid "initial-executable TLS relocation cannot be used " +#~ msgstr "最初に実行される TLS リロケーションが使用されません " + +#~ msgid "Input File Control:" +#~ msgstr "入力ファイル制御:" + +#~ msgid "Include whole archives in the output from now on." +#~ msgstr "今から出力中の全アーカイブを含める。" + +#, fuzzy +#~ msgid "Stop including the whole archives in the output." +#~ msgstr "出力中の全アーカイブを含めるのを止める。" + +#~ msgid "FILE" +#~ msgstr "ふぁいる" + +#~ msgid "Start a group." +#~ msgstr "グループの開始。" + +#~ msgid "End a group." +#~ msgstr "グループの終了。" + +#~ msgid "PATH" +#~ msgstr "パス" + +#~ msgid "Add PATH to list of directories files are searched in." +#~ msgstr "ファイルが検索されるディレクトリーの一覧にPATHを追加する。" + +#~ msgid "Only set DT_NEEDED for following dynamic libs if actually used" +#~ msgstr "" +#~ "実際に使用されるのなら以下のダイナミックライブラリーに DT_NEEDED を設定す" +#~ "る" + +#~ msgid "Always set DT_NEEDED for following dynamic libs" +#~ msgstr "以下のダイナミックライブラリーに常に DT_NEEDED を設定する" + +#~ msgid "Ignore LD_LIBRARY_PATH environment variable." +#~ msgstr "LD_LIBRARY_PATH 環境変数を無視する。" + +#~ msgid "Output File Control:" +#~ msgstr "出力ファイル制御:" + +#~ msgid "Place output in FILE." +#~ msgstr "出力を ふぁいる に置く。" + +#~ msgid "Object is marked to not use default search path at runtime." +#~ msgstr "オブジェクトは実行時に省略値の検索パスを使わないと記されています。" + +#~ msgid "Same as --whole-archive." +#~ msgstr "--whole-archive と同じ。" + +#~ msgid "" +#~ "Default rules of extracting from archive; weak references are not enough." +#~ msgstr "" +#~ "アーカイブから抽出する時の省略値の規則: 弱い参照では十分ではありません。" + +#~ msgid "Weak references cause extraction from archive." +#~ msgstr "弱い参照はアーカイブから抽出します。" + +#~ msgid "Allow multiple definitions; first is used." +#~ msgstr "複数の定義を認めます: 最初を使用します。" + +#~ msgid "Disallow/allow undefined symbols in DSOs." +#~ msgstr "DSO 中の未定義のシンボルを認めない/認める。" + +#~ msgid "Object requires immediate handling of $ORIGIN." +#~ msgstr "オブジェクトには %ORIGIN の直接ハンドルが必要です。" + +#~ msgid "Relocation will not be processed lazily." +#~ msgstr "リロケーションは遅延処理されません。" + +#~ msgid "Object cannot be unloaded at runtime." +#~ msgstr "オプションは実行時にはアンロードできません。" + +#~ msgid "Mark object to be initialized first." +#~ msgstr "オブジェクトは最初に初期化されると記します。" + +#~ msgid "Enable/disable lazy-loading flag for following dependencies." +#~ msgstr "以下の依存性のための遅延ロードを有効/無効にします。" + +#~ msgid "Mark object as not loadable with 'dlopen'." +#~ msgstr "'dlopen' でロードできないと記します。" + +#~ msgid "Ignore/record dependencies on unused DSOs." +#~ msgstr "使用されない DSO の依存性を無視/記録します。" + +#~ msgid "Generated DSO will be a system library." +#~ msgstr "生成された DSO はシステムライブラリーになります。" + +#~ msgid "ADDRESS" +#~ msgstr "アドレス" + +#~ msgid "Set entry point address." +#~ msgstr "入口点アドレスを設定します。" + +#~ msgid "Do not link against shared libraries." +#~ msgstr "共用ライブラリーに対してリンクを設定してはいけません。" + +#~ msgid "Prefer linking against shared libraries." +#~ msgstr "共用ライブラリーに対してリンクを好みます。" + +#~ msgid "Export all dynamic symbols." +#~ msgstr "全ダイナミックシンボルをエクスポートします。" + +#~ msgid "Strip all symbols." +#~ msgstr "全シンボルを取り除きます。" + +#~ msgid "Strip debugging symbols." +#~ msgstr "デバッグシンボルを取り除きます。" + +#~ msgid "Assume pagesize for the target system to be SIZE." +#~ msgstr "ターゲットシステムのページサイズを SIZE と見做します。" + +#~ msgid "Set runtime DSO search path." +#~ msgstr "実行時 DSO 検索パスを設定します。" + +#~ msgid "Set link time DSO search path." +#~ msgstr "リンク時 DSO 検索パスを設定します。" + +#~ msgid "Generate dynamic shared object." +#~ msgstr "動的共用オブジェクトを生成します。" + +#~ msgid "Generate relocatable object." +#~ msgstr "リロケータブルオブジェクトを生成します。" + +#~ msgid "Causes symbol not assigned to a version be reduced to local." +#~ msgstr "バージョンが指定されていないシンボルはローカルに減少します。" + +#~ msgid "Remove unused sections." +#~ msgstr "使用されていないセクションを取り除きます。" + +#~ msgid "Don't remove unused sections." +#~ msgstr "利用されていていセクションを取り除いてはいけません。" + +#~ msgid "Set soname of shared object." +#~ msgstr "共用ライブラリーの so 名を設定します。" + +#~ msgid "Set the dynamic linker name." +#~ msgstr "動的リンカーの名前を設定します。" + +#~ msgid "Add/suppress addition indentifying link-editor to .comment section." +#~ msgstr "" +#~ ".comment セクションにリンクエディターを識別する追加情報を追加/抑止します。" + +#~ msgid "Create .eh_frame_hdr section" +#~ msgstr ".eh_frame_hdr セクションを生成します" + +#~ msgid "Set hash style to sysv, gnu or both." +#~ msgstr "ハッシュ形式を sysvか、gnu、両方のどれかに設定します。" + +#~ msgid "Generate build ID note (md5, sha1 (default), uuid)." +#~ msgstr "ビルド ID ノート (md5、sh1 (省略値)、uuid) を生成します。" + +#~ msgid "Linker Operation Control:" +#~ msgstr "リンカー操作制御:" + +#~ msgid "Verbose messages." +#~ msgstr "饒舌メッセージ。" + +#~ msgid "Trace file opens." +#~ msgstr "ファイルのオープンを追跡します。" + +#~ msgid "Trade speed for less memory usage" +#~ msgstr "速度と引き換えにメモリー使用量を減らします" + +#~ msgid "LEVEL" +#~ msgstr "れべる" + +#~ msgid "Set optimization level to LEVEL." +#~ msgstr "最適化レベルを れべる に設定します。" + +#~ msgid "Use linker script in FILE." +#~ msgstr "ふぁいる でリンカースクリプトを使用します。" + +#~ msgid "Select to get parser debug information" +#~ msgstr "パーサーのデバッグ情報を得るように選択します" + +#~ msgid "Read version information from FILE." +#~ msgstr "ふぁいる からバージョン情報を読みます。" + +#~ msgid "Set emulation to NAME." +#~ msgstr "エミュレーションを なまえ に設定します。" + +#~ msgid "Combine object and archive files." +#~ msgstr "オブジェクトとアーカイブファイルを一体化します。" + +#~ msgid "[FILE]..." +#~ msgstr "[ふぁいる]..." + +#~ msgid "At least one input file needed" +#~ msgstr "少なくとも 1 つの入力ファイルが必要です" + +#~ msgid "error while preparing linking" +#~ msgstr "リンクの準備中にエラー" + +#~ msgid "cannot open linker script '%s'" +#~ msgstr "リンカースクリプト '%s' を開けません" + +#~ msgid "-( without matching -)" +#~ msgstr "-( 何も一致しない -)" + +#~ msgid "only one option of -G and -r is allowed" +#~ msgstr "-G か -r のどちらかひとつのオプションだけ認められます" + +#~ msgid "more than one '-m' parameter" +#~ msgstr "-m パラメーターが1つを越えています" + +#~ msgid "unknown option `-%c %s'" +#~ msgstr "不明なオプション `%c %s'" + +#~ msgid "invalid hash style '%s'" +#~ msgstr "不当なハッシュスタイル '%s'" + +#~ msgid "invalid build-ID style '%s'" +#~ msgstr "不当なビルド-ID スタイル '%s'" + +#~ msgid "Invalid optimization level `%s'" +#~ msgstr "不当な最適化レベル `%s'" + +#~ msgid "nested -( -) groups are not allowed" +#~ msgstr "ネストされた -( -) グループは認められません" + +#~ msgid "-) without matching -(" +#~ msgstr "対応する -( がない -)" + +#~ msgid "unknown option '-%c %s'" +#~ msgstr "不明なオプション '-%c %s'" + +#~ msgid "could not find input file to determine output file format" +#~ msgstr "出力ファイル形式を決定するための入力ファイルが見つかりません" + +#~ msgid "try again with an appropriate '-m' parameter" +#~ msgstr "適切な '-m' パラメーターを付けて再試行してください" + +#~ msgid "cannot read version script '%s'" +#~ msgstr "バージョンスクリプト '%s' を読めません" + +#~ msgid "duplicate definition of '%s' in linker script" +#~ msgstr "リンカースクリプトに '%s' の重複定義" + +#~ msgid "cannot create string table" +#~ msgstr "文字列テーブルを生成できません" + +#~ msgid "cannot load ld backend library '%s': %s" +#~ msgstr "ld バックエンドライブラリー '%s' をロードできません: %s" + +#~ msgid "cannot find init function in ld backend library '%s': %s" +#~ msgstr "ld バックエンドライブラリー '%s' に初期化機能が見つかりません: %s " + +#~ msgid "%s listed more than once as input" +#~ msgstr "入力に %s が 1回を越えて書かれています" + +#~ msgid "%s (for -l%s)\n" +#~ msgstr "%s (-l%s 用)\n" + +#~ msgid "%s (for DT_NEEDED %s)\n" +#~ msgstr "%s (DT_NEEDED %s 用)\n" + +#~ msgid "Warning: type of `%s' changed from %s in %s to %s in %s" +#~ msgstr "" +#~ "警告: `%1$s' のタイプが %3$s の %2$s から %5$s の %4$s に変更されました" + +#~ msgid "" +#~ "Warning: size of `%s' changed from % in %s to % in %s" +#~ msgstr "" +#~ "警告: `%1$s の大きさが %3$s の %2$ から %5$s の %4$ に変更" +#~ "されました" + +#~ msgid "(%s+%#): multiple definition of %s `%s'\n" +#~ msgstr "(%s+%#): %s の複数定義 '%s'\n" + +#~ msgid "(%s+%#): first defined here\n" +#~ msgstr "(%s+%#): 最初の定義はここ\n" + +#~ msgid "%s: cannot get section group data: %s" +#~ msgstr "%s: セクショングループデータを得られません: %s" + +#~ msgid "%s: section '%s' with group flag set does not belong to any group" +#~ msgstr "" +#~ "%s: グループフラグが設定されているセクション '%s' はどのグループにも属して" +#~ "いません" + +#~ msgid "%s: section [%2d] '%s' is not in the correct section group" +#~ msgstr "" +#~ "%s: セクション [%2d] '%s& は正しいセクショングループに入っていません" + +#~ msgid "%s: invalid ELF file (%s:%d)\n" +#~ msgstr "%s: 不当な ELF ファイル (%s:%d)\n" + +#~ msgid "%s: only files of type ET_REL might contain section groups" +#~ msgstr "" +#~ "%s: タイプ ET_REL のファイルのみセクショングループを含むことができます" + +#~ msgid "%s: cannot determine signature of section group [%2zd] '%s': %s" +#~ msgstr "%s: セクショングループ [%2zd] '%s' の署名を決定できません: %s" + +#~ msgid "%s: cannot get content of section group [%2zd] '%s': %s'" +#~ msgstr "%s: セクショングループ [%2zd] '%s' の内容を得られません: %s'" + +#~ msgid "" +#~ "%s: group member %zu of section group [%2zd] '%s' has too high index: " +#~ "%" +#~ msgstr "" +#~ "%1$s: セクショングループ [%3$2zd] '%4$s' のグループメンバー %2$zu は大きす" +#~ "ぎるインデックスを持っています: %5$" + +#~ msgid "%s: section '%s' has unknown type: %d" +#~ msgstr "%s: セクション '%s' は不明なタイプを持っています: %d" + +#~ msgid "cannot get descriptor for ELF file (%s:%d): %s\n" +#~ msgstr "ELF ファイル (%s:%d) のための記述子を得られません: %s\n" + +#~ msgid "cannot read archive `%s': %s" +#~ msgstr "アーカイブ `%s' を読めません: %s" + +#~ msgid "file of type %s cannot be linked in\n" +#~ msgstr "%s のファイルタイプがリンクされていません\n" + +#~ msgid "%s: input file incompatible with ELF machine type %s\n" +#~ msgstr "%s: 入力ファイルは ELF マシンタイプ %s と互換性がありません\n" + +#~ msgid "%s: cannot get section header string table index: %s\n" +#~ msgstr "" +#~ "%s: セクションヘッダー文字列テーブルインデックスを得られません: %s\n" + +#~ msgid "cannot use DSO '%s' when generating relocatable object file" +#~ msgstr "リロケータブルオブジェクトファイル生成時に DSO '%s' を使えません" + +#~ msgid "input file '%s' ignored" +#~ msgstr "入力ファイル '%s' を無視しました" + +#~ msgid "undefined symbol `%s' in %s" +#~ msgstr "%2$s 中に未定義のシンボル `%1$s'" + +#~ msgid "cannot create ELF descriptor for output file: %s" +#~ msgstr "出力ファイル用の ELF 記述子を生成できません: %s" + +#~ msgid "could not create ELF header for output file: %s" +#~ msgstr "出力ファイル用の ELF ヘッダーを生成できませんでした: %s" + +#~ msgid "cannot create section for output file: %s" +#~ msgstr "出力ファイル用のセクションを生成できません: %s" + +#~ msgid "address computation expression contains variable '%s'" +#~ msgstr "アドレス計算式が変数 '%s' を含んでいます" + +#~ msgid "" +#~ "argument '%' of ALIGN in address computation expression is no " +#~ "power of two" +#~ msgstr "" +#~ "アドレス計算式中の ALIGN のパラメーター % が 2 の累乗ではありませ" +#~ "ん" + +#~ msgid "cannot find entry symbol '%s': defaulting to %#0*" +#~ msgstr "" +#~ "エントリーシンボル '%s' が見つかりません: デフォルトの %#0* にしま" +#~ "す" + +#~ msgid "no entry symbol specified: defaulting to %#0*" +#~ msgstr "" +#~ "エントリーシンボルが指定されていません: デフォルトの %#0* にします" + +#~ msgid "cannot create GNU hash table section for output file: %s" +#~ msgstr "出力ファイル用の GNU ハッシュテーブルセクションを生成できません: %s" + +#~ msgid "cannot create hash table section for output file: %s" +#~ msgstr "出力ファイル用のハッシュテーブルセクションを生成できません: %s" + +#~ msgid "cannot create build ID section: %s" +#~ msgstr "ビルド ID セクションを生成できません: %s" + +#~ msgid "cannot convert section data to file format: %s" +#~ msgstr "セクションデータをファイル形式に変換できません: %s" + +#~ msgid "cannot convert section data to memory format: %s" +#~ msgstr "セクションデータをメモリー形式に変換できません: %s" + +#~ msgid "cannot read enough data for UUID" +#~ msgstr "UUID に十分なデータを読めません" + +#~ msgid "cannot create symbol table for output file: %s" +#~ msgstr "出力ファイル用のシンボルテーブルを生成できません: %s" + +#~ msgid "section index too large in dynamic symbol table" +#~ msgstr "動的シンボルテーブルのセクションインデックスが大きすぎます" + +#~ msgid "cannot create versioning section: %s" +#~ msgstr "バージョニングセクションを生成できません: %s" + +#~ msgid "cannot create dynamic symbol table for output file: %s" +#~ msgstr "出力ファイル用の動的シンボルテーブルを生成できません: %s" + +#~ msgid "cannot create versioning data: %s" +#~ msgstr "バージョニングデータを生成できません: %s" + +#~ msgid "cannot create section header string section: %s" +#~ msgstr "セクションヘッダー文字列セクションを生成できません: %s" + +#~ msgid "cannot create section header string section" +#~ msgstr "セクションヘッダー文字列セクションを生成できません" + +#~ msgid "cannot create program header: %s" +#~ msgstr "プログラムヘッダーを生成できません: %s" + +#~ msgid "while determining file layout: %s" +#~ msgstr "ファイルレイアウトを決定中: %s" + +#~ msgid "internal error: non-nobits section follows nobits section" +#~ msgstr "内部エラー: 非 nobits セクションが nobits セクションに続きます" + +#~ msgid "linker backend didn't specify function to relocate section" +#~ msgstr "" +#~ "リンカーバックエンドがセクションをリロケートするための機能を指定していませ" +#~ "ん" + +#~ msgid "while writing output file: %s" +#~ msgstr "出力ファイルに書込み中: %s" + +#~ msgid "while finishing output file: %s" +#~ msgstr "出力ファイルの仕上げ中: %s" + +#~ msgid "cannot stat output file" +#~ msgstr "出力ファイルを stat できません" + +#~ msgid "WARNING: temporary output file overwritten before linking finished" +#~ msgstr "警告: リンクを仕上げる前に一時出力ファイルが上書きされました" + +#~ msgid "no machine specific '%s' implementation" +#~ msgstr "マシン固有の '%s' 実装はありません" + +#~ msgid "mode for segment invalid\n" +#~ msgstr "セグメント用のモードが不当です\n" + +#~ msgid "while reading version script '%s': %s at line %d" +#~ msgstr "バージョンスクリプト '%1$s' 読込み中: %3$d 行目の %2$s" + +#, fuzzy +#~ msgid "" +#~ "symbol '%s' is declared both local and global for unnamed version '%s'" +#~ msgstr "名前なしバージョン用のローカルとグローバルで宣言されたシンボル '%s'" + +#, fuzzy +#~ msgid "symbol '%s' is declared both local and global for version '%s'" +#~ msgstr "" +#~ "バージョン '%2$s' 用のローカルとグローバルで宣言されたシンボル '%1$s'" + +#~ msgid "default visibility set as local and global" +#~ msgstr "ローカルとグローバルに設定されたデフォルトの可視性" + +#, fuzzy +#~ msgid "cannot attach to core" +#~ msgstr "検索ツリーを生成できません" + +#~ msgid "unknown tag %hx" +#~ msgstr "不明なタグ %hx" + +#~ msgid "unknown user tag %hx" +#~ msgstr "不明な利用者タグ %hx" + +#~ msgid "unknown attribute %hx" +#~ msgstr "不明な属性 %hx" + +#~ msgid "unknown user attribute %hx" +#~ msgstr "不明な利用者属性 %hx" + +#~ msgid "" +#~ "\n" +#~ "\n" +#~ "Symbols from %s[%s]:\n" +#~ "\n" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "%s[%s]からのシンボル:\n" +#~ "\n" + +#~ msgid " Version String: " +#~ msgstr "バージョン文字列:" + +#~ msgid "Equivalent to: -e -h -l" +#~ msgstr "右記と同等: -e -h -l" + +#~ msgid "" +#~ "\n" +#~ "Section [%Zu] '%s' is empty.\n" +#~ msgstr "" +#~ "\n" +#~ "セクション [%Zu] '%s' は空です。\n" diff --git a/po/pl.gmo b/po/pl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..8800779b533b945c1cc6b310b67d046dc08ce4e5 GIT binary patch literal 167391 zcmb@v2Vhji`uD$yNQqRXN;{ND0!gSUB49!iAQFlsbPzVlrbx1hy9w2Tf*mW^yy|><#C_w(vxFF+2|*22)nqvWwto{I$-%38vtG40eWJ!>+K|DK=go zsCpE^G`Jd`0k^_AF#FU%pd(xlyTQ${JA4@`zi;7Wm~>ho&Vc2~g?Q zLA7riYz<$4YUjI9y89J2hx?sw!`s6S`1?TB<1p9@PH~Jt>2EC@0I!Fg;L9)zegXT# zbQ&ejgeh>P<3^Z{|5fMThmJcKe;UkzMQ|j%9xB~VCvSCDATSpHR5%P?3J-zLLDg^H z)waI<;6VJN;ejv=rPnjy1o#n5hJ(+x^`8Mv{orim8=>r_**R7(-C%$G$?zaJ1vZ0= zq59!O=YJlmyd6;af9L$2&$a1>LZzDxWe-KLB|HHt-C0n2z0S$ELiP9KFde=N)sL;t zv+;YuKKMt%esBTY7oHB=!gF96To2Ws+hJ??0c;Dub@IgXtvz&xDsKpE11CWB{~Rd& zMx1;t9Eg7dJOaJ~Ghq7*Z2WBK;hzm>4$ex;Bu z2%G{n&O2UW;|+zK@Xv%JU=37%+zbc6d!g#}3G57igKFmim)iMkEL6WNgKFJR=}?CGRMtO_VE%t5Ps+Ut^Q^0Djh0(0#x`ysQx<@ zX2Tny^!F8%9{z-CUz>GSKOR&&`$OqxI8=Bh>;{j5$}bE(cs`s3?|`YW<$B9QU>5!b z@Bnx<90WH*>G>0Q6l{NGAaEosh3dcCq3ZoKl%79=(r?SF?7Wx(d*CmD9pFkRJGd0e zZXbg);P+5^o^Z9Te>GJ8E1>jxDeMI|L5;6h9shFdca5#b6exRL2uH&6U`O~Y{IUu2 zF_itic!Sm7PIxf>uc5|g-y3bYg;08|f|KD1Q1yKdJ`VqYvX@70vi186s^9my+3Kq& z%)*}!HQvvG+>i0{a?0F+pdtQMZ;4bHHy4jA? z-caGwq3RuhD*tRKJGdFDzg~iB#}82Db-LTO_YkQ5T?qTYRZ#lB0S<+)L(Nkyx7hjQ za5xHo0aSg@hbs4W*b#1r9{dotflanDwqbiHJ@s^)2vwiuusvJ{)xJ$o?SBd?zqg^< z@dH%7yWV5A(HaJUVspMG@m z9@~h6e-&%$KLt?w zD1p**4eSh0g5>;%7Y zZ1#xFwF@O`Ly?}DX$;ZN9ksm}3AsD66}%ImFN9;@6;SPb7s_6n?6CUFg3|xdFc~g^vV(Q-6L=pS z46l9N+S?A;2md~ASpD>aDrYD>7?!|c@G_`!o`-60%m3K%mjb1S39ucU0~KBc)8QFV z`QHuu!8f7mz0aGr9x2enKO3q)mqXdprEns=7fN3(-r}qe=fR+al)g*eM%OS5 zhBMs^x677J8ukw8n5GE zYZ!&9_sLN4Hb9O0r{RHc2UI@aLG^3*_pN>=!d(2zq3qxxsQ67ku=)3b9q~_u9xQ=r z@Dw-%-T^hfKZ3pBUr^_Hr`5+0=;5CW z75{kH2VMqy!~325eW-MQL5-JAAK7|mLiuOFE^q}@eJ*qUZBY5X20Ov;q1wCO$95d_ zhU$l-;Qnwal>Syj>2n)YyFP)kpG1sY{o+B{Up`d6%b@gj0aU#ofU3_2upj&bCd0m; z+WH*{55ivw`@%KOzXfW1z6+JU^=CF+3Y6VUg3@mZR6AEf#k&@&{tvkDm!RtREmXNZ zKezSDg=$wh>3b7YJ$FD4{tcDR`@-fk7Ak%%RD0J#^~XlX$Ds7|4orc+Le;PL zmsVdnQ03G>wQns{d5=KN7hgc>xBFLi9ylDTT}zz!0%~1XMChQ7-fr{7uYg>K> zJOqCpOoJ;NZ*lw&)cn)z8@vA-4pr{4Q0+Pw%08}#YTx}({ka1w-fwUK?7Yj$bD-K; z1_#13pyF+X>faqu_5KS=e|^5S`pJfhR|(agGokc%Jyicb4BNu@VQcuE^Cx^~>$yKv z{rW?t&xR_00hC_OgG1m(xIcUss@~s0mD}TcTd$E&7~^#HvRx8JI;lvunM+=7rXEqVHE!((1VBmYTGjts{R#l6g&lvgpWY! zE%2MQ-(=VY?^L)LR>J+@PN?*|pz7E1cUzC4Q0~W(^{tVQ3`W_w)JN;qH zT?9Mf-vnhZ&%n;`9e5!88K%Si|FrpKLe;Aj9s*au!SHUVarc>H$G@ySWy3beXE=Wu z?23Q6^Ir^A&dsnDd>nRwuR!(x=g$8-?2fVG3t`g@%G38;R47fRnv5)({&J3;9o9m;OUL+O1vlzrU@H9lT;+-IKz)83)bLq5j& zi=pZtfwISw9oNDh_^*Q+Z;!!V@N200wrygW0+l`!s-LGo)$16jemMn7@0UaM#~o1l zy#STpuTbsly049&3DrN-q4c#7D*PNMJ#K=k*AA$D`N_$00G&~KChmXS? z*ru7)Zz1f4KM1Aw6QJ@t7v{pdp!)B3D7~gNxBWgFs^3n5vg3_V@!o;5hc+#2Jr0M7 z_$RQV7C_lW7)t*q zIbIIc|983YkD&VL7pQWY?`Q2H8Oq*!250&4`F8o7y zB>tbF^fjiXEvE)bPiMns@ByfLKLKSQuR_`D7f|s!v`R4NzHw0XJP~S~UIB-}o8eLL zJvb5$X`Nusht*K!-wIW)-(WkK)W)Xo237t5sPR4&s=p^g^-mp?-8>GDfPccda8%m_ zb3b$$JRJW!P~+{ub_wQQXd=wUe=1b?(~eE|xAHOYV1>g;a2uQm_dCG)XTbveH#q+v zPA~?-sD5|=YWyV~Xv@ii z8dpo8+IK(9g!^>0_054L_!mRz@hvF5bncd5?n5eJ9{xMwQ1};AKMm=g5I6=#pvK?Z zQ0-{Z!+w+Sdkm_-5>ssa zESQOZB~&{eh2!9_Q2m>gYRg#-gZN*E($|RoHlK5$?EN{Y{^&ly>R|?y{|q=6J^~j& zFU`h33Cd1hfSIskx~E^n58)yl0^F)OnzdpYM1+)Oddl zN?-j3+4+11)O>IP8~``K5%2}5^7b2S^)v+z$A7lt<4}708>(HShgdx=fztPbPHF}56U_b0N~m()fU{udLlOc-Fap(oufln7 z|3hv38n^)ed$p||i%y2v%YW~{_ zmG75O^__CKZO3Xj8UNc*?MWY*5U7O9Ul_dCBp~m~gP~p!)>9tvo-RI=NzWB?a2UkPQ)3?B0@HHrV`vq#f z>XB>b_Y5e11j;^7hRXjAI3IrLm_OFmXCssz-hml#-*L8_VNms-2fM>dq1t&j)cW%` z><1@~x8tY|O5e9Y?K3`r+SmUEmHvP{yIv25TEE9Z?MtRPc_~!<<6t*e5dW?ojUkbaz6P^EZC_UZ@Ro)v=`<>6B+WRL|JJKdtJ1T?+;6Dj^ z@It8go1ykuPeJWRKZEMeK)wwh0wvFd+P}_)`@qGp4_ppa&Uz?&eFCZE1>GV4r*LI1T`-N z3T^qr;H!9#ffvEdX;xo5pwfTm{B5UOeGhtJhm0+c?^hKhe3>;)fm{J_bZ%(U}B4=DRS5{`vMQ2V1Bq4c-| zsvi<(Sq^{-FLeHsq1OAGq4fFz%z|mNZTv7ChyP-z@OPossnj`k90#H7=yK@6N8oU{ z6RQ2)=i2pjBs>cLI;eSK7t}n~ah{!j$H1HL*Fo94ceK^ZFsS;Df{MQoYW!UcH6Lz( zvb*o0?D}u0@z`g+wX-9k(v?E#`2r}tUJjGsT~PM;Ae0{8g3A8~sPUDsz}Bx9Y>&SX zs$CUO<(v*R?rw#u$NR7y{0hp>{)U=Ah6b%2Pk|bj#ZdKK2Gzgooc}?n@SV_uzeDM( zTahh)4AeX^18TiH6>9uG0yVGff~rr4V(T9V)&G@H{d^(RxZ4h8mx(1deRrt&^+>4x zJryec{ct?|5oW^CA=~dK!V&nlLe1+xK-H^nskOTTsQLE|{NZ{%&^RA4A!}uTbT6t+IBO1~rZ+zy)v-90hkk*=>ig!&_HqxDo}Y%Y|Bs;hf4@jVU?I$a>hH^- z?D-j(4HKev{>X*0k6BQ5eKstIPr)iUq}KNPl~CjOL6{0Zfzo%oI;+2t(2P?kyIlvR zuX~~T`)jCuOut3e{!fGIzs*p3cmm4KKZeSG|HZc7M>;NsqmkbMHBP^U8oviFvHh73 zWj|}-oDCm_8lT-)un$gPn*cRV)}LhO z@8_Y1|7WOi)A?kZ?^vjDvlgBVpMr~E{z^Mu9)Vf-KZRPi`me&?SO~MB`fd4Hww$Zr zOZZ=evdaytZ8;x64}aUUt=^tcsj zTz>$iuf%ihcF20i#LlsyE_v-u5x8n+Xm(w_=d-)rF! z@KqPy;e1=p6ev4B32J;^0X1*zgsNZS1vb1lRJ}$)*-sd1T$~8iZ|6Xjb05_F_!U%p z_g`b#5B9=85~@8%L+N1=l)bKpS|?tDD*tb&c6MKD^^*zdw!jRi`Ds4X{I?Jm!@J-d z*yTc7?>eY??m{Sg{Sd1B4j0*YheFNMYv6SF0z4A-yV#z`BJeQ$_e0GizrYaO{}MZ{ zmOzb{+hHMm6W#&`U26N|9jN-XxXkLk0LuQ>z)ZLiYCrgu<35*Lc^9a3v!U#K1C)Kg z1P_JHuCVjQ5m5aQh3bb@Q1-C~%ARh6W_&}n`(xZh(( z+H@6A_PY``hxa@A6HxQa`>+-K0m{x2ud?;%2PMyj9y|)Fo)ITMA4*T_q3rA5Q1-eV zs@{J<54OMBraKsB;V*>J>qSuW)h5U^7kCV6+-!$q;U{nw%(x~YPzFzjvgch;`E=i4 z+dm(U!G94{|Gfd#-p^fl^0l_Sxlrw03RUmbPJTI5x-C%l^AuG7ybEQ|ovyRvv=Fwz ze+pDTUI>+LBh-3xAC%sIg_{4zU2pXmh0^P}Q2MzOsy}za!{A?VSt9pYH`sKWZnE>n zyHI-VceC~9LhU=whRWw9sB#lG+I}Am`{6$sYM#6aY94qIO5aUxv3A-Esvi%59-Ic% zo<&f4J=^)8hqA+uq2~3ZesC8Yq}*ovaXbtnFNT^=AA_>r zT`s)E?N*CRJ!}1 z?C}j)3crQD;LJ@{pUYr5{s-VoDtzC2tX=0o zm2)E0`f@i^d;f+S9|zrQ^;!UB&&5!BSqfGEi=pCehsx(y=O4Vy=6^Jl-CPP~x7(rm z?_0P4cDv7x%j01L{|>0}cI5pDfh*uCP~)rj0||kb;b52q_kGarhucEc_dqxoX2B_N z9h?onfwGe$AF}(rVkmpK6iRQK9Y2ApSLcVVy=6n$$I(!BaUPW2UIR5ApMn~%KSH&u z=_7W04}h8Y%N=iobMSu-)vse8wf*-msD616dhi>l{%!l1?Vk~FD*mNV_1zAo=g*+l z<&KYAJ3j(y{2mP@KL@76yP?MKM^N=`^@MHDVbH_B5NhAM8YN7TLab4+o0_J2j}njlubVgs$Gkq;$I7;=jWit4RzjUZ_OQ8DeY^Z+R1Z9UGLDjGGvv!>x2Nk~D z`EP;4@xKo>Umf_I)$eGiaTj*}^Bo_8D*s!k`JwakR&T?g>bU@_yvw2V`ZQGjKSTA) zpcicTT&Vf`ENJF8sPVN69uAXVwCRIT`Z@=yotvHfT`2vwe95LugKB>ej)JE-`C~8> z|8G$JfB4IG-Z~blKAYhL_yJV^X1rqCKLx5ES3s42J5>H}IQ|W#hvZl7J$61+J1>B0 z|1(hi^&8YYH{vzBpF07{?w^7l{2prlZok9odni=;=}`4M1xio1L)rNkPJN}=?<2C9GWcYGgeU2XCoJKy(!n)eQY(n}#!Ig6mu z{|k!9lM4pjY`zGeLfL-pr8D7!n=$!~(1UtWT$|Ics? z?DMwumqOL!0yq+Gg=*JNQ1;X39cvdeq4c`M`7d_7+sSu8_18~Oc02H08~+%n^3QE(B*c`E098^0E+omW9)?@)T(1xw)mA6R`a zhSJN0Q1*5|^x#g%eLuAIItWVdg;4rF1)BWfM*NRK4@P#{`Fssje_jW*pMMnQ!qy*I zdn|;~-w9ChHo;o>B20o~KeqWF1*PvgDE(Xw)gLcF>EUM=p8AOmpAI$dR>7m;J#Z52 z@~PEBIn+2_1Er5mj;}(s?`J4GNcqf`UkLN@FM%3gk3r2B`+jcwGYfk7m%%pha(E!T z87lwBq3rxqDEm+R!tU#mq4YQcc7oHP^bm$Be>Id{Y=N??x1sX;19pTxzO;Hc7;62R z3uO;Wq0(IiWe<-->FFmZ`%C%Cj_)AsjQ?^dz1|5AfFHn7@F%EwW7yYL|3^dF(OJ&F z8LD0%LgkbAjZNPbO1}f4%AX9?t`ni^`7bEDxd%#*@4!rW;4W+5bD-v*a~z+9+7~5$ zYwff%ls>bd^f1TyBT#x=4OPz#Q29R()vx<~XUiSwxBx2ORZx1p%*nSw^~-zEgMUDc zkM7^wdX0seS5`pj^;W2My$@Bdzo6oG{=vq}f~rpql%6kld;iC_1E=qD7+U=gWo{uFZX9Vf1C&vz8R{%pF_=)-F~t03gN-{ z&w*<9qi`Si9-IhwLe+1`uXdj}9?CxhYJRGM(%%Lre;le`-h%3n@1e%Se!tm!`-5P6 z{6nGaW;|5-Ak_S`63YH=gwp3HjtRe8d+Q2iPa~l6nF-adDyV$c!zS<{sD61ID&G%X zc#A)*-UdLWKLXB&g)kG|3Dr+O!eOw_pLRZ)30vVWhSJlqP{!fRnEyaOHyyZmj>9VKu9{yU-ivje~4lHO9G#!(h*34>7cUKpy}3!(O}kHgWh zOG2Vq2WG;>_^*PqB~MHY%!IWt3qA`AV4Hms&3U94D*erlpF5^DNi_N>hl+nARDOTL zS#ajQiRL_Thhv+jiDsU!gcXEuhO%F;S)!SLkAsly1y$@x- zJzFH2b#fL|JJ&k@Cs2Csos?+i8zX{HTzrk^EMk||sJyiQ&hH6j0*0!BXpz?bdo(zA3s>ktd63zX`BT)4o&^FPW zOHP1C;C~fPfF0T;25Mjs4uvnlY}j=FMDusAN5Vz;uZD%N%K?dIJceO4{%y{m);`gE z?_35|{?kzFd)p3H?{#oG{zswurEAATbB}ill)k=z(r5opiRSxXDa^#b1rCS5!Ub?h zXB&SF)cW)i)HwMIYX6be#pE82i5-%10@dzj zDK>sSlzy&+vX4)o>^?o!_D>B|d0XIQ_#@Q3pW8pt?4Q=aWAJ|m=fQactp8r9`W}>K z$M4Bd`9BZU?hffT{sO3Z=YF^V1~RN22BG@z85o574Yc`H!7BVu!DHc}gKWKSgc>)$ zLY0#{*xJomQ0;jL%I=yBNi_FEB~W^L7D~TOhuZif;BokCpwfK>i{YSQZXSZNgZH7v z-=KqSeXfUV@OL=G>g`6Tb>~|s`|NY5ZRa8=JKqA;-@BmZ-@}Gm{{>L}^(IvL`yFQc zZIa_jQ0=%AYW-oJ(oe*-yKlnCuyXu&jKhtZG!6GU!mrKLq^$j zXG7)lI#m68j!rcD#t787z8GpfeGI0;Phc`^cZBsH3ftiiLZy#Ft@DpV_3Qgk<@d@= z44eeZ;41hT)OZhPC7ONx1}OiFQ2o_xjO~X^*c1QR&VLJ({r?7~_et4y9Ib%T_XDsK z{26wHZE|e-gJ2i@V__S(0PYWKV0*X{s@|8t9&nT6OHk|Xw@~T+f|~bQ=UV-YfU@gy zsB||uJ_SAepThpI#aNsFFvrPI>)bI=`^X!h>c7KQAk^I$I+ghSv;C_Qg>@-Ly*gVuR=eqI9m;Qt8rhAob?<24PM zet-(U1xhb3!UU+Nc@y^UD%3r1!BcRL;2tH?t4@ABaYDrX7JmZrx%l7a{bHQPTxMJz zXC?AY8;7|BwmEqXJcM+s$fH;?-e>U6ktnc@c$J9s)Z(9pTzb{hf-pT}kn6b|_b+52 zn2Eceyf)x(O?YpZj60h5k6;Am5q=!+PvP|Zt+ILA;=hCN6X5wyR^sB=7<>Nv1ELnh z%_rVlF3q*PPbVKe2RL%94KzVsN;_&{5plcQD1lmJdL|>+^9NxMy1bgf8{GR);@wR? zrxI^IGLE2uAhNCax8oMzxMnbRwpwZMClg-E`_(RwO9^MnHBS{`ZE<=YcHw$|*S$yO ziF@`#-U5Fv>;RdH&BKw;JV&{775FvA^jzY?${i(pTJNshyLk<|uW zCPx>|faA7#E~hL#nsa`4@9)5=F8q7s2f6fzxbPanPIt22$Ufx#aTk9Zd_fuVOy>Pk z`)dCE(xn-X{8l7Ky8IN_3Yq4QgPp7rKSvJpTx$_nK-hP?HDh$;FdMYx|kb z|B;L1qXY7vNjns$X9sCJBFl2|+d1Au_#*cn!xq$c9yq8&TfFoxhgiOx@ zS5{M~^=CiWgYa{S|B_4J*VUsXXVlIGL6NE=Bvi}0Z?uU8zi zkbRFk+|@&SlGh09i2o_L0~f-TBY%%Pw!#yM|F)|~ic6=Wt|nf?X9aQDN|@(-{_RKn z;l#TW`N_y9@~-t>d)!Kw*FA)>oelgO>bVlP(1k^jt;K&4>9|TX&pybmA%1`2^mS#G zxwML~j`uCZ{SRSByL@)oq~_l@;@UGkxZ48vb5sJWb8R6~8>nvoY zgmD}Vu;mNfhtqSuqu!sl1_J03oWY%s31OPlKIPyu@p=K|8*LiidN9(8s24&LP63tU(`;(kEflW=-^;P;;g zh@N?o0iwjfuwJ!W%>e7|>5%6OLxaU=5%ia4`ab^9*dziSt!;$bR zmruEia|UT1r>t9%U*l&6*Wl7zT!~x7)#oSDzJ~v4ftaRzd!ybem z1h>F@2s@rMohbJU7ykg4x4fHi>+r9LlSw{}w0a(aeaY)>=RX|T1oAqM_)Cy2HnEsj zkTrZ>CeBFY2jTj;z*NU+@OI?K;(q5n)#bm))#Fw;)xF;hgT$%8O`$Fvk^dzd&#pG@vbIb6W&kYJ;?iWxVQ1gKcgD>6*kY+p6kA9Q)1hfaG80(v5TVn@^fU zT-?FPUU%U)$K}5->0WgH4C0^Y;(to~+X*`d>U^i?0*kVy9j;wIyYc|Xd9KjiY^h#oi$_Z$9|Bw9*6ZglOv5^i$wz9j4i-e2zK^iLfW|`%g0RHO_woVO{WVhR47^kUxu?PyOzMhaoF;b*)lf`1=vp zfBNIs^B7Eb?~7gDt&k`3J_H`ENIZ4ql?VTg%jW$d!ngbB9DBO_TjFnz`<^%*acf=p zZG<1E%-nO1ldpzDi8q&gvw80pS5HO#!^JOh@ehP$#MRxp^3k)L_b%jf zI4%W$m6I#%S(pDLm!D+*a~5IUU7qig<{SLeU3@=|xS6mqxWioBONsLs{%JTpoh<@O z2)`8BU6l0+9OL4jNchdJ{Ey&Qq#sLoFX-VG;o1>*3$n9aUcwD=@6W{5zt+i@!TzMV zm-KoH$YU(=Jopp*EiTO&?tPl$LgF9E`>ihRVUEgYFnL~&)AKLnQ^{{6@3}_8T7Z8R zPS0?{kFc-&Hxb+mvNH(Zj(2=qz6#C2zmmK+68A0Ki}>fcyn5sR(Ut3R3N%O763<1r zPA;!A9TN!~<|4LndHCu6bou=01W&3h@Nu)oMuo=WV*~y|V&mWL~ zfUK0TV__EZ(WGsQdli3A!jI?Of7avw0+)v@0X~A$vk6`T&&8d?`wOIfjyQD+ z^?DKERg^Ua_l*l1Nxb)XFM&&tKMzOYX1Y3sNi!YiKkxJM4B`IsAn~g3k4Dg*czKll z0{%ev$%`#KTrCfc>e`A5ceLkZ*jNru4gdedM+g2 zO5A*xzm<~C<@p~3BZ&JW{>gqIEQou*g|ye>?*@~o&w;oZ#2*Zkklp3-`oNW$j(;KV z&0LxL;_r_83jb;3Q|#p9NIwSo6LDqjgRGPDx8hyT>BO0d+ZTTcE*sgyt}KQ3CrnR* zi+_ysOZIx)dm`bV;D6qge+2&F?p<;Fx%bX+9sYmA{ovW8xsUQzDH6}mxPkZ|Mc$P6 z3wS@`;y)XAf)f~OnJ-f(n2>H#k-oO{g)A45$cRgXpAYaaV7i4+{;I2Xb zGww;`-$Ok)F1!F)U-FoPe1i*nA0Fr4758J}_)ly1@*A?pNY@7LaCHmAD_pvfacTbM zeKqM`a`7fmb~ji4JA~yUUq-rLUASMCSWUdo;_5P&_hU%YwL#oJ;^O$}k0jowaq=mo z`3BiJMEDz*gntF$Wyo&l{cD%!O@!TmOwZ@I^IaZ8TzGS2%c$2^u#~XryeAO$8vfz9 zWAP8e&2f3$=h9`y)#XOQ!o(dwJUvHQ#Qy!v0MEl;jeMt*MTonQ_v_$P!kW5#c-5b$2i_#?7WfSEUM@`fc!vS0vGWm>|0~BI z9DjFAoRDbNpcYW^+e5|g=Hz{#)}RcS1cy0}cJlF1@h3S>bDRq|ma{j+y@LA`_Xn;s z2lZjNDY#193fx-U7Tk8+d$=EPZJAvA;)dh$aSL#@xYKc0;BLb`ihCXRB~Cx2Xpc+5 zjl@mCmEe}(R^x8KZNt5Q+ll)H*S?aq1DB60$F0I$g4>9D5cdjh7p_Sa^~R;)GI52t za@=va^Kct*TX5TP@8N#HHD|)4qDG%fZdW zRpM6Q*5Yo!ZNt5Q+ll)H*OH4u4>t@q9=8_vBM?+zYs!xLy9#@Gw54REb zDXuS%q zadUAsxK+4IaNBUN*-|oA)Cd!rbtb#O4}vh{;mpd?CxFR3R_Cpp}Z?@FGoM@ zWx~>t>FIA_@>RODiS{=aN~gW2=%+h@Fx63h<*E4h#KmvxWIrGq=;F0@RJ)bV&nuG+ zLKgn`{8u6ygG`Sf?+IkeOOG%61zA7mZwce`NS|zf+oHIBeZt66U3`6`P`$Sy8`?nD zev17)j`Hj5;*CP4Hpk0qkc~p7$FI|^$W$jizU*~m(xH}b-BqgGeK-g-lw~-X;`s4q zH6mLTC-d#+W@LW*+qp6xh>Pdv_j#PmPuq@5=!R*N8<8D`Om$XXim!GQAsfcK9<@)h z%a9E+627@Op5wwwIXtLb#Z7XuW0CdYU5~G`i;(45k=bJ@->FBZW)gGru?E*fzH*XH zN2YNQFDpUTaLh$rTIou4P})^-GC#lb8l~y&EU%?PN_k z-1zbOI@!QDnZ~Bl&O@g8PHk0tBs(3MKdyY)y~w0L#q;&@E;5aGwXF+IX`9cjPwU4U zf=u<7-*4|YCzCz-vbl}KJGK$osmT2L&2!}@&9i0THSJJYDpPgy^B?Wv#Mh$$+5W`Q zdf>+^b23CR*>Wd~PkU~hOmek<12UDXM`cTPuam{6eF2&JRgcP6y!Vhvk9z$4{y^rB zIX_;jqwQ}FbtR7!>GBVkj9uKFw+|Y>Zxj31|isJo^ zOyf^&_3gX;{6zD+DMYa{1|akMOk+ez=OgRLyV@$5+Ueos*SxAZOZ6B1F)6to#nI#I z>1*=p?)?8PFTdS$7TC2%`TMdkvfj#=M|D#@uS3>{ca`^N7NgK?^F8!j{bv8uN1gHyP|a$Q*bxF|=a`Bm|JJuE>c z-N(z$bn%pzAMY|`(v!+L1gA1SM%K{A0wp$H{CMw-O!1`C1ebQOix=M~c`hDNV&xVi z(;h+b{Bdy_GTET=^XqpmGQBIFud{z4>wsT6@aG6W>_x(SJ5~GDp5`3BHAlqjqMMV& z*K?4Q#kVoX$)sPuPBW2p!>`A;*&fy#8-LFeC)vrQZ`D<0sXi@A?Hr?V=jYi2nZ}6f z?8}BVB0I7X*@8x7iyD!wMy9@28U9}Fo3)g}^ZVA%b4(GAv?Y zPZBl+nc{1|6Q6FtLaQ(3lY&!S>yRDh;%R(H_6V{uyepn>!~Xd4>(IN>{*6O?{?*8) zkVcOm?;&J^tSBb?9@zjFM|KdO$G|FEAEnngRehEtQ#&Oa=45XpJG_A`KWxXi@{`>u z?QzI@^BynTifk-0J$^kCs_k#t<7ESo^+%v_sC||4o85@)43}1M{CJy@r8>Va+ZiYG z?Wc9ko@ayJ$Qq`df=qQ$UVhr;jif!d5!p4!WD80wJ*XY8BFp7nkJ=|$k7KRvNaox5 zOnG>G|7`1x`IGT0?NO2XbB8~#9*s=p>hbk_F0yEb-m~~d!CY>HAm?2?dTrD{JnwS$4?-W4ao1yUPab$4%z9_s_*=@ z;Kw+bpEmJ$TZZEKvNp(+Ms4)xi4nm?6xpA+og z8L6!;oNN%Xbl&x--HKO^%;R10e7&57tSx@k*K@ASp1%% zi<8C28`Oww95TOt{@OBzy!H6wqxA~=_eYYcj>^;D6Zv&G(#44{uNay3;?jj5ZxJ%B z&w6~>naGr1eA@NMWKWXGNpD+_sZM&NC&^w$ru^d5eu7N()Z@qd9a(QHisk2>Wa}3n z?_gy9T;P{`0y5dB9>313k@>64gg~d@7C}zx_2U z>+Sl#<>lAuBhqN>D}P`12QrN*J^o$5*j0ADS6TmS-cOLmZ?E6KzaY~dLHS6}vN_++ zRk9g-@@ougtc!}LGDY7n`g7urQ|r%7>T88*?1}!~$2-mL15~c&cfTF#gCZBEI{G?T zjm)=eU$y~R!!dn7GU-TV`SIRxGU@anoTxpgsIpb&#MAdYSCt`CnX&;tuM=H7*^9qF zxCEKXjPJ8ejpX+%vOX@JU+!PXWTVQ@FQX|Ry`|sy{MsXv?xYic4)JX^k1)Sq{XRGa znRG9``uVOy=G(3>yVJ?y+xRpxm8ClR@!m%!-RaTTQ@;Mb-5-l9&a}3qII6qqs&zy9 z-A0(^8`aOx^95w8kLDa-_HiS!Kai=-@$uT7W$PF(OF`B!-Y8_6TNF?FP+h`}$krqC z8pL}oP9{50+Lo*LJXiHZHi&TPM0(Sscf~Iw%ya&RVe9`P-6w>lxpWy&kDq7G*>>OB zSb3+!g*8kUXfbDM=-9eYw6-E#=G8>1%Ob%luOeIMCR-k`Q`cc4aUc9pU}clN?pd>|kZ37pRZm@Q}?(KBRWZJa2X=QteUW zs)}&1wmL$g$^Dhe8yN}Jgo3qEFS*XEs*X^DimFg_v}bb6iWHYuEDCx3lB4~+@?g{p zS9?*@RJ2eMT0%B{6yqO(Abaw}oUB4G>grz>sjjP`7DJZR&9nI|uBa`iv1L@Gj`B?2 z#ns{3U`3c(EUWWqYh>yFyR0fg^au5lj!Wsl5OoXEFstiWMg1yfgv#feX!FZUBK?#y zry@dQsv}Edy_377I87h!?F5)`nymQ4D5MwMRV~3Bxd^=H^e%&MM5CJjt7y zn>~4IPJuUe@>Dt{I&VZ$a(e%$S2$}*?jB}3Ju81&F75YCaSnBHeduhVBv>1ig_hJ+ z)nxo*%xG-{EkzrP{Qt*7{Hpz5=HZlTN3ZKb?7(kjy;a5;<^LMlM zRt7Gc@`s19{*vmDhE}Z?T2c|Mtq+`&TuD_LgvPpQWZootC@;rjxMht_3b=s$ilRsm zTW$O)WORE4wZW>I`ta=XQ1QZOU6nUI6p3oi8Cw}Fiw0~2CNm~9KlkLic;6fwXHIr? z74u=#r1c6amW52xtjc-+5blRI)`~H86_q7kUJetOa>C{pV(yDu2_PBl z^)IWeF4{{J#n`i1$$bVLvSfreiD9owdsfT#)hQlNd7Y}@;!X)hH18*uC{~<2E_%ss z`Iu=$xggFC*Sa^q$i{Q1BM0Uq6%k8hDuGgci`d&5mRw$5qFi&B2lf^RW$3XDFqZYt zF>S=W616bypzlz_mPV~5}p^>0i^QTutYN>8q^}H$N zOQQ`$8iZ8J^CpI>44ELxysSz#N_!UDSl)4Y{`b6gv*(!FVlR~Vk7Lh9O!mj08#4YB zo#qt>!&=X3f|01UTV^YZidfG)Gqw7=NS2~{eUH#K(XG9WL}pz5L+q3}gXWnvG`J{O zQK>~YHQ=SNsY;IW(!YOyFBFMXN4&-5+I&UmZS`}os3;OzR1wr(&P}qhsA*nR1#23y ze4~ilK6_b_GFHZbm$fJq36{n7U2Nf4UD%PKp=e!kF{@%}T_ugKURYN{38hIbTD0)I zx^Uxx0dI`mxW^p{LgC_SRhBH1`z)czT{UY}~n$X$(wVyoVh$G0y9aHvPH)8?QCQU2I&GE)%O&yapF4xP` zUbdjnn>^Ml$j#Q?R$Cw!J5*IuyOjNKv=&*gWKl3&%pQy(NO!RQ>#W1Bwb3Bh3*GX~h!su*j?eHX6kgSJx~JpzRVVGpb`Fg(8Tvy3$A}WbCP~C_OiStXC3>7Dp;- zI9fQ{3oWT71M;q}q0d9qL2BjD6^xYCnVo({fV}Ar*A~+X35tTziej&b!L`sUW&38M zl~kwzcji-*leMxdeyFCRvbu~_tSD4g5sphz5j8vdSVT^}HlkYQa;^zs3YGDdboCj4 zHbzlne?G9y2yoOirwsFtITXjuqc(&yh?|L-Wr?p*=nub~8S^J*W#>&AJ9$1`6RDkF zsv+#FM0@L)*3CrYrw><$)BPhaI(4JCk?0&dqh3ixY3T@0-C~!50J50aKl{5?qPV&) zT)SHYe?Q+y2**gjY_p)mrPKDb$Zd8pATAbm%XYWmN;7C1BrXfqG>|l?X>v(}aKEBD z%%$Pnfv)kw<0Jonjkt#v)tW{!WSxk+1lUsn|Cpqf#r+=|=;~~W2y0fX@6)~2#!iV0 zVI_+GQ-U;R8|kmHjO`tXy%UIOx?yGwBh70Np)SlU!Z-_7$=o!pR8-YeN6hTxv|=il zQW7c+)>YP~Dm{Z)J3+mf>zYWYtgbQ`@ib;6rCC^76~o`3%F|10DvAfDmrlvcHtC}7 zy2-{g_cBB!-yq8vn@lsghHG`VeZtGFU#v{Gj zW5rJ|Wzi3X%@{NnX#OROiH^ZVII5G!vXWG_(ziGK-U8iwp~u>4ZdaIaq`?vPe#-7H z_Yz<2TwG3r7l%00GhJ%3AfZ_c>T0+)G0Olm1Cvs?gkzzreEe!r%qGRetDln^jaL?` z{a>>4w>-7wA=4*~<`t`3BW0RdcW)gz0@Yayh|SC9YJ>P*zx4EC7LiE5q}^jg>4=bS zGt<3(!OF$KrO|$AUcaRw0}>X8`q{v6h&_qI!qxWQupbhvt2Lt9+NBDqC{5R!4AWSZ zI+xYnj0$(N)+-hmt*g;!lBMm%Hq?zl?B3nUxgo?XrmdD)X6(T zr>UivQ!rV^J|!=A_kdXS>o?`>xM`PblwFegP5SRO;il8;SK`+w8t504%8U5NgjDoX zcY3BVT(wp&_U9MVk}5)#K2o1PrEqd#R(?ThQXs`#$zVb3P^9EkCxOLv5#53CW)%^v zO!abS=4MYT%o>xQ>(y$IvE-H16;m8no4I52@^b@e<}NgOKnc4Mw4Q{Zx@Nv4Uv+C{)6jq0t)498q%J5I5CYL3)LY zX&0K^?0|`|vZAN>9cibCEXS#fzqS$QZz!D0U- zNk~lFno{F(GIPA0=}Q8d^7qnI7e(`VgoTw$eL7DIL!CL~v9`u#8c45UEak*iEa=r# z^NB{6^B9~CcJu&MWMOW+zzkz8^R+dOEh=tH8*pLf#@=6W8VO^+yZ5x!#e2=Rx>#qQ z=-$F3!EhN%-d+lhgv zHnN+5k5;i;Rr5t-biLm{0>(*ZO&l{hpD6xyUi}*@Ur8WqYWDcN>A8U{E`>ET*k|c< z6O9*8r5b7#4OQA3j1h5xOxYOiV)sQU$U?Bl?tAJpj76yn+jT-a#rOjJ2o+%&0>>*q zqWS(5b%vQUBWtS8icCEf;nHfag0DpW9fy}<%$CkfFG+2rc2&%b%r|D~R$}eKv^m?e zlF{lq7To_5Q>!WSqrJ`W8dglrGpnin$|l2SlmxiK;>)2{Std2EU6zchMpnr*M(2Aq zm336U#>>EV*e{#clBJx%iH_9GiAo@4Gjo_ys01@YZ3KmxI|+0W4rxsCEMbALRTf?hI&l zOSy&f8DmC&RN3tnszTMkfFQ6@kmy)d< z(%x7|Gp-w{)``c*k9BIh`?<2Tcb z4|1urw%ftycUB{joE>rmE}3V491)kS!TGmjUclT9v2!6`W+{Iw5y-BtD$=)YSy4@m zCQ4KvwY#WTN7624-1(kSgOB6`Fs|D07ofM$!!Z z{(&u(o&QW!y~pLlu|a|=S!Rmg=u{gaCCZOVm^sa6+Z>GSc8`rQn_QAb7FRH>^1_)y z)i7B_wM>wsT@K7_k>Po!Ch@n6n3vny&`q(*mva43qUQU@8oyQA?=Oy2&}j2J727Ms zWf)AJRybu^VR}v;KR76yJarbQ5C1qDtt%>Vzo^i`TRLWA8!GWDlwPGO(*~Pgd5|4f zBlX{-wI-tUX6B)I9V#Pp=~2lLwPxejU@3Q%)HlpjRK7>0X|wIDu&yXiBb#@!tw z1;exxHq*MlrnsGh#&w8qlTMW*l3ElLW=$;|P>?q}*Bdh}FF%JZrZG5Ud*;m=*(A2b zNhY!}Xp=ximxq>c1yfv6#eM~|l#Qv$Zmnf})10Wzos!yqLa%;NOl|QQsCtSQyMipL zsAY;lnywK*o2edY%-ngni5j20D!5duaA~zW?XhlV4qB3xlQXrksxh-ue-%fj3_3o} zv(l)d9O3*zsH+`+c5IrCGu>%y&}<^=8x~(vIzgk=L^JXXvrh_}3thCu7aGm$v3-+z zPD9&l1%lzF#%S!sLLKURgG4GYHp|p+!(w%duSVQ*(MWYn)BJ_gJbJ#>a z`f!Ge@Z%mQvTrOk`hLYCs;?CIn8(!Li>pmrt(6+X)8%1BE&CzTo3&Fti}CnAH*ee9 z5vwVsR(x|4ZSwUecWzWzZV2FefIl&-W>&yDAFMTpSE|CLw8>Mqh33~U?!GYU&EaDv zYsztEVw&gq7nfWf89A#dA5mns=JYx+XuhA>U!>_LD`p;5ci7=&Vn;YC*0Lg}>YAsJ zuux@bU2O%w#VgS^L-&zUZ)9?GbOtK`y~+RSGmIClF0EaRDi5b`ty%gzV3ee9IT~8@ zl|3CqF$ywA^Q50NIf;}UqH32OZj6Y6_=G~biMgCAvLFE**Dxz2V?r(T+Gz6|Iv@*(58%&+qn8zX74De zJte5STzdAC4f-~at&U+P@TYEnVloS;ovLGVv>(}zL+$;U-V9PR!RoGdx4lvPGV5~S z%c;6>sl5}>E|Bw)8)|kd$)3-h9`vD}WzOs=H6Vi}$J9mjnNj-0YMELWsw;{(L>#UT z(Zmr8@zU$!Gy1>GVAdorrJx*R;LKTc45~MCeQF?wvBFn4P9EuY&+4`_X8okr>?WPj zn0Q7^BD2c4aj4&ex~n#ttQ{g>hxBi%JgQ7@ zl`7!&$}A_Wl%}$=-=q~+@>@!3!k0!}Lf2J9%gM5KvG(QcCG>+?wcjn^}a z&C=>R|B{8Nfn|-%boCZumqb6Or-zn=itFrQ2#ZKhcNx%93?W>LnHe3_@SRhqf||Mr z_cT_qrWaoopy?iWukd@w-U^LJ8BeDgYu0L25mM;NqMEFwu?3IQoL40omWgf z(WI`-o%vLmNr|3tKN+Ut94TzeE8Xw&QnUo|xzJvFX=Ba?j=Xdq#ixt(xU}i%E>VV8 zP)#qZBx_%bD=-&lCzt~VB5m;N3swX9Y-5Y0BV7|T#8@x)-VWuisV+8!r;vACja-hY zuC9JGbUjI*^UQQ%YiM504Jc#RoV8N?`6G4DeY%&D?k-uCBsFf6iw^wdB*o0PwOkpN zncXcbhS9fQfL~8{W=f@2`4!>1B^-R%=+*CQwU7pNvevW_pFi`FhLyEPrn_)7lE7=}c3r09|D#+957?yGmh^q41)LNOf52GTTLd%)=bG$7CH_j$ zP+|W|ljxbr8Z_GD*@mQqGRiV&U=dAom$TZ9nPZ$CWR3L^Bh>bio%Hp&PupYkID{e! z>Dcsiu8sNegyx}R{haj~$y`iu<*C8xKH&u;`kdo-D)ywHNmI*wF?mu~nTkxr70dF# zuQhZb<)38D-ZXAO(xO=rt*K<&onnWFvf#4JPONdq=~z6w$ohLY4G?UB@!;-D{T0B? zjrP}2^aVF}{A;g?)6ABU^I6Pq_8n^T~0QTPjd|Ih4w%=D`DRn$b^Ze{; z>WZA%aI|Hs5G>X~-MsKO3h37UUS8Lfesg!*6S;2~#imqup-JIpr&OPUo1!W{wP-KL z63%dqTSxqjZ!ES`j9HEC2BlurW{Zv~*v~kwZ(=ET*S@yBY+ht`IzDMR^LsOvf=y_x z{X-Js6x9_k#GrKF&b63+l@*OeG?TP{n;w@h##UWvPJZSWNM=*)&VM>lagSjyjM-Vm z@-h=JKNFxMV)nIrpniH3(Jgqx7Mi5mDK?(C{w^`TKkC(2A70-wU;k!#jrBGcdiHNA zVil8l`)i&5s~q1X{4nP3P<_t34G8-yh23)F^D6759R}ujqkE26bz-yfZfX4K+$|@& zh4~}P{Qbf1)$nuW4`(n4P9eJ|w4>F2lEe_0W!yHgv1oSt18iaZby8)Jy{Gxh2!Gjei>f~^v0-Qde?y@-fZ0b$-K_Zf&0l&#QqW}XK`sI%cmM@ z@2I&HP#>LcjZ zmJ4zvutpd6>Tj3*%hi<7e6xXO7sfB&INI{lv-*UZmi3c*&zw?->->9(?Z*-uMzOn@ zxQ}Qm#Tiipsk2sNoBT>KpfCMiN^boLKpmYL$mKIciM{5tw?*}nZaPEB{Z=xNYkqFS zX~=xv9mqH?wwAJ#Il9UPtDj_73e`7VyZ;H~`iE9o)^11Fj98d##$JZgxAudD=3mTB zwc`IerbX#<@2*m6#wuATVckDFC^%GM^$>L@9t|8s_ zl;1F&LH5{z$Es|9SZ1z@jBVI6ILdJABww-OPmOWavpRA!rz)T^#wpXCPwGps5zPk; z{jr*{gNC81vfHl5?WL5fZRY&`_1&z4l{-HB7xYXr5lkY|Fk8PF_4@Tv+yPOC4-ViB zdeEIEcWblXYYh_arPspPrTy7oygp?%_3O;Q-Bsn3s!zKd`zjVvtKE*YS{Llrs6oQG zIeVtx9*PM}3}J!n$F9x2c`0TO`e{BO@?w(lmVw zo;sP|yYh2a^Fu(~{;|u4H&ng)2w=Q5)*h^A%Cy9zGblLBv=&;4<-u#}D*^K@Uo^5j zookEdwmQ2lY+CyGbC4*}^{bbH`d__Rf&D3hd$+&mb=MvvT$0#o?%#(fAj&6pqfakb z%4W)&GckAKnB1xJ=-;@oBKws-KG2;7ikh~<_Mn4oX#8VK4M z$F>D=CvH}GCRUxcI8y1?gOw%b(C@w-6LX^dtY&|OXa6K$mk`xl!76`qg=H?4bartU z^nv_>oGgBzW(ENRgF`QN$RCg7&z_iN4)FDVp{wg7hJL=ghm25ix&HJ@|0RQ%urAz~ zILhy&^yjO7WKOOAbY)K<%mSK_vHf6%uFBXR`-9;BF!yfFaa`HCV7@kfMMm_&5g@a` zOSfqaT2dP%KnYC{z!0D*kw<|ppo(DORyZhBgH@+bgsqXrG0!s(ZaZe8V;&}Ap8aO` zQ=9lB{w4E$>#{FdnS}x=pBULKp)&Vgxi9O!)?RxFz}a3ztEp5|+DdMLyVsTdQ|1!8 zfycVJ$Bnt-h4?ld zBPFDSu9B9*m#I=Gx(K?6M#Le@AQ1Mx6x)mxd!ZZskgj;wBiQm)CyL*xp z;{HTxWY#$v_-yw`~^;k9JsnDRsj|Y zWOhskR={5bQ;|umIVc0|+%aEdjs@sq3Jg;iY`o&%GOQ*Q2NZ?J+@+vFC0-_IK|eGz z$>B27K#Op`Pg?y?bPzK)2iHaVdFu`OX;x<<-|PuAL{9}x=d|E@e#oj0(Nw9Gvgi=W zkKLBWX50}4NxXPOr#C(19(hxDI3}cNgWwy4*q6PfN?m)YY%faJ>~ZWOl8@my2O_+M zh$e*Hl^YvCSD?fC2ZB)_^QW z;1gU%P=&Yk%m!36q_`q>K-nXSMNVw{a=d zwwc~Z2usr#(Fzhp;#e|vrai(P$IJ-kB_NX$aa&9qA?egkPfK75Oxa|)>#k_UTzKGw z(2?M0y6g{s88E^8N~SgoD!_qvG4eeJjFg8lnG%eZ+LMObXbQm2(aiIK^%CxYXHo1c z-ldSlYwP61wr__>SHck%%k?3P@=>~q<;EfDLLAXNuG}p@yHno3C#!w`A;dk&kH;%c zkg=rSCEN18LM7>R6J3hxUyHXGY9Su5+zl%* z>`VHCaHgf=e;)Qg`t+Na*wt{6t98urUU;s$u#AIWUM%pW{SMsWP4}w2@B~%~&tUkd zNb&X(q-a^xjtc|y;xVR>v+pd~pNn|pDF$#h)KpMAz+XBab9ad-B2)o+BnpNS$0X3X zg2aoT-nOzl5i%bPHP3Cp?a4LZb>=KlD8oLmY%G5X@ zk|>;(8F49|4^!u5;Sp(}c}T`ol-())?G4s*aJdMUf3o!Jh4G@S$ETkx7CXDo*SELV zRyD&rCVS7lR&xwa`R|GyvK+AM7Ek`cfA9rDYLgFn66{@kyuTFw{%zXvlbXka(cpL4 zb3GDs|6bk0hcypB!!v56VBg517DQ7`Q+)JfT*)>UJ6h_F#=I~#&%KFQsLTcp)l(Qa zia!{Pz@pw^i^c36Ks3RsuzV_2>CqQy2uO*1vj@}etS`UesnK8M!Z+W1@aJdx=YQM3bMoKu^ZrBo{pijH zfB)hEe-}Gh;+1R>;wvIvK8V%FlIl1 z*%2mFBg8F-BnQpF=e#s^5G&#^EtfEowD=#X@d%NM>jOt0+em?=JZE?nJQ&HY;_%ZL zrg^!6kOGyy1UMMtK}$$GC^6zbclTuZ;4dHQao2l-B14Sz6b@zZTmizBfOM9RW}1NL zjQTD?xpKh{RpOawFs+@%UtujAjEe;@ERYxw2jLhB1aW9g^gS1&_?-=h<)VQXgyd^@0*gD(iua`KxA|EP~JdS!!}T?)>aRROQbjtE{KtN zet^AUt-q{;TL{$vP4W^SgC1($&x7{YFls-DdxiVsgxW8>*2a-Oh+PIAJOi40<@ zlks4Glq$e*7@|OxIqaB*;ZO|#&O15aF(_V~32p%>@l1VQiimutCjc!uimchcTK*OX z-{3&>CZfwA`|JgZbV-Q_d`^Q6>655?Nsa_sU*V&~ENVotC)FqTNT_ikuw{w;#S0bz zfpH_5$tTQc*C_%Ag2MO$x|28xuyPlD00n^wlOSKi8F^qVK#mHwd%m)|{*AD2u_>a4 zt!1h(e>8${Vm+B5+14TdMVydv#Ls#ZXi0iVzEn^iL`Xs@lCy2vz*%PbS`I>f$1##g z>04u#h%A!!#P2LHgpJ7uqB`#?UJy$>48AAxCCVcg7@XUM2!xYvyo9RwK0q_XRP~K@ zZlA5}f&=Iu9<%=~)H+n6xF~-sREYPxU}YAnpgfTV9{}@?K@`}cCVo-_T$Mm>$(VJS zi6XOaii_1NQjZ`y7jbaRa|h519*g4AEnl25nHC#Me-#!luiwTlJ8*81*KZ3m3v#H-+nR%tHDDO z?yHUUM}f`(NBuXp57rbhwtW;AAq9arc$j>Vt1Dnyz!8928msVxyAT|HgftHSp1}M> zTBQJr*Nhp7#{Zh@qkmasGT^e+2q=>#n-||nT|BL{m;8H|r#bwe6)-*jTmHNC=8gW| zVd)tDgQ6Et#NDuQT&|zJDOXO4*S7?2Kn-LKz;E z1_%=Ll6W*3gx3`GmL>aXDHUeUsMP}LD1loxB{z_lS`^w;A(NxARhBj_-vE|`?||it zuZN_Wh~UsYa)0SMc)KSd6E?Tcsy!7tBpO*dxU3afw8`uJaqs*ARwJFa1#T(Z)pLoF zab>MqshkU9Hjz6o=8CCJDW=dorX|hRp2;Q@v(2q>YKZBC@UR1^fJ{;~UmZK5U1(rU zb%ACmviyz%DI~F-blnUU2t-b;WA()Ql5TeL$~ThYhaAiNbut~kNLh%(5COVB zb~wbev|sJ%dM{z&Xyniim=x*{ecwTzL?M%#)b~>Oc5nc1#VtBN2(a`-fxmDO2<3aS zMLbX@C&oa{2^=%^goZ-b{uxM{XO&>B0cjv7EA!@YNfF1o$=Q(kD#w9|*Gc9-svhI*V3DfcJ*&yp$HZ*7)rp3Qyd);Lk@YV*I zwxLx>U8yqM;EJf5B(jQ)8B}`FBiUsgN={ESunE-CIlAkzrvLdY{p&DKA?G*%S5AU; z+QOL`PUluWk8EAd*vuv!nWJgvw&TfjQ4GUl#KPt9Ws(MzF{f-$w7{#)4HxrvD41$z zO?=drmu{MLDrivv4lJ>{_M*c@>wg*tkf!-DHvek+DzK2iA>^&A?t$wN9khsLN;1+` z4P}TyK^Hb`U`pCrb1PCPmQn};1tvF8SRjCg#wnH{{?8-c<}0thu?$^`&oH|xn<4~n zr-zYlfCf+8%`NDoziC)AeJ#}8nm$Er%tVc?x|y!7ubI7FT`RJm%7(CBBFlyvt#GB- zO1WA6(+M=rJ5f!nB6{AUW?0on9vGof3BfbvwTlVXSgav2emMb_w64PBQVIozHmX@B zD>Km~l29`=B@ih_SPM$u+efpFP|hHuN8(!Cxazk;HPNP}7YDKo-se__H#q14lQeam zPHRnpAvUZvst)Rm$#y`+Y0tCSN(b7a6Fov@UP_|C*toMZG4#Bl4L4)uY>|s8;EYw? ztwZIyw$)Kr+DMF^C2Jd~qoFyWW~)?b$7nv{wY1Ibl9>sl&3jab8O<3&QE(U~D9JZ} z3Sq_0Rj}S!>pxBEMqF`kGj*x6MonL-!)EU|$;t9J+3M!6GH&3vM44tjtsA!30b%i) z2CV}lK9GzMrL#WMAg6YVZdS^o{i6nXvhfW=$vQYNL5b-do8Hpesu|xz^T5BBqiQG! zqFEz8lG9>Z^4A6BjeGJY2Jnq^u$!s7C!DN1Y{pIzjF%B zaxP435e6Pxq5hkR5^JWuZE?@Jn1KJQ(#Tyow6F202_SxOLlg0!_f0gkGzZCUm^3*g z9wt(zhR4ZE(_eMgfsrG!*E>hi5}0&nJf&;v=A)O00B?TEALKt%{Zl&7I5ev&>zATH zn8+kkuRVH|;@W-k!bacs_>(=k;0g0x-x0^x}GoaeioVobxp@Z{zY9)0tM z(o9Qs(MN}mMqd+$>`G5)kF!p|mF#Cq!3avn?@qjk#FYVvk29LnvvP@1lkSbZoTkfK zlV&Z-8r17T_R{gF22~~`O>LK&L7VKD@L}qiK%pb-RZ2zrCPBm$s=oArvU?%5`x&-i z%t*T-r1kP^oH4LKjb>X}34g|BK#z1SeKTCt>7Z<~GD*&Cc zGv{XJk(7gwbX@oMrIwHnR96&WSWc5Kcr;}g zPH-{MCC@zjMwA0A=WGq_6O8o0-|Nxc^imeR&PpzKD*QO4WKtUuL(vjS)pvTs*}(~N z6fv;e`zF{vTQf{Iy}An197tJ@AVjm*Q*XA)AmO+&G;t11)-WPs;hBXjWhw7sUOcl^ z1G7lT!8j@L*Roa6ljm$=o4Y7?pea|`&AySb_~olo-mqOxo;t|_SfcPJ;2G~kddSX} zqzH2$0!MrzxwJ6je6G+q9_FK!C&Gf-bFgdW!Vry>C1RO9#@;&m!m5bmpDDoIB=#z{ zN){)h0CtY)CaJP6Lc$3JMAt)#u#vZz?!_U(k>K_<(MT}>9B5)4$7^eiN|47XXX1#d zb46n}jzks@nVUF#H#o-W_lph`%ElgH+;8`=IbgsO6@vc^XyR(X- z0>tKy?^L$rqi+u-$3Qb}wFXw`fYJ)A=_p)0JVX=}x;$M|NTpuN&|ah7D3{H6LbQ!0z)W4)0LPcVeqm#zGDiXzwBe%}E>{>{Y=m>T zz#E=1#1z~ZF}2T^O?EE-8bUZ4pvl(PiyO&-AIijt`ls!8y;D@!hmo!YF(geCABDj_ z)MOJd0CK1>HUt%=iy|+XtOVM?Pt27jR+bO4$yv>We%?eDhtk+Gx}F-^`xcvcY-q2h zT$o1i9S_yxsZOkfIoWNFJ`q`=vq&Cc#R9}o7a=~$0=m-*@ZjIbyqJ`T$)Nl zE-Nfb_;t*sU~zFmL|wV7Mh?fhDygklzPVMRqJ)SOGq zRXSKvp&486ZtNJv-w3#B&zk41`h7Q}>V)zD3?ea3^_Rb4OR`f)mWVeHj4N(~>wo_%JB3_}f)RWypMRg4`Q21e_31 zG@yGMQi&x-@ZR&JEXh7z>mV;7@{d&&MpGCcJkxWjY4Ch+Vm3lk1OQXO#+qUw;}-jt zJ;=>te_@dMCqrJ1&qRa|yM{MP7tHRnIT+=Dmss+bZ>5O?<7~oS2r2G)SSBypAqo_l zG!hj18$6MP{7LgCbkt)G(0upR0nI^*5@3oF0Zf$5frl9fPoU*s-Na^MvNu}7XN$|h z%LNAU7a9AvXMV0tPPK;hWNXX_c4vYT2to6{8WygGt!vyJ&JIcfU0XRg5jh|ZrDo;w z@SA3N2zTiDU9rq_rT~^1&MX0V3upCO=lI_-{`XYQrt|Vra4Tljq7X^mT52BRcE#+a zxqwB8aE0~TZUy@`i`_jaAkf5xZj-ZwQ}gRY6w0Da`#>Edka8P^=^b!Pq68EnIPEtd%K8{6L;SYR;-bs{vWoeMkP@K9J z{(y&cRv6X;AR_+M_m!=}S82Z@*F>p_l)?w~T^<0N#mN#6m%i=2;bA|CUSLj0A(&jC znh6&D!(5&DC%AzS`J&w6akTV^yvpT+vJR;Jb4+gmq`> z3j6G|z71VhX78)k!#rzH@zmX+9;BBeeN(^x&HCo*nx4tK#d6zn>}k!gJ-Oz1&&?WB z-Sku}5O3)aTQ_wOQ^7?F=ee0|59^n7Mrau%VGs4-+QWA!T1gL|vvo54@VBs(5QcJf zS%T%n;}3@EcDX8VR}D*_mQwAu~Ix}^?=}S z7k7K5$T$~CRAUCSWPE1vPHyrtqL~UqgeZ}oo*S~4DAAkw#m%Zp{lJrc)NaXSZ*J(P zzswhEIHzfPH}+11q=iv#?Bc7%5#FjX&Lw-_D19=$&R?71Ks^mdLFF>GnMY^7KFJ!r z`GeMa#?>;R&vAuf(6fF+Nc4kx3YJd61qmYX7B`+Z$Cbu#FhITYwak`UqrB8Oj5lck zI_9p__ehq%4E!bDh#i58CQsFW=j$hXUp?P?v8~1?GHDthpPr+}uiXiQ+XF6o7z^mr z#@*0~g~1pZ{~(5%v14bQqI`#`&G1?8I1A6M{bJrxZ1o^Lnu)3wlqv1d>x3stn;E8X zGoR1C_Q4#z21?}JA2jjwz$GPYl)E#ooC0tOJdZeH9ie0cSMIOoS+>%uyg<2@jF$l} zUS^&IEo}Txv~|Lfz{b>%1nk2-=~mmJBgGXFU>Z#wpz{Vr$BGuI58%N|fZPVre_o4!Q zW1rk$(qW0iL4n-Z--}RJ^awZ0fqs+Ik6g0Dq9tZ|-S{crcZ_UWThT@;!$Bnb7Z3Jc zBDJ8Qrx)l}TScUa2nw7@=kaR_vm33wQ03catiWhnh8XMvkLBtbh`l{vKIjL7ci8HO znPr@!*4b55fvid>4}RWXuNAIeDe0^+d9I3qVP`tb%!gu=(fRW#&)dQ>|JaNJ`LIdo zCM(7Z&am#!1&RFihlOPTtOqU{2H&7Yv~OLV53bWn!c8%ND#Innh4w%!1X`4HVU%8lU@(|{^hOGpU! z+k+-*aY!Uj{QzC1NW+Id5ka)uccZ6idM|ehrPLYMM~-31BHjQ+Sx00CDh=y9;a~*B zG%sZ|HZBI02XTDH>DGxIr@%jYm2+`W@#)kL7>}D?X2}7*@$grsDySEX6?Rzz20qjd#LYz42Cj?`i8cq^hY~@I zlA+mBHBAkH9SBN@d-`knKf1-ypK9I>I}JXX<_gwtCbI*@Z3+bo`Wv0-OjmA@=cd?+ zK^*KR7EpBHz(nYgfiDWFH8?g?SSU`32+yE=v9b2({)5j%J$JJ#1>dNm%nWQc2)wq; zZ!3`NR&a+jb|MZ*6_5H&OUL5e)smXPpMPo~VeM}oOvuChkUm$y4(|K?1BqVFQ7Zc}hj|exxxoI0&;m){I zB_t}bfO;LdetJQzL&Oz659QdZwTYaIO0`F&=&6x_B~%xRO7L%H+^A}DcZe7 zDo?>U`RTw&VXde!CLFdAC|OfJdyYmHAnI%l>^EWU!oH*|PV%sAx5$`E0*)&)ZgNf~ zJq4T-da9yNod?UkWj&jkSTT@o*SQ z(Bl3UvWUPhDv1SC(gA$o4f-q+SkDgg@?Bl3*-Y!O zTvkBCS@DqoL$VE)(w4z#M3^pa8o~e1I65bv0D*q08T%>;_z;AUR0)As;5K8(NC~o1 z%9o4W0Zs5M^1fmwm@K*HjH9Cu#2}mIrW<_w?#d#5vVl!S|427t0Z^6^T|}>J)F~&> zd2qR>p41uC=@~mybWR=ljO!YP2I-~(`6q#@djyK8^N4F!ED-`cwmm#S%6AV}(#Wm2 zGY&f>0tD?r1r50cNV-9W8dc5s4P-@wb2}fRj({~c)vehAnAkrLeeskm>uyjfyWA7a zcjkd;L3{&^qn13Beap_XjCk3V3w3%3&QASIz!lD_R#MH5@oIIO;vv+QJG8@|>P}DH zOJ8#w9)bQSg%O_&Cc1QlV4ypUaetrqlc{Aw58Rg7opZH`&_1A;UT0|)n=n- zV{Zafm&P7CVpXJ^c+BXQ@A_%I`Z=Og(jKUVg-sqfqBYH0y5o$9T=nGWt&C9@SRu9& zPebE4e4r%s;aT`~(-1t@r9PY!R>zxxWKs&iw_@p>Nz)+jPCBIp8%|i(&qY3EZG9T` zE!l_{rl4SfrVN@!`+?+bK{77jO$)x96t*fYr3#yg|0kdEovb-orfiM`g|-|&9pt;; zZm-qOkSBG(#e*~*f}-`vlHtcTAIJ2 zn_6c)kp&vzR4t=S^$;)4q`ER=?QwQ1NsHV2c$k}blDhxmoEyHc&Ly}{ ze5JV4)BxiGHuTiHpUgm{W89Gi7OdX0A)~2V=Ui!x@P7;Yl+*Ym$*K{*4xkrK3c(j0 zcS8@PdV`=sS<7VG@`iOJD-1b&%UURZcD6VXU)NTHA~FDuHci98*bpOAa)54;!=Ktsn4mGgsRIe{ z@4cKqr8!_e5rVc zD>=y2hMKi2azhkbkD%F=L6kgRr$t6WY2=yqMbLkZ0+@Rv&$1e7CX`4<@blG`Mw<=J zDX%ORS~nKi1P$Xux)n0)HF24|Nt1GLK^Km(A;0bH@bYbuXroTjqJ{|Ok&Z+dIk73D z#pa-&+T6)uQFj!ZoitIYZZ33U$tG{jGj|TmnG6LUN748~5F)%4ei(}JI50i*?!Rbw zQhJ6?C%Ard$P4Is4Saa&<#d8d?fnzI#e&j6s=AlKiR~}5iP+oF(^p|(9@oIZsV-Y1 zALkP^i?{EsJX#NnR=c*b>DErk)|FO7U5+`nbI~EBl)Vsl=D@#~b#lE|JIUpL3yTsF zpiYT{%=DOh6q-`Dh-Lh`>Fc=Ya@|1W?^2SaKFr? z7e?mDDCi|}Pz%|6 zpfssC0LCV=dFntv6!PFLB>Y(i5s4|oX2R6e2FkLhHX-rZnTm<2r@N=66-@J=GA6Pd zd~k4yv)gsG5r1EPZv5=aV*8?h1Qn>Y-f8^}?@A|Lc2C}bZchet&!v<`>)8MWoLi5E zhlAE`9~sz}m*<1!yLYvOEAH3sF7+=C?}DnwC|TIPJGZ^n!X4}Ia>ISH3YuOnAKZIz zzjg0H>%jwDhQ0jYFaP4+{d@Q3Hjo3@+68wSAiJr5v0QHV`jEBg{%l+m|#yKRVo?LI1Ly)8dScH!Beb$;^KQdDi}O&7UrZRl~F8V46U zF5~Xqxo7Lo*5Y*UFWsAatVJkVyI8tqsVQ<7cl7qoekC`5!w&l5#qN{VXR#eW2wktW zhFpA7{&M*lOrN=JsGjYU))VkHR7F2Km!E?#e(@`OmT$gTIQ!y@`{l38dnI1a-@o_e z7Z1w+{Ga8|&%gL3|6JhXd!OIGSN{I@@|WIv5X+d)!Lg%h^6X<|9L{cCrLnm0GMWM`rkO3?uUdl|6tKIqd%a;QIUF zp#i@d9lihY@))B?!5$tQ>~-HAbk8sMFrt%g4*IM;z5?m=*bCq*8yB}4+l-91k{e*N zT$jp-m?`gVfJx5Ja;FC45db~9XdeSHfZ0RY@oJN$Vs3kV=UY~D*m}D1_&4k2>c$F& zJ@{^UZoc*DfY-@R(hn}A-QBwW$M^p$*2Y#st)75FhLRm9^Q`mQFUJ?-;Q?yxv~i$% zdY^+H*dk|9?UkXfS(xF2ABM9Z1Z5IgKM0KNpYtB!Up-zNv$Z z^;VzAhXp=h#u#`3b1AWV!aUk>jNEISuEKwgy5a5X`4h||dlm5L^Ud|O?dK~m*H^Fq zZtLY*xw^8s_T^k*?;rK{PaqPz$L-J|`Qz~zYF_1^ogv8Lm__k{_MmvV*|%3{E5BOJ zeu>2JZ@tzwub)DL$AKPpecm6Rq9lg2UOD-0S_6MQWjgD0+l=1yz&W5tANS9DJxBop zx1mA+3?SQK3__4Y>BR*rI=Gz?vWu(?>cQyfY($Ot4lN`Du>IKnSnX559H2J=V~_s* zZ~wPP;BDvK>+iAtAUT0p`$FE_D?dHyAGc4=MxSzIm46ESzF&T-d0Vwj*rIU_=6`+c~jMAs3q0PNPfOV|W(aOnxCk#z(k5GeAsefkT`4r*Qs0wITf6 zimFC(xc^<`*Bw>p``3S>{cthv;zEXt@d)ImON@nsaP{Dkv2GcI33}h3<%%|ub?hQc zNT%Oq&)anDSw|{%Gjv>deNXg&4#d>^Kb)V97K?HL;V$H_7Uid(ep>EdfB*i+4h^LP z%69%|bU9KzeQ=DuymXlzTcd~t6;~~WA^$!Q*_dgzV4-tN(_K1mYx1r;AQFw)7 z@%kSxx*h8MxKd@j50e0?yVP?q^C3u~YsLXh0|t6$wS+tERK>Gg0^}l}m651YiJ0f@mKgCW`Y^#q=Mz&O-ZU_`SYI0%TXq`Oz*yx&&c$5%qz&o3+6OD9v4k62&>A{gR3D$lejwMyDy;_ZQfcFE9_xOMNA= zc>#Zjn4j`5@#7@2MBl(T-4P2Pf(FfnIizbhMCIeXXDg4_H=k_nVRbGp_ayNNLy&QT zgNhf#J98Lq#Klnf(!om=URVIFQYfbKgLr|uQh4O4Moa-U*UjM$6lo*(G{fuZzp;Ut(o zh!0G?gh7mNib|Wbp!7KJlXs#>xa$wbSACpP;EhGi{;D)^NXUA%)iUxZ{iVkqAP`LV){O z20+i{2=K-T9b?rEUGOs!$N+2=9`Fu;ccl-eDLxtYg&(ZGSJ=4A(dnHMUUMjekYrtP z`St})MOL?uS+Ke{7U2#=j29r62)WDh<*KRZ;dH2^EZoF;UHjn}BG;V4H$%@9U%G-t z?X81b8Mw16Fqw2PT#zXUQo*rN&^h8pbPy8(+hPUwll}!9)^jONx{d-DV~J+}H=F7m zlxTT}zYwJLKY^YHba}_7awDa`KI_N7&hmD=!_r?~UXJ|F-kX;GBGnqAD}E?BJJLbh z4e#AeUqV-|!_9y~Tz!yy2%HEA$HF?44LzZzLGeOdn*I-}5ZnSHuljF?1@$sfTh&ju zTu?3?U{;LafRur;1a>((Ifm2x&ws?FKZqu9HQ%9;v<@*J;Zr`*npdl+kOK-Vw{Zsm zKU3c^GdHim6)}g)lOBj#HH%?f1_0TdKGgPU&&OK!{`^OD=-9B^_^)8aJ|XD49{(h{ zclzTi;212iY~lv(H1;4C77LG8uK(`o*30$XHJnvm*l!=vnj>QnvRMp|_*buc{U_Ll zZT!u(grY56zuewff7*Ka?bEGISR@;p-`**Y0R>f_hH7qu#Y>aNThG^uI~G!z|BDV( zRtWexJnEn0_yjXI@nkr?1x%0mA-dq>7!JOHe_??+pkCQ(33U`N@DQmEEmjrkAK(}j zBF(LkA-LZid;2%V7CN>YT52Ac;07>heAw?mi4_5bI~5M`KfpglW&x=BRI1csFTykX zT+zA@n;3U~A*z^bidSkHfXl;f28#uwKJTCQ53q?goAV_Z9>SNcCzJ-1PMxcv5CvQ^ zY{hqC@mJopx)a;t!;qat+7qi6HGf;~iiqDAX;k?JzuzrekP)pm{`VXSOzm;m>WSpf zaS@Al)V_j@hEW8L0BkH;XXUe%r#s(11InzlHr5}%dbHAdzVdACDJxkrq|&)J?I`S$*i$qI1vEirts{dN)Vc<0M!kud<)6m`zZ@>5!(sN+izH2e8|LcM|Bz9 zN_@qIvwaql4Eq9a3zQ?y5L8sO&cQEMbv81@4wf6iozol>z#XByAHWEY%gs8|)$LXd zM8nNXg3^0T&M9i1GeM~7ISjb^KK+B*E_Ur)-8;<^t9^5JD0vli?;5_3$9sM8G$XlJ zx_2>G5Cgb z`4jGkPOl9CxF7MDUOFLW z38&Y$qE#@$v5Yf@pX-}kiFoRE44$!QX~#pn*u8CrW!vD!U~-EskjJJjP& zTX>Lgm&N*TSvnqB0DMQvRCr4XY~0y9T>lF!4AIO-r%A7KJl!7xvZfkPE!Nq`GckG> z6ZI-{VCl-Opb9?@_Te!YF%sY`L%?=&Xjr{E8cBg@7cV2i zX7h54oP4idFtJX-&oz^x5sX`}kfCN>P6E`0^p>Q1Yx)X#Vf{h>ii=K}e++7Ztw*71 zo*KAzP2Du*rVUQLCYN#)YgT056+r4;s^XcsiCFzhk>Ozcst$--z}pv(kWV@8m)ta@ zuV6c=-FN6I#w|<--GjHV3Hsw+|8!VB5FW8qJOUdVBj(c{h(j4V6RH`Gf>5IzgELB_ z=`gE60XEfbNEcjBfa_#wEt?6gniidHM6I!V!+1wu$ttP(^q{Y!9}dRHhzv`H7DyM@ zSa)%D69)l7bwvhWCfn}_4${IV>QkK$bXZWSD;M}&REovI=wPIua?_@yfZtqyiggTW zXk#2FyaZz7zyJ2n2R+#5VyySCFgB7~@rX9Jr50WPz;%e6)lAB~>!xWSf)$-J+Q`@cL_RSFa_Oc4n}>tp+4~>E z1_tCRlJ5Nwn9^y9cIH@^HVnY9qa$YxM~>Q4dnnlq=}AJR9B5=Y2qRM`E@>tDQMWus z_MfC)Q1HO3@gtlrwEX(80mxB-6JlTmJOQnVFN$0QD-c8le+%lUqhM)nZW~e{0hUu_}avAz;GFIU>sBvY9Cgy`X_^4Zqvi|fCW zCN%u6# zMg@7Y8cuY0t)zbmCdf4nf{>QXNf#Um`=_8rSh|;xH2#~bBisdiblir!DCD1Uzxfu! zeY&!{va$8m3s`@@x&Ft;>sv3seRii5T&B)}&9OwkUf48FI*7`WhT2tI6cpRSQx(!& zsZ+jan0D=IX$KV&$$ltF4aY;x&Vy}mB?of>%wag>`YuU@XS6!l*qui7Ay3>_G^K)ur-N5sqqXONyy zU&T6uD$DKQ-%te+8dUv?8*T$!svV6;3V{mf2~hl^Hik@Rf~c6l5-bt@9h|ELheSY= ztf9$V)5Cw|vFGF~Z4542f^nzYx3Y@3sIvjgOlNebJS6|5r|76dy+K^c*>}Te zWOCH;dTqG7yGy$EK@-3n6~_{?!iI9*wq~_+L=$3A?4+h9mSQPgiardyu^bbT54x^C z0-}Lh1qc89N5xA*q-G*)NQR_CP1&a{CYoW`F4~EII)xzFYlmDN??mft#i{$d&d{)B!2=K&KLxLl0GGYJ6-9OA2g zpwX3TAFG;*A}r0vVJnK>^yGusYnHffIPCc;zZ& z6yflL&Y5fkOTHMAV!F%44*r&DLGy>|a;blx;yWVAER;dTGYMPZ*J~V~fjj2+QikNa z7*athoW5DasLy*GArm`B#44A^cMTsTDDQS=@wk6Jx{#xSfBt_?Lg_c{$Jqx-URNE$w1jtioO09AcU9z$go9C!I23E zkP;);N&8^xQ!y1vr4q}mn&YLkUBE?5Js?}LD>+LPCLnhbDc8?-8cdtm6eV$Jts(|C zP+&srh7A@WdBAQ?{QNsmXQrSjH0t7a9OrcVDNc|Viy%ML^ETd_XB*#GDptXN?5<>t z%ym-bRBEqK#ZrTfP0b*NnoJ)b(FBV0KzNuZ^~zV<5$Av)j78G#r!0d*09nhytri>* zaR_{4X3~HBXTRMvTL@JRgv71}=SXn)-Zgb-gvBb%IuSUyNCRXbb|HO7xp50L(+6yv zP!%|J@nSGUP@1S9dbgXQOL&1}6-dfL8mV$~GBD_MQSTF%ZK}`HJ&7b0^`U~fh#Ae* z!`31GhZ-EG_&3=O))6~}9f4K=v&|*OQn^(Fw0{Vgvh3I*s7A0#4`6U&E21{dhaD=l z8q;sJ5G$t=Kqa2pLEK?FA!t_(zy~xiE4-bX3LF4mXYvS)^7a6}@l)VWC$cYE8_>n9 zt^;x%@mu$WZ}OeNyBJeoz#6nh?-@qlY9$2$BsANy8=A2kQC}dlNtDjGlo+0D1~qkR zh5R9$1Q<)>gQTw3D&RqJl%<7vW~p`fzI{%=9S4JTT0zxr;jZuho{?H!s7Ab#HA*xh zW8IL1gt70(0Yuh@pEQJA47h-9we03?a&-&@&QIl8JsHwI z_6Of^{3BH(M*v(TNE`_vgaOjqlGxSxgmuw$+OnoVc9U2!DWF`)z-QB+GAFON1@+0L zTpKhe2yq82+$UwqjmUr7#06)o-NndNK{`?ADHmE6l423$MKH$HBE%A+{5XnV`_RHhO2ncfk({s-g0qegb3;bO(JO(ExxW z0X37li&$wosKmMk{;GC)-cS*BcM`Do16V>+5abK09#XX@K*d2Oe2U9MVTz3w z2lyaB5)B)xiBn~#aOYhxC6!znj`syPJ>f2gN6L~PG|Ry9M3k^B$w6H+NHf7puo?XJCn5)y$P3xHRFM?3%Uu+)NR_#B&hej=aK zW6v{noYLYZ(_ce-+YHYBz^xuDR z2RY^k_!lCAp{M@v?&rgO9!UovtR3{c_JMZCAE@U-j;V(&;Veq06f{PoGuI1_GMzY3 z7Whuuo2Eh=r(!{9;8O0HA3?i-J_&oHdHJHY^D+h`bp4^Uj7Wk^4$U}j`ekn#wu(9l z@=9W&TK?^~NSf{+Vu?#n--Nlz;AVL|+{eK%@~9NPigJx)g2fqVDy&Q%7j0P#A)fmI zB^CN-rY;f11IUjl|L;VayKl(o$ifLuHj*cp)>A91D(om`uq)HP=(LhV-##1BT5T zrEkT*2WgU0n~5CSI2J%jzv8EEkd|P_;8S>qIN^=EIyASrzT4zWOCr{dfC6e~%u~3w zO1Z~9ZNTFQ5IQWU0>oj`6XlO2GVKpg7bY1?zEyJUr6<898mUJe!#B!?$fO_^1?R}$ zs#r&{e-#L;Dxkz#h2e+HLpA&0g^~O~fMGa6z1EPx8p3JYNK79iG?!0}LC@&^U`FXC z#TaN4=UwRju*0!*P^KD!TB0Bx==J;nh)xY_Cp-4d)*#FusOkYs)p#yo4Rx^iBAjg( zi&rWiz*fegcmkVLkWJ5Bz&G6$ULlT37%t?YBAtuXt2Za*5u~T&s9~4MtQd!*7}U39 zT})sLFKKCslq@z4T{SnJ$%4;t%-{eAO$yFBSVrg$%R;?U=p1bnIYB|!ORqr0i4sYc zONcL_NYdhSF|E?1CFV(aBTbOR>7zXXzG%&%*o{CjxV3LQ!lWi!TYaTU`^k0ygUx@L zXHRgL%k>ZSxK~&JQ+$wf}0+Z@)NiWz=vH`uQo#hn@nd3R(l% zhjo#ZBnmxfXf&%9h?UYIv@ekpx!3?nl_vDf%}Z!C0*pOtLCVD0Eg4Dr4KSu4-o0&V zSPArCf0ddgbqD{wQbmS7v_3o1-_p4nr?AyikB>uK1{tNDCXxr- z(UxZKQ|io#wcmmD5A|I`yQAdm>5jOp^yw%4Eit5m8jUNGqQfKJBrqvuDc%5MeA)ImFP#l8td{4`FW`Eb@{kt!^`2AU`-Xb#Axukp(30EXM2|$RA&V^FBP9(BL&= zN0uVj1D6U-n?mZ&9%{)v-$KHM)&HRH1~@g|?;%=*(s(Q*8`+ZR30gpjNghKKbCS@3 ze8UsaffX8(fwDF@XR-w?U~$J&#iHh}NRPc)D$LX2`Dk}Td`UzB4+*3)-q_%3Wy#tN1fcr*&2{i(^DQ-&6bK&XX{7pFG z<{gRu67-8uk;Tv+OX-!oFK-1UL0sgIgOv|oZ3u$VCF!4lTG=`TKW2!T`C_8_G3}dT zibm)AKLr1f5FD%->^YA(Lz7}UQ}>h(-;nqK-XM`1dK|&x#FvKLfu-U%RB4b52?vRV zf}jGZ!UJU>(HyS^NJse>NM;4~VeyXkN8|^1gL0`sz zP+Vdkwcx<$dBntydMN%%04Rwop!_667VwJ3&S3Iyp&-Hn{o&m+^&LdT3wE$) zp!AGqNPcNhG`MU*gi*7W*N9yr5oHWd29r^PubHH-j&Dz#F%Bp>)AAOGtBDUt3})6C z6(XfMekos?1X>88u)dpo)X+Zg5OnpwR{PA^-c|{vY%(=v<(R zFtMCQJ6s8H7h-2IF)Li4X%C@0Q-28odDEi0z5?D+tqNg|V(ZD1owZ#sG@j0a3jl6j z(>9lJRP`MWneB=ji`yz^sU%du)O+fd)Wdj254N2C3!UADh zH?3d|VII)ODGuE>)F&`g6SP=B`k*+Ep*WI6z2bYLHM~V!1T@i0W?-KQ_$h<6U6*{m zbh_5KLVsjX1d9p4@t+@vh3ilg_zL*paUgKWgLdQh0n6FD!Qc9sXGB|6M>yCV;j?E<6l{18Dx;!`~2 zku25>{VHcR)SK(>T1lY6Ic{h%agijyB#hFPIzO-Ezg5W#bDr4J?cF^ZENfryJ>eNX z6;S>C?tugxky5ZP=jX+hUS@?s=ZYOxW<6w@4Baxx*$EhX;BBh>8gdK!p$ZIovJ^Pb z{^81_^}FW-{5w@JvjY_12R2EO&Z0vk%ILIrp3YqZAS&HVFI&6**Qf9Qfg&?OOm3P` zJb6o^=n*&N_yY)Flo2@WM)>%UqO1XI$qzn)UXWRoU|h-}Qp95RPSOd!Upr(~O7kTg*unEgzZfW^QXj!4n_rxRRU#&v={Pxto>A?h&q`(fA? za@R4FmherE%cazntFe?rT<|#f(g*I=&F#nWAdJI@Z)=aw=;;~;9wEi`G_eVK>K_~m zDN$kreBhd;Fe0pn%TGvd+(4CNb9lTyEXKoMW=JbuFT*RkPLO*`#HFDE_Jg7y2_K7? zlQ4ats71b2wZ`4M%rT@kdqz<#XB%^|DRPvWRMY^IuOzT(KMKZEc_A&(Qv(^mxKtN~ z+m3{24#wm_@IYni1(p$yp@MLmrIgW7?NO-{1?CeIlKbUncS=;@<|^NRm@N;v0L&2` zMZP`)6Pi_X`yi<$=`LGb)7-P=HH(Ssr>>+SZCDH+XQ*f@SP&Hpn|P0a4Cxj*j1VU# zvY3*SwhIy!R3;N4)Jevqb95D}?4X7+BkM@s|iVrmdIHU*@d|X4UIb3WO7LtIrj%pF7oZ65*V>oMiCoqOD zx`)WB0w02JPb1r!8+g(^2J~>A&c8tGL6bCPDX{UZMNjvOJ&qJ$8<^&YS({*(KzmfV zN&Rz-6~gsmaQIjjC~YQSp?&D5aTthG0SXv`O-Xtpz7EU{r_S_~U2a-kd{(F+p67yM zf>cEiVNS2t|0=%s6pfg_C1v(7D-doxVvzp84LVSzL6hoe22KB`;<@EmD7Wx4zd#ip zn+oX)Axl(NjJj45K?>-F!;q>|`avR}v8A0;9K;@+0E*K}%AH9y&!bPUNm) zU}1UtovVvBuBM{Wg!!>(gl1alactz>y+OoM8}Yy>94t(rKut@mqQ$I>7j(g6UJwAX z+%cAh05YptX_T63N=2vWp^SsPTv7cEOrYv-%G?vs@RxqQFkY0|e+pF}gM0dX>o-WB zZ&ATgBQ80eH1}HF3W!I3N81$1#mG~_u~aGCf#VNfAicp~;5kcdsK@RLuP7o~TW3UY3jK?xXR2%*Tf(ZElV2H{ga0Eq8?@LHpd4{1;r*AJ9#?=&K^+gOZ z-0C@w4pIZ&?BN2XvwqE6xM1~NxgbjYH{X1NP}&3#TnW+)LO`1lVWMV8d3B6aKS!qV z^B6kl1()riEX-fo2{Irketi~x{kQ!)C;uH!?mvu=9^KjCqhCDWqfzn5os2N>vTS?^ z7WGpmGGrg;{>KOiBF)i#T%;n>Eh*8?D%$Zu7EI-RUi9i`g2V@jeJ zBn$+k5AEdY7zydRMO>KRJ4{XBU}n%2oY@w(E*of)GK^rDICS@Xw!bQ1(YsKU$ zr;A@OqwTQVgm!Xtg^W$;O`(L#`yaH1%lm(5J>6Kr*+u%1XnlY|r7q0}fBEnZO1iMt z8oX+17SjBXL?YmAHoqXr#UtW@K5%SmF-dq$loOMYdX8Q=s_qyz5|V>{CJ2<)&f>4Y z@U1T;g$Yim6jWOMas@cL%!j#f1Hf|;bgg&Uz+I~2!!Aj%l>Dwmk50>lZ5&^Ewzm6R zd9B5BL-7p@bBy`Eo*C zR&zZ&Sw?Kf)Y5)~A=cW7*i=`ax-#QXX2kUz*&vD0VbG+^3?7Z^=xddPO>rZ57~krB z0X5lD?gtqrA#;jA@p-E5X zz}tnO0creP-lr;1=p=riK*rSBT5q5m%vgd8(kU*8d%74Q3F?CB1LkL_7^0AnvH={8 zirF$NvIssw{!4?KTLM!T2UbNP6ZWE^6-5Uo_5g~f2Wp;Hu>&m#O94Z4RJ`&OcZwGE z0tKBkM9Z++tdQl-1~2{rvo&@P4z1vGDRDA|x;4Z5r~AHbZzty)Nca3Y6K zn8$KFjXBCh;FK+bd8W5vp-ZhEWE4Upm4k~3Yj*0UP26X$9rb28(mWDh-h!rEX|%@t zzKZ5@zS3q+Sn~tf+4GXgVq@qyd&=W; zZZ7nwZiD)`ZTz3&XuPCIgY=h>gyMs+lc2?l<&tncm7*ciC3df5oB1qWh+=_4-s(YI z*QJN3u-ps?ySH3fW)hpVLcu6i?x4;;T6ra5x|o(5BG2H$ZnN7*=m`L>fiJ#TU%gX) zg`f+0Zkw@E49b!Om|zrrD&CbIG)&Z0R1AfNwL}a(sZmuWIAL{4nFM-mC16m)9-I{} zPiw?qCM>9Tc*eXuHYV>)p_72vj@*Jt^$HdM+Y@BKWZH|mh6@!XVbO(p@TgE6inXo- zezNua*~;zm3 zUlIcd=EcOP)IcIXbF;=4mZ>4S4!7NFkZ7VZNy#c~WxVtY^@DgCS&~U;PSCK7R!#`x>%`keaXyI;E(k zx&)*!rgPL=lB>2fY#6EtVtH_-B@3cL?zsMU#3O)sGsdY!dE+o(!Q&Az19rOYER17o zimZ+O9@_&gQ1-SxSoBR|uNE+|0&EGP2$VeFvf$hsPQ)WtBG9a9fK$AdTmrF=UvmZZ zFAMvBS4JB0;&WxvZ1du~aud|l=4}V*KU}Hs&k76vhhO+(%kOuA1BGV|$`a)=Gy=A9 zj0;QNlq)C2>stahpahBQq-p>ca4n>MP!7GMfr^6)bS7n~>NOj)lSL?F1x41iPz0;&lB=r_o`)N3d#VPpDKfcuUu;EQIY50fMg zc%_Aik#i+kiOIPk`M?cJ)c_xwf$Dm5g|7#wfIbbz)F8q<1}VswG$D=n!6|A9Hc1Z< zRGWwWVSNm@AJb1}4a_drkySy7d_g#QhB|D)C7%r3Di$ZhASb$jJ&QmibUd<7Dk-J{ zlNim7M%f^0XLUqisW89+QIedPc$j>z^3vpeqL(RB*gsaskPwSN2K{zblwp+4FW zPUTyaE=KGDulW_+9Bf_RAOnd&B6r_GRwoz1R(drzoW8aZpl77X_Z4HHr(`60Q{(#i z1+S)0s=k>Kv*hu%VZ9;Mw7#L`qI7W^Kr&VbK4l>U^TnDTPKA7aTgcPtE3R7D3UP!c z7bMpY2dBqTtR&;H^$qp=@T!u6b(X#yX@?*KmFP6VIia)4`$-D7s4cmUlw^y_hIq1@ zC~~q}J(YF3dURWcmk#_&PO0ImNwRsa$??YBn7&xWfyD6FrAn>)S(t4CK>0E^P(2Lk zIFn}jQuO!GqoHXyR^Vb!u)1;?OtMYMSFo~DEE5?yHnABbN7CPQs5)$kXj@@56AY?> zM^w61H%0E=AoGXbE4Nj`tH6sOa!D3iWxU+anX!UFV~-I01z<01uEhy%(*^fr-LCn8 zR4BhqpW6@W;!NwHH-4pdwQ!WcOQAP*RDBOObI}xT+KS}fG>8bn2i>_G6L`7Gq;yZI zAnb17jG_QEi@$o1w{71zGt8#(U5ZXtMqsA4rqkg{ifJq=tVH^m*tPLXw$X|CrnmCe zuJUB#oXgDg6*If!ij9OTg$Yc4#0<)MB+A!--p7X2HC>@aMNW*AB%sENg&(lYvvYGoW;=3I<9z?DHT=u7aTTp8tBj#Fu2@L+AZ-q>65Lpbw(@>ip5bk17ZSw8{YDCFh8fxpV1l9ovlJKOt&no{ zb>5GeoD62dw87Ti;MUNTJv6m_LbRZX8HT35(vt?L`u(VL^JeDYN6l6sTnRD1^l9ca zjF&~^nnHZ;BddoO97q*USM2Z6jexcFfF_zvAV-+Pq&e?n6fS&|6EzM^0fqQ2RV;^8 zKgbEw+ndk!VY$nP8#QV2YQ+t{GXeu-xrfRM5$_GpIy^%+u_^(kPR2{QG`CB*C+)cT z!2<4lpSAgI+U2ww#%VZTV|B$fNbR9%YZd87W}j_Z_@FIlh+j=AsHVy}Bu>gm8+l&)Vh^bj-E;%0 z?+<&OX|F-GQ@am(sQr>K^(y$`1o)9&1%%PLe*>I3uo=wAP9}GcQ@C2?3!OAD5-Q>& zeuW`=rTkhxA%Q(1VU+cOas}E-Ay2$^<}tNV81PK3D;y0Mp(RT;F@TBIwbMeNI~23Q zy5#($inP_nw1J(aHJHTJE`Blx8`R(}uk>g%RVwX_+CGGu8kayB#SN=4UA2;MF44xu zhZyGsHw$eh33>9{P=yk3I>G|k@TjeVvIQ}X@e9=t ztE(0uP~}gJxtLy1_dV6h8uAf1$-9FCy|=`D0n zI{zw=y~PslTA@-bn(UDpJ4k1}VCu?zXRbiVB4jq0JWgadg>k@%+vYLM4lYSsu=*;bii{P^tg02E( zj!bW22yl+IT>Y%{pjM$Ny7{P;Asc%G=fY+ur=W1gDI9**16pvX2p7|M8p^amY#vDo ziBx_%Gxt)N%(s^fj448+yQ@1}Om-BM#b>j62ZAR!BG~MotkhBv@T^x6KFO3_eu7A$ zhuvYxLKvyAhDGGcQy{h|mr0{M&LJ7iz7dl-R(;tU6=D1g?hpzk_?Xkl!cYB_f#|vj z3&GJKuWPGIBjaQ`m?pesG3Y|Lcuxo`wy^Z>N9K+Oe zK;qZL0AohyA+pIPC($mX0|2rZp5Wc<`OFt6%WPzfU0@VnLpTp9D2^{==_f9sY73Db?eg)H_52Np(r$7rEpgm*^9bG( z_$%Kuh{30nb`VkpBgwyIxs{5;6K_%9%@Sh+20KrD3z?UF9mTi;<1A6-3|BqwtnOAC zu|A;J>fJ?dt{6#ilsNXO2Mi>=XzfIb=v2Rglxu{TsvkERfD+Ao*O0GPZ6>P_q`IS|~e0m%uzBB|PXA1!%d1`PE!zHeXuaDddRB%HxC^`*D% z!CPLUeVg_Ve_7K5a{O52=>e0jp<&E-mRK?fr!9uRD#zhK-Newm404UW`veF7bWL_CqZf{3o$3L;f- z-=>L+HT07EtgBrDFZtC&TnH#}>j?&cxb&cRI^?x_Xu@=F_#S$^hI}Z6A5%>-p9&?_ zS?`pY#3`xTK^&MbkpIC8E*ZCyM3=G`3COAj!YEQ$jZ{m><`k-9QfXlqvyOj)o-vG7 zStCzr&S&pWC3+#r6rScFew%cbVKpne2M}EIvkLFQriOwH)o;2asyIurcUc9o@@Y1wOg#yL!Uqi)FqT2={T z3VPcd>L-Y(Si{ug8*zCAq@CEjxWRr}BeHPB{+jm8hy(tSJ}N~^lIo33;~DH46~Kr@ zS&>L5BUuqTIczYca8Hs8Ihm$Y;BZ0-L>KxW+J%JOC0GVO^U=A+o?6VjqBY#yZFgg*v5(Y6wBuye0Yj?G zia@xJP$QZ7H#l-MV~_3|s0LIf)Fn4-zv#6yV(Q)4Q}`T)YH1GsJzTBazw91VZsSvD z0kELRsz6db#qo2%P^`7ncjjbnm*QmB274Xxl%-ED;9+7-$>5dss=o46afYUx{EV5) znnOUY0}S$N3OvRMRqYIw7*U%aB%c&_g+Ui?t5#rs12@cnKQ|6)vogW*IW?@s3x_jp z2XCu`5K^#X6X_^Sy|U(#9s$P-FxItHo3q;I!zx&*_Es4qCZmGJT8AWdyr?r1vsLlN zWJOBjR3vnPz03!ApnA;2wP*6rPkN=QkqNrWe&ouBab)DS@*-S%i1zr&g&&=>peNS{Bi59OP31O?GaJRELX(5Ou zTpm%21yAaH|KlPPLF3DSkMIuChJbi7{qXvS*ea@PaV_MuI85?j{hCwe@}&!wahaBjB&p>s=-g|t(W(-I)wt4O~9m4CQWverDo*1 zVHKgUy(Iu-!jm^$v3f#aKjDC(*_{x%a@d~*>cU=9Tac2WdPEzvD$WKb4dpXZCX8&G$oiU8gGWm zj!E?5hl9urYsd4(F1`wpjs6044*doEEX$dm&q>Mtp7-H*;%YyD$fRU#>TUQK(%En+)7CB2Ku7*|4|ecHVqW%dsFz~5Z#bB(5f)wt8U>} z%bcPRQ=Mw3j(=*yki_W^c%)HC0Tyxl0)mfB((I=c{HVUgfK*-IhgWh@+1QKR@@+_WvJs-FL=>6;sQ_b?UX})++}y${8Lj6- zx1wxG(IZ&^td6TwLG^>+ZTRkTDVze@p=D^RqQJ0_)>e~CLf}c%*q9Qfy3ZAi#RkuKpM6c>)F&qoc*bZx89!5KoKbv5h-ppD$J8N1vKqG2qqyNp?^S#a0Z}z_0*m|_G z(FkXCm$v1~1n2?=ptNv}&1MMNDA+%M`^Q&|?< z&#Gj0j~fS92S$xoe7#9_)~mS6E2teCwFDui$-B22gR32^f+JD?TlF^cTgUO?JyAeT zKvcDv`uQh%urB}<^{9YM%-`0#|AHj!0F&a}a zaw@WM5T-wdSThMXmHx0H8aC3Mq{6bPHBvf}D5fC4ZK)W773Hr<w(*gbM`5@KH<6 z=~CZ;-ovcXo6$&Z12H}-KY zl7mgl3aZlq?n$JH{o=vi%l<_(J(-vUD8JPKZhf_I>56fQ$s7GZ-}ExJaf5g$AvCi8%+sYXXXvQ;@h6^k~-48fr96$94-#e4Dw1a0Ghw{ia?><731c zk%&e0R@NzVvp23x&`1)`1TqA%v~~wD&Ko&IEBtJ(%iOI#oCg*2ak-Ko66I z6<*@$C`XOUQR$v0%2+DP%ze%8XFSCA%}kL{{8YAM*3mdb%Y7kdR9&SJfJTD$wSY1% z_o0{Fd6sl$ON`(gXk>?RWAnsAsyW@LWU#_`F-ylqc>uG8DvHYn;%Q`c@E zJZqpV_dlrYuRFsZ;~>!wnwQ`41^tJ{JNhGJhktWRBxR;~ zHw0B?Jk3$%yZE@rSb+3MDezm-m;%u_WV0^Cp@ro#%u5V>h%iESw`bG}r^PN(sOYVy ztavs>HNzJhYme?f_>8uM^9~%mv#+B(NpLUBH0)VFU|^el73rwmTK9{nfvLI=|j(Q4f zBg!ZoMA&8>%p?>mPjJ!i3=fd2G9!6-^B6D`nFEvn7N0dsrWCK}A5S3P21l@|t)GQT4pWNlpiXAi|v8DO?CkO+3LJx|$G-EHSImfz3X{ z9UJa}*PVwcc06cl1 z9@6Gv+My2h=$ML0OxF~n)Uor;H+!q2v!4jk^X^GA6V|h}HW;vo%xA;F(SXNY8%Qn) zku6EKYaCn#F}h_LLgp*5w44*o2naFQ(Fr&lGj-rIwZTlu8_C82#nzAC61iskCOg@8 zrtx2j0&p;1p`;NT`ql(@gqsmnJn0cS8kRvPBCBYAv&Qkb5vdAta2?G?{JA^F_L!2; z?(*RFLIur@-NvD~11CXTGYhM^d_0`of3pxBl+A7i0Va8)l3ws*jFwR|R;R|n`28Pv zD5w;d90`;dUD-+mTO&*r6|^aWYuXYM^zIcbIS5pS z1|#_p$^IZsb4SI6Aof z;`u6Yk{dmM*x4}JW+mPS3(xoh>f9+lXsJd;d3=iZDr@Bh`gVO3(O}FGz%y7xtpnKNroUCka6P+sD*{7>C3V|vNpzHhiAp>%9w~=PTmB-gmGZY6F zBun~cCvM$zs~->!Jo{8ZL{$jsC1)Q$#6V8LE0I%^5+tsshnEJGV3;XQ@z@h-4dj}A zDuc_t-?dMM*tT>AAKU+@jO3c1imJeJJ{0Sej-G=Gi5FoxSP0IDP6r46u%5`@yK!o0u&or@Kj&EQx z<_BVyrZ{sh_xhJ_yEqakW1LLbn}B5y80AGE<3|?$apuwNwQPbiqWL((w=2vJ3^W{e zo}QOmQQcz<=|+h=8(|5~d7KEPC`?LuY_bqHuZALKZT`xwzFkkh0xo!Q?>ITv`R zGN%Cdq1GF)lk1%s2rKSkA_CSX6$;v*;4@feFf=AbvEq#kjC+fmD25)A6I05B(lwg! z1i(~`Tz_R_W9zZ<5}LG@RfOY(^pD8d`pku#0W&~gq|A*>AaVM58IIp4zz#D*DFbJ{ z#G$jf^=N&Ux|T3eop3z(B!;H=eAFS#k^wwTq8b={mp3S2*=K1v!_$;}QI_|A(AVJU z{s}%O3#DhGto{=m8J6&ZWff~U!`Qh>goFfRm}PKhcBN?`jh*IX3o#VFD4 zx7%w?E6(#YLX_a|?Gu#DGAThU)XXhksOvwq#g`jVCo=qIY|Pw6QW+KHj^Jr!9)*YH z#YE8=G!HZB8^f{m`6g1pi%Cu#N5~f%ixXW>%$>LTN|IA(^aq+TtpV{!Pg7=2TIP27 zNVthM(mZiWaU{=mFAi->UC*{)OsyZx;14lpvv6)2rw$IF`Cr5+6at7)4VImeU_fAIM^PR9ms2 zFx$mj$wX~6M7(HKnfHH>LJ3}f)@v{n?)4TCONIm);t7uMd8AuU9isY(bD+B0LwTf2 zR6~-4(({Yn+2tE`RI)*=mdm6Tw$cKIiR_WAEfY&>art&;I0@eqFAlif*Q8Np3}ZWzaHCJ+X3FFoz8Y%MWuE6$S8OUq?Kuwl}X(^pzMW;%n> zPMCxnyOfObNnp|2JuBl|C|mGgvq!rt>>+Fbj*B85yU!X?x9gZ$R@LDAT;T-CHd4)cqz0pj5}KQw zqyl+~o?e0BR*V;;Lcu%o0{G&bWAMO2b~=LHB{!)A5q2*;I1_k|-j_O2WnRj+uwQVA zpj@zDaHa65ZUx07ekOYyw#nb8C5DYPhXK;C`LW|Ip`GA@t^P(NsIw?Xi}O{ z9ecZd@IOOO9gV!*wrZj`4+>7kM2YEp63?EIM|5N<`PG2&#f33{z3`9?x5@sagRa= zx)|zLLMbjknIC-8)CMWrmsHrGRcJf!1Z5X>uh=yvqlDxFE3q>ibUPHfl9TeTyn5TC zm%cwd!BfPudS@ucwTFG^yn}d?WGNj`3cEHd(*tc9Q^mYGeas7W<3Q|}_y$i#*yP%s z4$QIvCeOXTC45?e<@^-r+MogQ>bILK&(gZ~lk_&;BF5iMkwOImCAP1<{H2=O#S*Qn%z3JxgbRVk$xOwA2Y&~CqFOyBb zzW3b{3_|M3iv^}>U&)6a`_+CWZ#?BIWK{S{_GM;-%9o9U+g3u^=$#$XKm`d2$0CE6 zD|V40(Z!7ypr&zTbhg5GSOW6mk{uJ|{`oTc&8?~*DzM_f6Xs8bia5)2}kV=aIi z#xnnxtm6gTn15K#xBd!Zwe^ty`k(MG{xK-#{stvssCb=qyPc@1L|my`#t+82TYu~) z#lkRGJqBIHE??m4wvIA7$npOsGV=-F?u-91vsSInp_n&SQxN`g_W5Xhz z%X^T!5B1Oazg)WiW*%zn{9kn@p0Y`3Q0}Ns{HWKa;yauxAN4L->_7xCp8S8!o!xF! z$q~nWJx_5YYa|vC1RH`jC?FYQh_l967z<^Q6^-oy24fp}W_H0>D{i7(=PG%CJVbJt z^^5G28yuCDrbHRmmtlB#YOfeAAsWFA%3w}*R`3*2u9 zuSb@3p|dss8I9m$<5G-9l3i!u$nx*Lxg~2QsFWzEjfmXk{ z{o5gb?&ybp-obUvZQLp8*JA{0I)D4N|0G&u)b06NK>8uR&9Gb_!il#@RaJj@@qBB2 zdFjQdDgchf7aZ9#l7P-b|F_y9AP#OV1ydD>D(joC~alSJg5v zpl_39X=mrS|Kp%8CKRbPDzDfAx5E*}2)_Gv@E)o8kRKqDM!h%sGDrOj)td2vuOQy$HR!l4*Gtsx^txC9p{g3nR17IH#M1HOOOO4eAhv1Z^TU1M32A zb?akS0&@H*I;aayUMgbNZC9GO_bS$&XJQZvLEB28^^L@xWxz7kYc>x_@Qz)TY;+!n z(nPx!yVqURfdREf>ac}~A$)sxxVHIdsj|~s-{khrf@u1xyIt+}4yE3B1JlfFX_u+4 z33_%aweQo>|#pqQ*FrvO2RqHxV5zAku*RRw18CjB@ zRGVBt8(!_h7&RGWEuJ4F*}x2T^oENmE~#Y>8`6@bJ{6i}P|C?(r%F78i^IEmXFamo zSdJ1sh0gw1q3dCrbyC^W-bc4h>ZCBNc)zgB!Ju}kRfc$g+~~@@0eb1d@GryB!3a&X zJ|y8_+z;F+)L;J-lbE4$qR*C=B+ovG6-+M&O@k-l)V@%Om$U75-@esbn{Tj(m6(*x@-cpD>0&CR22RgfL=X)rHv;RRiC5EP`tLBIKNj>nVQ>9 z*`cMT^g#Hl1{lD7#56eD3k1dSQnQg>&}`Os-Ik5mheBLt4nd|uxI}$sS}U60kZMd+ zsqtB+Q;VQuVH>@@JyckcTo(4Kdk0~{Hq;@#jA8|)EOsKPb8K3DO!e?tLx_}K>_ZRj zsDFyAOSWobghlJEiO!Qp56|7M3o$AP^I9_#6G4O85L>MEY-)93CWJx+llJ1Kqnc~3hs34sACRKFxHVxk&jeHX8 z2y|1^s{4EX*KAyuEul?*I^!r6Gr0xotb~8WShP1j_@JFMR}xPST3|tQpJfj_taWD1 zcuhLn@u4TXjzUC!iJOP~!A6+eLcA zr(uCLw0g6$42kfiHJn6)3dis@}{t)sI*@1}Vi{$#IIArkb0?PH(wmN7ne zn;hJ8WYcXc(d*Fjbjy-C8yx{V9{c2Yy`(o5b&uqfqa9_mWAM-Xw{vP+*lQtdEzG~e;%&kj>OYa1z=>$PcyMPr#9sDWpiTc zH4v9Oz|WeA>#cVavw+8S6LW0XME0OGM!P~(wrN>amp;stDs`wsK{aR z3_l6sR5xPLGC7CtCYsdZPw;hZ{E1t__@NezTo*9p)hI1?6xVKpjz{UV->`FsTPCtX ziy~&8U!J+bn=X&!n+Q;<#@LICy-vg_{BQAA9x03jHc(%*c!ubUmT!a8UPHOn zH)%R673L{pYFFne#QQUYg+5FPE)H>J(7a#=A5@L;PYW{+w{!Ljtjjp1@_^1;`DNDY z?YUo{JCbYX0_q3!d z;)cq2r+@m{?sy`b_!f?8QfRWcR;p`?8FL1c%GWdW_Z_-$v0Xcs3=hg+imPni{^0++ zc?|B=G|VHl!|LlY!Y=cwj+;VAbi>ShvU5! zn-+pky`2HKrBEU6YrfUwpgH#W%NA8`_m?fpmTc-|P#h2#9dk|eGaewzbNDQPlMRmX zQ1mi@lg;m+|M&09&(>EG;3QluJ&Nxvb2pPGns|zhOU==Z63@Q-&8G2!>Dc0J)N?br zo?)h3rpi-A%mNHeKgn~-V3z6v!IhQ9*}E08vILaM`s&Ko>3{zGa%p{~I{oL<)s^Md zl?T86{IALefiGDga&zW6lhV*C-yiJ>tP-R+pX(a%`UI8*VgjqeJ>#Q;zJ?K~3I}?7 zbX>o3c{8>HP)2%=p*T>RrRJp`1?;(j*5fQVu5VYHDxwxV^h29)N|=RW_hxEN7RfPa zG)^WLE1+DV7c0TnB|~5snDB;`k=}4HaZmi^uk;rzOi-F*9>O?BkYQn3NNkvvI)N?d znQIT1w*tWhn+aiw-j*U$seOs1^!($zdc$pIFG5}lXpD~Z zNf&^zMw$S2b1My-R7=h{+QnT}v~$2_FadL;lQ-t^B8vC~^XGMq%qiIVm6b+X$XH6dTx;T=FSqfW%|EY6(6Dn#7i^xrU2W*MA}eNu8xMBN0&G1Igb!|`b(u*;ut(~iG? zl!Jg!>;alWmrGKgm$W6#=OEi9CS`Fbiw*|8$J|%IBk<4a#{ExxU5>c1kTCwZ=9>x_p<1B$;w{Hk8E7tyHXzL8D7Mp*NE;B$WVTI)>_L`hhvnBGi#O;dc^wrQj zG35|6&pv1#DP7${RTOS1f%FUx@DHAkFz^7!_+SUf8fU71+S?!A#CmROVFpaEZ{m}U ztSS93|Db$zK3&1iFB{^d>76_h547Y1;s*~saUDn`LEDTcOnf{RtxO$Lxj*!<=x{Cl zj8s;C;=ie7xhJVWw7#oAZjQ%vv@cmgJ6Xi{e8369L4Sm!*4AKLO0|Z=mWYWe04}ck zYj|cKYQY8NEz+?;_%U*D5H=h0c8S*lp?HiavgSY~`NYtH5zR2hrEpZRbXJSTqY=Ju zkRf^FX~x6_8KbC8HjrXO&GlqL5aEmogw46B5EW-n=DfE);*J4|3@wcqU(_|hjG9w~ z9HqP#7^$x%LDA*xS6DtH1c=CwY1lN;$OAjt2vdZ+hzWKS_;(O+ z5uotHEGk^qK!rvqzQiHp&%_!KQo~G=fzmC z1Cg>VidACHmy(=9p&61?u&|bd3|Sn&HN3fC+rS-8ZgPw(%X8k6niP}huK||A_AcDg zIr35#n{~j}=rt#mra&0AC|OdAjC>*V#a3)=8Jc)-8R%zyn{>5cE!zG&qZymX8VVv4 zRcbpW@P(v|4kEtG*D(XgrTH>g6D23jnhngj?3~FEY=CsjUl(V73D0Y1;n)?OWSh literal 0 HcmV?d00001 diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 00000000..85c39b87 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,7487 @@ +# Polish translation for elfutils. +# Copyright © 2003-2021 the elfutils authors. +# This file is distributed under the same license as the elfutils package. +# Jakub Bogusz , 2003-2007. +# Piotr Drąg , 2010-2021. +# +msgid "" +msgstr "" +"Project-Id-Version: elfutils\n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2021-02-22 16:25+0100\n" +"Last-Translator: Piotr Drąg \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" +"koloruje wyjście. WHEN domyślnie wynosi „always” lub może wynosić „auto” lub " +"„never”" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" +"%s: nieprawidłowy parametr „%s” dla „--color”\n" +"prawidłowe parametry:\n" +" • „always”, „yes”, „force”\n" +" • „never”, „no”, „none”\n" +" • „auto”, „tty”, „if-tty”\n" + +#: lib/color.c:194 src/objdump.c:728 +#, c-format +msgid "cannot allocate memory" +msgstr "nie można przydzielić pamięci" + +#: lib/printversion.c:40 +#, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"Copyright © %s programiści projektu elfutils <%s>.\n" +"Niniejszy program jest wolnym oprogramowaniem; proszę zobaczyć kod źródłowy\n" +"w celu poznania warunków kopiowania. Niniejszy program rozprowadzany jest\n" +"BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI\n" +"HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "pamięć wyczerpana" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "brak błędu" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "brak pamięci" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "nie można utworzyć pliku wyjściowego" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "nieprawidłowy parametr" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "nie można zmienić trybu pliku wyjściowego" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "nie można zmienić nazwy pliku wyjściowego" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "powtórzony symbol" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "nieprawidłowy typ sekcji dla działania" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "błąd podczas wyprowadzania danych" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "brak dostępnej obsługi zaplecza" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "nieznany błąd" + +#: libcpu/i386_lex.l:122 +#, c-format +msgid "invalid character '%c' at line %d; ignored" +msgstr "nieprawidłowy znak „%c” w %d. wierszu; zignorowano" + +#: libcpu/i386_lex.l:123 +#, c-format +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "nieprawidłowy znak „\\%o” w %d. wierszu; zignorowano" + +#: libcpu/i386_parse.y:554 +#, c-format +msgid "while reading i386 CPU description: %s at line %d" +msgstr "podczas odczytywania opisu procesora i386: %s w %d. wierszu" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "nieprawidłowy dostęp" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "nie jest zwykłym plikiem" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "błąd wejścia/wyjścia" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "nieprawidłowy plik ELF" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "brak informacji DWARF" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "nie można dekompresować DWARF" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "brak pliku ELF" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "nie można uzyskać nagłówka ELF" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "niezaimplementowane" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "nieprawidłowe polecenie" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "nieprawidłowa wersja" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "nieprawidłowy plik" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "nie odnaleziono wpisów" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "nieprawidłowy DWARF" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "brak danych w postaci ciągu" + +#: libdw/dwarf_error.c:75 +msgid ".debug_str section missing" +msgstr "brak sekcji .debug_str" + +#: libdw/dwarf_error.c:76 +msgid ".debug_line_str section missing" +msgstr "brak sekcji .debug_line_str" + +#: libdw/dwarf_error.c:77 +msgid ".debug_str_offsets section missing" +msgstr "brak sekcji .debug_str_offsets" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "brak wartości adresu" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "brak wartości stałej" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "brak wartości odwołania" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "nieprawidłowa wartość odwołania" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr "brak sekcji .debug_line" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "nieprawidłowa sekcja .debug_line" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "informacje debugowania są za duże" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "nieprawidłowa wersja DWARF" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "nieprawidłowy indeks katalogu" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "adres jest spoza zakresu" + +#: libdw/dwarf_error.c:88 +msgid ".debug_loc section missing" +msgstr "brak sekcji .debug_loc" + +#: libdw/dwarf_error.c:89 +msgid ".debug_loclists section missing" +msgstr "brak sekcji .debug_loclists" + +#: libdw/dwarf_error.c:90 +msgid "not a location list value" +msgstr "nie jest wartością listy położeń" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "brak danych blokowych" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "nieprawidłowy indeks wiersza" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "nieprawidłowy indeks zakresu adresów" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "brak pasującego zakresu adresów" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "brak wartości flagi" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "nieprawidłowy offset" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr "brak sekcji .debug_ranges" + +#: libdw/dwarf_error.c:98 +msgid ".debug_rnglists section missing" +msgstr "brak sekcji .debug_rnglists" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "nieprawidłowa wersja CFI" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "nie odnaleziono alternatywnego dowiązania debugowania" + +#: libdw/dwarf_error.c:101 +msgid "invalid opcode" +msgstr "nieprawidłowa instrukcja" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "nie jest CU (jednostką) DIE" + +#: libdw/dwarf_error.c:103 +msgid "unknown language code" +msgstr "nieznany kod języka" + +#: libdw/dwarf_error.c:104 +msgid ".debug_addr section missing" +msgstr "brak sekcji .debug_addr" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "Opcje wyboru wejścia:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "Wyszukuje adresy w PLIKU" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "Wyszukuje adresy z podpisów odnalezionych w PLIKU-CORE" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "Wyszukuje adresy w plikach zmapowanych do PID procesów" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" +"Wyszukuje adresy w plikach zmapowanych jako odczyt z PLIKU w formacie /proc/" +"PID/maps systemu Linux" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "Wyszukuje adresy w uruchomionych jądrze" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "Jądro ze wszystkimi modułami" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "Wyszukuje ścieżkę dla oddzielnych plików debuginfo" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "dopuszczalna jest tylko jedna z opcji -e, -p, -k, -K lub --core" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "nie można wczytać symboli jądra" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "nie można odnaleźć modułów jądra" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "nie można odnaleźć jądra lub modułów" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "nie można odczytać pliku core ELF: %s" + +#: libdwfl/argp-std.c:317 +msgid "Not enough memory" +msgstr "Za mało pamięci" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "Nie rozpoznano żadnych modułów w pliku core" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "Proszę zobaczyć errno" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "Proszę zobaczyć elf_errno" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "Proszę zobaczyć dwarf_errno" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "Proszę zobaczyć ebl_errno (brak XXX)" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "dekompresja gzip się nie powiodła" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "dekompresja bzip2 się nie powiodła" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "dekompresja LZMA się nie powiodła" + +#: libdwfl/libdwflP.h:61 +msgid "zstd decompression failed" +msgstr "dekompresja zstd się nie powiodła" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "nie odnaleziono biblioteki obsługi dla komputera" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "Brak wywołań zwrotnych dla pliku ET_REL" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "Nieobsługiwany typ relokacji" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "r_offset jest fałszywe" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "offset spoza zakresu" + +#: libdwfl/libdwflP.h:67 +msgid "relocation refers to undefined symbol" +msgstr "relokacja odnosi się do nieokreślonego symbolu" + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "Wywołanie zwrotne zwróciło niepowodzenie" + +#: libdwfl/libdwflP.h:69 +msgid "No DWARF information found" +msgstr "Nie odnaleziono informacji DWARF" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "Nie odnaleziono tabeli symboli" + +#: libdwfl/libdwflP.h:71 +msgid "No ELF program headers" +msgstr "Brak nagłówków programu ELF" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "zakres adresów pokrywa się z istniejącym modułem" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "skrócono obraz" + +#: libdwfl/libdwflP.h:76 +msgid "ELF file opened" +msgstr "otwarto plik ELF" + +#: libdwfl/libdwflP.h:77 +msgid "not a valid ELF file" +msgstr "nie jest prawidłowym plikiem ELF" + +#: libdwfl/libdwflP.h:78 +msgid "cannot handle DWARF type description" +msgstr "nie można obsłużyć opisu typu DWARF" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "plik ELF nie ma pasującego identyfikatora kopii" + +#: libdwfl/libdwflP.h:80 +msgid "corrupt .gnu.prelink_undo section data" +msgstr "uszkodzone dane sekcji .gnu.prelink_undo" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "Wewnętrzny błąd z powodu ebl" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "Brak danych w pliku core" + +#: libdwfl/libdwflP.h:83 +msgid "Invalid register" +msgstr "Nieprawidłowy rejestr" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "Błąd podczas odczytywania pamięci procesu" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "Nie można odnaleźć architektury żadnego ELF" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "Błąd podczas przetwarzania systemu plików /proc" + +#: libdwfl/libdwflP.h:87 +msgid "Invalid DWARF" +msgstr "Nieprawidłowy DWARF" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "Nieobsługiwany DWARF" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "Nie można odnaleźć więcej wątków" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "Dwfl już ma załączony stan" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "Dwfl nie ma załączonego stanu" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "Odwijanie nie jest obsługiwane dla tej architektury" + +#: libdwfl/libdwflP.h:93 +msgid "Invalid argument" +msgstr "Nieprawidłowy parametr" + +#: libdwfl/libdwflP.h:94 +msgid "Not an ET_CORE ELF file" +msgstr "Nie jest plikiem ELF ET_CORE" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "Brak zaplecza" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr ": %#" + +#: libebl/eblobjnote.c:58 +#, c-format +msgid "unknown SDT version %u\n" +msgstr "nieznana wersja SDT %u\n" + +#: libebl/eblobjnote.c:76 +#, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "nieprawidłowy deskryptor sondy SDT\n" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr " PC: " + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr " Podstawa: " + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr " Semafor: " + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr " Dostawca: " + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr " Nazwa: " + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr " Parametry: " + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " Identyfikator kopii: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr " Wersja konsolidatora: %.*s\n" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " System operacyjny: %s, ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "Samodzielny" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr ": %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "nieznana wersja" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "nieznany typ" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "nieprawidłowa obsługa „Elf”" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "nieprawidłowy rozmiar operandu źródłowego" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "nieprawidłowy rozmiar operandu docelowego" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "nieprawidłowe kodowanie" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "nieprawidłowy deskryptor pliku" + +#: libelf/elf_error.c:99 +msgid "invalid ELF file data" +msgstr "nieprawidłowe dane pliku ELF" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "nieprawidłowe działanie" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "wersja ELF nie została ustawiona" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "nieprawidłowe pole fmag w nagłówku archiwum" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "nieprawidłowy plik archiwum" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "deskryptor nie jest dla archiwum" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "brak dostępnego indeksu" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "nie można odczytać danych z pliku" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "nie można zapisać danych do pliku" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "nieprawidłowa klasa pliku binarnego" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "nieprawidłowy indeks sekcji" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "nieprawidłowy operand" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "nieprawidłowa sekcja" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "nie utworzono najpierw nagłówka pliku wykonywalnego" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "deskryptor pliku jest wyłączony" + +#: libelf/elf_error.c:171 +msgid "archive/member file descriptor mismatch" +msgstr "deskryptory archiwum/elementu nie zgadzają się" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "nie można zmieniać pustej sekcji" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "dane/scn nie zgadzają się" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "nieprawidłowy nagłówek sekcji" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "nieprawidłowe dane" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "nieznane kodowanie danych" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "sekcja „sh_size” jest za mała dla danych" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "nieprawidłowe wyrównanie sekcji" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "nieprawidłowy rozmiar wpisu sekcji" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "update() dla zapisu pliku tylko do odczytu" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "nie ma takiego pliku" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "tylko relokowalne pliki mogą zawierać grupy sekcji" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" +"tylko pliki wykonywalne, obiektów współdzielone i pliki core mogą mieć " +"nagłówki programu" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "plik nie ma nagłówków programu" + +#: libelf/elf_error.c:241 +msgid "invalid section type" +msgstr "nieprawidłowy typ sekcji" + +#: libelf/elf_error.c:246 +msgid "invalid section flags" +msgstr "nieprawidłowe flagi sekcji" + +#: libelf/elf_error.c:251 +msgid "section does not contain compressed data" +msgstr "sekcja nie zawiera skompresowanych danych" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "sekcja zawiera skompresowane dane" + +#: libelf/elf_error.c:261 +msgid "unknown compression type" +msgstr "nieznany typ kompresji" + +#: libelf/elf_error.c:266 +msgid "cannot compress data" +msgstr "nie można kompresować danych" + +#: libelf/elf_error.c:271 +msgid "cannot decompress data" +msgstr "nie można dekompresować danych" + +#: src/addr2line.c:57 +msgid "Input format options:" +msgstr "Opcje formatowania wejścia:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "Traktuje adresy jako offsety względne do sekcji NAZWA." + +#: src/addr2line.c:61 +msgid "Output format options:" +msgstr "Opcje formatowania wyjścia:" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "Wyświetla adres pliku przed każdym wpisem" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "Wyświetla tylko podstawowe nazwy plików źródłowych" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "Wyświetla bezwzględne nazwy plików używając katalogu kompilacji" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "Wyświetla także nazwy funkcji" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "Wyświetla także nazwy symboli lub sekcji" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "Wyświetla także nazwy symboli i sekcji" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "Wyświetla także flagi tabeli wierszy" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" +"Wyświetla wszystkie położenia źródłowe, które spowodowały wstawione " +"rozszerzenie podprogramów pod tym adresem." + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "" +"Wyświetla symbole z usuniętym dekorowaniem (PARAMETR jest zawsze ignorowany)" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "Wyświetla wszystkie informacje w jednym wierszy i wyrównuje wstawki" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "Różne:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "" +"Odnajdywanie plików źródłowych i informacji o wierszu dla ADRESU (domyślne " +"w a.out)." + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "[ADRES…]" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "Składnia sekcji wymaga dokładnie jednego modułu" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "offset %# leży poza sekcją „%s”" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "nie można odnaleźć symbolu „%s”" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "offset %# leży poza zawartością „%s”" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "Polecenia:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "Usuwa pliki z archiwum." + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "Przenosi pliki w archiwum." + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "Wyświetla pliki w archiwum." + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "Szybko dodaje pliki do archiwum." + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "Zastępuje istniejący lub umieszcza nowy plik w archiwum." + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "Wyświetla zawartość archiwum." + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "Wypakowuje pliki z archiwum." + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "Modyfikatory poleceń:" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "Zachowuje pierwotne daty." + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "Używa wystąpienia [LICZNIK] nazwy." + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "Nie zastępuje istniejących plików wypakowanymi plikami." + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "Zezwala na skrócenie nazwy pliku, jeśli jest to wymagane." + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "Wyświetla więcej informacji." + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "Wymusza ponowne utworzenie tabeli symboli." + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "Umieszcza plik po [ELEMENCIE]." + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "Umieszcza plik przed [ELEMENTEM]." + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "To samo, co -b." + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "Zmniejsza komunikat, jeśli biblioteka musi zostać utworzona." + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "Używa pełnej ścieżki do dopasowywania plików." + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "Aktualizuje tylko starsze pliki w archiwum." + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "Tworzenie, modyfikowanie i wypakowywanie archiwów." + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[ELEMENT] [LICZNIK] ARCHIWUM [PLIK…]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "„a”, „b” i „i” są dozwolone tylko z opcjami „m” i „r”" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "parametr ELEMENT jest wymagany dla modyfikatorów „a”, „b” i „i”" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "„N” ma znaczenie tylko z opcjami „x” i „d”" + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "wymagany jest parametr LICZNIK" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "nieprawidłowy parametr LICZNIK %s" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "„%c” ma znaczenie tylko z opcją „x”" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "wymagana jest nazwa archiwum" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "wymagana jest opcja polecenia" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "Podano więcej niż jedno działanie" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "nie można otworzyć archiwum „%s”" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "nie można otworzyć archiwum „%s”: %s" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: nie jest plikiem archiwum" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "nie można wykonać stat na archiwum „%s”" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "brak wpisu %s w archiwum\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "nie można utworzyć tabeli mieszającej" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "nie można umieścić w tabeli mieszającej" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "nie można wykonać stat na „%s”" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "nie można odczytać zawartości %s: %s" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "nie można otworzyć %.*s" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "zapisanie %s się nie powiodło" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "nie można zmienić trybu %s" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "nie można zmienić czasu modyfikacji %s" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "nie można zmienić nazwy pliku tymczasowego na %.*s" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "nie można utworzyć nowego pliku" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "nie odnaleziono położenia elementu %s" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: brak wpisu %s w archiwum.\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "nie można otworzyć %s" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "nie można wykonać stat na %s" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "%s nie jest zwykłym plikiem" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "nie można uzyskać deskryptora ELF dla %s: %s\n" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "nie można odczytać %s: %s" + +#: src/ar.c:1483 +#, c-format +msgid "cannot represent ar_date" +msgstr "nie można przedstawić ar_date" + +#: src/ar.c:1489 +#, c-format +msgid "cannot represent ar_uid" +msgstr "nie można przedstawić ar_uid" + +#: src/ar.c:1495 +#, c-format +msgid "cannot represent ar_gid" +msgstr "nie można przedstawić ar_gid" + +#: src/ar.c:1501 +#, c-format +msgid "cannot represent ar_mode" +msgstr "nie można przedstawić ar_mode" + +#: src/ar.c:1507 +#, c-format +msgid "cannot represent ar_size" +msgstr "nie można przedstawić ar_size" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "Używa zero jako UID, GID i datę w elementach archiwum." + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "Używa prawdziwe UID, GID i datę w elementach archiwum." + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "%s (domyślnie)" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "archiwum „%s” jest za duże" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "nie można odczytać nagłówka ELF %s(%s): %s" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "otwieranie" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "odczytywanie" + +#: src/elfclassify.c:245 +msgid "ELF header" +msgstr "nagłówek ELF" + +#: src/elfclassify.c:256 +msgid "program headers" +msgstr "nagłówki programu" + +#: src/elfclassify.c:265 +msgid "program header" +msgstr "nagłówek programu" + +#: src/elfclassify.c:285 +msgid "section headers" +msgstr "nagłówki sekcji" + +#: src/elfclassify.c:296 +msgid "section header string table index" +msgstr "sekcja nagłówek ciąg tabela indeks" + +#: src/elfclassify.c:310 +msgid "could not obtain section header" +msgstr "nie można uzyskać nagłówka sekcji" + +#: src/elfclassify.c:316 +msgid "could not obtain section name" +msgstr "nie można uzyskać nazwy sekcji" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "zapisywanie do standardowego wyjścia" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "odczytywanie ze standardowego wejścia" + +#: src/elfclassify.c:877 +msgid "Classification options" +msgstr "Opcje klasyfikacji" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "" +"Plik wygląda jak obiekt ELF lub archiwum/biblioteka statyczna (domyślnie)" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "" +"Plik jest zwykłym obiektem ELF (nie jest archiwum/biblioteką statyczną)" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "Plik jest archiwum lub biblioteką statyczną ELF" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "Plik jest plikiem zrzutu core ELF" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" +"Plik jest plikiem ELF z tabelą symboli lub sekcjami .debug_* i może być " +"dalej okrojony" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "Plik jest (głównie) wykonywalnym programem ELF (nie jest głównie DSO)" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "Plik jest wykonywalnym programem ELF (może być także DSO)" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" +"Plik jest (głównie) obiektem współdzielonym ELF (DSO) (nie jest głównie " +"plikiem wykonywalnym)" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "" +"Plik jest obiektem współdzielonym ELF (DSO) (może być także plikiem " +"wykonywalnym)" + +#: src/elfclassify.c:907 +msgid "File is a linux kernel module" +msgstr "Plik jest modułem jądra Linux" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" +"Plik jest wyłącznie plikiem debugowania ELF (oddzielne .debug, .dwo lub " +"wieloplikowe dwz)" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "" +"Plik jest wczytywalnym obiektem ELF (programem lub obiektem współdzielonym)" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "Flagi wejścia" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "" +"Klasyfikuje tylko zwykłe (niebędące dowiązaniami symbolicznymi lub " +"urządzeniami specjalnymi) pliki" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" +"Odczytuje także nazwy plików do przetworzenia ze standardowego wejścia, " +"rozdzielone znakami nowego wiersza" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" +"Odczytuje także nazwy plików do przetworzenia ze standardowego wejścia, " +"rozdzielone bajtami NUL ASCII" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "Bez odczytywania plików ze standardowego wejścia (domyślnie)" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "Próbuje otwierać skompresowane pliki lub osadzone obrazy ELF (jądra)" + +#: src/elfclassify.c:956 +msgid "Output flags" +msgstr "Flagi wyjścia" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "Wyświetla nazwy plików, rozdzielone znakami nowego wiersza" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "Wyświetla nazwy plików, rozdzielone znakami NUL ASCII" + +#: src/elfclassify.c:962 +msgid "Do not output file names" +msgstr "Bez wyświetlania nazw plików" + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "Podczas wyświetlana nazw plików wyświetla pasujące pliki (domyślnie)" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "Podczas wyświetlania nazw plików wyświetla niepasujące pliki" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "Dodatkowe flagi" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "Wyświetla dodatkowe informacje (można podać wiele razy)" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "Zmniejsza wyjście błędów (odpowiednik opcji --verbose)" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "PLIK…" + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" +"Ustala typ pliku ELF.\n" +"\n" +"Wszystkie opcje klasyfikacji muszą być zastosowane w tym samym czasie do " +"konkretnego pliku. Opcje klasyfikacji mogą zostać zaprzeczone za pomocą " +"przedrostka „--not-”.\n" +"\n" +"Ponieważ nowoczesny format ELF nie rozróżnia jasno między programami " +"a dynamicznymi obiektami współdzielonymi, należy zwykle użyć --executable " +"lub --shared do identyfikacji głównego zastosowania pliku. Jeden plik może " +"pasować tylko do jednego z testów --shared lub --executable.\n" +"\n" +"Aby poznać, czy obiekt ELF może być programem lub biblioteką współdzieloną " +"(ale może być obydwoma), należy użyć opcji --program lub --library. Niektóre " +"pliki ELF będą klasyfikowane jako program oraz biblioteka jednocześnie.\n" +"\n" +"Aby poznać tylko, czy plik ELF jest wczytywalny (jako program lub " +"biblioteka), należy użyć opcji --loadable. Proszę zauważyć, że pliki " +"zawierające tylko (oddzielne) informacje debugowania (--debug-only) nigdy " +"nie są --loadable (nawet jeśli mogą zawierać nagłówki programu). Moduły " +"jądra Linux także nie są --loadable (w zwyczajowym sensie).\n" +"\n" +"Bez podania żadnej z opcji --print program kończy działanie ze stanem 0, " +"jeśli żądane testy zgadzają się dla wszystkich plików wejściowych, ze stanem " +"1, jeśli test się nie powiedzie dla któregoś z plików, a ze stanem 2, jeśli " +"jest problem środowiskowy (taki jak błąd odczytu pliku lub błąd przydziału " +"pamięci).\n" +"\n" +"Podczas wyświetlania nazw plików program kończy działanie ze stanem 0, nawet " +"jeśli żadne nazwy plików nie zostały wyświetlone, a ze stanem 2, jeśli jest " +"problem środowiskowy.\n" +"\n" +"Przy błędnym użyciu (np. podaniu błędnej opcji) program kończy działanie " +"z kodem stanu wyższym niż 2.\n" +"\n" +"Opcje --quiet i -q zmniejszają wyjście błędów i ostrzeżeń, ale nie zmieniają " +"stanów zakończenia." + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "Opcje sterujące:" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "Wyświetlanie wszystkich różnic, nie tylko pierwszej" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" +"Sterowanie traktowaniem luk w segmentach wczytywalnych [ignore|match] " +"(domyślne: ignore)" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "Ignorowanie permutacji kubełków w sekcji SHT_HASH" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "Ignorowanie różnic w identyfikatorze kopii" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "Bez wypisywania; przekazanie tylko kodu wyjścia" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "Porównywanie odpowiednich części dwóch plików ELF pod kątem równości." + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "PLIK1 PLIK2" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "Nieprawidłowa liczba parametrów.\n" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "nie można uzyskać nagłówka ELF „%s”: %s" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "%s %s różnią się: nagłówek ELF" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, c-format +msgid "cannot get section count of '%s': %s" +msgstr "nie można uzyskać licznika sekcji „%s”: %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "%s %s różnią się: licznik sekcji" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "nie można uzyskać licznika nagłówka programu „%s”: %s" + +#: src/elfcmp.c:233 +#, c-format +msgid "%s %s diff: program header count" +msgstr "%s %s różnią się: licznik nagłówka programu" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "nie można uzyskać hdrstrndx „%s”: %s" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "%s %s różnią się: indeks ciągu shdr" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "%s %s różnią się: nazwa sekcji [%zu], [%zu]" + +#: src/elfcmp.c:330 +#, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "%s %s różnią się: nagłówek sekcji [%zu] „%s”" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "nie można uzyskać zawartości sekcji %zu w „%s”: %s" + +#: src/elfcmp.c:353 +#, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "tabela symboli [%zu] w „%s” ma zerowe sh_entsize" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "nie można uzyskać symbolu w „%s”: %s" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "%s %s różnią się: tabela symboli [%zu]" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "%s %s różnią się: tabela symboli [%zu,%zu]" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "%s %s różnią się: liczba notatek sekcji [%zu] „%s”" + +#: src/elfcmp.c:451 +#, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "nie można odczytać notatki sekcji [%zu] „%s” w „%s”: %s" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "%s %s różnią się: nazwa notatki sekcji [%zu] „%s”" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "%s %s różnią się: sekcja [%zu] „%s” notatka „%s” typ" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "%s %s różnią się: długość identyfikatora kopii" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "%s %s różnią się: zawartość identyfikatora kopii" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "%s %s różnią się: sekcja [%zu] „%s” notatka „%s” zawartość" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "%s %s różnią się: zawartość sekcji [%zu] „%s”" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "%s %s różnią się: zawartość sekcji [%zu,%zu] „%s”" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "%s %s różnią się: różna liczba ważnych sekcji" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "nie można wczytać danych z „%s”: %s" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "nie można uzyskać wpisu nagłówka programu %d z „%s”: %s" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "%s %s różnią się: nagłówek programu %d" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "%s %s różnią się: luka" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "Nieprawidłowa wartość „%s” dla parametru --gaps." + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "nie można otworzyć „%s”" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "nie można utworzyć deskryptora ELF dla „%s”: %s" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "nie można utworzyć deskryptora EBL dla „%s”" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "nie można uzyskać nagłówka sekcji dla sekcji %zu: %s" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "nie można uzyskać zawartości sekcji %zu: %s" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "nie można uzyskać relokacji: %s" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "Opcję -o podano dwukrotnie" + +#: src/elfcompress.c:124 +#, c-format +msgid "-t option specified twice" +msgstr "Opcję -t podano dwukrotnie" + +#: src/elfcompress.c:133 +#, c-format +msgid "unknown compression type '%s'" +msgstr "nieznany typ kompresji „%s”" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, c-format +msgid "No input file given" +msgstr "Nie podano pliku wejściowego" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "Tylko jeden plik wejściowy jest dozwolony z „-o”" + +#: src/elfcompress.c:1307 +msgid "Place (de)compressed output into FILE" +msgstr "Umieszcza zdekompresowane wyjście w PLIKU" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" +"Typ stosowanej kompresji. TYP może wynosić „none” (dekompresja), " +"„zlib” (kompresja zlib ELF, domyślna, „zlib-gabi” to alias) lub „zlib-" +"gnu” (kompresja .zdebug w stylu GNU, „gnu” to alias)" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" +"Nazwa SEKCJI do (de)kompresowania, SEKCJA jest rozszerzonym wzorem " +"(domyślnie „.?(z)debug*”)" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "Wyświetla komunikat dla każdej (de)kompresowanej sekcji" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" +"Wymusza kompresję sekcji, nawet jeśli spowodowałoby to jej zwiększenie lub " +"zaktualizowanie/przepisanie pliku, nawet jeśli żadna sekcja nie zostałaby " +"(zde)kompresowana" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "Łagodzi kilka reguł, aby obsłużyć lekko uszkodzone pliki ELF" + +#: src/elfcompress.c:1325 +msgid "Be silent when a section cannot be compressed" +msgstr "Bez zgłaszania, kiedy nie można zdekompresować sekcji" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "Kompresuje lub dekompresuje sekcje w pliku ELF." + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "Bardzo ścisłe sprawdzanie, cechy poziomu 2 flag." + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "Nie wypisywanie niczego w przypadku powodzenia" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "Plik binarny jest oddzielnym plikiem debuginfo" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" +"Plik binarny został utworzony przez program GNU ld, przez co jest uszkodzony " +"w pewien sposób" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "" +"Szczegółowe sprawdzanie zgodności plików ELF ze specyfikacją gABI/psABI." + +#: src/elflint.c:154 src/readelf.c:368 +#, c-format +msgid "cannot open input file '%s'" +msgstr "nie można otworzyć pliku wejściowego „%s”" + +#: src/elflint.c:161 +#, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "nie można utworzyć deskryptora ELF dla „%s”: %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "błąd podczas zamykania deskryptora ELF: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "Brak błędów" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "Brak nazwy pliku.\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr " błąd podczas zwalniania deskryptora pod-ELF: %s\n" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "To nie jest plik ELF — ma błędne bajty magiczne na początku\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "e_ident[%d] == %d nie jest znaną klasą\n" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "e_ident[%d] == %d nie jest znanym kodowaniem danych\n" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "nieznany numer wersji nagłówka ELF e_ident[%d] == %d\n" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "nieobsługiwane ABI systemu operacyjnego e_ident[%d] == „%s”\n" + +#: src/elflint.c:380 +#, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "nieobsługiwana wersja ABI e_ident[%d] == %d\n" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] nie wynosi zero\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "nieznany typ pliku obiektu %d\n" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "nieznany typ komputera %d\n" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "nieznana wersja pliku obiektu\n" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "nieprawidłowy offset nagłówka programu\n" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "" +"pliki wykonywalne i DSO nie mogą mieć zerowego offsetu nagłówka programu\n" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "nieprawidłowa liczba wpisów nagłówka programu\n" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "nieprawidłowy offset tabeli nagłówków sekcji\n" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "tabela nagłówków sekcji musi istnieć\n" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "nieprawidłowa liczba wpisów tabeli nagłówków sekcji\n" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "nieprawidłowy indeks nagłówka sekcji\n" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "Można sprawdzić tylko nagłówki %u, shnum wynosiło %u\n" + +#: src/elflint.c:487 +#, c-format +msgid "invalid number of program header table entries\n" +msgstr "nieprawidłowa liczba wpisów tabeli nagłówka programu\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "Można sprawdzić tylko nagłówki %u, phnum wynosiło %u\n" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "nieprawidłowe flagi komputera: %s\n" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "nieprawidłowy rozmiar nagłówka ELF: %hd\n" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "nieprawidłowa rozmiar nagłówka programu: %hd\n" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "nieprawidłowe położenie lub rozmiar nagłówka programu\n" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "nieprawidłowy rozmiar nagłówka sekcji: %hd\n" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "nieprawidłowe położenie lub rozmiar nagłówka sekcji\n" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" +"sekcja [%2d] „%s”: sekcja z flagą SHF_GROUP nie jest częścią grupy sekcji\n" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" +"sekcja [%2d] „%s”: grupa sekcji [%2zu] „%s” nie poprzedza elementu grupy\n" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać danych sekcji\n" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" +"sekcja [%2d] „%s”: użyta jako tabela ciągów dla sekcji [%2d] „%s”, ale nie " +"jest typu SHT_STRTAB\n" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" +"sekcja [%2d] „%s”: tabela symboli nie może mieć więcej niż jednej " +"rozszerzonej sekcji indeksów\n" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "sekcja [%2u] „%s”: rozmiar wpisu nie zgadza się z ElfXX_Sym\n" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" +"sekcja [%2u] „%s”: liczba lokalnych wpisów w „st_info” jest większa niż " +"rozmiar tabeli\n" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać symbolu %d: %s\n" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "sekcja [%2d] „%s”: „%s” w zerowym wpisie nie jest zerem\n" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "sekcja [%2d] „%s”: XINDEX dla zerowego wpisu nie jest zerem\n" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać symbolu %zu: %s\n" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "sekcja [%2d] „%s”: symbol %zu: nieprawidłowa wartość nazwy\n" + +#: src/elflint.c:728 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): za duży indeks sekcji, ale nie ma sekcji " +"rozszerzonych indeksów sekcji\n" + +#: src/elflint.c:734 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): XINDEX użyty dla indeksu, który " +"zmieściłby się w st_shndx (%)\n" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "sekcja [%2d] „%s”: symbol %zu (%s): nieprawidłowy indeks sekcji\n" + +#: src/elflint.c:754 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "sekcja [%2d] „%s”: symbol %zu (%s): nieznany typ\n" + +#: src/elflint.c:760 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "sekcja [%2d] „%s”: symbol %zu (%s): nieznane dowiązanie symbolu\n" + +#: src/elflint.c:765 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): unikalny symbol nie jest typem obiektu\n" + +#: src/elflint.c:773 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): COMMON jest dozwolone tylko w plikach " +"relokowalnych\n" + +#: src/elflint.c:777 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): lokalne symbole COMMON to nonsens\n" + +#: src/elflint.c:781 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): funkcja w sekcji COMMON to nonsens\n" + +#: src/elflint.c:832 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "sekcja [%2d] „%s”: symbol %zu (%s): st_value spoza zakresu\n" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s) nie mieści się w całości we wskazywanej " +"sekcji [%2d] „%s”\n" + +#: src/elflint.c:847 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): wskazywana sekcja [%2d] „%s” nie ma " +"ustawionej flagi SHF_TLS\n" + +#: src/elflint.c:857 src/elflint.c:905 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): st_value spoza zakresu wskazywanej " +"sekcji [%2d] „%s”\n" + +#: src/elflint.c:884 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): symbol TLS, ale brak wpisu TLS nagłówka " +"programu\n" + +#: src/elflint.c:890 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): symbol TLS, ale nie można uzyskać wpisu " +"TLS nagłówka programu\n" + +#: src/elflint.c:898 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): st_value pomija wskazywaną sekcję [%2d] " +"„%s”\n" + +#: src/elflint.c:925 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): lokalny symbol spoza zakresu określonego " +"w sh_info\n" + +#: src/elflint.c:932 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): nielokalny symbol spoza zakresu " +"określonego w sh_info\n" + +#: src/elflint.c:939 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "sekcja [%2d] „%s”: symbol %zu (%s): nielokalny symbol sekcji\n" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" +"sekcja [%2d] „%s”: symbol _GLOBAL_OFFSET_TABLE_ odnosi się do błędnej sekcji " +"[%2d]\n" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" +"sekcja [%2d] „%s”: symbol _GLOBAL_OFFSET_TABLE_ odnosi się do sekcji [%2d] " +"„%s”\n" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" +"sekcja [%2d] „%s”: wartość symbolu _GLOBAL_OFFSET_TABLE_ %# nie " +"pasuje do adresu sekcji %s %#\n" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" +"sekcja [%2d] „%s”: rozmiar symbolu _GLOBAL_OFFSET_TABLE_ % nie " +"pasuje do rozmiaru sekcji %s %\n" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" +"sekcja [%2d] „%s”: symbol _GLOBAL_OFFSET_TABLE_ istnieje, ale brak sekcji ." +"got\n" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" +"sekcja [%2d] „%s”: wartość symbolu _DYNAMIC_ %# nie pasuje do adresu " +"segmentu dynamicznego %#\n" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" +"sekcja [%2d] „%s”: rozmiar symbolu _DYNAMIC_ % nie pasuje do " +"rozmiaru segmentu dynamicznego %\n" + +#: src/elflint.c:1063 +#, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): symbol w dynamicznej tabeli symboli " +"z niedomyślną widocznością\n" + +#: src/elflint.c:1067 +#, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %zu (%s): ustawiono nieznany bit w st_other\n" + +#: src/elflint.c:1105 +#, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać danych sekcji.\n" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "sekcja [%2d] „%s”: DT_RELCOUNT użyte dla tej sekcji RELA\n" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "sekcja [%2d] „%s”: DT_RELCOUNT %d za duże dla tej sekcji\n" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" +"sekcja [%2d] „%s”: relokacje względne po indeksie %d podanym przez " +"DT_RELCOUNT\n" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" +"sekcja [%2d] „%s”: relokacja bezwzględna pod indeksem %zu; DT_RELCOUNT podał " +"%d relokacji względnych\n" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "sekcja [%2d] „%s”: DT_RELACOUNT użyte dla tej sekcji REL\n" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "sekcja [%2d] „%s”: nieprawidłowy indeks sekcji docelowej\n" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "sekcja [%2d] „%s”: nieprawidłowy typ sekcji docelowej\n" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "sekcja [%2d] „%s”: sh_info musi wynosić zero\n" + +#: src/elflint.c:1286 +#, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" +"sekcja [%2d] „%s”: relokacje dla sekcji złączalnych ciągów są niemożliwe\n" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "sekcja [%2d] „%s”: rozmiar wpisu sekcji nie zgadza się z ElfXX_Rela\n" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "" +"flaga relokacji tekstu jest ustawiona, ale nie ma segmentu tylko do odczytu\n" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "sekcja [%2d] „%s”: relokacja %zu: nieprawidłowy typ\n" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" +"sekcja [%2d] „%s”: relokacja %zu: typ relokacji nieprawidłowy dla tego typu " +"pliku\n" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "sekcja [%2d] „%s”: relokacja %zu: nieprawidłowy indeks symbolu\n" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" +"sekcja [%2d] „%s”: relokacja %zu: z %s można użyć tylko symbolu " +"„_GLOBAL_OFFSET_TABLE_”\n" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "sekcja [%2d] „%s”: relokacja %zu: offset spoza zakresu\n" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" +"sekcja [%2d] „%s”: relokacja %zu: relokacja kopii względem symbolu typu %s\n" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" +"sekcja [%2d] „%s”: relokacja %zu: sekcja tylko do odczytu została " +"zmodyfikowana, ale nie ustawiono flagi relokacji tekstu\n" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "" +"sekcja [%2d] „%s”: relokacje względem wczytanych i niewczytanych danych\n" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać relokacji %zu: %s\n" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "obecna jest więcej niż jedna sekcja dynamiczna\n" + +#: src/elflint.c:1668 +#, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" +"sekcja [%2d]: wskazane jako tabela ciągów dla sekcji [%2d] „%s”, ale wartość " +"dowiązania sekcji jest nieprawidłowa\n" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "sekcja [%2d] „%s”: rozmiar wpisu sekcji nie zgadza się z ElfXX_Dyn\n" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "sekcja [%2d] „%s”: sh_info nie wynosi zero\n" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "" +"sekcja [%2d] „%s”: nie można uzyskać wpisu %zu sekcji dynamicznej: %s\n" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "sekcja [%2d] „%s”: wpisy nie-DT_NULL występują po wpisie DT_NULL\n" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "sekcja [%2d] „%s”: wpis %zu: nieznany znacznik\n" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "sekcja [%2d] „%s”: wpis %zu: więcej niż jeden wpis ze znacznikiem %s\n" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "sekcja [%2d] „%s”: wpis %zu: użyto znacznika %s poziomu 2\n" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %zu: wartość DT_PLTREL musi wynosić DT_REL lub " +"DT_RELA\n" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %zu: wskaźnik nie pasuje do adresu sekcji [%2d] „%s” " +"wskazywanej przez sh_link\n" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %zu: wartość %s musi wskazywać na wczytany segment\n" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %zu: wartość %s musi być prawidłowym offsetem " +"w sekcji [%2d] „%s”\n" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "sekcja [%2d] „%s”: zawiera wpis %s, ale nie %s\n" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "sekcja [%2d] „%s”: brak obowiązkowego znacznika %s\n" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "sekcja [%2d] „%s”: brak sekcji skrótów\n" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "sekcja [%2d] „%s”: nie wszystkie z %s, %s i %s są obecne\n" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "" +"sekcja [%2d] „%s”: brak znacznika %s w DSO oznaczonym podczas wstępnej " +"konsolidacji\n" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "" +"sekcja [%2d] „%s”: plik nie-DSO oznaczony jako zależność podczas wstępnej " +"konsolidacji\n" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "" +"sekcja [%2d] „%s”: brak znacznika %s we wstępnie konsolidowanym pliku " +"wykonywalnym\n" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" +"sekcja [%2d] „%s”: tylko pliki relokowalne mogą mieć rozszerzoną sekcję " +"indeksów\n" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" +"sekcja [%2d] „%s”: sekcja rozszerzonych indeksów sekcji nie dla tabeli " +"symboli\n" + +#: src/elflint.c:1948 +#, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "" +"sekcja [%2d] „%s”: rozszerzony indeks sekcji sh_link [%2d] jest " +"nieprawidłowy\n" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "nie można uzyskać danych dla sekcji symboli\n" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "sekcja [%2d] „%s”: rozmiar wpisu nie zgadza się z Elf32_Word\n" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "" +"sekcja [%2d] „%s”: tabela rozszerzonych indeksów jest za mała dla tabeli " +"symboli\n" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" +"sekcja [%2d] „%s”: rozszerzony indeks sekcji w sekcji [%2zu] „%s” odwołuje " +"się do tej samej tabeli symboli\n" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "symbol 0 musi mieć zerowy rozszerzony indeks sekcji\n" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "nie można uzyskać danych dla symbolu %zu\n" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "" +"rozszerzony indeks sekcji wynosi %, ale indeks symbolu nie wynosi " +"XINDEX\n" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" +"sekcja [%2d] „%s”: sekcja tabeli mieszającej jest za mała (%ld, oczekiwano " +"%ld)\n" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "sekcja [%2d] „%s”: tabela łańcuchowa jest za duża\n" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "" +"sekcja [%2d] „%s”: odwołanie do kubełka skrótu %zu jest spoza zakresu\n" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "" +"sekcja [%2d] „%s”: odwołanie do łańcucha skrótu %zu jest spoza zakresu\n" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "" +"sekcja [%2d] „%s”: odwołanie do łańcucha skrótu % jest spoza " +"zakresu\n" + +#: src/elflint.c:2140 +#, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "sekcja [%2d] „%s”: brak wystarczającej ilości danych\n" + +#: src/elflint.c:2152 +#, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "" +"sekcja [%2d] „%s”: rozmiar maski bitowej wynosi zero lub nie jest potęgą 2: " +"%u\n" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" +"sekcja [%2d] „%s”: sekcja tabeli mieszającej jest za mała (wynosi %ld, " +"oczekiwano co najmniej %ld)\n" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "" +"sekcja [%2d] „%s”: drugie przesunięcie funkcji mieszającej jest za duże: %u\n" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" +"sekcja [%2d] „%s”: łańcuch mieszający dla kubełka %zu jest mniejszy niż " +"przesunięcie indeksu symboli\n" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %u wskazywany w łańcuchu dla kubełka %zu jest " +"nieokreślony\n" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"sekcja [%2d] „%s”: wartość skrótu dla symbolu %u w łańcuchu dla kubełka %zu " +"jest błędna\n" + +#: src/elflint.c:2254 +#, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"sekcja [%2d] „%s”: indeks maski dla symbolu %u w łańcuchu dla kubełka %zu " +"jest błędny\n" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "sekcja [%2d] „%s”: łańcuch skrótu dla kubełka %zu jest spoza zakresu\n" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" +"sekcja [%2d] „%s”: odwołanie do symbolu w łańcuchu dla kubełka %zu jest " +"spoza zakresu\n" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "" +"sekcja [%2d] „%s”: maska bitowa nie pasuje do nazw w tabeli mieszającej\n" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "" +"sekcja [%2d] „%s”: pliki relokowalne nie mogą mieć tabeli mieszających\n" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "" +"sekcja [%2d] „%s”: tabela mieszająca nie dla tabeli dynamicznych symboli\n" + +#: src/elflint.c:2330 +#, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "" +"sekcja [%2d] „%s”: nieprawidłowy indeks sekcji tabeli symboli sh_link [%2d]\n" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "sekcja [%2d] „%s”: niepoprawny rozmiar wpisu tabeli mieszającej\n" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "sekcja [%2d] „%s”: nieoznaczona do przydzielenia\n" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" +"sekcja [%2d] „%s”: tabela mieszająca nie ma miejsca nawet na początkowe " +"wpisy administracyjne\n" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "" +"sh_link w sekcjach skrótu [%2zu] „%s” i [%2zu] „%s” nie są identyczne\n" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "" +"sekcja mieszania [%2zu] „%s” nie zawiera wystarczającej ilości danych\n" + +#: src/elflint.c:2444 +#, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "sekcja mieszania [%2zu] „%s” ma zerowe słowa maski bitów\n" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "sekcja mieszania [%2zu] „%s” używa za dużo danych\n" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" +"sekcja mieszająca [%2zu] „%s” nieprawidłowy indeks symboli % " +"(max_nsyms: %, nentries: %\n" + +#: src/elflint.c:2557 +#, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "sekcja mieszania [%2zu] „%s” nieprawidłowe sh_entsize\n" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "sekcja [%2zu] „%s”: odwołanie do symbolu o indeksie 0\n" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" +"symbol %d wymieniony w nowej tabeli mieszającej w [%2zu] „%s”, ale nie " +"w poprzedniej tabeli mieszającej [%2zu] „%s”\n" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" +"symbol %d wymieniony w poprzedniej tabeli mieszającej w [%2zu] „%s”, ale nie " +"w nowej tabeli mieszającej w [%2zu] „%s”\n" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "sekcja [%2d] „%s”: niezerowe sh_%s dla sekcji NULL\n" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" +"sekcja [%2d] „%s”: w plikach obiektów relokowalnych dozwolone są tylko grupy " +"sekcji\n" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać tabeli symboli: %s\n" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "" +"sekcja [%2d] „%s”: odwołanie do sekcji w sh_link nie ma tabeli symboli\n" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "sekcja [%2d] „%s”: nieprawidłowy indeks symbolu w sh_info\n" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "sekcja [%2d] „%s”: niezerowe sh_flags\n" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać symbolu dla podpisu\n" + +#: src/elflint.c:2664 +#, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać nazwy symbolu dla podpisu\n" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "sekcja [%2d] „%s”: symbol podpisu nie można być pustym ciągiem\n" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "sekcja [%2d] „%s”: sh_flags nie ustawione poprawnie\n" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać danych: %s\n" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "" +"sekcja [%2d] „%s”: rozmiar sekcji nie jest wielokrotnością " +"sizeof(Elf32_Word)\n" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "sekcja [%2d] „%s”: grupa sekcji bez słowa flag\n" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "sekcja [%2d] „%s”: grupa sekcji bez elementów\n" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "sekcja [%2d] „%s”: grupa sekcji z tylko jednym elementem\n" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "sekcja [%2d] „%s”: nieznane flagi grupy sekcji\n" + +#: src/elflint.c:2731 +#, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "sekcja [%2d] „%s”: indeks sekcji %zu jest spoza zakresu\n" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "" +"sekcja [%2d] „%s”: nie można uzyskać nagłówka sekcji dla elementu %zu: %s\n" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "sekcja [%2d] „%s”: grupa sekcji zawiera inną grupę [%2d] „%s”\n" + +#: src/elflint.c:2753 +#, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" +"sekcja [%2d] „%s”: element %zu odwołuje się do sekcji [%2d] „%s” bez flagi " +"SHF_GROUP\n" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "sekcja [%2d] „%s” jest zawarta w więcej niż jednej grupie sekcji\n" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" +"sekcja [%2d] „%s” odwołuje się w sh_link do sekcji [%2d] „%s”, która nie " +"jest tabelą symboli dynamicznych\n" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" +"sekcja [%2d] „%s” ma inną liczbę wpisów niż tabela symboli [%2d] „%s”\n" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "sekcja [%2d] „%s”: symbol %d: nie można odczytać danych wersji\n" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "sekcja [%2d] „%s”: symbol %d: symbol lokalny z zakresem globalnym\n" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "sekcja [%2d] „%s”: symbol %d: symbol lokalny z wersją\n" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "sekcja [%2d] „%s”: symbol %d: nieprawidłowy indeks wersji %d\n" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %d: indeks wersji %d jest dla wersji określonej\n" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" +"sekcja [%2d] „%s”: symbol %d: indeks wersji %d jest dla wersji żądanej\n" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "obecna jest więcej niż jedna sekcja odniesienia wersji\n" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "sekcja [%2d] „%s”: sh_link nie łączy się z tabelą ciągów\n" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "sekcja [%2d] „%s”: wpis %d ma błędną wersję %d\n" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "sekcja [%2d] „%s”: wpis %d ma błędny offset dla danych dodatkowych\n" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "sekcja [%2d] „%s”: symbol %d ma błędne odniesienie do pliku\n" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "sekcja [%2d] „%s”: wpis %d odnosi się do nieznanej zależności\n" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma nieznaną flagę\n" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" +"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma nieprawidłowe " +"odniesienie do nazwy\n" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" +"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma błędną wartość skrótu: " +"%#x, oczekiwano %#x\n" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" +"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma powtórzoną nazwę wersji " +"„%s”\n" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" +"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma błędne następne pole\n" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "sekcja [%2d] „%s”: wpis %d ma błędny offset do następnego wpisu\n" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %d ma zerowy offset do następnego wpisu, ale sh_info " +"zawiera informacje o większej liczbie wpisów\n" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "obecna jest więcej niż jedna sekcja definicji wersji\n" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "sekcja [%2d] „%s”: jest więcej niż jedna definicja BASE\n" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "sekcja [%2d] „%s”: definicja BASE musi mieć indeks VER_NDX_GLOBAL\n" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "sekcja [%2d] „%s”: wpis %d ma nieznaną flagę\n" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "sekcja [%2d] „%s”: wpis %d ma nieprawidłowe odniesienie do nazwy\n" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %d ma błędną wartość skrótu: %#x, oczekiwano %#x\n" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "sekcja [%2d] „%s”: wpis %d ma powtórzoną nazwę wersji „%s”\n" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %d ma nieprawidłowe odniesienie do nazwy w danych " +"dodatkowych\n" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "" +"sekcja [%2d] „%s”: wpis %d ma błędne następne pole w danych dodatkowych\n" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "sekcja [%2d] „%s”: brak definicji BASE\n" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "sekcja [%2d] „%s”: nieznana wersja rodzica „%s”\n" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "sekcja [%2d] „%s”: pusta sekcja atrybutów obiektu\n" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "sekcja [%2d] „%s”: nierozpoznany format atrybutu\n" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: pole o zerowej długości w sekcji atrybutów\n" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: nieprawidłowa długość w sekcji atrybutów\n" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "sekcja [%2d] „%s”: offset %zu: niezakończony ciąg nazwy producenta\n" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: niekończące się ULEB128 w znaczniku podsekcji " +"atrybutów\n" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "sekcja [%2d] „%s”: offset %zu: skrócona sekcja atrybutów\n" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: zerowej długości pole w podsekcji atrybutów\n" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: nieprawidłowa długość w podsekcji atrybutów\n" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: podsekcja atrybutów ma nieoczekiwany znacznik " +"%u\n" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: niekończące się ULEB128 w znaczniku atrybutu\n" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "sekcja [%2d] „%s”: offset %zu: niezakończony ciąg w atrybucie\n" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "sekcja [%2d] „%s”: offset %zu: nierozpoznany znacznik atrybutu %u\n" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: atrybut %s ma nierozpoznaną wartość " +"%\n" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "sekcja [%2d] „%s”: offset %zu: producent „%s” jest nieznany\n" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" +"sekcja [%2d] „%s”: offset %zu: dodatkowe bajty po ostatniej sekcji " +"atrybutów\n" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "nie można uzyskać nagłówka sekcji zerowej\n" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "sekcja zerowa ma niezerową nazwę\n" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "sekcja zerowa ma niezerowy typ\n" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "sekcja zerowa ma niezerowe flagi\n" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "sekcja zerowa ma niezerowy adres\n" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "sekcja zerowa ma niezerowy offset\n" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "sekcja zerowa ma niezerową wartość wyrównania\n" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "sekcja zerowa ma niezerową wartość rozmiaru wpisu\n" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" +"sekcja zerowa ma niezerową wartość rozmiaru, a nagłówek ELF ma niezerową " +"wartość shnum\n" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" +"sekcja zerowa ma niezerową wartość dowiązań, a nagłówek ELF nie wskazuje " +"przepełnienia w shstrndx\n" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" +"sekcja zerowa ma niezerową wartość dowiązań, a nagłówek ELF nie wskazuje " +"przepełnienia w phnum\n" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "nie można uzyskać nagłówka sekcji dla sekcji [%2zu] „%s”: %s\n" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "sekcja [%2zu]: nieprawidłowa nazwa\n" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "sekcja [%2d] „%s” ma błędny typ: oczekiwano %s, jest %s\n" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "sekcja [%2zu] „%s” ma błędne flagi: oczekiwano %s, jest %s\n" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" +"sekcja [%2zu] „%s” ma błędne flagi: oczekiwano %s i być może %s, jest %s\n" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "sekcja [%2zu] „%s” jest obecna w pliku obiektu\n" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" +"sekcja [%2zu] „%s” ma flagę SHF_ALLOC, ale nie ma segmentu wczytywalnego\n" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" +"sekcja [%2zu] „%s” nie ma flagi SHF_ALLOC, ale są segmenty wczytywalne\n" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" +"sekcja [%2zu] „%s” jest tabelą indeksów sekcji rozszerzeń w pliku " +"nieobiektowym\n" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "sekcja [%2zu] „%s”: rozmiar nie jest wielokrotnością rozmiaru wpisu\n" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "nie można uzyskać nagłówka sekcji\n" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "sekcja [%2zu] „%s” ma nieobsługiwany typ %d\n" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" +"sekcja [%2zu] „%s” zawiera nieprawidłowe flagi dla konkretnego procesora " +"%#\n" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "sekcja [%2zu] „%s” zawiera nieznane flagi %#\n" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "" +"sekcja [%2zu] „%s”: adres sekcji danych lokalnych dla wątków nie jest zerem\n" + +#: src/elflint.c:3974 +#, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "sekcja [%2zu] „%s”: nie można skompresować przydzielonej sekcji\n" + +#: src/elflint.c:3979 +#, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "sekcja [%2zu] „%s”: nie można skompresować sekcji „nobits”\n" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "sekcja [%2zu] „%s”: skompresowana sekcja bez nagłówka kompresji: %s\n" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "" +"sekcja [%2zu] „%s”: nieprawidłowe odwołanie do sekcji w wartości dowiązania\n" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "" +"sekcja [%2zu] „%s”: nieprawidłowe odwołanie do sekcji w wartości " +"informacyjnej\n" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "sekcja [%2zu] „%s”: flaga ciągów jest ustawiona bez flagi merge\n" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "" +"sekcja [%2zu] „%s”: flaga merge jest ustawiona, ale rozmiar wpisu jest " +"zerowy\n" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "sekcja [%2zu] „%s” ma nieoczekiwany typ %d dla sekcji wykonywalnej\n" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "sekcja [%2zu] „%s” musi być typu NOBITS w plikach debuginfo\n" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "sekcja [%2zu] „%s” jest wykonywalne i zapisywalne\n" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" +"sekcja [%2zu] „%s” nie jest w całości zawarta w segmencie wpisu %d nagłówka " +"programu\n" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" +"sekcja [%2zu] „%s” ma typ NOBITS, a jest odczytywana z pliku w segmencie " +"wpisu %d nagłówka programu\n" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" +"sekcja [%2zu] „%s” ma typ NOBITS, ale jest odczytywana z pliku w segmencie " +"wpisu %d nagłówka programu, a zawartość pliku jest niezerowa\n" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" +"sekcja [%2zu] „%s” nie ma typu NOBITS, a nie jest odczytywana z pliku " +"w segmencie wpisu %d nagłówka programu\n" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "sekcja [%2zu] „%s” jest wykonywalne w segmencie niewykonywalnym %d\n" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "sekcja [%2zu] „%s” jest zapisywalne w niezapisywalnym segmencie %d\n" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" +"sekcja [%2zu] „%s”: ma flagę alloc, ale sekcja nie jest w żadnym segmencie " +"wczytywalnym\n" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" +"sekcja [%2zu] „%s”: według nagłówka ELF to jest tabela ciągów nagłówków " +"sekcji, ale typ nie jest SHT_TYPE\n" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" +"sekcja [%2zu] „%s”: pliki relokowalne nie mogą mieć tabeli symboli " +"dynamicznych\n" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "obecna jest więcej niż jedna tabela symboli wersji\n" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "jest wpis nagłówka programu INTERP, ale nie ma sekcji .interp\n" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" +"wczytywalny segment [%u] jest wykonywalny, ale nie zawiera wykonywalnych " +"sekcji\n" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "" +"wczytywalny segment [%u] jest zapisywalny, ale nie zawiera zapisywalnych " +"sekcji\n" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" +"brak sekcji .gnu.versym, ale istnieje sekcja .gnu.versym_d lub .gnu." +"versym_r\n" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "powtórzony indeks wersji %d\n" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr "sekcja .gnu.versym istnieje bez .gnu.versym_d lub .gnu.versym_r\n" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "" +"phdr[%d]: nieznany typ notatki pliku core % pod offsetem %\n" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" +"sekcja [%2d]: „%s”: nieznany typ notatki pliku core % pod offsetem " +"%zu\n" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" +"phdr[%d]: nieznany typ notatki pliku obiektu % o nazwie właściciela " +"„%s” pod offsetem %zu\n" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" +"sekcja [%2d] „%s”: nieznany typ notatki pliku obiektu % o nazwie " +"właściciela „%s” pod offsetem %zu\n" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "phdr[%d]: brak określonych wpisów notatek dla typu pliku\n" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "phdr[%d]: nie można uzyskać zawartości sekcji notatki: %s\n" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "phdr[%d]: dodatkowe % B po ostatniej notatce\n" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "sekcja [%2d] „%s”: brak określonych wpisów notatek dla typu pliku\n" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "sekcja [%2d] „%s”: nie można uzyskać zawartości sekcji notatek\n" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "sekcja [%2d] „%s”: dodatkowe % B po ostatniej notatce\n" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" +"tylko pliki wykonywalne, obiekty współdzielone i pliki core mogą mieć " +"nagłówki programu\n" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "nie można uzyskać wpisu nagłówka programu %d: %s\n" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" +"wpis nagłówka programu %d: nieznany typ wpisu nagłówka programu %#\n" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "więcej niż jeden wpis INTERP w nagłówku programu\n" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "więcej niż jeden wpis TLS w nagłówku programu\n" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "statyczny plik wykonywalny nie może mieć sekcji dynamicznych\n" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "odniesienie sekcji dynamicznej w nagłówku programu ma błędny offset\n" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "różne rozmiary sekcji dynamicznej w nagłówku programu i sekcji\n" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "więcej niż jeden wpis GNU_RELRO w nagłówku programu\n" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "wczytywalny segment wskazywany przez GNU_RELRO nie jest zapisywalny\n" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "flagi wczytywalnego segmentu [%u] nie pasują do flag GNU_RELRO [%u]\n" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" +"flagi GNU_RELRO [%u] nie są podzbiorem flag wczytywalnego segmentu [%u]\n" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "segment %s nie zawiera się we wczytywalnym segmencie\n" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "" +"offsety nagłówka programu w nagłówku ELF i wpisie PHDR nie zgadzają się" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "" +"odniesienie tabeli wyszukiwania ramki wywołania w nagłówku programu ma " +"błędny offset\n" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "" +"różne rozmiary tabel wyszukiwania ramki wywołania w nagłówku programu " +"i sekcji\n" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "PT_GNU_EH_FRAME jest obecne, ale brak sekcji .eh_frame_hdr\n" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "tabela wyszukiwania ramki wywołania musi być przydzielona\n" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "sekcja [%2zu] „%s”: musi być przydzielona\n" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "tabela wyszukiwania ramki wywołania nie może być zapisywalna\n" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "sekcja [%2zu] „%s” nie może być zapisywalna\n" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "tabela wyszukiwania ramki wywołania nie może być wykonywalna\n" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "sekcja [%2zu] „%s” nie może być wykonywalna\n" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "wpis nagłówka programu %d: rozmiar pliku większy niż rozmiar pamięci\n" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "wpis nagłówka programu %d: wyrównanie nie jest potęgą 2\n" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" +"wpis nagłówka programu %d: offset w pliku i adres wirtualny nie są " +"wielokrotnością wyrównania\n" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" +"plik wykonywalny/DSO z sekcją .eh_frame_hdr nie ma wpisu nagłówka programu " +"PT_GNU_EH_FRAME" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "nie można odczytać nagłówka ELF: %s\n" + +#: src/elflint.c:4797 +#, c-format +msgid "cannot create backend for ELF file\n" +msgstr "nie można utworzyć zaplecza dla pliku ELF\n" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "flaga relokacji tekstu jest ustawiona, ale niepotrzebna\n" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "Wybór wejścia:" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "Dołącza ŚCIEŻKĘ do wszystkich nazw plików" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "Używa ŚCIEŻKI jako korzenia dla hierarchii debuginfo" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "Odnajduje źródło relokacji tekstu w PLIKACH (domyślnie a.out)." + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "[PLIK…]" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "nie można uzyskać nagłówka ELF „%s”: %s" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "„%s” nie jest DSO ani PIE" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "uzyskiwanie nagłówka sekcji dla sekcji %zu: %s" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "nie można odczytać sekcji dynamicznej: %s" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "brak relokacji tekstu w „%s”" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "podczas odczytywania pliku ELF" + +#: src/findtextrel.c:314 +#, c-format +msgid "cannot get program header count: %s" +msgstr "nie można uzyskać liczby nagłówków programu: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "nie można uzyskać indeksu nagłówka programu pod offsetem %zd: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "nie można uzyskać sekcji tabeli symboli %zu w „%s”: %s" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "nie można uzyskać relokacji pod indeksem %d w sekcji %zu w „%s”: %s" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "%s nie został skompilowany z -fpic/-fPIC\n" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "plik zawierający funkcję „%s” nie został skompilowany z -fpic/-fPIC\n" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" +"plik zawierający funkcję „%s” mógł nie zostać skompilowany z -fpic/-fPIC\n" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"plik zawierający funkcję „%s” lub plik zawierający funkcję „%s” nie został " +"skompilowany z -fpic/-fPIC\n" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" +"relokacja modyfikuje pamięć pod offsetem %llu w segmencie zabezpieczonym " +"przed zapisem\n" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "Wybór wyjścia:" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "Wyświetla symbole wyłącznie debugowania" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "Wyświetla tylko określone symbole" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "Wyświetla symbole dynamiczne zamiast zwykłych" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "Wyświetla tylko symbole zewnętrzne" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "Wyświetla tylko nieokreślone symbole" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "Dołącza indeks dla symboli z elementów archiwum" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "Format wyjścia:" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "Wyświetla nazwę pliku wejściowego przed każdym symbolem" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"Używa FORMATU wyjściowego. Może to być „bsd”, „sysv” lub „posix”. Domyślny " +"jest format „sysv”" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "To samo, co --format=bsd" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "To samo co, --format=posix" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "Używa BAZY do wypisywania wartości symboli" + +#: src/nm.c:87 +msgid "Mark special symbols" +msgstr "Oznacza specjalne symbole" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "Wyświetla rozmiar określonych symboli" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "Opcje wyjścia:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "Porządkuje symbole numerycznie według adresu" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "Bez porządkowania symboli" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "Odwraca kierunek porządkowania" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "Dekoduje niskopoziomowe nazwy symboli na nazwy kodu źródłowego" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "Wyświetla listę symboli z PLIKU (domyślnie a.out)." + +#: src/nm.c:116 src/objdump.c:79 +msgid "Output formatting" +msgstr "Formatowanie wyjścia" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: BŁĄD WEWNĘTRZNY %d (%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "podczas zamykania „%s”" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: nie rozpoznano formatu pliku" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"Indeks archiwum:\n" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "nieprawidłowy offset %zu dla symbolu %s" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "%s w %s\n" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "nie można przywrócić offsetu w archiwum na początek" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: nie rozpoznano formatu pliku" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "nie można utworzyć drzewa wyszukiwania" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "nie można uzyskać indeksu tabeli ciągów nagłówków sekcji" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"Symbole z %s:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" +"%*s%-*s %-*s Klasa Typ %-*s %*s Sekcja\n" +"\n" + +#: src/nm.c:776 +#, fuzzy +#| msgid " Name: " +msgctxt "sysv" +msgid "Name" +msgstr " Nazwa: " + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "" + +#: src/nm.c:1250 +#, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "%s: rozmiar wpisu w sekcji %zd „%s” nie jest tym, czego oczekiwano" + +#: src/nm.c:1255 +#, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: rozmiar sekcji %zd „%s” nie jest wielokrotnością rozmiaru wpisu" + +#: src/nm.c:1336 +#, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "%s: wpisy (%zd) w sekcji %zd „%s” są za duże" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: nieprawidłowe działanie" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: brak symboli" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "Wybór trybu:" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "Wyświetla informacje o relokacji." + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "Wyświetla pełną zawartość żądanych sekcji" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "Wyświetla kod asemblera sekcji wykonywalnych" + +#: src/objdump.c:59 +msgid "Output content selection:" +msgstr "Wybór zawartości wyjścia:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "Wyświetla tylko informacje o sekcji NAZWA." + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "Wyświetla informacje z PLIKÓW (domyślnie a.out)." + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "Nie podano działania.\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "podczas zamykania „%s”" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "NIEPRAWIDŁOWY SYMBOL" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "NIEPRAWIDŁOWA SEKCJA" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" +"\n" +"PISY RELOKACJI DLA [%s]:\n" +"%-*s TYP WARTOŚĆ\n" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "OFFSET" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "Zawartość sekcji %s:\n" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "nie można deasemblować" + +#: src/objdump.c:760 +#, c-format +msgid "cannot create backend for elf file" +msgstr "nie można utworzyć zaplecza dla pliku ELF" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "Tworzenie indeksu w celu przyspieszenia dostępu do archiwów." + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "ARCHIWUM" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "Wymagana jest nazwa archiwum" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "„%s” nie jest archiwum" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "błąd podczas zwalniania deskryptora pod-ELF: %s" + +#: src/readelf.c:97 +msgid "ELF input selection:" +msgstr "Wybór wyjścia ELF:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" +"Używa podanej SEKCJI (domyślnie .gnu_debugdata) jako (skompresowanych) " +"danych wejściowych ELF" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" +"Używane z opcją -w do wyszukiwania szkieletów jednostek kompilacji w PLIKU " +"powiązanych z jednostkami podzielonej kompilacji w pliku wejściowym .dwo" + +#: src/readelf.c:104 +msgid "ELF output selection:" +msgstr "Wybór wyjścia ELF:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "Wszystkie te plus -p .strtab -p .dynstr -p .comment" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "Wyświetla segment dynamiczny" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "Wyświetla nagłówek pliku ELF" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "Wyświetla histogram długości list kubełków" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "Wyświetla nagłówki programu" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "Wyświetla relokacje" + +#: src/readelf.c:114 +msgid "Display the section groups" +msgstr "Wyświetla grupy sekcji" + +#: src/readelf.c:115 +msgid "Display the sections' headers" +msgstr "Wyświetla nagłówki sekcji" + +#: src/readelf.c:118 +msgid "Display the symbol table sections" +msgstr "Wyświetla sekcje tabeli symboli" + +#: src/readelf.c:120 +msgid "Display (only) the dynamic symbol table" +msgstr "Wyświetla (tylko) tabelę symboli dynamicznych" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "Wyświetla informacje o wersji" + +#: src/readelf.c:122 +msgid "Display the ELF notes" +msgstr "Wyświetla notatki ELF" + +#: src/readelf.c:124 +msgid "Display architecture specific information, if any" +msgstr "Wyświetla informacje dla konkretnej architektury, jeśli są" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "Wyświetla sekcje do obsługi wyjątków" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "Dodatkowy wybór wyjścia:" + +#: src/readelf.c:130 +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" +"Wyświetla zawartość sekcji DWARF. SEKCJA może być jednym z abbrev, addr, " +"aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, " +"decodedline, ranges, pubnames, str, macinfo, macro lub exception" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "Zrzuca niezinterpretowaną zawartość SEKCJI, według liczny lub nazwy" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "Wyświetla zawartość ciągów sekcji" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "Wyświetla indeks symboli archiwum" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "Kontrola wyjścia:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "Bez odnajdywania nazw symboli dla adresów w danych DWARF" + +#: src/readelf.c:145 +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "" +"Wyświetla tylko offsety zamiast rozwiązywania wartości na adresy w danych " +"DWARF" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "Ignorowane dla zgodności (wiersze są zawsze szerokie)" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" +"Wyświetla informacje o kompresji dla skompresowanych sekcji (kiedy jest " +"używane z opcją -S); dekompresuje sekcję przed zrzuceniem danych (kiedy jest " +"używane z opcją -p lub -x)" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "Wyświetla informacje z pliku ELF w postaci czytelnej dla człowieka." + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "tak" + +#: src/readelf.c:351 +msgid "no" +msgstr "nie" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "Nieznana sekcja debugowania DWARF „%s”.\n" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "nie można utworzyć deskryptora ELF: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "nie można określić liczby sekcji: %s" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "nie można uzyskać sekcji: %s" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "nie można uzyskać nagłówka sekcji: %s" + +#: src/readelf.c:663 +#, c-format +msgid "cannot get section name" +msgstr "nie można uzyskać nazwy sekcji" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "nie można uzyskać zwartości %s: %s" + +#: src/readelf.c:688 +#, c-format +msgid "cannot create temp file '%s'" +msgstr "nie można utworzyć pliku tymczasowego „%s”" + +#: src/readelf.c:697 +#, c-format +msgid "cannot write section data" +msgstr "nie można zapisać danych sekcji" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "błąd podczas zamykania deskryptora ELF: %s" + +#: src/readelf.c:710 +#, c-format +msgid "error while rewinding file descriptor" +msgstr "błąd podczas przewijania deskryptora pliku" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "„%s” nie jest archiwum, nie można wyświetlić indeksu archiwum" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "nie można wykonać stat na pliku wejściowym" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "plik wejściowy jest pusty" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "odczytanie „%s” się nie powiodło: %s" + +#: src/readelf.c:881 +#, c-format +msgid "No such section '%s' in '%s'" +msgstr "Brak sekcji „%s” w „%s”" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "nie można odczytać nagłówka ELF: %s" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "nie można utworzyć uchwytu EBL" + +#: src/readelf.c:961 +#, c-format +msgid "cannot determine number of program headers: %s" +msgstr "nie można określić liczby nagłówków programu: %s" + +#: src/readelf.c:993 +#, c-format +msgid "cannot read ELF: %s" +msgstr "nie można odczytać danych ELF: %s" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "NONE (żaden)" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "REL (plik relokowalny)" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "EXEC (plik wykonywalny)" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "DYN (plik obiektu współdzielonego)" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "CORE (plik core)" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "Zależny od systemu: (%x)\n" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "Zależny od procesora: (%x)\n" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" +"Nagłówek ELF:\n" +" Magic: " + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" +"\n" +" Klasa: %s\n" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr " Dane: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr " Wersja Ident: %hhd %s\n" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(bieżąca)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr " System operacyjny/ABI: %s\n" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr " Wersja ABI: %hhd\n" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " Typ: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr " Komputer: %s\n" + +#: src/readelf.c:1109 +#, c-format +msgid " Machine: : 0x%x\n" +msgstr " Komputer: : 0x%x\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr " Wersja: %d %s\n" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr " Adres punktu wejściowego: %#\n" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr " Początek nagłówków programu: % %s\n" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "(bajtów w pliku)" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr " Początek nagłówków sekcji: % %s\n" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr " Flagi: %s\n" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr " Rozmiar tego nagłówka: % %s\n" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(bajtów)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr " Rozmiar wpisów nagłówka programu: % %s\n" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr " Liczba wpisów nagłówków programu: %" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr " (% w [0].sh_info)" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr " ([0] niedostępny)" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr " Rozmiar wpisów nagłówka sekcji: % %s\n" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr " Liczba wpisów nagłówków sekcji: %" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr " (% w [0].sh_size)" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr " (% w [0].sh_link)" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" +" Indeks tabeli ciągów nagłówków sekcji: XINDEX%s\n" +"\n" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" +" Indeks tabeli ciągów nagłówków sekcji: %\n" +"\n" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, c-format +msgid "cannot get number of sections: %s" +msgstr "nie można uzyskać liczby sekcji: %s" + +#: src/readelf.c:1233 +#, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" +"Liczba nagłówków sekcji: %zd, rozpoczynających się od offsetu %#:\n" +"\n" + +#: src/readelf.c:1242 +#, c-format +msgid "cannot get section header string table index: %s" +msgstr "nie można uzyskać indeksu tabeli ciągów nagłówków sekcji: %s" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "Nagłówki sekcji:" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" +"[Nr] Nazwa Typ Adres Offset Rozm. ES Flagi Lk " +"Inf Al" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" +"[Nr] Nazwa Typ Adres Offset Rozmiar ES " +"Flagi Lk Inf Al" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr " [Kompresja Rozmiar Al]" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr " [Kompresja Rozmiar Al]" + +#: src/readelf.c:1335 +#, c-format +msgid "bad compression header for section %zd: %s" +msgstr "błędny nagłówek kompresji dla sekcji %zd: %s" + +#: src/readelf.c:1346 +#, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "błędny rozmiar kompresji gnu dla sekcji %zd: %s" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "Nagłówki programu:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" +" Typ Offset AdresWirt AdresFiz RozmPlik RozmPam Flg " +"Wyrównanie" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" +" Typ Offset AdresWirtualny AdresFizyczny RozmPlik " +"RozmPam Flg Wyrównanie" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "\t[Wywołanie interpretera programu: %s]\n" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" +"\n" +" Mapowanie sekcji do segmentów:\n" +" Segment sekcji…" + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "nie można uzyskać nagłówka programu: %s" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Grupa sekcji COMDAT [%2zu] „%s” z podpisem „%s” zawiera %zu wpis:\n" +msgstr[1] "" +"\n" +"Grupa sekcji COMDAT [%2zu] „%s” z podpisem „%s” zawiera %zu wpisy:\n" +msgstr[2] "" +"\n" +"Grupa sekcji COMDAT [%2zu] „%s” z podpisem „%s” zawiera %zu wpisów:\n" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Grupa sekcji [%2zu] „%s” z podpisem „%s” zawiera %zu wpis:\n" +msgstr[1] "" +"\n" +"Grupa sekcji [%2zu] „%s” z podpisem „%s” zawiera %zu wpisy:\n" +msgstr[2] "" +"\n" +"Grupa sekcji [%2zu] „%s” z podpisem „%s” zawiera %zu wpisów:\n" + +#: src/readelf.c:1623 +msgid "" +msgstr "" + +#: src/readelf.c:1637 +msgid "" +msgstr "" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "Nie można dekompresować sekcji" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "nie można uzyskać nagłówka sekcji [%zd]: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, c-format +msgid "invalid sh_link value in section %zu" +msgstr "nieprawidłowa wartość sh_link w sekcji %zu" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Segment dynamiczny zawiera %lu wpis:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"'%s'\n" +msgstr[1] "" +"\n" +"Segment dynamiczny zawiera %lu wpisy:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"'%s'\n" +msgstr[2] "" +"\n" +"Segment dynamiczny zawiera %lu wpisów:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"'%s'\n" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr " Typ Wartość\n" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "Biblioteka współdzielona: [%s]\n" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "soname biblioteki: [%s]\n" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "rpath biblioteki: [%s]\n" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "runpath biblioteki: [%s]\n" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "% (bajtów)\n" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" +"\n" +"Nieprawidłowa tabela symboli pod offsetem %#0\n" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +"\n" +"Sekcja relokacji [%2zu] „%s” dla sekcji [%2u] „%s” pod offsetem %#0 " +"zawiera %d wpis:\n" +msgstr[1] "" +"\n" +"Sekcja relokacji [%2zu] „%s” dla sekcji [%2u] „%s” pod offsetem %#0 " +"zawiera %d wpisy:\n" +msgstr[2] "" +"\n" +"Sekcja relokacji [%2zu] „%s” dla sekcji [%2u] „%s” pod offsetem %#0 " +"zawiera %d wpisów:\n" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Sekcja relokacji [%2u] „%s” pod offsetem %#0 zawiera %d wpis:\n" +msgstr[1] "" +"\n" +"Sekcja relokacji [%2u] „%s” pod offsetem %#0 zawiera %d wpisy:\n" +msgstr[2] "" +"\n" +"Sekcja relokacji [%2u] „%s” pod offsetem %#0 zawiera %d wpisów:\n" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr " Offset Typ Wartość Nazwa\n" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr " Offset Typ Wartość Nazwa\n" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr " Offset Typ Wartość Koniec Nazwa\n" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr "" +" Offset Typ Wartość Koniec Nazwa\n" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +"\n" +"Tabela symboli [%2u] „%s” zawiera %u wpis:\n" +msgstr[1] "" +"\n" +"Tabela symboli [%2u] „%s” zawiera %u wpisy:\n" +msgstr[2] "" +"\n" +"Tabela symboli [%2u] „%s” zawiera %u wpisów:\n" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] " %lu symbol lokalny Tabela ciągów: [%2u] „%s”\n" +msgstr[1] " %lu symbole lokalne Tabela ciągów: [%2u] „%s”\n" +msgstr[2] " %lu symboli lokalnych Tabela ciągów: [%2u] „%s”\n" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Numer: Wartość Rozm Typ Bind Widoczność Ndx Nazwa\n" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " Numer: Wartość Rozm Typ Bind Widoczność Ndx Nazwa\n" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "%5u: %0* %6 %-7s %-6s %-9s %6s %s" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "błędny symbol dynamiczny" + +#: src/readelf.c:2680 +msgid "none" +msgstr "brak" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| " + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Sekcja wymaganych wersji [%2u] „%s” zawiera %d wpis:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" +msgstr[1] "" +"\n" +"Sekcja wymaganych wersji [%2u] „%s” zawiera %d wpisy:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" +msgstr[2] "" +"\n" +"Sekcja wymaganych wersji [%2u] „%s” zawiera %d wpisów:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: Wersja: %hu Plik: %s Licznik: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: Nazwa: %s Flagi: %s Wersja: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Sekcja definicji wersji [%2u] „%s” zawiera %d wpis:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" +msgstr[1] "" +"\n" +"Sekcja definicji wersji [%2u] „%s” zawiera %d wpisy:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" +msgstr[2] "" +"\n" +"Sekcja definicji wersji [%2u] „%s” zawiera %d wpisów:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr "" +" %#06x: Wersja: %hd Flagi: %s Indeks: %hd Licznik: %hd Nazwa: %s\n" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr " %#06x: Rodzic %d: %s\n" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +"\n" +"Sekcja symboli wersji [%2u] „%s” zawiera %d wpis:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] „%s”" +msgstr[1] "" +"\n" +"Sekcja symboli wersji [%2u] „%s” zawiera %d wpisy:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] „%s”" +msgstr[2] "" +"\n" +"Sekcja symboli wersji [%2u] „%s” zawiera %d wpisów:\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] „%s”" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *lokalny* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *globalny* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Histogram dla długości listy kubełków w sekcji [%2u] „%s” (w sumie %d " +"kubełek):\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" +msgstr[1] "" +"\n" +"Histogram dla długości listy kubełków w sekcji [%2u] „%s” (w sumie %d " +"kubełki):\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" +msgstr[2] "" +"\n" +"Histogram dla długości listy kubełków w sekcji [%2u] „%s” (w sumie %d " +"kubełków):\n" +" Adres: %#0* Offset: %#08 Dowiązanie do sekcji: [%2u] " +"„%s”\n" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr " Długość Liczba % całości Pokrycie\n" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" +" Średnia liczba testów: udane wyszukania: %f\n" +"\t\t\t nieudane wyszukania: %f\n" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "nie można uzyskać danych dla sekcji %d: %s" + +#: src/readelf.c:3254 +#, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "nieprawidłowe dane w sekcji sysv.hash %d" + +#: src/readelf.c:3283 +#, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "nieprawidłowy łańcuch w sekcji sysv.hash %d" + +#: src/readelf.c:3318 +#, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "nieprawidłowe dane w sekcji sysv.hash64 %d" + +#: src/readelf.c:3349 +#, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "nieprawidłowy łańcuch w sekcji sysv.hash64 %d" + +#: src/readelf.c:3385 +#, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "nieprawidłowe dane w sekcji gnu.hash %d" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" +" Przesunięcie symboli: %u\n" +" Rozmiar maski bitowej: %zu B %%% b ustawionych drugie " +"przesunięcie skrótu: %u\n" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Sekcja listy bibliotek [%2zu] „%s” pod offsetem %#0 zawiera %d " +"wpis:\n" +msgstr[1] "" +"\n" +"Sekcja listy bibliotek [%2zu] „%s” pod offsetem %#0 zawiera %d " +"wpisy:\n" +msgstr[2] "" +"\n" +"Sekcja listy bibliotek [%2zu] „%s” pod offsetem %#0 zawiera %d " +"wpisów:\n" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" +" Biblioteka Czas Suma k. Wersja " +"Flagi" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" +"\n" +"Sekcja atrybutów obiektu [%2zu] „%s” % B pod offsetem %#0:\n" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr " Właściciel Rozmiar\n" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " Plik: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %, %s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, c-format +msgid "sprintf failure" +msgstr "sprintf się nie powiodło" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "pusty blok" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "blok o %zu B:" + +#: src/readelf.c:4800 +#, c-format +msgid "%*s[%2] %s \n" +msgstr "%*s[%2] %s \n" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "%s %# zostało użyte z różnymi rozmiarami adresu" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "%s %# zostało użyte z różnymi rozmiarami offsetu" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "%s %# zostało użyte z różnymi adresami podstawowymi" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "%s %# zostało użyte z różnymi atrybutami %s i %s" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr " [%6tx] … % B…\n" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %#:\n" +" [ Kod]\n" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" +"\n" +"Sekcja skrótów pod offsetem %:\n" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr " *** błąd podczas odczytywania skrótu: %s\n" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr " [%5u] offset: %, potomek: %s, znacznik: %s\n" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %#:\n" + +#: src/readelf.c:5182 +#, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "nie można uzyskać danych sekcji .debug_addr: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, c-format +msgid " Length: %8\n" +msgstr " Długość: %8\n" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, c-format +msgid " DWARF version: %8\n" +msgstr " Wersja DWARF: %8\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, c-format +msgid " Address size: %8\n" +msgstr " Rozmiar adresu: %8\n" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, c-format +msgid " Segment size: %8\n" +msgstr " Rozmiar segmentu: %8\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, c-format +msgid "Unknown version" +msgstr "Nieznana wersja" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, c-format +msgid "unsupported address size" +msgstr "nieobsługiwany rozmiar adresu" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "nieobsługiwany rozmiar segmentu" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "nie można uzyskać zawartości .debug_aranges: %s" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %# zawiera %zu wpis:\n" +msgstr[1] "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %# zawiera %zu wpisy:\n" +msgstr[2] "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %# zawiera %zu wpisów:\n" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" +" [%*zu] początek: %0#*, długość: %5, offset CU DIE: " +"%6\n" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" +"\n" +"Tabela pod offsetem %zu:\n" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "nieprawidłowe dane w sekcji [%zu] „%s”" + +#: src/readelf.c:5511 +#, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr "" +"\n" +" Długość: %6\n" + +#: src/readelf.c:5523 +#, c-format +msgid " DWARF version: %6\n" +msgstr " Wersja DWARF: %6\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "nieobsługiwana wersja aranges" + +#: src/readelf.c:5538 +#, c-format +msgid " CU offset: %6\n" +msgstr " Offset CU: %6\n" + +#: src/readelf.c:5544 +#, c-format +msgid " Address size: %6\n" +msgstr " Offset adresu: %6\n" + +#: src/readelf.c:5555 +#, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr "" +" Rozmiar segmentu: %6\n" +"\n" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr " %zu B wypełnienia\n" + +#: src/readelf.c:5654 +#, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "nie można uzyskać zawartości .debug_rnglists: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr "" +"Tabela pod offsetem 0x%:\n" +"\n" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, c-format +msgid " Offset entries: %8\n" +msgstr " Wpisy offsetu: %8\n" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr " Nieznana podstawa CU: " + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr " Podstawa CU [%6]: " + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr " Brak powiązania z CU.\n" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "za dużo wpisów offsetu dla długości jednostki" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " Offsety zaczynające się w 0x%:\n" + +#: src/readelf.c:5823 +#, c-format +msgid "invalid range list data" +msgstr "nieprawidłowe dane listy zakresów" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" +" %zu B wypełnienia\n" +"\n" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "nie można uzyskać zawartości .debug_ranges: %s" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" +"\n" +" Nieznana podstawa CU: " + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" +"\n" +" Podstawa CU [%6]: " + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] \n" + +#: src/readelf.c:6097 src/readelf.c:9719 +msgid "base address" +msgstr "adres podstawowy" + +#: src/readelf.c:6107 src/readelf.c:9729 +#, c-format +msgid " [%6tx] empty list\n" +msgstr " [%6tx] pusta lista\n" + +#: src/readelf.c:6367 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:6624 +#, c-format +msgid "cannot get ELF: %s" +msgstr "nie można uzyskać ELF: %s" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Sekcja informacji o ramce wywołania [%2zu] „%s” pod offsetem %#:\n" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" +"\n" +" [%6tx] Zerowy koniec\n" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, c-format +msgid "invalid augmentation length" +msgstr "nieprawidłowa długość powiększenia" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "Kodowanie adresu FDE: " + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "Kodowanie wskaźnika LSDA: " + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr " (offset: %#)" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr " (kończący offset: %#)" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr " %-26sWskaźnik LSDA: %#\n" + +#: src/readelf.c:7053 +#, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "DIE [%] nie można uzyskać kodu atrybutu: %s" + +#: src/readelf.c:7063 +#, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "DIE [%] nie można uzyskać formy atrybutu: %s" + +#: src/readelf.c:7085 +#, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "DIE [%] nie można uzyskać wartości atrybutu „%s” (%s): %s" + +#: src/readelf.c:7415 +#, c-format +msgid "invalid file (%): %s" +msgstr "nieprawidłowy plik (%): %s" + +#: src/readelf.c:7419 +#, c-format +msgid "no srcfiles for CU [%]" +msgstr "brak plików źródłowych dla CU [%]" + +#: src/readelf.c:7423 +#, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "nie można uzyskać CU DWARF: %s" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %#:\n" +" [Offset]\n" + +#: src/readelf.c:7788 +#, c-format +msgid "cannot get next unit: %s" +msgstr "nie można uzyskać następnej jednostki: %s" + +#: src/readelf.c:7808 +#, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" +" Jednostka typu pod offsetem %:\n" +" Wersja: %, offset sekcji skrótów: %, rozmiar adresu: " +"%, rozmiar offsetu: %\n" +" Podpis typu: %#, offset typu: %# [%]\n" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Jednostka kompilacji pod offsetem %:\n" +" Wersja: %, offset sekcji skrótów: %, rozmiar adresu: " +"%, rozmiar offsetu: %\n" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr " Typ jednostki: %s (%)" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "nieznana wersja (%d) lub typ jednostki (%d)" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "nie można uzyskać offsetu DIE: %s" + +#: src/readelf.c:7895 +#, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "" +"nie można uzyskać znacznika DIE pod offsetem [%] w sekcji „%s”: %s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "nie można uzyskać następnego DIE: %s\n" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "nie można uzyskać następnego DIE: %s" + +#: src/readelf.c:7985 +#, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Jednostka podzielonej kompilacji pod offsetem %:\n" +" Wersja: %, offset sekcji skrótów: %, rozmiar adresu: " +"%, rozmiar offsetu: %\n" + +#: src/readelf.c:8037 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %#:\n" +"\n" + +#: src/readelf.c:8369 +#, c-format +msgid "unknown form: %s" +msgstr "nieznana forma: %s" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "nie można uzyskać danych sekcji danych wiersza: %s" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" +"\n" +" Długość: %\n" +" Wersja DWARF: %\n" +" Długość prologu: %\n" +" Rozmiar adresu: %zd\n" +" Rozmiar selektora segmentu: %zd\n" +" Minimalna długość instrukcji: %\n" +" Maks. liczba działań na instrukcję: %\n" +" Wartość początkowa, jeśli „is_stmt”: %\n" +" Podstawa wiersza: %\n" +" Zakres wiersza: %\n" +" Podstawa instrukcji: %\n" +"\n" +"Instrukcje:\n" + +#: src/readelf.c:8524 +#, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "nie można obsłużyć wersji .debug_line: %u\n" + +#: src/readelf.c:8532 +#, c-format +msgid "cannot handle address size: %u\n" +msgstr "nie można obsłużyć rozmiaru adresu: %u\n" + +#: src/readelf.c:8540 +#, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "nie można obsłużyć rozmiaru selektora segmentu: %u\n" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "nieprawidłowe dane pod offsetem %tu w sekcji [%zu] „%s”" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] " [%*] %hhu parametr\n" +msgstr[1] " [%*] %hhu parametry\n" +msgstr[2] " [%*] %hhu parametrów\n" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" +"\n" +"Tabela katalogu:" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, c-format +msgid " [" +msgstr " [" + +#: src/readelf.c:8653 +msgid "" +"\n" +"File name table:" +msgstr "" +"\n" +"Tabela nazw plików:" + +#: src/readelf.c:8714 +msgid " Entry Dir Time Size Name" +msgstr " Wpis Kat Czas Rozmiar Nazwa" + +#: src/readelf.c:8753 +msgid "" +"\n" +"No line number statements." +msgstr "" +"\n" +"Brak instrukcji numerów wierszy." + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" +"\n" +"Instrukcje numerów wierszy:" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "nieprawidłowe maksimum operacji na instrukcję wynosi zero" + +#: src/readelf.c:8811 +#, c-format +msgid " special opcode %u: address+%u = " +msgstr " instrukcja specjalna %u: adres+%u = " + +#: src/readelf.c:8815 +#, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr ", op_index = %u, wiersz%+d = %zu\n" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr ", wiersz%+d = %zu\n" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr " instrukcja rozszerzona %u: " + +#: src/readelf.c:8841 +msgid " end of sequence" +msgstr " koniec sekwencji" + +#: src/readelf.c:8859 +#, c-format +msgid " set address to " +msgstr " ustawienie adresu na " + +#: src/readelf.c:8887 +#, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr "" +" definicja nowego pliku: dir=%u, mtime=%, długość=%, nazwa=" +"%s\n" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr " ustawienie dyskryminatora na %u\n" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +msgid " unknown opcode" +msgstr " nieznana instrukcja" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr " kopiowanie" + +#: src/readelf.c:8929 +#, c-format +msgid " advance address by %u to " +msgstr " zwiększenie adresu o %u do " + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr ", op_index do %u" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr " zwiększenie wiersza o stałą %d do %\n" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr " ustawienie pliku na %\n" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr " ustawienie kolumny na %\n" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr " ustawienie „%s” na %\n" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr " ustawienie podstawowej flagi bloku" + +#: src/readelf.c:8990 +#, c-format +msgid " advance address by constant %u to " +msgstr " zwiększenie adresu o stałą %u do " + +#: src/readelf.c:9010 +#, c-format +msgid " advance address by fixed value %u to \n" +msgstr " zwiększenie adresu o stałą wartość %u do \n" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr " ustawienie flagi końca prologu" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr " ustawienie flagi początku epilogu" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr " ustawienie isa na %u\n" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] " nieznana instrukcja z % parametrem:" +msgstr[1] " nieznana instrukcja z % parametrami:" +msgstr[2] " nieznana instrukcja z % parametrami:" + +#: src/readelf.c:9084 +#, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "nie można uzyskać zawartości .debug_loclists: %s" + +#: src/readelf.c:9250 +#, c-format +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9290 +#, c-format +msgid "invalid loclists data" +msgstr "nieprawidłowe dane loclists" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "nie można uzyskać zawartości .debug_log: %s" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr " \n" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "nie można uzyskać danych sekcji informacji o makrach: %s" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "%*s*** niezakończony ciąg na końcu sekcji" + +#: src/readelf.c:9914 +#, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "%*s*** brak parametru DW_MACINFO_start_file na końcu sekcji" + +#: src/readelf.c:10015 +#, c-format +msgid " Offset: 0x%\n" +msgstr " Offset: 0x%\n" + +#: src/readelf.c:10027 +#, c-format +msgid " Version: %\n" +msgstr " Wersja: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr " nieznana wersja, nie można przetworzyć sekcji\n" + +#: src/readelf.c:10040 +#, c-format +msgid " Flag: 0x%" +msgstr " Flaga: 0x%" + +#: src/readelf.c:10069 +#, c-format +msgid " Offset length: %\n" +msgstr " Długość offsetu: %\n" + +#: src/readelf.c:10077 +#, c-format +msgid " .debug_line offset: 0x%\n" +msgstr " Offset .debug_line: 0x%\n" + +#: src/readelf.c:10102 +#, c-format +msgid " extension opcode table, % items:\n" +msgstr " tabela instrukcji rozszerzenia, % elementów:\n" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr " [%]" + +#: src/readelf.c:10121 +#, c-format +msgid " % arguments:" +msgstr " Parametry %:" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr " brak parametrów." + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr " [%5d] offset DIE: %6, offset CU DIE: %6, nazwa: %s\n" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" +"\n" +"Sekcja DWARF [%2zu] „%s” pod offsetem %#:\n" +" %*s Ciąg\n" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "" + +#: src/readelf.c:10396 +#, c-format +msgid " *** error, missing string terminator\n" +msgstr " *** błąd, brak znaku kończącego ciąg\n" + +#: src/readelf.c:10425 +#, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "nie można uzyskać danych sekcji .debug_str_offsets: %s" + +#: src/readelf.c:10524 +#, c-format +msgid " Length: %8\n" +msgstr " Długość: %8\n" + +#: src/readelf.c:10526 +#, c-format +msgid " Offset size: %8\n" +msgstr " Rozmiar offsetu: %8\n" + +#: src/readelf.c:10540 +#, c-format +msgid " DWARF version: %8\n" +msgstr " Wersja DWARF: %8\n" + +#: src/readelf.c:10549 +#, c-format +msgid " Padding: %8\n" +msgstr " Wypełnienie: %8\n" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" +"\n" +"Sekcja tabeli wyszukiwania ramki wywołania [%2zu] „.eh_frame_hdr”:\n" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" +"\n" +"Sekcja tabeli obsługiwania wyjątków [%2zu] „.gcc_except_table”:\n" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr " Kodowanie LPStart: %#x " + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr " Kodowanie TType: %#x " + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr " Kodowanie strony wywołania: %#x " + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" +"\n" +" Tabela strony wywołania:" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" +" [%4u] Początek strony wywołania: %#\n" +" Długość strony wywołania: %\n" +" Lądowisko: %#\n" +" Działanie: %u\n" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "nieprawidłowe kodowanie TType" + +#: src/readelf.c:10882 +#, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" +"\n" +"Sekcja GDB [%2zu] „%s” pod offsetem %# zawiera % B:\n" + +#: src/readelf.c:10911 +#, c-format +msgid " Version: %\n" +msgstr " Wersja: %\n" + +#: src/readelf.c:10929 +#, c-format +msgid " CU offset: %#\n" +msgstr " offset CU: %#\n" + +#: src/readelf.c:10936 +#, c-format +msgid " TU offset: %#\n" +msgstr " offset TU: %#\n" + +#: src/readelf.c:10943 +#, c-format +msgid " address offset: %#\n" +msgstr " offset adresu: %#\n" + +#: src/readelf.c:10950 +#, c-format +msgid " symbol offset: %#\n" +msgstr " offset symbolu: %#\n" + +#: src/readelf.c:10957 +#, c-format +msgid " constant offset: %#\n" +msgstr " offset stałej: %#\n" + +#: src/readelf.c:10971 +#, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Lista CU pod offsetem %# zawiera %zu wpisów:\n" + +#: src/readelf.c:10996 +#, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Lista TU pod offsetem %# zawiera %zu wpisów:\n" + +#: src/readelf.c:11025 +#, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Lista adresów pod offsetem %# zawiera %zu wpisów:\n" + +#: src/readelf.c:11057 +#, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" +"\n" +" Tabela symboli pod offsetem %# zawiera %zu gniazd:\n" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "nie można uzyskać deskryptora kontekstu debugowania: %s" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "nie można konwertować danych notatki core: %s" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" +"\n" +"%*s… …" + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr " Właściciel Rozmiar danych Typ\n" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr " %-13.*s %9 %s\n" + +#: src/readelf.c:12518 +#, c-format +msgid "cannot get content of note: %s" +msgstr "nie można uzyskać zawartości notatki: %s" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Segment notatki [%2zu] „%s” o długości % B pod offsetem " +"%#0:\n" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Segment notatki o długości % B pod offsetem %#0:\n" + +#: src/readelf.c:12622 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" +"\n" +"Sekcja [%zu] „%s” nie ma danych do zrzucenia.\n" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "nie można uzyskać danych dla sekcji [%zu] „%s”: %s" + +#: src/readelf.c:12654 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" +"\n" +"Segment zrzutu szesnastkowego [%zu] „%s”, % B pod offsetem " +"%#0:\n" + +#: src/readelf.c:12659 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" +"\n" +"Zrzut szesnastkowy sekcji [%zu] „%s”, % B (%zd nieskompresowanych) " +"pod offsetem %#0:\n" + +#: src/readelf.c:12673 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" +"\n" +"Sekcja [%zu] „%s” nie ma ciągów do zrzucenia.\n" + +#: src/readelf.c:12705 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" +"\n" +"Sekcja ciągów [%zu] „%s” zawiera % B pod offsetem %#0:\n" + +#: src/readelf.c:12710 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" +"\n" +"Sekcja ciągów [%zu] „%s” zawiera % B (%zd nieskompresowanych) pod " +"offsetem %#0:\n" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" +"\n" +"sekcja [%lu] nie istnieje" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" +"\n" +"sekcja „%s” nie istnieje" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "nie można uzyskać indeksu symboli archiwum „%s”: %s" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" +"\n" +"Archiwum „%s” nie ma indeksu symboli\n" + +#: src/readelf.c:12853 +#, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" +"\n" +"Indeks archiwum „%s” ma %zu wpisów:\n" + +#: src/readelf.c:12871 +#, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "nie można wydobyć elementów pod offsetem %zu w „%s”: %s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "Element archiwum „%s” zawiera:\n" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" +"Używa FORMATU wyjścia. Może to być „bsd” lub „sysv”. Domyślny jest „bsd”" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "To samo, co „--format=sysv”" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "To samo, co „--format=bsd”" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "To samo, co „--radix=10”" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "To samo, co „--radix=8”" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "To samo, co „--radix=16”" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "Podobne do wyjścia „--format=sysv”, ale w jednym wierszu" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "Wyświetla rozmiar i flagi uprawnień dla segmentów wczytywalnych" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "Wyświetla całkowite rozmiary (tylko bsd)" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "Wyświetla listę rozmiarów sekcji PLIKU (domyślnie a.out)." + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "Nieprawidłowy format: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "Nieprawidłowa baza: %s" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "%s: nie rozpoznano formatu pliku" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr " (ex %s)" + +#: src/size.c:420 +#, fuzzy +#| msgid "invalid section" +msgctxt "sysv" +msgid "section" +msgstr "nieprawidłowa sekcja" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "" + +#: src/size.c:482 +#, c-format +msgid "cannot get section header" +msgstr "nie można uzyskać nagłówka sekcji" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "(CAŁKOWITE)\n" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "-p PID musi być dodatnim identyfikatorem procesu." + +#: src/stack.c:493 +#, c-format +msgid "Cannot open core file '%s'" +msgstr "Nie można otworzyć pliku core „%s”" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "-n MAKSYMALNA-LICZBA-RAMEK musi wynosić 0 lub więcej." + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "-e PLIK-WYKONYWALNY wymaga pliku core podanego za pomocą opcji --core." + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "-1 wymaga identyfikatora wątku podanego za pomocą opcji -p." + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "Tylko jedna z opcji -p PID lub --core PLIK-CORE może zostać podana." + +#: src/stack.c:645 +msgid "Show stack of process PID" +msgstr "Wyświetla stos numeru PID procesu" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "Wyświetla stos odnaleziony w PLIKU-CORE" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "(opcjonalnie) PLIK-WYKONYWALNY, który utworzył PLIK-CORE" + +#: src/stack.c:652 +msgid "Output selection options:" +msgstr "Opcje wyboru wyjścia:" + +#: src/stack.c:654 +msgid "Additionally show frame activation" +msgstr "Dodatkowo wyświetla aktywację ramki" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "Dodatkowo próbuje wyszukać nazwy debuginfo DWARF dla adresu ramki" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" +"Dodatkowo wyświetla wstawione ramki używając debuginfo DWARF, jeśli jest " +"dostępne (zakłada opcję -d)" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "Dodatkowo wyświetla informacje o pliku modułu" + +#: src/stack.c:663 +msgid "Additionally show source file information" +msgstr "Dodatkowo wyświetla informacje o pliku źródłowym" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" +"Wyświetla wszystkie dodatkowe informacje (aktywację, nazwę debugowania, " +"wstawki, moduł i źródło)" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "Nie rozwiązuje nazw symboli adresów do funkcji" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "" +"Wyświetla surowe nazwy symboli funkcji, nie próbuje usuwać dekoracji z nazw" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "Wyświetla identyfikator kopii modułu, wczytuje adres i offset pc" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "Wyświetla ślad stosu, jeśli jest tylko jeden wątek" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "" +"Wyświetla najwyżej MAKSYMALNĄ-LICZBĘ-KLATEK na wątek (domyślnie 256, 0 " +"oznacza brak ograniczenia)" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "" +"Wyświetla mapę pamięci modułu z identyfikatorem kopii, wykryte pliki elf " +"i debug" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" +"Wyświetla stos dla każdego wątku w procesie lub pliku core.\n" +"\n" +"Program kończy działanie z kodem zwrotnym 0, jeśli wszystkie ramki zostały " +"wyświetlone bez żadnych błędów. Jeśli niektóre ramki zostały wyświetlone, " +"ale wystąpiły niekrytyczne błędy, które mogą spowodować niepełny ślad stosu, " +"to program kończy działanie z kodem zwrotnym 1. Jeśli żadne ramki nie mogły " +"zostać wyświetlone lub wystąpił krytyczny błąd, to program kończy działanie " +"z kodem zwrotnym 2. Jeśli program został wywołany za pomocą błędnych lub " +"brakujących parametrów, to zakończy on działanie z kodem zwrotnym 64." + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "Nie można wyświetlić żadnych ramek." + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "Wybór wyjścia:" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "Przeszukuje cały plik, nie tylko wczytane sekcje" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" +"Wyświetlane są tylko zakończone NUL sekwencje o MIN-LEN lub większej liczbie " +"znaków" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" +"Wybór rozmiaru i kolejności znaków: s = 7 bitów, S = 8 bitów, {b,l} = 16 " +"bitów, {B,L} = 32 bity" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "Wyświetla nazwę pliku przed każdym ciągiem." + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "Wyświetla położenie ciągu z podstawą odpowiednio 8, 10 lub 16." + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "Alias dla --radix=o" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "Wyświetla ciągi znaków drukowalnych w plikach." + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "nieprawidłowa wartość „%s” dla parametru %s" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "nieprawidłowa minimalna długość dopasowanego rozmiaru ciągu" + +#: src/strings.c:585 +#, c-format +msgid "lseek failed" +msgstr "lseek się nie powiodło" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "ponowne mmap się nie powiodło" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "mprotect się nie powiodło" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "Pomijanie sekcji %zd „%s” dane poza plikiem" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "Umieszcza okrojone wyjście w PLIKU" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "Wydobywa usunięte sekcje do PLIKU" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "Osadza nazwę PLIKU zamiast parametru -f" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "Usuwa wszystkie symbole debugowania" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "Usuwa nagłówki sekcji (niezalecane)" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "Kopiuje czasy modyfikacji/dostępu do wyjścia" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" +"Rozwiązuje wszystkie proste relokacje między sekcjami debugowania, jeśli " +"usunięte sekcje zostały umieszczone w pliku debugowania (ma znaczenie tylko " +"dla plików ET_REL, działanie jest nieodwracalne, wymaga użycia opcji -f)" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" +"Podobne do opcji --reloc-debug-sections, ale rozwiązuje wszystkie proste " +"relokacje między sekcjami debugowania na miejscu. Żadne inne okrajanie nie " +"jest wykonywane (działania nie jest odwracalne, nie jest zgodne z opcjami -" +"f, -g, --remove-comment i --remove-section)" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "Usuwa sekcję .comment" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" +"Usuwa podaną sekcję. SEKCJA jest rozszerzonym wzorem. Może być podane więcej " +"niż raz. Można usuwać tylko nieprzydzielone sekcje." + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" +"Zachowuje podaną sekcję. SEKCJA jest rozszerzonym wzorem. Może być podane " +"więcej niż raz." + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "Odrzuca symbole z plików obiektów." + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "Użyto --reloc-debug-sections bez opcji -f" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" +"Opcja --reloc-debug-sections-only jest niezgodna z -f, -g, --remove-comment " +"i --remove-section" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "Tylko jeden plik wejściowy jest dozwolony z „-o” i „-f”" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "Opcję -f podano dwukrotnie" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "Opcję -F podano dwukrotnie" + +#: src/strip.c:362 +#, c-format +msgid "cannot both keep and remove .comment section" +msgstr "nie można jednocześnie zachować i usunąć sekcji .comment" + +#: src/strip.c:481 +#, c-format +msgid "bad relocation" +msgstr "błędna relokacja" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "nie można wykonać stat na pliku wejściowym „%s”" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "podczas otwierania „%s”" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "%s: nie można używać -o lub -f podczas okrajania archiwum" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: brak obsługi okrajania archiwum" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "nie można otworzyć zaplecza EBL" + +#: src/strip.c:1092 +#, c-format +msgid "cannot get number of phdrs" +msgstr "nie można uzyskać liczby phdr" + +#: src/strip.c:1106 src/strip.c:1149 +#, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "nie można utworzyć nowego ehdr dla pliku „%s”: %s" + +#: src/strip.c:1116 src/strip.c:1159 +#, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "nie można utworzyć nowego phdr dla pliku „%s”: %s" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "plik „%s” ma błędny format" + +#: src/strip.c:1250 +#, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "Nie można usunąć przydzielonej sekcji „%s”" + +#: src/strip.c:1259 +#, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "Nie można jednocześnie zachować i usunąć sekcji „%s”" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "podczas tworzenia pliku wyjściowego: %s" + +#: src/strip.c:1688 +#, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "%s: błąd podczas aktualizowania nagłówka ELF: %s" + +#: src/strip.c:1697 +#, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "%s: błąd podczas uzyskiwania shdrstrndx: %s" + +#: src/strip.c:1705 src/strip.c:2550 +#, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "%s: błąd podczas aktualizowania shdrstrndx: %s" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "podczas przygotowywania wyjścia dla „%s”" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "podczas tworzenia sekcji nagłówka sekcji: %s" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "nie można przydzielić danych sekcji: %s" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "podczas tworzenia tabeli ciągów nagłówka sekcji: %s" + +#: src/strip.c:1866 +#, c-format +msgid "no memory to create section header string table" +msgstr "brak pamięci do utworzenia tabeli ciągów nagłówka sekcji" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "Nie można usunąć symbolu [%zd] z przydzielonej tabeli symboli [%zd]" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "podczas zapisywania „%s”: %s" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "podczas tworzenia „%s”" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "podczas obliczania sumy kontrolnej dla informacji debugowania" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "%s: błąd podczas tworzenia nagłówka ELF: %s" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "%s: błąd podczas odczytywania pliku: %s" + +#: src/strip.c:2599 src/strip.c:2619 +#, c-format +msgid "while writing '%s'" +msgstr "podczas zapisywania „%s”" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "błąd podczas kończenia „%s”: %s" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "nie można ustawić czasu dostępu i modyfikacji „%s”" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "Dopasowuje MODUŁY do nazw plików, a nie nazwy modułów" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "Pomija nieodnalezione pliki bez zgłaszania tego" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "Umieszcza wyjście w PLIKU" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "Tworzy wiele plików wyjściowych w KATALOGU" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "Używa nazw modułów zamiast nazw plików" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "" +"Tworzy wyjście dla modułów niemających oddzielnych informacji debugowania" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "Zastosowuje relokacje do zawartości sekcji w plikach ET_REL" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "Wyświetla tylko nazwy modułów i plików, identyfikatory kopii" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "" +"Wymusza łączenie plików, nawet jeśli niektóre nagłówki ELF się nie zgadzają" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "opcję -d podano dwukrotnie" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "dozwolona jest tylko jedna z opcji -o lub -d" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "opcja -n nie może być używana z jawnymi plikami albo z opcją -o lub -d" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "katalog wyjściowy „%s”" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "wymagane są dokładnie dwa parametry plików" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "opcje -m, -a, -R oraz -i nie są dozwolone z jawnymi plikami" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "opcja -o lub -d jest wymagana podczas używania ukrytych plików" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "nie można utworzyć nagłówka ELF: %s" + +#: src/unstrip.c:240 +#, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "nie można uzyskać shdrstrndx: %s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "nie można uzyskać nagłówka ELF: %s" + +#: src/unstrip.c:254 +#, c-format +msgid "cannot get new zero section: %s" +msgstr "nie można uzyskać nowej sekcji zerowej: %s" + +#: src/unstrip.c:257 +#, c-format +msgid "cannot update new zero section: %s" +msgstr "nie można zaktualizować nowej sekcji zerowej: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "nie można skopiować nagłówka ELF: %s" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, c-format +msgid "cannot get number of program headers: %s" +msgstr "nie można uzyskać liczby nagłówków programu: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "nie można utworzyć nagłówków programu: %s" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "nie można skopiować nagłówka programu: %s" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "nie można skopiować nagłówka sekcji: %s" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "nie można uzyskać danych sekcji: %s" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "nie można skopiować danych sekcji: %s" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "nie można utworzyć katalogu „%s”" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "nie można uzyskać wpisu tabeli symboli: %s" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "nie można zaktualizować tabeli symboli: %s" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "nie można zaktualizować nagłówka sekcji: %s" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "nie można zaktualizować relokacji: %s" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "nie można uzyskać wersji symbolu: %s" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "nieoczekiwany typ sekcji w [%zu] z sh_link do tabeli symboli" + +#: src/unstrip.c:848 +#, c-format +msgid "cannot get symbol section data: %s" +msgstr "nie można uzyskać danych sekcji symboli: %s" + +#: src/unstrip.c:850 +#, c-format +msgid "cannot get string section data: %s" +msgstr "nie można uzyskać danych sekcji ciągów: %s" + +#: src/unstrip.c:867 +#, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "nieprawidłowy offset ciągu w symbolu [%zu]" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "nie można odczytać nazwy sekcji [%zu]: %s" + +#: src/unstrip.c:1040 +#, c-format +msgid "bad sh_link for group section: %s" +msgstr "błędne sh_link dla sekcji grupy: %s" + +#: src/unstrip.c:1046 +#, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "nie można uzyskać shdr dla sekcji grupy: %s" + +#: src/unstrip.c:1051 +#, c-format +msgid "bad data for group symbol section: %s" +msgstr "błędne dane dla sekcji symboli grupy: %s" + +#: src/unstrip.c:1057 +#, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "nie można uzyskać symbolu dla sekcji grupy: %s" + +#: src/unstrip.c:1062 +#, c-format +msgid "bad symbol name for group section: %s" +msgstr "błędna nazwa symbolu dla sekcji grupy: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "nie można odnaleźć pasującej sekcji dla [%zu] „%s”" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "nie można odczytać sekcji „.gnu.prelink_undo”: %s" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "przepełnienie z shnum = %zu w sekcji „%s”" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "nieprawidłowa zawartość w sekcji „%s”" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "nie można nazwy sekcji do tabeli ciągów: %s" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "nie można zaktualizować danych tabeli ciągów nagłówków sekcji: %s" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "nie można uzyskać indeksu sekcji tabeli ciągów nagłówków sekcji: %s" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "nie można uzyskać licznika sekcji: %s" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "" +"więcej sekcji w okrojonym pliku niż w pliku debugowania — odwrócono " +"parametry?" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "brak sekcji w okrojonym pliku" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "nie można odczytać tabeli ciągów nagłówków sekcji: %s" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "nie można dodać nowej sekcji: %s" + +#: src/unstrip.c:1758 +#, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "symbol [%zu] ma nieprawidłowy indeks sekcji" + +#: src/unstrip.c:1790 +#, c-format +msgid "group has invalid section index [%zd]" +msgstr "grupa ma nieprawidłowy indeks sekcji [%zd]" + +#: src/unstrip.c:2065 +#, c-format +msgid "cannot read section data: %s" +msgstr "nie można odczytać danych sekcji: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "nie można zaktualizować nagłówka ELF: %s" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "nie można zaktualizować nagłówka programu: %s" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "nie można zapisać pliku wyjściowego: %s" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"Dane DWARF nie zostały dostosowane do przesunięcia wczesnego konsolidowania; " +"proszę rozważyć polecenie prelink -u" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"Dane DWARF w „%s” nie zostały dostosowane do przesunięcia wczesnego " +"konsolidowania; proszę rozważyć polecenie prelink -u" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "nie można utworzyć deskryptora ELF: %s" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "OSTRZEŻENIE: " + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr ", należy użyć opcji --force" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "Różna identyfikacja nagłówka ELF (e_ident)" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "Różne typy nagłówka ELF (e_type)" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "Różne typy maszyny nagłówka ELF (e_machine)" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "okrojony nagłówek programu (e_phnum) jest mniejszy niż nieokrojony" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "nie można odnaleźć okrojonego pliku dla modułu „%s”: %s" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "nie można otworzyć okrojonego pliku „%s” dla modułu „%s”: %s" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "nie można odnaleźć pliku debugowania dla modułu „%s”: %s" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "nie można otworzyć pliku debugowania „%s” dla modułu „%s”: %s" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "moduł „%s” pliku „%s” nie został okrojony" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "" +"nie można utworzyć pamięci podręcznej adresów sekcji dla modułu „%s”: %s" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "nie odnaleziono pasujących modułów" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "pasuje więcej niż jeden moduł" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" +"OKROJONY-PLIK PLIK-DEBUGOWANIA\n" +"[MODUŁ…]" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" +"Łączy okrojone pliki z oddzielnymi symbolami i informacjami debugowania.\n" +"\n" +"Pierwsza forma umieszcza wynik w PLIKU-DEBUGOWANIA, jeśli nie podano opcji -" +"o.\n" +"\n" +"Parametry MODUŁ podają wzorce nazw plików dopasowujące moduły do procesów.\n" +"Za pomocą opcji -f dopasowuje nazwę głównego (okrojonego) pliku (ukośniki " +"nigdy nie są specjalne), w innym przypadku dopasowują proste nazwy modułów. " +"Jeśli nie podano parametrów, przetwarza wszystkie odnalezione moduły.\n" +"\n" +"Wiele modułów zostaje zapisanych do plików w KATALOGU-WYJŚCIOWYM, tworząc " +"podkatalogi, jeśli są wymagane. Używając opcji -m te pliki mają proste nazwy " +"modułów, w innym przypadku mają nazwy głównego pliku uzupełnione katalogiem " +"w KATALOGU-WYJŚCIOWYM.\n" +"\n" +"Używając opcji -n żadne pliki nie zostają zapisane, a jeden wiersz do " +"standardowego wyjścia dla każdego modułu:\n" +"\tPOCZĄTEK+ROZMIAR IDENTYFIKATOR-KOPII PLIK PLIK-DEBUGOWANIA NAZWA-MODUŁU\n" +"POCZĄTEK i ROZMIAR są liczbami szesnastkowymi podającymi zakres adresów " +"modułu. IDENTYFIKATOR-KOPII jest liczbą szesnastkową dla bitów " +"identyfikatora kopii lub „-”, jeśli identyfikator jest nieznany; liczba " +"szesnastkowa może być uzupełniona @0xADRES podającym adres, gdzie znajduje " +"się identyfikator, jeśli jest to wiadome. PLIK jest nazwą pliku " +"odnalezionego dla modułu lub „-”, jeśli go nie odnaleziono lub „.”, jeśli " +"obraz ELF jest dostępny, ale nie z żadnego nazwanego pliku. PLIK-DEBUGOWANIA " +"jest nazwą oddzielnego pliku debuginfo lub „-”, jeśli nie odnaleziono " +"debuginfo lub „.”, jeśli PLIK zawiera informacje debugowania." + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "Żąda zawartość powiązaną z debuginfo z debuginfod wymienionych w $" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" +"debuginfo IDENTYFIKATOR-KOPII\n" +"debuginfo ŚCIEŻKA\n" +"executable IDENTYFIKATOR-KOPII\n" +"executable ŚCIEŻKA\n" +"source IDENTYFIKATOR-KOPII /NAZWA-PLIKU\n" +"source ŚCIEŻKA /NAZWA-PLIKU\n" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "Uruchamia plik wykonywalny" + +#: tests/dwflmodtest.c:209 +msgid "Additionally show function names" +msgstr "Dodatkowo wyświetla nazwy funkcji" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "Wyświetla wystąpienia wstawionych funkcji" diff --git a/po/quot.sed b/po/quot.sed new file mode 100644 index 00000000..0122c463 --- /dev/null +++ b/po/quot.sed @@ -0,0 +1,6 @@ +s/"\([^"]*\)"/“\1”/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“”/""/g diff --git a/po/remove-potcdate.sin b/po/remove-potcdate.sin new file mode 100644 index 00000000..8c70dfbf --- /dev/null +++ b/po/remove-potcdate.sin @@ -0,0 +1,25 @@ +# Sed script that removes the POT-Creation-Date line in the header entry +# from a POT file. +# +# Copyright (C) 2002 Free Software Foundation, Inc. +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. This file is offered as-is, +# without any warranty. +# +# The distinction between the first and the following occurrences of the +# pattern is achieved by looking at the hold space. +/^"POT-Creation-Date: .*"$/{ +x +# Test if the hold space is empty. +s/P/P/ +ta +# Yes it was empty. First occurrence. Remove the line. +g +d +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/po/stamp-po b/po/stamp-po new file mode 100644 index 00000000..9788f702 --- /dev/null +++ b/po/stamp-po @@ -0,0 +1 @@ +timestamp diff --git a/po/uk.gmo b/po/uk.gmo new file mode 100644 index 0000000000000000000000000000000000000000..492ca3a9acd2a85c540cb9eeeab37b356ecc23c9 GIT binary patch literal 195958 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%0D!+|?x9!{ps-LDn`A>m|!c(EbZGeN| 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 literal 0 HcmV?d00001 diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 00000000..b076a983 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,8101 @@ +# Ukrainian translation of elfutils +# Copyright (C) 2010 Free Software Foundation, Inc. +# This file is distributed under the same license as the elfutils package. +# +# Yuri Chornoivan , 2010, 2011, 2012, 2013, 2014, 2015, 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n" +"POT-Creation-Date: 2021-05-22 20:29+0200\n" +"PO-Revision-Date: 2020-03-28 14:59+0200\n" +"Last-Translator: Yuri Chornoivan \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 20.03.70\n" + +#: lib/color.c:53 +msgid "" +"colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'" +msgstr "" +"розфарбовувати виведене. Типові значення «always» (завжди), «auto» (авто) " +"або «never» (ніколи)" + +#: lib/color.c:129 +#, c-format +msgid "" +"%s: invalid argument '%s' for '--color'\n" +"valid arguments are:\n" +" - 'always', 'yes', 'force'\n" +" - 'never', 'no', 'none'\n" +" - 'auto', 'tty', 'if-tty'\n" +msgstr "" +"%s: некоректний аргумент «%s» до «--color»\n" +"коректними аргументами є такі:\n" +" - «always», «yes», «force»\n" +" - «never», «no», «none»\n" +" - «auto», «tty», «if-tty»\n" + +#: lib/color.c:194 src/objdump.c:728 +#, c-format +msgid "cannot allocate memory" +msgstr "не вдалося розподілити пам’ять" + +#: lib/printversion.c:40 +#, c-format +msgid "" +"Copyright (C) %s The elfutils developers <%s>.\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"© Розробники elfutils, %s <%s>.\n" +"Це програмне забезпечення є вільним, умови копіювання викладено у його " +"початкових кодах. Умовами ліцензування програми НЕ передбачено жодних " +"гарантій, зокрема гарантій працездатності або придатності для певної мети.\n" + +#: lib/xmalloc.c:48 lib/xmalloc.c:61 lib/xmalloc.c:73 src/readelf.c:3461 +#: src/readelf.c:11512 src/unstrip.c:312 src/unstrip.c:2404 src/unstrip.c:2609 +#, c-format +msgid "memory exhausted" +msgstr "пам’ять вичерпано" + +#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51 +#: libelf/elf_error.c:60 +msgid "no error" +msgstr "без помилок" + +#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53 +#: libelf/elf_error.c:91 +msgid "out of memory" +msgstr "нестача пам'яті" + +#: libasm/asm_error.c:67 +msgid "cannot create output file" +msgstr "не вдалося створити файл виводу даних" + +#: libasm/asm_error.c:68 +msgid "invalid parameter" +msgstr "некоректний параметр" + +#: libasm/asm_error.c:69 +msgid "cannot change mode of output file" +msgstr "не вдалося змінити права доступу до файла виводу даних" + +#: libasm/asm_error.c:70 +msgid "cannot rename output file" +msgstr "не вдалося перейменувати файл виводу даних" + +#: libasm/asm_error.c:71 +msgid "duplicate symbol" +msgstr "дублювання символів" + +#: libasm/asm_error.c:72 +msgid "invalid section type for operation" +msgstr "некоректний тип розділу для дії" + +#: libasm/asm_error.c:73 +msgid "error during output of data" +msgstr "помилка під час спроби виведення даних" + +#: libasm/asm_error.c:74 +msgid "no backend support available" +msgstr "підтримки серверів не передбачено" + +#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52 +#: libelf/elf_error.c:63 +msgid "unknown error" +msgstr "невідома помилка" + +#: libcpu/i386_lex.l:122 +#, fuzzy, c-format +#| msgid "invalid page size value '%s': ignored" +msgid "invalid character '%c' at line %d; ignored" +msgstr "некоректне значення розміру сторінки «%s»: проігноровано" + +#: libcpu/i386_lex.l:123 +#, fuzzy, c-format +#| msgid "invalid page size value '%s': ignored" +msgid "invalid character '\\%o' at line %d; ignored" +msgstr "некоректне значення розміру сторінки «%s»: проігноровано" + +#: libcpu/i386_parse.y:554 +#, fuzzy, c-format +#| msgid "while reading linker script '%s': %s at line %d" +msgid "while reading i386 CPU description: %s at line %d" +msgstr "під час читання скрипту компонування «%s»: %s у рядку %d" + +#: libdw/dwarf_error.c:59 +msgid "invalid access" +msgstr "некоректний доступ" + +#: libdw/dwarf_error.c:60 +msgid "no regular file" +msgstr "не є звичайним файлом" + +#: libdw/dwarf_error.c:61 +msgid "I/O error" +msgstr "помилка вводу/виводу" + +#: libdw/dwarf_error.c:62 +msgid "invalid ELF file" +msgstr "некоректний файл ELF" + +#: libdw/dwarf_error.c:63 +msgid "no DWARF information" +msgstr "немає відомостей DWARF" + +#: libdw/dwarf_error.c:64 +msgid "cannot decompress DWARF" +msgstr "не вдалося розпакувати DWARF" + +#: libdw/dwarf_error.c:65 +msgid "no ELF file" +msgstr "немає файла ELF" + +#: libdw/dwarf_error.c:66 +msgid "cannot get ELF header" +msgstr "не вдалося отримати заголовок ELF" + +#: libdw/dwarf_error.c:68 +msgid "not implemented" +msgstr "не реалізовано" + +#: libdw/dwarf_error.c:69 libelf/elf_error.c:111 libelf/elf_error.c:159 +msgid "invalid command" +msgstr "некоректна команда" + +#: libdw/dwarf_error.c:70 +msgid "invalid version" +msgstr "некоректна версія" + +#: libdw/dwarf_error.c:71 +msgid "invalid file" +msgstr "некоректний файл" + +#: libdw/dwarf_error.c:72 +msgid "no entries found" +msgstr "запис не знайдено" + +#: libdw/dwarf_error.c:73 +msgid "invalid DWARF" +msgstr "некоректний запис DWARF" + +#: libdw/dwarf_error.c:74 +msgid "no string data" +msgstr "немає рядкових даних" + +#: libdw/dwarf_error.c:75 +msgid ".debug_str section missing" +msgstr "пропущено розділ .debug_str" + +#: libdw/dwarf_error.c:76 +msgid ".debug_line_str section missing" +msgstr "пропущено розділ .debug_line_str" + +#: libdw/dwarf_error.c:77 +msgid ".debug_str_offsets section missing" +msgstr "пропущено розділ .debug_str_offsets" + +#: libdw/dwarf_error.c:78 +msgid "no address value" +msgstr "немає значення адреси" + +#: libdw/dwarf_error.c:79 +msgid "no constant value" +msgstr "немає значення сталої" + +#: libdw/dwarf_error.c:80 +msgid "no reference value" +msgstr "немає значення для порівняння" + +#: libdw/dwarf_error.c:81 +msgid "invalid reference value" +msgstr "некоректне значення для порівняння" + +#: libdw/dwarf_error.c:82 +msgid ".debug_line section missing" +msgstr "немає розділу .debug_line" + +#: libdw/dwarf_error.c:83 +msgid "invalid .debug_line section" +msgstr "некоректний розділ .debug_line" + +#: libdw/dwarf_error.c:84 +msgid "debug information too big" +msgstr "занадто великі відомості для діагностики" + +#: libdw/dwarf_error.c:85 +msgid "invalid DWARF version" +msgstr "некоректна версія DWARF" + +#: libdw/dwarf_error.c:86 +msgid "invalid directory index" +msgstr "некоректний покажчик каталогу" + +#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:73 +msgid "address out of range" +msgstr "некоректна адреса" + +#: libdw/dwarf_error.c:88 +msgid ".debug_loc section missing" +msgstr "пропущено розділ .debug_loc" + +#: libdw/dwarf_error.c:89 +msgid ".debug_loclists section missing" +msgstr "пропущено розділ .debug_loclists" + +#: libdw/dwarf_error.c:90 +msgid "not a location list value" +msgstr "не є значенням списку адрес" + +#: libdw/dwarf_error.c:91 +msgid "no block data" +msgstr "немає блокових даних" + +#: libdw/dwarf_error.c:92 +msgid "invalid line index" +msgstr "некоректний номер рядка" + +#: libdw/dwarf_error.c:93 +msgid "invalid address range index" +msgstr "некоректний індекс діапазону адрес" + +#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:74 +msgid "no matching address range" +msgstr "не виявлено відповідного діапазону адрес" + +#: libdw/dwarf_error.c:95 +msgid "no flag value" +msgstr "немає значення прапорця" + +#: libdw/dwarf_error.c:96 libelf/elf_error.c:236 +msgid "invalid offset" +msgstr "некоректне значення зміщення" + +#: libdw/dwarf_error.c:97 +msgid ".debug_ranges section missing" +msgstr "немає розділу .debug_ranges" + +#: libdw/dwarf_error.c:98 +msgid ".debug_rnglists section missing" +msgstr "пропущено розділ .debug_rnglists" + +#: libdw/dwarf_error.c:99 +msgid "invalid CFI section" +msgstr "некоректний розділ CFI" + +#: libdw/dwarf_error.c:100 +msgid "no alternative debug link found" +msgstr "альтернативного діагностичного посилання не знайдено" + +#: libdw/dwarf_error.c:101 +msgid "invalid opcode" +msgstr "некоректний код операції" + +#: libdw/dwarf_error.c:102 +msgid "not a CU (unit) DIE" +msgstr "не є DIE CU (модуля)" + +#: libdw/dwarf_error.c:103 +msgid "unknown language code" +msgstr "невідомий код мови" + +#: libdw/dwarf_error.c:104 +msgid ".debug_addr section missing" +msgstr "пропущено розділ .debug_addr" + +#: libdwfl/argp-std.c:47 src/stack.c:643 src/unstrip.c:2550 +msgid "Input selection options:" +msgstr "Вибір параметрів виведення даних:" + +#: libdwfl/argp-std.c:48 +msgid "Find addresses in FILE" +msgstr "Знайти адреси у ФАЙЛІ" + +#: libdwfl/argp-std.c:50 +msgid "Find addresses from signatures found in COREFILE" +msgstr "Знайти адреси за сигнатурами з файла COREFILE" + +#: libdwfl/argp-std.c:52 +msgid "Find addresses in files mapped into process PID" +msgstr "Знайти адреси у файлах, відображених на процес з PID" + +#: libdwfl/argp-std.c:54 +msgid "" +"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps " +"format" +msgstr "" +"Знайти адреси у файлах, відображених як read за ФАЙЛОМ у форматі /proc/PID/" +"maps Linux" + +#: libdwfl/argp-std.c:56 +msgid "Find addresses in the running kernel" +msgstr "Знайти адреси у запущеному ядрі" + +#: libdwfl/argp-std.c:58 +msgid "Kernel with all modules" +msgstr "Ядро з усіма модулями" + +#: libdwfl/argp-std.c:60 src/stack.c:650 +msgid "Search path for separate debuginfo files" +msgstr "Шукати у вказаному каталозі окремі файли debuginfo" + +#: libdwfl/argp-std.c:161 +msgid "only one of -e, -p, -k, -K, or --core allowed" +msgstr "" +"можна використовувати лише один за параметрів: -e, -p, -k, -K або --core" + +#: libdwfl/argp-std.c:234 +msgid "cannot load kernel symbols" +msgstr "не вдалося завантажити символи ядра" + +#. Non-fatal to have no modules since we do have the kernel. +#: libdwfl/argp-std.c:238 +msgid "cannot find kernel modules" +msgstr "не вдалося виявити модулі ядра" + +#: libdwfl/argp-std.c:255 +msgid "cannot find kernel or modules" +msgstr "не вдалося виявити ядро або модулі" + +#: libdwfl/argp-std.c:294 +#, c-format +msgid "cannot read ELF core file: %s" +msgstr "не вдалося прочитати файл core ELF: %s" + +#: libdwfl/argp-std.c:317 +msgid "Not enough memory" +msgstr "Бракує пам'яті" + +#: libdwfl/argp-std.c:327 +msgid "No modules recognized in core file" +msgstr "Не вдалося виявити модулі у файлі core" + +#: libdwfl/libdwflP.h:54 +msgid "See errno" +msgstr "Див. errno" + +#: libdwfl/libdwflP.h:55 +msgid "See elf_errno" +msgstr "Див. elf_errno" + +#: libdwfl/libdwflP.h:56 +msgid "See dwarf_errno" +msgstr "Див. dwarf_errno" + +#: libdwfl/libdwflP.h:57 +msgid "See ebl_errno (XXX missing)" +msgstr "Див. ebl_errno (не виявлено XXX)" + +#: libdwfl/libdwflP.h:58 +msgid "gzip decompression failed" +msgstr "Помилка під час спроби видобування з gzip" + +#: libdwfl/libdwflP.h:59 +msgid "bzip2 decompression failed" +msgstr "Помилка під час спроби видобування з bzip2" + +#: libdwfl/libdwflP.h:60 +msgid "LZMA decompression failed" +msgstr "Помилка під час спроби видобування з LZMA" + +#: libdwfl/libdwflP.h:61 +#, fuzzy +msgid "zstd decompression failed" +msgstr "Помилка під час спроби видобування з gzip" + +#: libdwfl/libdwflP.h:62 +msgid "no support library found for machine" +msgstr "у системі не виявлено бібліотеки підтримки" + +#: libdwfl/libdwflP.h:63 +msgid "Callbacks missing for ET_REL file" +msgstr "Немає зворотних викликів для файла ET_REL" + +#: libdwfl/libdwflP.h:64 +msgid "Unsupported relocation type" +msgstr "Непідтримуваний тип пересування" + +#: libdwfl/libdwflP.h:65 +msgid "r_offset is bogus" +msgstr "r_offset є фіктивним" + +#: libdwfl/libdwflP.h:66 libelf/elf_error.c:115 libelf/elf_error.c:175 +msgid "offset out of range" +msgstr "перевищення можливого зміщення" + +#: libdwfl/libdwflP.h:67 +msgid "relocation refers to undefined symbol" +msgstr "пересування посилається на невизначений символ." + +#: libdwfl/libdwflP.h:68 +msgid "Callback returned failure" +msgstr "Зворотним викликом повернуто помилку" + +#: libdwfl/libdwflP.h:69 +msgid "No DWARF information found" +msgstr "Не виявлено відомостей DWARF" + +#: libdwfl/libdwflP.h:70 +msgid "No symbol table found" +msgstr "Не виявлено таблиці символів" + +#: libdwfl/libdwflP.h:71 +msgid "No ELF program headers" +msgstr "Немає заголовків програми ELF" + +#: libdwfl/libdwflP.h:72 +msgid "address range overlaps an existing module" +msgstr "діапазон адрес перекриває існуючий модуль" + +#: libdwfl/libdwflP.h:75 +msgid "image truncated" +msgstr "образ обрізано" + +#: libdwfl/libdwflP.h:76 +msgid "ELF file opened" +msgstr "Відкритий файл ELF" + +#: libdwfl/libdwflP.h:77 +msgid "not a valid ELF file" +msgstr "не є коректним файлом ELF" + +#: libdwfl/libdwflP.h:78 +msgid "cannot handle DWARF type description" +msgstr "не вдалося обробити опис типу DWARF" + +#: libdwfl/libdwflP.h:79 +msgid "ELF file does not match build ID" +msgstr "Файл ELF не відповідає ідентифікатору збирання" + +#: libdwfl/libdwflP.h:80 +msgid "corrupt .gnu.prelink_undo section data" +msgstr "дані розділу «.gnu.prelink_undo» пошкоджено" + +#: libdwfl/libdwflP.h:81 +msgid "Internal error due to ebl" +msgstr "Внутрішня помилка через ebl" + +#: libdwfl/libdwflP.h:82 +msgid "Missing data in core file" +msgstr "У файлі ядра не вистачає даних" + +#: libdwfl/libdwflP.h:83 +msgid "Invalid register" +msgstr "Некоректний регістр" + +#: libdwfl/libdwflP.h:84 +msgid "Error reading process memory" +msgstr "Помилка під час спроби читання пам’яті процесу" + +#: libdwfl/libdwflP.h:85 +msgid "Couldn't find architecture of any ELF" +msgstr "Не вдалося знайти хоч якусь архітектуру ELF" + +#: libdwfl/libdwflP.h:86 +msgid "Error parsing /proc filesystem" +msgstr "Помилка під час спроби обробки файлової системи /proc" + +#: libdwfl/libdwflP.h:87 +msgid "Invalid DWARF" +msgstr "Некоректний запис DWARF" + +#: libdwfl/libdwflP.h:88 +msgid "Unsupported DWARF" +msgstr "Непідтримуваний запис DWARF" + +#: libdwfl/libdwflP.h:89 +msgid "Unable to find more threads" +msgstr "Не вдалося знайти додаткові потоки" + +#: libdwfl/libdwflP.h:90 +msgid "Dwfl already has attached state" +msgstr "Dwfl уже перебуває у стані долучення до процесу" + +#: libdwfl/libdwflP.h:91 +msgid "Dwfl has no attached state" +msgstr "Dwfl не перебуває у стані долучення до процесу" + +#: libdwfl/libdwflP.h:92 +msgid "Unwinding not supported for this architecture" +msgstr "Для цієї архітектури розгортання не передбачено" + +#: libdwfl/libdwflP.h:93 +msgid "Invalid argument" +msgstr "Некоректний аргумент" + +#: libdwfl/libdwflP.h:94 +msgid "Not an ET_CORE ELF file" +msgstr "Не є файлом ET_CORE ELF" + +#: libebl/eblbackendname.c:41 +msgid "No backend" +msgstr "Немає сервера" + +#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:79 +#: libebl/eblobjnotetypename.c:110 libebl/eblobjnotetypename.c:131 +#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83 +#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:81 +msgid "" +msgstr "<невідомо>" + +#: libebl/ebldynamictagname.c:103 +#, c-format +msgid ": %#" +msgstr "<невідомо>: %#" + +#: libebl/eblobjnote.c:58 +#, c-format +msgid "unknown SDT version %u\n" +msgstr "невідома версія SDT, %u\n" + +#: libebl/eblobjnote.c:76 +#, c-format +msgid "invalid SDT probe descriptor\n" +msgstr "некоректний дескриптор зондування SDT\n" + +#: libebl/eblobjnote.c:126 +#, c-format +msgid " PC: " +msgstr " PC: " + +#: libebl/eblobjnote.c:128 +#, c-format +msgid " Base: " +msgstr "Основа: " + +#: libebl/eblobjnote.c:130 +#, c-format +msgid " Semaphore: " +msgstr " Семафор: " + +#: libebl/eblobjnote.c:132 +#, c-format +msgid " Provider: " +msgstr " Постачальник: " + +#: libebl/eblobjnote.c:134 +#, c-format +msgid " Name: " +msgstr "Назва: " + +#: libebl/eblobjnote.c:136 +#, c-format +msgid " Args: " +msgstr " Арг.: " + +#: libebl/eblobjnote.c:300 +#, c-format +msgid " Build ID: " +msgstr " Ід. збирання: " + +#. A non-null terminated version string. +#: libebl/eblobjnote.c:311 +#, c-format +msgid " Linker version: %.*s\n" +msgstr " Версія компонувальника: %.*s\n" + +#: libebl/eblobjnote.c:638 +#, c-format +msgid " OS: %s, ABI: " +msgstr " ОС: %s, ABI: " + +#: libebl/eblosabiname.c:70 +msgid "Stand alone" +msgstr "Окремий" + +#: libebl/eblsymbolbindingname.c:68 libebl/eblsymboltypename.c:74 +#, c-format +msgid ": %d" +msgstr "<невідомий>: %d" + +#: libelf/elf_error.c:67 +msgid "unknown version" +msgstr "невідома версія" + +#: libelf/elf_error.c:71 +msgid "unknown type" +msgstr "невизначений тип" + +#: libelf/elf_error.c:75 +msgid "invalid `Elf' handle" +msgstr "некоректний дескриптор «Elf»" + +#: libelf/elf_error.c:79 +msgid "invalid size of source operand" +msgstr "некоректна розмірність вхідного параметра" + +#: libelf/elf_error.c:83 +msgid "invalid size of destination operand" +msgstr "некоректна розмірність вихідного параметра" + +#: libelf/elf_error.c:87 src/readelf.c:6217 +#, c-format +msgid "invalid encoding" +msgstr "некоректне кодування" + +#: libelf/elf_error.c:95 +msgid "invalid file descriptor" +msgstr "некоректний дескриптор файла" + +#: libelf/elf_error.c:99 +msgid "invalid ELF file data" +msgstr "некоректні дані щодо файла ELF" + +#: libelf/elf_error.c:103 +msgid "invalid operation" +msgstr "недійсна дія" + +#: libelf/elf_error.c:107 +msgid "ELF version not set" +msgstr "версію ELF не вказано" + +#: libelf/elf_error.c:119 +msgid "invalid fmag field in archive header" +msgstr "некоректне поле fmag у заголовку архіву" + +#: libelf/elf_error.c:123 +msgid "invalid archive file" +msgstr "некоректний файл архіву" + +#: libelf/elf_error.c:127 +msgid "descriptor is not for an archive" +msgstr "дескриптор не належить архіву" + +#: libelf/elf_error.c:131 +msgid "no index available" +msgstr "такого номера немає" + +#: libelf/elf_error.c:135 +msgid "cannot read data from file" +msgstr "не вдалося прочитати дані з файла" + +#: libelf/elf_error.c:139 +msgid "cannot write data to file" +msgstr "не вдалося записати дані до файла" + +#: libelf/elf_error.c:143 +msgid "invalid binary class" +msgstr "некоректний бінарний клас" + +#: libelf/elf_error.c:147 +msgid "invalid section index" +msgstr "некоректний номер розділу" + +#: libelf/elf_error.c:151 +msgid "invalid operand" +msgstr "некоректний параметр" + +#: libelf/elf_error.c:155 +msgid "invalid section" +msgstr "некоректний розділ" + +#: libelf/elf_error.c:163 +msgid "executable header not created first" +msgstr "заголовок виконуваного файла не було створено першим" + +#: libelf/elf_error.c:167 +msgid "file descriptor disabled" +msgstr "дескриптор файла вимкнено" + +#: libelf/elf_error.c:171 +msgid "archive/member file descriptor mismatch" +msgstr "невідповідність дескрипторів файлів архіву/елемента" + +#: libelf/elf_error.c:179 +msgid "cannot manipulate null section" +msgstr "не можна оперувати нульовим розділом" + +#: libelf/elf_error.c:183 +msgid "data/scn mismatch" +msgstr "невідповідність полів data/scn" + +#: libelf/elf_error.c:187 +msgid "invalid section header" +msgstr "некоректний заголовок розділу" + +#: libelf/elf_error.c:191 src/readelf.c:10023 src/readelf.c:10623 +#: src/readelf.c:10724 src/readelf.c:10906 +#, c-format +msgid "invalid data" +msgstr "некоректні дані" + +#: libelf/elf_error.c:195 +msgid "unknown data encoding" +msgstr "невідоме кодування даних" + +#: libelf/elf_error.c:199 +msgid "section `sh_size' too small for data" +msgstr "розділ «sh_size» є замалим для даних" + +#: libelf/elf_error.c:203 +msgid "invalid section alignment" +msgstr "некоректне вирівнювання розділу" + +#: libelf/elf_error.c:207 +msgid "invalid section entry size" +msgstr "некоректна розмірність запису розділу" + +#: libelf/elf_error.c:211 +msgid "update() for write on read-only file" +msgstr "update() для запису придатного лише для читання файла" + +#: libelf/elf_error.c:215 +msgid "no such file" +msgstr "такого файла не виявлено" + +#: libelf/elf_error.c:219 +msgid "only relocatable files can contain section groups" +msgstr "містити групи розділів можуть лише придатні до пересування файли" + +#: libelf/elf_error.c:224 +msgid "" +"program header only allowed in executables, shared objects, and core files" +msgstr "" +"заголовок програми можна використовувати лише у виконуваних файлах, об’єктах " +"спільного використання та файлах ядра" + +#: libelf/elf_error.c:231 +msgid "file has no program header" +msgstr "у файлі немає заголовка програми" + +#: libelf/elf_error.c:241 +msgid "invalid section type" +msgstr "некоректний тип розділу" + +#: libelf/elf_error.c:246 +msgid "invalid section flags" +msgstr "некоректні прапорці розділу" + +#: libelf/elf_error.c:251 +msgid "section does not contain compressed data" +msgstr "розділ не містить стиснутих даних" + +#: libelf/elf_error.c:256 +msgid "section contains compressed data" +msgstr "розділ містить стиснені дані" + +#: libelf/elf_error.c:261 +msgid "unknown compression type" +msgstr "невідомий тип стиснення" + +#: libelf/elf_error.c:266 +msgid "cannot compress data" +msgstr "неможливо стиснути дані" + +#: libelf/elf_error.c:271 +msgid "cannot decompress data" +msgstr "неможливо розпакувати дані" + +#: src/addr2line.c:57 +msgid "Input format options:" +msgstr "Параметри форматування вхідних даних:" + +#: src/addr2line.c:59 +msgid "Treat addresses as offsets relative to NAME section." +msgstr "Вважати адреси зміщеннями відносно розділу НАЗВА." + +#: src/addr2line.c:61 +msgid "Output format options:" +msgstr "Параметри форматування результатів:" + +#: src/addr2line.c:62 +msgid "Print address before each entry" +msgstr "Виводити адресу перед кожним записом" + +#: src/addr2line.c:63 +msgid "Show only base names of source files" +msgstr "Показувати лише базові назви файлів коду програми" + +#: src/addr2line.c:65 +msgid "Show absolute file names using compilation directory" +msgstr "Показувати абсолютні назви файлів з використанням каталогу збирання" + +#: src/addr2line.c:66 +msgid "Also show function names" +msgstr "Показувати також назви функцій" + +#: src/addr2line.c:67 +msgid "Also show symbol or section names" +msgstr "Показувати також назви символів та розділів" + +#: src/addr2line.c:68 +msgid "Also show symbol and the section names" +msgstr "Показувати також назви символів та розділів" + +#: src/addr2line.c:69 +msgid "Also show line table flags" +msgstr "Показувати також прапорці рядків таблиці" + +#: src/addr2line.c:71 +msgid "" +"Show all source locations that caused inline expansion of subroutines at the " +"address." +msgstr "" +"Показати усі місця у початковому коді, у яких було виявлено вбудоване " +"розгортання підпрограм за вказаною адресою." + +#: src/addr2line.c:74 +msgid "Show demangled symbols (ARG is always ignored)" +msgstr "Виводити розшифровані символи (АРГ завжди ігнорується)" + +#: src/addr2line.c:76 +msgid "Print all information on one line, and indent inlines" +msgstr "Вивести усі дані у один рядок і додати відступи до перенесених рядків" + +#: src/addr2line.c:78 src/elfcmp.c:70 src/findtextrel.c:65 src/nm.c:100 +#: src/strings.c:78 +msgid "Miscellaneous:" +msgstr "Інше:" + +#. Short description of program. +#: src/addr2line.c:86 +msgid "" +"Locate source files and line information for ADDRs (in a.out by default)." +msgstr "Шукати АДРЕСИ у файлах кодів та даних про рядки (типово, у a.out)." + +#. Strings for arguments in help texts. +#: src/addr2line.c:90 +msgid "[ADDR...]" +msgstr "[АДРЕСА...]" + +#: src/addr2line.c:519 +#, c-format +msgid "Section syntax requires exactly one module" +msgstr "Синтаксис розділів вимагає точного одного модуля" + +#: src/addr2line.c:542 +#, c-format +msgid "offset %# lies outside section '%s'" +msgstr "зміщення %# розташовано поза межами розділу «%s»" + +#: src/addr2line.c:652 +#, c-format +msgid "cannot find symbol '%s'" +msgstr "не вдалося знайти символ «%s»" + +#: src/addr2line.c:657 +#, c-format +msgid "offset %# lies outside contents of '%s'" +msgstr "зміщення %# розташовано поза межами вмісту «%s»" + +#: src/ar.c:67 +msgid "Commands:" +msgstr "Команди:" + +#: src/ar.c:68 +msgid "Delete files from archive." +msgstr "Вилучити файли з архіву." + +#: src/ar.c:69 +msgid "Move files in archive." +msgstr "Пересунути файли до архіву." + +#: src/ar.c:70 +msgid "Print files in archive." +msgstr "Надрукувати список файлів у архіві." + +#: src/ar.c:71 +msgid "Quick append files to archive." +msgstr "Швидко додати файли до архіву." + +#: src/ar.c:73 +msgid "Replace existing or insert new file into archive." +msgstr "Замінити поточний або вставити новий файл до архіву." + +#: src/ar.c:74 +msgid "Display content of archive." +msgstr "Показати вміст архіву." + +#: src/ar.c:75 +msgid "Extract files from archive." +msgstr "Видобути файли з архіву." + +#: src/ar.c:77 +msgid "Command Modifiers:" +msgstr "Модифікатори команд:" + +#: src/ar.c:78 +msgid "Preserve original dates." +msgstr "Зберігати початкові часові мітки." + +#: src/ar.c:79 +msgid "Use instance [COUNT] of name." +msgstr "Використовувати екземпляр [НОМЕР] назви." + +#: src/ar.c:81 +msgid "Do not replace existing files with extracted files." +msgstr "Не замінювати поточні файли видобутими." + +#: src/ar.c:82 +msgid "Allow filename to be truncated if necessary." +msgstr "Уможливити, за потреби, обрізання назв файлів." + +#: src/ar.c:84 +msgid "Provide verbose output." +msgstr "Докладний вивід даних." + +#: src/ar.c:85 +msgid "Force regeneration of symbol table." +msgstr "Примусове повторне створення таблиці символів." + +#: src/ar.c:86 +msgid "Insert file after [MEMBER]." +msgstr "Вставити файл після [ЕЛЕМЕНТ]." + +#: src/ar.c:87 +msgid "Insert file before [MEMBER]." +msgstr "Вставити файл перед [ЕЛЕМЕНТ]." + +#: src/ar.c:88 +msgid "Same as -b." +msgstr "Те саме, що і -b." + +#: src/ar.c:89 +msgid "Suppress message when library has to be created." +msgstr "Придушити повідомлення, якщо має бути створено бібліотеку." + +#: src/ar.c:91 +msgid "Use full path for file matching." +msgstr "Використовувати для порівняння повний шлях до файла." + +#: src/ar.c:92 +msgid "Update only older files in archive." +msgstr "Оновлювати у архіві лише старіші файли." + +#. Short description of program. +#: src/ar.c:98 +msgid "Create, modify, and extract from archives." +msgstr "Створення, зміна архівів і видобування даних з архівів." + +#. Strings for arguments in help texts. +#: src/ar.c:101 +msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]" +msgstr "[ЕЛЕМЕНТ] [НОМЕР] АРХІВ [ФАЙЛ...]" + +#: src/ar.c:180 +#, c-format +msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options" +msgstr "" +"модифікатори «a», «b» і «i» можна використовувати лише разом з параметрами " +"«m» і «r»" + +#: src/ar.c:185 +#, c-format +msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers" +msgstr "" +"Для модифікаторів «a», «b» та «i» слід використовувати параметр ЕЛЕМЕНТ" + +#: src/ar.c:201 +#, c-format +msgid "'N' is only meaningful with the 'x' and 'd' options" +msgstr "«N» має значення лише разом з параметрами «x» і «d»" + +#: src/ar.c:206 +#, c-format +msgid "COUNT parameter required" +msgstr "потрібен параметр НОМЕР" + +#: src/ar.c:218 +#, c-format +msgid "invalid COUNT parameter %s" +msgstr "некоректний параметр НОМЕР %s" + +#: src/ar.c:225 +#, c-format +msgid "'%c' is only meaningful with the 'x' option" +msgstr "«%c» має сенс лише у разі використання параметра «x»" + +#: src/ar.c:231 +#, c-format +msgid "archive name required" +msgstr "слід вказати назву архіву" + +#: src/ar.c:244 +#, c-format +msgid "command option required" +msgstr "має бути вказано параметр команди" + +#: src/ar.c:295 +#, c-format +msgid "More than one operation specified" +msgstr "Вказано більше за одну дію" + +#: src/ar.c:389 +#, c-format +msgid "cannot open archive '%s'" +msgstr "не вдалося відкрити архів «%s»" + +#: src/ar.c:399 +#, c-format +msgid "cannot open archive '%s': %s" +msgstr "не вдалося відкрити архів «%s»: %s" + +#: src/ar.c:403 +#, c-format +msgid "%s: not an archive file" +msgstr "%s: не є файлом архіву" + +#: src/ar.c:407 +#, c-format +msgid "cannot stat archive '%s'" +msgstr "не вдалося отримати дані архіву «%s» за допомогою stat" + +#: src/ar.c:419 +#, c-format +msgid "no entry %s in archive\n" +msgstr "у архіві немає запису %s\n" + +#: src/ar.c:472 src/ar.c:927 src/ar.c:1134 +#, c-format +msgid "cannot create hash table" +msgstr "не вдалося створити таблицю хешів" + +#: src/ar.c:479 src/ar.c:934 src/ar.c:1143 +#, c-format +msgid "cannot insert into hash table" +msgstr "не вдалося вставити запис до таблиці хешів" + +#: src/ar.c:487 src/ranlib.c:148 +#, c-format +msgid "cannot stat '%s'" +msgstr "не вдалося отримати дані з «%s» за допомогою stat" + +#: src/ar.c:589 +#, c-format +msgid "cannot read content of %s: %s" +msgstr "не вдалося прочитати вміст з %s: %s" + +#: src/ar.c:632 +#, c-format +msgid "cannot open %.*s" +msgstr "не вдалося відкрити %.*s" + +#: src/ar.c:654 +#, c-format +msgid "failed to write %s" +msgstr "не вдалося записати %s" + +#: src/ar.c:666 +#, c-format +msgid "cannot change mode of %s" +msgstr "не вдалося змінити права доступу до %s" + +#: src/ar.c:682 +#, c-format +msgid "cannot change modification time of %s" +msgstr "не вдалося змінити часову мітку зміни %s" + +#: src/ar.c:728 +#, c-format +msgid "cannot rename temporary file to %.*s" +msgstr "не вдалося перейменувати файл тимчасових даних на %.*s" + +#: src/ar.c:764 src/ar.c:1019 src/ar.c:1423 src/ranlib.c:222 +#, c-format +msgid "cannot create new file" +msgstr "не вдалося створити файл" + +#: src/ar.c:1225 +#, c-format +msgid "position member %s not found" +msgstr "не виявлено елемента позиції %s" + +#: src/ar.c:1235 +#, c-format +msgid "%s: no entry %s in archive!\n" +msgstr "%s: у архіві немає запису %s!\n" + +#: src/ar.c:1264 src/objdump.c:241 +#, c-format +msgid "cannot open %s" +msgstr "не вдалося відкрити %s" + +#: src/ar.c:1269 +#, c-format +msgid "cannot stat %s" +msgstr "не вдалося отримати дані %s за допомогою stat" + +#: src/ar.c:1275 +#, c-format +msgid "%s is no regular file" +msgstr "%s не є звичайним файлом" + +#: src/ar.c:1288 +#, c-format +msgid "cannot get ELF descriptor for %s: %s\n" +msgstr "не вдалося отримати дескриптор ELF для %s: %s\n" + +#: src/ar.c:1308 +#, c-format +msgid "cannot read %s: %s" +msgstr "не вдалося прочитати %s: %s" + +#: src/ar.c:1483 +#, c-format +msgid "cannot represent ar_date" +msgstr "неможливо представити ar_date" + +#: src/ar.c:1489 +#, c-format +msgid "cannot represent ar_uid" +msgstr "неможливо представити ar_uid" + +#: src/ar.c:1495 +#, c-format +msgid "cannot represent ar_gid" +msgstr "неможливо представити ar_gid" + +#: src/ar.c:1501 +#, c-format +msgid "cannot represent ar_mode" +msgstr "неможливо представити ar_mode" + +#: src/ar.c:1507 +#, c-format +msgid "cannot represent ar_size" +msgstr "неможливо представити ar_size" + +#: src/arlib-argp.c:32 +msgid "Use zero for uid, gid, and date in archive members." +msgstr "" +"Використовувати нульове значення для uid, gid, та дати у елементах архіву." + +#: src/arlib-argp.c:34 +msgid "Use actual uid, gid, and date in archive members." +msgstr "" +"Використовувати поточні значення для uid, gid, та дати у елементах архіву." + +#: src/arlib-argp.c:63 +#, c-format +msgid "%s (default)" +msgstr "%s (типово)" + +#. The archive is too big. +#: src/arlib.c:213 +#, c-format +msgid "the archive '%s' is too large" +msgstr "розмір архіву «%s» є занадто великим" + +#: src/arlib.c:226 +#, c-format +msgid "cannot read ELF header of %s(%s): %s" +msgstr "не вдалося прочитати заголовок ELF з %s(%s): %s" + +#: src/elfclassify.c:92 +msgid "opening" +msgstr "" + +#: src/elfclassify.c:99 +msgid "reading" +msgstr "" + +#: src/elfclassify.c:245 +#, fuzzy +#| msgid "cannot get ELF header" +msgid "ELF header" +msgstr "не вдалося отримати заголовок ELF" + +#: src/elfclassify.c:256 +#, fuzzy +#| msgid "Program Headers:" +msgid "program headers" +msgstr "Заголовки програми:" + +#: src/elfclassify.c:265 +#, fuzzy +#| msgid "Program Headers:" +msgid "program header" +msgstr "Заголовки програми:" + +#: src/elfclassify.c:285 +#, fuzzy +#| msgid "Section Headers:" +msgid "section headers" +msgstr "Заголовки розділів:" + +#: src/elfclassify.c:296 +#, fuzzy +#| msgid "cannot get section header string table index" +msgid "section header string table index" +msgstr "не вдалося визначити індекс заголовка розділу у таблиці рядків" + +#: src/elfclassify.c:310 +#, fuzzy +#| msgid "cannot get section header" +msgid "could not obtain section header" +msgstr "не вдалося отримати заголовок розділу" + +#: src/elfclassify.c:316 +#, fuzzy +#| msgid "cannot get section name" +msgid "could not obtain section name" +msgstr "не вдалося отримати назву розділу" + +#: src/elfclassify.c:829 +msgid "writing to standard output" +msgstr "" + +#: src/elfclassify.c:856 +msgid "reading from standard input" +msgstr "" + +#: src/elfclassify.c:877 +#, fuzzy +#| msgid "Input selection options:" +msgid "Classification options" +msgstr "Вибір параметрів виведення даних:" + +#: src/elfclassify.c:879 +msgid "File looks like an ELF object or archive/static library (default)" +msgstr "" + +#: src/elfclassify.c:882 +msgid "File is an regular ELF object (not an archive/static library)" +msgstr "" + +#: src/elfclassify.c:885 +msgid "File is an ELF archive or static library" +msgstr "" + +#: src/elfclassify.c:888 +msgid "File is an ELF core dump file" +msgstr "" + +#: src/elfclassify.c:891 +msgid "" +"File is an ELF file with symbol table or .debug_* sections and can be " +"stripped further" +msgstr "" + +#: src/elfclassify.c:894 +msgid "File is (primarily) an ELF program executable (not primarily a DSO)" +msgstr "" + +#: src/elfclassify.c:897 +msgid "File is an ELF program executable (might also be a DSO)" +msgstr "" + +#: src/elfclassify.c:900 +msgid "" +"File is (primarily) an ELF shared object (DSO) (not primarily an executable)" +msgstr "" + +#: src/elfclassify.c:903 +msgid "File is an ELF shared object (DSO) (might also be an executable)" +msgstr "" + +#: src/elfclassify.c:907 +#, fuzzy +#| msgid "cannot find kernel modules" +msgid "File is a linux kernel module" +msgstr "не вдалося виявити модулі ядра" + +#: src/elfclassify.c:909 +msgid "File is a debug only ELF file (separate .debug, .dwo or dwz multi-file)" +msgstr "" + +#: src/elfclassify.c:912 +msgid "File is a loadable ELF object (program or shared object)" +msgstr "" + +#: src/elfclassify.c:941 +msgid "Input flags" +msgstr "" + +#: src/elfclassify.c:943 +msgid "Only classify regular (not symlink nor special device) files" +msgstr "" + +#: src/elfclassify.c:945 +msgid "" +"Also read file names to process from standard input, separated by newlines" +msgstr "" + +#: src/elfclassify.c:948 +msgid "" +"Also read file names to process from standard input, separated by ASCII NUL " +"bytes" +msgstr "" + +#: src/elfclassify.c:951 +msgid "Do not read files from standard input (default)" +msgstr "" + +#: src/elfclassify.c:953 +msgid "Try to open compressed files or embedded (kernel) ELF images" +msgstr "" + +#: src/elfclassify.c:956 +#, fuzzy +#| msgid "Output format:" +msgid "Output flags" +msgstr "Формат виводу:" + +#: src/elfclassify.c:958 +msgid "Output names of files, separated by newline" +msgstr "" + +#: src/elfclassify.c:960 +msgid "Output names of files, separated by ASCII NUL" +msgstr "" + +#: src/elfclassify.c:962 +#, fuzzy +#| msgid "More than one output file name given." +msgid "Do not output file names" +msgstr "Вказано декілька назв файлів виведення даних." + +#: src/elfclassify.c:964 +msgid "If printing file names, print matching files (default)" +msgstr "" + +#: src/elfclassify.c:966 +msgid "If printing file names, print files that do not match" +msgstr "" + +#: src/elfclassify.c:968 +msgid "Additional flags" +msgstr "" + +#: src/elfclassify.c:970 +msgid "Output additional information (can be specified multiple times)" +msgstr "" + +#: src/elfclassify.c:972 +msgid "Suppress some error output (counterpart to --verbose)" +msgstr "" + +#. Strings for arguments in help texts. +#: src/elfclassify.c:980 src/elfcompress.c:1334 src/elflint.c:77 +#: src/readelf.c:158 +msgid "FILE..." +msgstr "ФАЙЛ..." + +#: src/elfclassify.c:981 +msgid "" +"Determine the type of an ELF file.\n" +"\n" +"All of the classification options must apply at the same time to a " +"particular file. Classification options can be negated using a \"--not-\" " +"prefix.\n" +"\n" +"Since modern ELF does not clearly distinguish between programs and dynamic " +"shared objects, you should normally use either --executable or --shared to " +"identify the primary purpose of a file. Only one of the --shared and --" +"executable checks can pass for a file.\n" +"\n" +"If you want to know whether an ELF object might a program or a shared " +"library (but could be both), then use --program or --library. Some ELF files " +"will classify as both a program and a library.\n" +"\n" +"If you just want to know whether an ELF file is loadable (as program or " +"library) use --loadable. Note that files that only contain (separate) debug " +"information (--debug-only) are never --loadable (even though they might " +"contain program headers). Linux kernel modules are also not --loadable (in " +"the normal sense).\n" +"\n" +"Without any of the --print options, the program exits with status 0 if the " +"requested checks pass for all input files, with 1 if a check fails for any " +"file, and 2 if there is an environmental issue (such as a file read error or " +"a memory allocation error).\n" +"\n" +"When printing file names, the program exits with status 0 even if no file " +"names are printed, and exits with status 2 if there is an environmental " +"issue.\n" +"\n" +"On usage error (e.g. a bad option was given), the program exits with a " +"status code larger than 2.\n" +"\n" +"The --quiet or -q option suppresses some error warning output, but doesn't " +"change the exit status." +msgstr "" + +#: src/elfcmp.c:60 +msgid "Control options:" +msgstr "Параметри керування:" + +#: src/elfcmp.c:62 +msgid "Output all differences, not just the first" +msgstr "Показати всі відмінності, не лише першу з них" + +#: src/elfcmp.c:63 +msgid "" +"Control treatment of gaps in loadable segments [ignore|match] (default: " +"ignore)" +msgstr "" +"Керування обробкою проміжків у придатних до завантаження сегментах [ignore|" +"match] (типово, ignore)" + +#: src/elfcmp.c:65 +msgid "Ignore permutation of buckets in SHT_HASH section" +msgstr "Ігнорувати переставляння блоків у розділі SHT_HASH" + +#: src/elfcmp.c:67 +msgid "Ignore differences in build ID" +msgstr "Ігнорувати відмінності у ідентифікаторі збирання" + +#: src/elfcmp.c:68 +msgid "Output nothing; yield exit status only" +msgstr "Нічого не виводити; визначити лише стан виходу" + +#. Short description of program. +#: src/elfcmp.c:75 +msgid "Compare relevant parts of two ELF files for equality." +msgstr "Порівнює відповідні частини двох файлів ELF." + +#. Strings for arguments in help texts. +#: src/elfcmp.c:79 +msgid "FILE1 FILE2" +msgstr "ФАЙЛ1 ФАЙЛ2" + +#: src/elfcmp.c:141 +msgid "Invalid number of parameters.\n" +msgstr "Некоректна кількість параметрів.\n" + +#: src/elfcmp.c:172 src/elfcmp.c:177 +#, c-format +msgid "cannot get ELF header of '%s': %s" +msgstr "не вдалося отримати заголовок ELF «%s»: %s" + +#: src/elfcmp.c:203 +#, c-format +msgid "%s %s diff: ELF header" +msgstr "%s %s diff: заголовок ELF" + +#: src/elfcmp.c:210 src/elfcmp.c:213 +#, c-format +msgid "cannot get section count of '%s': %s" +msgstr "не вдалося отримати даних щодо кількості розділів «%s»: %s" + +#: src/elfcmp.c:218 +#, c-format +msgid "%s %s diff: section count" +msgstr "%s %s diff: кількість розділів" + +#: src/elfcmp.c:225 src/elfcmp.c:228 +#, c-format +msgid "cannot get program header count of '%s': %s" +msgstr "" +"не вдалося отримати даних щодо кількості заголовків програми у «%s»: %s" + +#: src/elfcmp.c:233 +#, c-format +msgid "%s %s diff: program header count" +msgstr "%s %s diff: кількість заголовків програми" + +#: src/elfcmp.c:241 src/elfcmp.c:244 +#, c-format +msgid "cannot get hdrstrndx of '%s': %s" +msgstr "не вдалося отримати hdrstrndx «%s»: %s" + +#: src/elfcmp.c:249 +#, c-format +msgid "%s %s diff: shdr string index" +msgstr "різниця між %s і %s: індекс рядків shdr" + +#: src/elfcmp.c:307 +#, c-format +msgid "%s %s differ: section [%zu], [%zu] name" +msgstr "%s %s diff: розділ [%zu], назва [%zu]" + +#: src/elfcmp.c:330 +#, c-format +msgid "%s %s differ: section [%zu] '%s' header" +msgstr "%s %s diff: розділ [%zu] заголовок «%s»" + +#: src/elfcmp.c:338 src/elfcmp.c:344 +#, c-format +msgid "cannot get content of section %zu in '%s': %s" +msgstr "не вдалося отримати вміст розділу %zu у «%s»: %s" + +#: src/elfcmp.c:353 +#, c-format +msgid "symbol table [%zu] in '%s' has zero sh_entsize" +msgstr "таблиця символів [%zu] у «%s» містить нульове значення sh_entsize" + +#: src/elfcmp.c:365 src/elfcmp.c:371 +#, c-format +msgid "cannot get symbol in '%s': %s" +msgstr "не вдалося отримати символ у «%s»: %s" + +#: src/elfcmp.c:393 +#, c-format +msgid "%s %s differ: symbol table [%zu]" +msgstr "%s %s diff: таблиця символів [%zu]" + +#: src/elfcmp.c:396 +#, c-format +msgid "%s %s differ: symbol table [%zu,%zu]" +msgstr "%s %s diff: таблиця символів [%zu,%zu]" + +#: src/elfcmp.c:443 src/elfcmp.c:513 +#, c-format +msgid "%s %s differ: section [%zu] '%s' number of notes" +msgstr "%s %s diff: розділ [%zu] кількість нотаток «%s»" + +#: src/elfcmp.c:451 +#, c-format +msgid "cannot read note section [%zu] '%s' in '%s': %s" +msgstr "не вдалося прочитати розділ нотаток [%zu] «%s» у «%s»: %s" + +#: src/elfcmp.c:462 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note name" +msgstr "%s %s diff: розділ [%zu] назва нотатки «%s»" + +#: src/elfcmp.c:470 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' type" +msgstr "%s %s diff: розділ [%zu] нотатка «%s» тип «%s»" + +#: src/elfcmp.c:485 +#, c-format +msgid "%s %s differ: build ID length" +msgstr "%s %s diff: довжина ідентифікатора збирання" + +#: src/elfcmp.c:493 +#, c-format +msgid "%s %s differ: build ID content" +msgstr "%s %s diff: вміст ідентифікатора збирання" + +#: src/elfcmp.c:502 +#, c-format +msgid "%s %s differ: section [%zu] '%s' note '%s' content" +msgstr "%s %s diff: розділ [%zu] нотатка «%s» вміст «%s»" + +#: src/elfcmp.c:543 +#, c-format +msgid "%s %s differ: section [%zu] '%s' content" +msgstr "%s %s diff: розділ [%zu] «%s», вміст" + +#: src/elfcmp.c:547 +#, c-format +msgid "%s %s differ: section [%zu,%zu] '%s' content" +msgstr "%s %s diff: розділ [%zu,%zu] «%s», вміст" + +#: src/elfcmp.c:562 +#, c-format +msgid "%s %s differ: unequal amount of important sections" +msgstr "%s %s diff: невідповідність об’ємів важливих розділів" + +#: src/elfcmp.c:595 src/elfcmp.c:600 +#, c-format +msgid "cannot load data of '%s': %s" +msgstr "не вдалося завантажити дані «%s»: %s" + +#: src/elfcmp.c:619 src/elfcmp.c:625 +#, c-format +msgid "cannot get program header entry %d of '%s': %s" +msgstr "не вдалося отримати запис заголовка програми %d «%s»: %s" + +#: src/elfcmp.c:631 +#, c-format +msgid "%s %s differ: program header %d" +msgstr "%s %s diff: заголовок програми %d" + +#: src/elfcmp.c:655 +#, c-format +msgid "%s %s differ: gap" +msgstr "%s %s diff: проміжок" + +#: src/elfcmp.c:706 +#, c-format +msgid "Invalid value '%s' for --gaps parameter." +msgstr "Некоректне значення «%s» параметра --gaps." + +#: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141 +#: src/size.c:272 src/strings.c:185 src/strip.c:1030 src/strip.c:1067 +#: src/unstrip.c:2195 src/unstrip.c:2224 +#, c-format +msgid "cannot open '%s'" +msgstr "не вдалося відкрити «%s»" + +#: src/elfcmp.c:738 src/findtextrel.c:212 src/ranlib.c:158 +#, c-format +msgid "cannot create ELF descriptor for '%s': %s" +msgstr "не вдалося створити дескриптор ELF для «%s»: %s" + +#: src/elfcmp.c:743 +#, c-format +msgid "cannot create EBL descriptor for '%s'" +msgstr "не вдалося створити дескриптор EBL для «%s»" + +#: src/elfcmp.c:761 src/findtextrel.c:394 +#, c-format +msgid "cannot get section header of section %zu: %s" +msgstr "не вдалося отримати заголовок розділу %zu: %s" + +#: src/elfcmp.c:771 +#, c-format +msgid "cannot get content of section %zu: %s" +msgstr "не вдалося отримати вміст розділу %zu: %s" + +#: src/elfcmp.c:781 src/elfcmp.c:795 +#, c-format +msgid "cannot get relocation: %s" +msgstr "не вдалося отримати пересування: %s" + +#: src/elfcompress.c:117 src/strip.c:308 src/unstrip.c:117 +#, c-format +msgid "-o option specified twice" +msgstr "параметр -o вказано двічі" + +#: src/elfcompress.c:124 +#, c-format +msgid "-t option specified twice" +msgstr "параметр -t вказано двічі" + +#: src/elfcompress.c:133 +#, c-format +msgid "unknown compression type '%s'" +msgstr "невідомий тип стиснення «%s»" + +#. We need at least one input file. +#: src/elfcompress.c:145 src/elfcompress.c:1345 +#, c-format +msgid "No input file given" +msgstr "Не надано файла вхідних даних" + +#: src/elfcompress.c:151 src/elfcompress.c:1350 +#, c-format +msgid "Only one input file allowed together with '-o'" +msgstr "З параметром «-o» можна використовувати лише один файл вхідних даних" + +#: src/elfcompress.c:1307 +msgid "Place (de)compressed output into FILE" +msgstr "Помістити результати розпакування або стискання до ФАЙЛа" + +#: src/elfcompress.c:1310 +msgid "" +"What type of compression to apply. TYPE can be 'none' (decompress), " +"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-" +"gnu' (.zdebug GNU style compression, 'gnu' is an alias)" +msgstr "" +"Визначає тип стискання, який слід застосувати. ТИПом може бути " +"«none» (розпакувати), «zlib» (стискання ELF ZLIB, типовий варіант, інша " +"назва — «zlib-gabi») або «zlib-gnu» (стискання у стилі GNU .zdebug, інша " +"назва — «gnu»)" + +#: src/elfcompress.c:1313 +msgid "" +"SECTION name to (de)compress, SECTION is an extended wildcard pattern " +"(defaults to '.?(z)debug*')" +msgstr "" +"назва РОЗДІЛу для розпакування або стискання, РОЗДІЛ є розширеним взірцем із " +"замінниками (типове значення -- «.?(z)debug*»)" + +#: src/elfcompress.c:1316 +msgid "Print a message for each section being (de)compressed" +msgstr "" +"Вивести повідомлення для кожного розділу, який розпаковується чи стискається" + +#: src/elfcompress.c:1319 +msgid "" +"Force compression of section even if it would become larger or update/" +"rewrite the file even if no section would be (de)compressed" +msgstr "" +"Примусове стискання розділу, навіть якщо він стане більшим, або оновлення чи " +"перезапис файла, навіть якщо жодного розділу не буде розпаковано або стиснено" + +#: src/elfcompress.c:1322 src/strip.c:93 +msgid "Relax a few rules to handle slightly broken ELF files" +msgstr "" +"Знехтувати декількома правилами для обробки трохи пошкоджених файлів ELF" + +#: src/elfcompress.c:1325 +msgid "Be silent when a section cannot be compressed" +msgstr "Не сповіщати, якщо розділ неможливо стиснути" + +#: src/elfcompress.c:1335 +msgid "Compress or decompress sections in an ELF file." +msgstr "Стиснути або розпакувати розділи у файлі ELF." + +#: src/elflint.c:63 +msgid "Be extremely strict, flag level 2 features." +msgstr "Висока строгість, увімкнути можливості рівня 2." + +#: src/elflint.c:64 +msgid "Do not print anything if successful" +msgstr "Не виводити ніяких даних у разі успіху" + +#: src/elflint.c:65 +msgid "Binary is a separate debuginfo file" +msgstr "Бінарний файл є окремим файлом debuginfo" + +#: src/elflint.c:67 +msgid "" +"Binary has been created with GNU ld and is therefore known to be broken in " +"certain ways" +msgstr "" +"Бінарний файл було створено за допомогою GNU ld, тому він, очевидно, є до " +"певної міри неправильним" + +#. Short description of program. +#: src/elflint.c:73 +msgid "Pedantic checking of ELF files compliance with gABI/psABI spec." +msgstr "" +"Педантична перевірка файлів ELF на сумісність зі специфікаціями gABI/psABI." + +#: src/elflint.c:154 src/readelf.c:368 +#, c-format +msgid "cannot open input file '%s'" +msgstr "не вдалося відкрити вхідний файл «%s»" + +#: src/elflint.c:161 +#, c-format +msgid "cannot generate Elf descriptor for '%s': %s\n" +msgstr "не вдалося створити дескриптор Elf для «%s»: %s\n" + +#: src/elflint.c:180 +#, c-format +msgid "error while closing Elf descriptor: %s\n" +msgstr "помилка під час спроби закриття дескриптора Elf: %s\n" + +#: src/elflint.c:184 +msgid "No errors" +msgstr "Без помилок" + +#: src/elflint.c:219 src/readelf.c:577 +msgid "Missing file name.\n" +msgstr "Не вказано назви файла.\n" + +#: src/elflint.c:284 +#, c-format +msgid " error while freeing sub-ELF descriptor: %s\n" +msgstr " помилка під час спроби вивільнення дескриптора суб-ELF: %s\n" + +#. We cannot do anything. +#: src/elflint.c:292 +#, c-format +msgid "Not an ELF file - it has the wrong magic bytes at the start\n" +msgstr "Не є файлом ELF. Виявлено помилкові магічні байти на початку файла\n" + +#: src/elflint.c:357 +#, c-format +msgid "e_ident[%d] == %d is no known class\n" +msgstr "e_ident[%d] == %d не є відомим класом\n" + +#: src/elflint.c:362 +#, c-format +msgid "e_ident[%d] == %d is no known data encoding\n" +msgstr "e_ident[%d] == %d не є відомим кодуванням даних\n" + +#: src/elflint.c:366 +#, c-format +msgid "unknown ELF header version number e_ident[%d] == %d\n" +msgstr "невідомий номер версії заголовка ELF e_ident[%d] == %d\n" + +#: src/elflint.c:374 +#, c-format +msgid "unsupported OS ABI e_ident[%d] == '%s'\n" +msgstr "непідтримуване ABI ОС e_ident[%d] == «%s»\n" + +#: src/elflint.c:380 +#, c-format +msgid "unsupported ABI version e_ident[%d] == %d\n" +msgstr "непідтримувана версія ABI e_ident[%d] == %d\n" + +#: src/elflint.c:385 +#, c-format +msgid "e_ident[%zu] is not zero\n" +msgstr "e_ident[%zu] не дорівнює нулеві\n" + +#: src/elflint.c:390 +#, c-format +msgid "unknown object file type %d\n" +msgstr "невідомий тип об’єктних файлів %d\n" + +#: src/elflint.c:397 +#, c-format +msgid "unknown machine type %d\n" +msgstr "невідомий тип архітектури %d\n" + +#: src/elflint.c:401 +#, c-format +msgid "unknown object file version\n" +msgstr "невідома версія об’єктних файлів\n" + +#: src/elflint.c:407 +#, c-format +msgid "invalid program header offset\n" +msgstr "некоректне зміщення заголовка програми\n" + +#: src/elflint.c:409 +#, c-format +msgid "executables and DSOs cannot have zero program header offset\n" +msgstr "" +"виконувані файли і DSO не можуть містити заголовка програми з нульовим " +"зміщенням\n" + +#: src/elflint.c:413 +#, c-format +msgid "invalid number of program header entries\n" +msgstr "некоректна кількість записів заголовків програми\n" + +#: src/elflint.c:421 +#, c-format +msgid "invalid section header table offset\n" +msgstr "некоректне зміщення таблиці заголовків розділів\n" + +#: src/elflint.c:424 +#, c-format +msgid "section header table must be present\n" +msgstr "має бути вказано таблицю заголовків розділів\n" + +#: src/elflint.c:438 +#, c-format +msgid "invalid number of section header table entries\n" +msgstr "некоректна кількість записів таблиці заголовків розділів\n" + +#: src/elflint.c:455 +#, c-format +msgid "invalid section header index\n" +msgstr "некоректний індекс заголовка розділу\n" + +#: src/elflint.c:473 +#, c-format +msgid "Can only check %u headers, shnum was %u\n" +msgstr "Можна перевірити лише %u заголовків, значенням же shnum було %u\n" + +#: src/elflint.c:487 +#, c-format +msgid "invalid number of program header table entries\n" +msgstr "некоректна кількість записів таблиці заголовків програми\n" + +#: src/elflint.c:504 +#, c-format +msgid "Can only check %u headers, phnum was %u\n" +msgstr "Можна перевірити лише %u заголовків, значенням же phnum було %u\n" + +#: src/elflint.c:509 +#, c-format +msgid "invalid machine flags: %s\n" +msgstr "некоректні прапорці архітектури: %s\n" + +#: src/elflint.c:516 src/elflint.c:533 +#, c-format +msgid "invalid ELF header size: %hd\n" +msgstr "некоректний розмір заголовка ELF: %hd\n" + +#: src/elflint.c:519 src/elflint.c:536 +#, c-format +msgid "invalid program header size: %hd\n" +msgstr "некоректний розмір заголовка програми: %hd\n" + +#: src/elflint.c:522 src/elflint.c:539 +#, c-format +msgid "invalid program header position or size\n" +msgstr "некоректне розташування або розмір заголовка програми\n" + +#: src/elflint.c:525 src/elflint.c:542 +#, c-format +msgid "invalid section header size: %hd\n" +msgstr "некоректний розмір заголовка розділу: %hd\n" + +#: src/elflint.c:528 src/elflint.c:545 +#, c-format +msgid "invalid section header position or size\n" +msgstr "некоректне розташування або розмір заголовка розділу\n" + +#: src/elflint.c:590 +#, c-format +msgid "" +"section [%2d] '%s': section with SHF_GROUP flag set not part of a section " +"group\n" +msgstr "" +"розділ [%2d] «%s»: розділ з встановленим прапорцем SHF_GROUP не є частиною " +"групи розділів\n" + +#: src/elflint.c:594 +#, c-format +msgid "" +"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n" +msgstr "" +"розділ [%2d] «%s»: групу розділів [%2zu] «%s» мало бути визначено до розділу-" +"елемента цієї групи\n" + +#: src/elflint.c:610 src/elflint.c:1498 src/elflint.c:1549 src/elflint.c:1655 +#: src/elflint.c:1991 src/elflint.c:2317 src/elflint.c:2943 src/elflint.c:3106 +#: src/elflint.c:3254 src/elflint.c:3456 src/elflint.c:4458 +#, c-format +msgid "section [%2d] '%s': cannot get section data\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати дані розділу\n" + +#: src/elflint.c:623 src/elflint.c:1662 +#, c-format +msgid "" +"section [%2d] '%s': referenced as string table for section [%2d] '%s' but " +"type is not SHT_STRTAB\n" +msgstr "" +"розділ [%2d] «%s»: надано посилання на таблицю рядків розділу [%2d] «%s», " +"але типом даних не є SHT_STRTAB\n" + +#: src/elflint.c:646 +#, c-format +msgid "" +"section [%2d] '%s': symbol table cannot have more than one extended index " +"section\n" +msgstr "" +"розділ [%2d] «%s»: у таблиці символів не може бути більше одного розширеного " +"розділу покажчика\n" + +#: src/elflint.c:658 +#, c-format +msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n" +msgstr "розділ [%2u] «%s»: розмірність запису не відповідає ElfXX_Sym\n" + +#: src/elflint.c:662 +#, c-format +msgid "" +"section [%2u] '%s': number of local entries in 'st_info' larger than table " +"size\n" +msgstr "" +"розділ [%2u] «%s»: кількість локальних записів у «st_info» перевищує розмір " +"таблиці\n" + +#: src/elflint.c:671 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %d: %s\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати символ %d: %s\n" + +#: src/elflint.c:676 src/elflint.c:679 src/elflint.c:682 src/elflint.c:685 +#: src/elflint.c:688 src/elflint.c:691 +#, c-format +msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n" +msgstr "розділ [%2d] «%s»: «%s» у нульовому записі не є нулем\n" + +#: src/elflint.c:694 +#, c-format +msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n" +msgstr "розділ [%2d] «%s»: XINDEX для нульового запису не є нулем\n" + +#: src/elflint.c:704 +#, c-format +msgid "section [%2d] '%s': cannot get symbol %zu: %s\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати символ %zu: %s\n" + +#: src/elflint.c:713 +#, c-format +msgid "section [%2d] '%s': symbol %zu: invalid name value\n" +msgstr "розділ [%2d] «%s»: символ %zu: некоректне значення назви\n" + +#: src/elflint.c:728 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): too large section index but no extended " +"section index section\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: занадто великий покажчик розділу за умови, що " +"не визначено розділу розширеного покажчика розділів\n" + +#: src/elflint.c:734 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit " +"in st_shndx (%)\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: XINDEX використано для індексування, яке не " +"відповідає st_shndx (%)\n" + +#. || sym->st_shndx > SHN_HIRESERVE always false +#: src/elflint.c:746 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): invalid section index\n" +msgstr "розділ [%2d] «%s»: символ %zu: некоректний індекс розділу\n" + +#: src/elflint.c:754 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown type\n" +msgstr "розділ [%2d] «%s»: символ %zu: невідомий тип\n" + +#: src/elflint.c:760 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n" +msgstr "розділ [%2d] «%s»: символ %zu: невідома прив’язка символу\n" + +#: src/elflint.c:765 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: унікальний символ, що не належить до типу " +"об’єктів\n" + +#: src/elflint.c:773 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable " +"files\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: COMMON можна використовувати лише у файлах, " +"придатних до пересування\n" + +#: src/elflint.c:777 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: використання локальних символів COMMON " +"позбавлене сенсу\n" + +#: src/elflint.c:781 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: використання функції у розділі COMMON " +"позбавлене сенсу\n" + +#: src/elflint.c:832 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: значення st_value поза можливим діапазоном\n" + +#: src/elflint.c:838 src/elflint.c:863 src/elflint.c:912 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced " +"section [%2d] '%s'\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu не повністю відповідає розділу, на який " +"посилається, [%2d] «%s»\n" + +#: src/elflint.c:847 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not " +"have SHF_TLS flag set\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: для розділу посилання [%2d] «%s» не " +"встановлено прапорець SHF_TLS\n" + +#: src/elflint.c:857 src/elflint.c:905 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced " +"section [%2d] '%s'\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: значення st_value поза межами розділу " +"посилання, [%2d] «%s»\n" + +#: src/elflint.c:884 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header " +"entry\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: символ TLS без запису заголовка програми TLS\n" + +#: src/elflint.c:890 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program " +"header entry\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: маємо символ TLS, але не вдалося отримати " +"запис заголовка програми TLS\n" + +#: src/elflint.c:898 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): st_value short of referenced section " +"[%2d] '%s'\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: значення st_value перед розділом посилання, " +"[%2d] «%s»\n" + +#: src/elflint.c:925 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): local symbol outside range described in " +"sh_info\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: у sh_info описано локальний символ поза " +"діапазоном\n" + +#: src/elflint.c:932 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): non-local symbol outside range " +"described in sh_info\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: у sh_info описано нелокальний символ поза " +"діапазоном\n" + +#: src/elflint.c:939 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): non-local section symbol\n" +msgstr "розділ [%2d] «%s»: символ %zu: нелокальний символ розділу\n" + +#: src/elflint.c:989 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section " +"[%2d]\n" +msgstr "" +"розділ [%2d] «%s»: символ _GLOBAL_OFFSET_TABLE_ посилається на помилковий " +"розділ, [%2d]\n" + +#: src/elflint.c:996 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] " +"'%s'\n" +msgstr "" +"розділ [%2d] «%s»: символ _GLOBAL_OFFSET_TABLE_ посилається на розділ [%2d] " +"'%s'\n" + +#. This test is more strict than the psABIs which +#. usually allow the symbol to be in the middle of +#. the .got section, allowing negative offsets. +#: src/elflint.c:1012 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %# does not " +"match %s section address %#\n" +msgstr "" +"розділ [%2d] «%s»: значення символу _GLOBAL_OFFSET_TABLE_ %# не " +"відповідає адресі розділу %s %#\n" + +#: src/elflint.c:1019 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size % does not " +"match %s section size %\n" +msgstr "" +"розділ [%2d] «%s»: розмір символу _GLOBAL_OFFSET_TABLE_ % не " +"відповідає розміру розділу %s %\n" + +#: src/elflint.c:1027 +#, c-format +msgid "" +"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got " +"section\n" +msgstr "" +"розділ [%2d] «%s»: виявлено символ _GLOBAL_OFFSET_TABLE_, але не виявлено " +"розділу .got\n" + +#: src/elflint.c:1043 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC_ symbol value %# does not match dynamic " +"segment address %#\n" +msgstr "" +"розділ [%2d] «%s»: значення символу _DYNAMIC_ %# не відповідає " +"адресі динамічного сегмента %#\n" + +#: src/elflint.c:1050 +#, c-format +msgid "" +"section [%2d] '%s': _DYNAMIC symbol size % does not match dynamic " +"segment size %\n" +msgstr "" +"розділ [%2d] «%s»: розмір символу _DYNAMIC % не відповідає розміру " +"динамічного сегмента %\n" + +#: src/elflint.c:1063 +#, fuzzy, c-format +msgid "" +"section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-" +"default visibility\n" +msgstr "" +"розділ [%2d] «%s»: символ %zu: символ у динамічній таблиці символів з " +"нетиповою видимістю\n" + +#: src/elflint.c:1067 +#, fuzzy, c-format +msgid "section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n" +msgstr "розділ [%2d] «%s»: символ %zu: невідомий набір бітів у st_other\n" + +#: src/elflint.c:1105 +#, c-format +msgid "section [%2d] '%s': cannot get section data.\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати дані розділу.\n" + +#: src/elflint.c:1121 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n" +msgstr "розділ [%2d] «%s»: для цього розділу RELA використано DT_RELCOUNT\n" + +#: src/elflint.c:1132 src/elflint.c:1185 +#, c-format +msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n" +msgstr "" +"розділ [%2d] «%s»: значення DT_RELCOUNT %d є занадто високим для цього " +"розділу\n" + +#: src/elflint.c:1157 src/elflint.c:1210 +#, c-format +msgid "" +"section [%2d] '%s': relative relocations after index %d as specified by " +"DT_RELCOUNT\n" +msgstr "" +"розділ [%2d] «%s»: відносні пересування після позиції %d, вказаної за " +"допомогою DT_RELCOUNT\n" + +#: src/elflint.c:1163 src/elflint.c:1216 +#, c-format +msgid "" +"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT " +"specified %d relative relocations\n" +msgstr "" +"розділ [%2d] «%s»: безвідносне пересування на позиції %zu; DT_RELCOUNT " +"визначено %d відносних пересування\n" + +#: src/elflint.c:1175 +#, c-format +msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n" +msgstr "розділ [%2d] «%s»: для цього розділу REL використано DT_RELACOUNT\n" + +#: src/elflint.c:1258 +#, c-format +msgid "section [%2d] '%s': invalid destination section index\n" +msgstr "розділ [%2d] «%s»: некоректний індекс розділу призначення\n" + +#: src/elflint.c:1270 +#, c-format +msgid "section [%2d] '%s': invalid destination section type\n" +msgstr "розділ [%2d] «%s»: некоректний тип розділу призначення\n" + +#: src/elflint.c:1278 +#, c-format +msgid "section [%2d] '%s': sh_info should be zero\n" +msgstr "розділ [%2d] «%s»: sh_info має бути нульовим\n" + +#: src/elflint.c:1286 +#, c-format +msgid "" +"section [%2d] '%s': no relocations for merge-able string sections possible\n" +msgstr "" +"розділ [%2d] «%s»: неможливі пересування для розділів рядків, які непридатні " +"до об'єднання\n" + +#: src/elflint.c:1294 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n" +msgstr "" +"розділ [%2d] «%s»: розмірність запису розділу не відповідає ElfXX_Rela\n" + +#: src/elflint.c:1354 +#, c-format +msgid "text relocation flag set but there is no read-only segment\n" +msgstr "" +"встановлено прапорець пересування тексту, але сегмент придатний лише до " +"читання\n" + +#: src/elflint.c:1381 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid type\n" +msgstr "розділ [%2d] «%s»: пересування %zu: некоректний тип\n" + +#: src/elflint.c:1389 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: relocation type invalid for the file " +"type\n" +msgstr "" +"розділ [%2d] «%s»: пересування %zu: некоректний тип пересування для типу " +"файла\n" + +#: src/elflint.c:1397 +#, c-format +msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n" +msgstr "розділ [%2d] «%s»: пересування %zu: некоректний індекс символу\n" + +#: src/elflint.c:1415 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can " +"be used with %s\n" +msgstr "" +"розділ [%2d] «%s»: пересування %zu: з %s можна використовувати лише символ " +"«_GLOBAL_OFFSET_TABLE_»\n" + +#: src/elflint.c:1432 +#, c-format +msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n" +msgstr "розділ [%2d] «%s»: пересування %zu: зміщення за межі діапазону\n" + +#: src/elflint.c:1447 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: copy relocation against symbol of type " +"%s\n" +msgstr "" +"розділ [%2d] «%s»: пересування %zu: пересування копіювання для символу типу " +"%s\n" + +#: src/elflint.c:1468 +#, c-format +msgid "" +"section [%2d] '%s': relocation %zu: read-only section modified but text " +"relocation flag not set\n" +msgstr "" +"розділ [%2d] «%s»: пересування %zu: змінено придатний лише для читання " +"розділ, але не встановлено прапорець пересування тексту\n" + +#: src/elflint.c:1483 +#, c-format +msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n" +msgstr "розділ [%2d] «%s»: пересування завантажених і незавантажених даних\n" + +#: src/elflint.c:1523 src/elflint.c:1574 +#, c-format +msgid "section [%2d] '%s': cannot get relocation %zu: %s\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати зміщення %zu: %s\n" + +#: src/elflint.c:1650 +#, c-format +msgid "more than one dynamic section present\n" +msgstr "вказано більше одного динамічного розділу\n" + +#: src/elflint.c:1668 +#, c-format +msgid "" +"section [%2d]: referenced as string table for section [%2d] '%s' but section " +"link value is invalid\n" +msgstr "" +"розділ [%2d]: надано посилання на таблицю рядків розділу [%2d] «%s», але " +"значення посилання на розділ є некоректним\n" + +#: src/elflint.c:1676 +#, c-format +msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n" +msgstr "" +"розділ [%2d] «%s»: розмірність запису розділу не відповідає ElfXX_Dyn\n" + +#: src/elflint.c:1681 src/elflint.c:1970 +#, c-format +msgid "section [%2d] '%s': sh_info not zero\n" +msgstr "розділ [%2d] «%s»: sh_info не є нульовим\n" + +#: src/elflint.c:1691 +#, c-format +msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n" +msgstr "" +"розділ [%2d] «%s»: не вдалося отримати запис динамічного розділу %zu: %s\n" + +#: src/elflint.c:1699 +#, c-format +msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n" +msgstr "" +"розділ [%2d] «%s»: за записом DT_NULL вказано записи, що не належать до " +"DT_NULL\n" + +#: src/elflint.c:1706 +#, c-format +msgid "section [%2d] '%s': entry %zu: unknown tag\n" +msgstr "розділ [%2d] «%s»: запис %zu: невідома мітка\n" + +#: src/elflint.c:1717 +#, c-format +msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n" +msgstr "розділ [%2d] «%s»: запис %zu: декілька записів з міткою %s\n" + +#: src/elflint.c:1727 +#, c-format +msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n" +msgstr "розділ [%2d] «%s»: запис %zu: використано мітку рівня 2 %s\n" + +#: src/elflint.c:1745 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n" +msgstr "" +"розділ [%2d] «%s»: запис %zu: значенням DT_PLTREL має бути DT_REL або " +"DT_RELA\n" + +#: src/elflint.c:1758 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: pointer does not match address of section " +"[%2d] '%s' referenced by sh_link\n" +msgstr "" +"розділ [%2d] «%s»: розділ %zu: вказівник не відповідає адресі розділу [%2d] " +"«%s», на яку посилається sh_link\n" + +#: src/elflint.c:1801 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n" +msgstr "" +"розділ [%2d] «%s»: запис %zu: значення %s має вказувати на завантажений " +"сегмент\n" + +#: src/elflint.c:1816 +#, c-format +msgid "" +"section [%2d] '%s': entry %zu: %s value must be valid offset in section " +"[%2d] '%s'\n" +msgstr "" +"розділ [%2d] «%s»: запис %zu: значенням %s має бути коректне зміщення у " +"розділі [%2d] «%s»\n" + +#: src/elflint.c:1836 src/elflint.c:1864 +#, c-format +msgid "section [%2d] '%s': contains %s entry but not %s\n" +msgstr "розділ [%2d] «%s»: містить запис %s, але не %s\n" + +#: src/elflint.c:1848 +#, c-format +msgid "section [%2d] '%s': mandatory tag %s not present\n" +msgstr "розділ [%2d] «%s»: немає обов’язкової мітки %s\n" + +#: src/elflint.c:1857 +#, c-format +msgid "section [%2d] '%s': no hash section present\n" +msgstr "розділ [%2d] «%s»: не виявлено розділу хешів\n" + +#: src/elflint.c:1872 src/elflint.c:1879 +#, c-format +msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n" +msgstr "розділ [%2d] «%s»: вказано не всі зі значень %s, %s і %s\n" + +#: src/elflint.c:1889 src/elflint.c:1893 +#, c-format +msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n" +msgstr "" +"розділ [%2d] «%s»: у DSO, позначеному на кроці попереднього компонування, " +"немає мітки %s\n" + +#: src/elflint.c:1899 +#, c-format +msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n" +msgstr "" +"розділ [%2d] «%s»: під час попереднього компонування як залежність позначено " +"файл, який не є файлом DSO\n" + +#: src/elflint.c:1910 src/elflint.c:1914 src/elflint.c:1918 src/elflint.c:1922 +#, c-format +msgid "section [%2d] '%s': %s tag missing in prelinked executable\n" +msgstr "" +"розділ [%2d] «%s»: у попередньо скомпонованому виконуваному файлі не " +"міститься мітки %s\n" + +#: src/elflint.c:1934 +#, c-format +msgid "" +"section [%2d] '%s': only relocatable files can have extended section index\n" +msgstr "" +"розділ [%2d] «%s»: розширений розділ покажчика можуть мати лише файли, " +"придатні до пересування\n" + +#: src/elflint.c:1944 +#, c-format +msgid "" +"section [%2d] '%s': extended section index section not for symbol table\n" +msgstr "" +"розділ [%2d] «%s»: розділ розширеного покажчика розділів не призначено для " +"таблиць символів\n" + +#: src/elflint.c:1948 +#, c-format +msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n" +msgstr "" +"розділ [%2d] «%s»: індекс розширеного розділу sh_link [%2d] є некоректним\n" + +#: src/elflint.c:1953 +#, c-format +msgid "cannot get data for symbol section\n" +msgstr "не вдалося отримати дані для розділу символів\n" + +#: src/elflint.c:1956 +#, c-format +msgid "section [%2d] '%s': entry size does not match Elf32_Word\n" +msgstr "розділ [%2d] «%s»: розмірність запису не відповідає Elf32_Word\n" + +#: src/elflint.c:1965 +#, c-format +msgid "section [%2d] '%s': extended index table too small for symbol table\n" +msgstr "" +"розділ [%2d] «%s»: розширена таблиця покажчика замала для таблиці символів\n" + +#: src/elflint.c:1980 +#, c-format +msgid "" +"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to " +"same symbol table\n" +msgstr "" +"розділ [%2d] «%s»: розширений покажчик розділів у розділі [%2zu] «%s» " +"посилається на ту саму таблицю розділів\n" + +#: src/elflint.c:1998 +#, c-format +msgid "symbol 0 should have zero extended section index\n" +msgstr "символу 0 має відповідати нульовий індекс розширеного розділу\n" + +#: src/elflint.c:2010 +#, c-format +msgid "cannot get data for symbol %zu\n" +msgstr "не вдалося отримати дані для символу %zu\n" + +#: src/elflint.c:2015 +#, c-format +msgid "extended section index is % but symbol index is not XINDEX\n" +msgstr "" +"індекс розширеного розділу дорівнює %, але індекс символу не є " +"XINDEX\n" + +#: src/elflint.c:2032 src/elflint.c:2089 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n" +msgstr "" +"розділ [%2d] «%s»: розділ таблиці хешів занадто малий (розмір %ld, мало бути " +"— %ld)\n" + +#: src/elflint.c:2046 src/elflint.c:2103 +#, c-format +msgid "section [%2d] '%s': chain array too large\n" +msgstr "розділ [%2d] «%s»: масив ланцюжка занадто великий\n" + +#: src/elflint.c:2060 src/elflint.c:2117 +#, c-format +msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n" +msgstr "" +"розділ [%2d] «%s»: посилання на хеш блоку %zu лежить поза межами діапазону\n" + +#: src/elflint.c:2070 +#, c-format +msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n" +msgstr "" +"розділ [%2d] «%s»: посилання ланцюжка хешів %zu лежить поза межами " +"діапазону\n" + +#: src/elflint.c:2127 +#, c-format +msgid "section [%2d] '%s': hash chain reference % out of bounds\n" +msgstr "" +"розділ [%2d] «%s»: посилання ланцюжка хешів % лежить поза межами " +"діапазону\n" + +#: src/elflint.c:2140 +#, c-format +msgid "section [%2d] '%s': not enough data\n" +msgstr "розділ [%2d] «%s»: недостатньо даних\n" + +#: src/elflint.c:2152 +#, c-format +msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n" +msgstr "" +"розділ [%2d] «%s»: розмір бітової маски є нульовим або не є степенем 2: %u\n" + +#: src/elflint.c:2168 +#, c-format +msgid "" +"section [%2d] '%s': hash table section is too small (is %ld, expected at " +"least %ld)\n" +msgstr "" +"розділ [%2d] «%s»: розділ таблиці хешів є надто малим (маємо %ld, мало бути " +"принаймні %ld)\n" + +#: src/elflint.c:2177 +#, c-format +msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n" +msgstr "розділ [%2d] «%s»: зсув 2-ої функції хешування занадто великий: %u\n" + +#: src/elflint.c:2211 +#, c-format +msgid "" +"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n" +msgstr "" +"розділ [%2d] '%s': ланцюжок хешів для блоку %zu розташовано нижче за позицію " +"відхилення індексу символу\n" + +#: src/elflint.c:2232 +#, c-format +msgid "" +"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is " +"undefined\n" +msgstr "" +"розділ [%2d] «%s»: символ %u, на який посилається ланцюжок у блоці %zu не " +"визначено\n" + +#: src/elflint.c:2245 +#, c-format +msgid "" +"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"розділ [%2d] «%s»: значення хешу для символу %u у ланцюжку для блоку %zu є " +"помилковим\n" + +#: src/elflint.c:2254 +#, c-format +msgid "" +"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n" +msgstr "" +"розділ [%2d] «%s»: індекс маски для символу %u у ланцюжку для блоку %zu є " +"помилковим\n" + +#: src/elflint.c:2284 +#, c-format +msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n" +msgstr "" +"розділ [%2d] «%s»: ланцюжок хешів для блоку %zu лежить поза межами " +"діапазону\n" + +#: src/elflint.c:2289 +#, c-format +msgid "" +"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n" +msgstr "" +"розділ [%2d] «%s»: посилання на символ у ланцюжку для блоку %zu лежить поза " +"межами діапазону\n" + +#: src/elflint.c:2295 +#, c-format +msgid "section [%2d] '%s': bitmask does not match names in the hash table\n" +msgstr "розділ [%2d] «%s»: бітова маска не відповідає назвам у таблиці хешів\n" + +#: src/elflint.c:2308 +#, c-format +msgid "section [%2d] '%s': relocatable files cannot have hash tables\n" +msgstr "" +"розділ [%2d] «%s»: придатні до пересування файли не можуть містити таблиць " +"хешів\n" + +#: src/elflint.c:2326 +#, c-format +msgid "section [%2d] '%s': hash table not for dynamic symbol table\n" +msgstr "" +"розділ [%2d] «%s»: таблицю хешів не призначено для зберігання таблиці " +"динамічних символів\n" + +#: src/elflint.c:2330 +#, c-format +msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n" +msgstr "" +"розділ [%2d] «%s»: некоректний індекс розділу таблиці символів sh_link " +"[%2d]\n" + +#: src/elflint.c:2340 +#, c-format +msgid "section [%2d] '%s': hash table entry size incorrect\n" +msgstr "розділ [%2d] «%s»: розмірність запису таблиці хешів є некоректною\n" + +#: src/elflint.c:2345 +#, c-format +msgid "section [%2d] '%s': not marked to be allocated\n" +msgstr "розділ [%2d] «%s»: не позначено для пересування\n" + +#: src/elflint.c:2350 +#, c-format +msgid "" +"section [%2d] '%s': hash table has not even room for initial administrative " +"entries\n" +msgstr "" +"розділ [%2d] «%s»: у таблиці хешів виявлено незвичайне розташування " +"початкових адміністративних записів\n" + +#: src/elflint.c:2399 +#, c-format +msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n" +msgstr "sh_link у розділах хешів [%2zu] «%s» і [%2zu] «%s» не збігаються\n" + +#: src/elflint.c:2423 src/elflint.c:2488 src/elflint.c:2523 +#, c-format +msgid "hash section [%2zu] '%s' does not contain enough data\n" +msgstr "розділ хешу [%2zu] «%s» містить недостатньо даних\n" + +#: src/elflint.c:2444 +#, c-format +msgid "hash section [%2zu] '%s' has zero bit mask words\n" +msgstr "розділ хешу [%2zu] «%s» містить нульові слова бітової маски\n" + +#: src/elflint.c:2455 src/elflint.c:2499 src/elflint.c:2536 +#, c-format +msgid "hash section [%2zu] '%s' uses too much data\n" +msgstr "розділ хешу [%2zu] «%s» використовує надто багато даних\n" + +#: src/elflint.c:2470 +#, c-format +msgid "" +"hash section [%2zu] '%s' invalid symbol index % (max_nsyms: " +"%, nentries: %\n" +msgstr "" +"розділ хешу [%2zu] «%s» некоректний індекс символу % (макс. к-ть " +"символів: %, кількість записів: %\n" + +#: src/elflint.c:2557 +#, c-format +msgid "hash section [%2zu] '%s' invalid sh_entsize\n" +msgstr "розділ хешу [%2zu] «%s» некоректне значення sh_entsize\n" + +#: src/elflint.c:2567 src/elflint.c:2571 +#, c-format +msgid "section [%2zu] '%s': reference to symbol index 0\n" +msgstr "розділ [%2zu] «%s»: посилання на індекс символів 0\n" + +#: src/elflint.c:2578 +#, c-format +msgid "" +"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash " +"table in [%2zu] '%s'\n" +msgstr "" +"виявлено посилання на символ %d у новій таблиці хешів у [%2zu] «%s», але " +"його немає у старій таблиці хешів у [%2zu] «%s»\n" + +#: src/elflint.c:2590 +#, c-format +msgid "" +"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash " +"table in [%2zu] '%s'\n" +msgstr "" +"виявлено посилання на символ %d у старій таблиці хешів у [%2zu] «%s», але " +"його немає у новій таблиці хешів у [%2zu] «%s»\n" + +#: src/elflint.c:2606 +#, c-format +msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n" +msgstr "розділ [%2d] «%s»: ненульове значення sh_%s для розділу NULL\n" + +#: src/elflint.c:2626 +#, c-format +msgid "" +"section [%2d] '%s': section groups only allowed in relocatable object files\n" +msgstr "" +"розділ [%2d] «%s»: групи розділів передбачено лише для придатних до " +"пересування об’єктних файлах\n" + +#: src/elflint.c:2637 +#, c-format +msgid "section [%2d] '%s': cannot get symbol table: %s\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати таблицю символів: %s\n" + +#: src/elflint.c:2642 +#, c-format +msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n" +msgstr "" +"розділ [%2d] «%s»: посилання на розділ у sh_link не має таблиці символів\n" + +#: src/elflint.c:2648 +#, c-format +msgid "section [%2d] '%s': invalid symbol index in sh_info\n" +msgstr "розділ [%2d] «%s»: некоректний індекс символу у sh_info\n" + +#: src/elflint.c:2653 +#, c-format +msgid "section [%2d] '%s': sh_flags not zero\n" +msgstr "розділ [%2d] «%s»: sh_flags не є нульовим\n" + +#: src/elflint.c:2660 +#, c-format +msgid "section [%2d] '%s': cannot get symbol for signature\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати символ для підпису\n" + +#: src/elflint.c:2664 +#, c-format +msgid "section [%2d] '%s': cannot get symbol name for signature\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати назву символу для підпису\n" + +#: src/elflint.c:2669 +#, c-format +msgid "section [%2d] '%s': signature symbol cannot be empty string\n" +msgstr "розділ [%2d] «%s»: символ підпису не може бути порожнім рядком\n" + +#: src/elflint.c:2675 +#, c-format +msgid "section [%2d] '%s': sh_flags not set correctly\n" +msgstr "розділ [%2d] «%s»: для sh_flags встановлено помилкове значення\n" + +#: src/elflint.c:2681 +#, c-format +msgid "section [%2d] '%s': cannot get data: %s\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати дані: %s\n" + +#: src/elflint.c:2690 +#, c-format +msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n" +msgstr "розділ [%2d] «%s»: розмір розділу не є кратним до sizeof(Elf32_Word)\n" + +#: src/elflint.c:2696 +#, c-format +msgid "section [%2d] '%s': section group without flags word\n" +msgstr "розділ [%2d] «%s»: група розділів без значення типу word прапорців\n" + +#: src/elflint.c:2704 +#, c-format +msgid "section [%2d] '%s': section group without member\n" +msgstr "розділ [%2d] «%s»: група розділів без елементів\n" + +#: src/elflint.c:2708 +#, c-format +msgid "section [%2d] '%s': section group with only one member\n" +msgstr "розділ [%2d] «%s»: група розділів, що містить лише один елемент\n" + +#: src/elflint.c:2719 +#, c-format +msgid "section [%2d] '%s': unknown section group flags\n" +msgstr "розділ [%2d] «%s»: невідомі прапорці групи розділів\n" + +#: src/elflint.c:2731 +#, c-format +msgid "section [%2d] '%s': section index %zu out of range\n" +msgstr "розділ [%2d] «%s»: індекс розділу %zu поза межами діапазону\n" + +#: src/elflint.c:2740 +#, c-format +msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n" +msgstr "" +"розділ [%2d] «%s»: не вдалося отримати заголовок розділу для елемента %zu: " +"%s\n" + +#: src/elflint.c:2747 +#, c-format +msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n" +msgstr "розділ [%2d] «%s»: група розділів містить іншу групу [%2d] «%s»\n" + +#: src/elflint.c:2753 +#, c-format +msgid "" +"section [%2d] '%s': element %zu references section [%2d] '%s' without " +"SHF_GROUP flag set\n" +msgstr "" +"розділ [%2d] «%s»: елемент %zu посилається на розділ [%2d] «%s» без " +"встановленого прапорця SHF_GROUP\n" + +#: src/elflint.c:2760 +#, c-format +msgid "section [%2d] '%s' is contained in more than one section group\n" +msgstr "розділ [%2d] «%s» міститься у більше ніж одній групі розділів\n" + +#: src/elflint.c:2957 +#, c-format +msgid "" +"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no " +"dynamic symbol table\n" +msgstr "" +"розділ [%2d] «%s» посилається у sh_link на розділ [%2d] «%s», який не має " +"динамічної таблиці символів\n" + +#: src/elflint.c:2969 +#, c-format +msgid "" +"section [%2d] '%s' has different number of entries than symbol table [%2d] " +"'%s'\n" +msgstr "" +"кількість записів у розділі [%2d] «%s» відрізняється від кількості у таблиці " +"символів [%2d] «%s»\n" + +#: src/elflint.c:2985 +#, c-format +msgid "section [%2d] '%s': symbol %d: cannot read version data\n" +msgstr "розділ [%2d] «%s»: символ %d: не вдалося прочитати дані щодо версії\n" + +#: src/elflint.c:3001 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n" +msgstr "" +"розділ [%2d] «%s»: символ %d: локальний символ у загальному контексті\n" + +#: src/elflint.c:3009 +#, c-format +msgid "section [%2d] '%s': symbol %d: local symbol with version\n" +msgstr "розділ [%2d] «%s»: символ %d: локальний символ з версією\n" + +#: src/elflint.c:3023 +#, c-format +msgid "section [%2d] '%s': symbol %d: invalid version index %d\n" +msgstr "розділ [%2d] «%s»: символ %d: некоректний індекс версії %d\n" + +#: src/elflint.c:3028 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for defined version\n" +msgstr "" +"розділ [%2d] «%s»: символ %d: індекси версії %d призначено до визначеної " +"версії\n" + +#: src/elflint.c:3038 +#, c-format +msgid "" +"section [%2d] '%s': symbol %d: version index %d is for requested version\n" +msgstr "" +"розділ [%2d] «%s»: символ %d: індекс версії %d призначено для версії, на яку " +"надійшов запит\n" + +#: src/elflint.c:3091 +#, c-format +msgid "more than one version reference section present\n" +msgstr "виявлено більше за один розділ посилань на версії\n" + +#: src/elflint.c:3099 src/elflint.c:3246 +#, c-format +msgid "section [%2d] '%s': sh_link does not link to string table\n" +msgstr "розділ [%2d] «%s»: sh_link не посилається на таблицю рядків\n" + +#: src/elflint.c:3124 src/elflint.c:3300 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong version %d\n" +msgstr "розділ [%2d] «%s»: запис %d має помилкову версію %d\n" + +#: src/elflint.c:3131 src/elflint.c:3307 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n" +msgstr "" +"розділ [%2d] «%s»: запис %d містить помилкове зміщення у допоміжних даних\n" + +#: src/elflint.c:3141 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid file reference\n" +msgstr "розділ [%2d] «%s»: запис %d містить некоректне посилання на файл\n" + +#: src/elflint.c:3149 +#, c-format +msgid "section [%2d] '%s': entry %d references unknown dependency\n" +msgstr "розділ [%2d] «%s»: запис %d посилається на невідому залежність\n" + +#: src/elflint.c:3161 +#, c-format +msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n" +msgstr "" +"розділ [%2d] «%s»: допоміжний запис %d запису %d позначено невідомим " +"прапорцем\n" + +#: src/elflint.c:3169 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name " +"reference\n" +msgstr "" +"розділ [%2d] «%s»: допоміжний запис %d запису %d містить некоректне " +"посилання на назву\n" + +#: src/elflint.c:3178 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: " +"%#x, expected %#x\n" +msgstr "" +"розділ [%2d] «%s»: допоміжний запис %d запису %d має помилкове значення " +"хешу: %#x, мало бути %#x\n" + +#: src/elflint.c:3187 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version " +"name '%s'\n" +msgstr "" +"розділ [%2d] «%s»: допоміжний запис %d запису %d містить дублікати назви " +"версії «%s»\n" + +#: src/elflint.c:3198 +#, c-format +msgid "" +"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n" +msgstr "" +"розділ [%2d] «%s»: допоміжний запис %d запису %d має помилкове наступне " +"поле\n" + +#: src/elflint.c:3215 src/elflint.c:3391 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n" +msgstr "" +"розділ [%2d] «%s»: запис %d має некоректне зміщення щодо наступного запису\n" + +#: src/elflint.c:3223 src/elflint.c:3399 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says " +"there are more entries\n" +msgstr "" +"розділ [%2d] «%s»: запис %d має нульове зміщення щодо наступного запису, але " +"за sh_info можна зрозуміти, що записів більше\n" + +#: src/elflint.c:3238 +#, c-format +msgid "more than one version definition section present\n" +msgstr "виявлено більше за один розділ визначення версій\n" + +#: src/elflint.c:3285 +#, c-format +msgid "section [%2d] '%s': more than one BASE definition\n" +msgstr "розділ [%2d] «%s»: повторне визначення BASE\n" + +#: src/elflint.c:3289 +#, c-format +msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n" +msgstr "" +"розділ [%2d] «%s»: визначення BASE повинно мати індекс VER_NDX_GLOBAL\n" + +#: src/elflint.c:3295 +#, c-format +msgid "section [%2d] '%s': entry %d has unknown flag\n" +msgstr "розділ [%2d] «%s»: невідомий прапорець запису %d\n" + +#: src/elflint.c:3322 +#, c-format +msgid "section [%2d] '%s': entry %d has invalid name reference\n" +msgstr "розділ [%2d] «%s»: запис %d містить некоректне посилання на назву\n" + +#: src/elflint.c:3329 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n" +msgstr "" +"розділ [%2d] «%s»: запис %d має помилкове значення хешу: %#x, мало бути %#x\n" + +#: src/elflint.c:3337 +#, c-format +msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n" +msgstr "розділ [%2d] «%s»: запис %d містить дублікати назви версії «%s»\n" + +#: src/elflint.c:3357 +#, c-format +msgid "" +"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n" +msgstr "" +"розділ [%2d] «%s»: запис %d містить некоректне посилання на назву у " +"допоміжних даних\n" + +#: src/elflint.c:3374 +#, c-format +msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n" +msgstr "" +"розділ [%2d] «%s»: у допоміжних даних запису %d міститься помилкове поле " +"наступного запису\n" + +#: src/elflint.c:3407 +#, c-format +msgid "section [%2d] '%s': no BASE definition\n" +msgstr "розділ [%2d] «%s»: немає визначення BASE\n" + +#: src/elflint.c:3423 +#, c-format +msgid "section [%2d] '%s': unknown parent version '%s'\n" +msgstr "розділ [%2d] «%s»: невідома основна версія «%s»\n" + +#: src/elflint.c:3448 +#, c-format +msgid "section [%2d] '%s': empty object attributes section\n" +msgstr "розділ [%2d] «%s»: порожній розділ атрибутів об’єкта\n" + +#: src/elflint.c:3464 +#, c-format +msgid "section [%2d] '%s': unrecognized attribute format\n" +msgstr "розділ [%2d] «%s»: не вдалося визначити формат атрибутів\n" + +#: src/elflint.c:3475 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute section\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: поле нульового розміру у розділі атрибутів\n" + +#: src/elflint.c:3484 +#, c-format +msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: некоректна довжина у розділі атрибутів\n" + +#: src/elflint.c:3496 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: незавершений рядок назви постачальника\n" + +#: src/elflint.c:3513 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: незавершене поле ULEB128 у тезі підрозділу " +"атрибутів\n" + +#: src/elflint.c:3522 +#, c-format +msgid "section [%2d] '%s': offset %zu: truncated attribute section\n" +msgstr "розділ [%2d] «%s»: зміщення %zu: обрізаний розділ атрибутів\n" + +#: src/elflint.c:3531 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: поле нульового розміру у підрозділі " +"атрибутів\n" + +#: src/elflint.c:3546 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: некоректна довжина у підрозділі атрибутів\n" + +#. Tag_File +#: src/elflint.c:3557 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: підрозділ атрибутів містить неочікуваний " +"теґ %u\n" + +#: src/elflint.c:3575 +#, c-format +msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: незавершене поле ULEB128 у тезі атрибуту\n" + +#: src/elflint.c:3586 +#, c-format +msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n" +msgstr "розділ [%2d] «%s»: зміщення %zu: незавершений рядок у атрибуті\n" + +#: src/elflint.c:3599 +#, c-format +msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n" +msgstr "розділ [%2d] «%s»: зміщення %zu: незавершений теґ атрибуту %u\n" + +#: src/elflint.c:3603 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: unrecognized %s attribute value %\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: невідоме значення %s атрибуту %\n" + +#: src/elflint.c:3613 +#, c-format +msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n" +msgstr "розділ [%2d] «%s»: зміщення %zu: невідомий постачальник «%s»\n" + +#: src/elflint.c:3619 +#, c-format +msgid "" +"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n" +msgstr "" +"розділ [%2d] «%s»: зміщення %zu: зайві байти після останнього розділу " +"атрибутів\n" + +#: src/elflint.c:3716 +#, c-format +msgid "cannot get section header of zeroth section\n" +msgstr "не вдалося отримати заголовок нульового розділу\n" + +#: src/elflint.c:3720 +#, c-format +msgid "zeroth section has nonzero name\n" +msgstr "нульовий розділ має ненульову назву\n" + +#: src/elflint.c:3722 +#, c-format +msgid "zeroth section has nonzero type\n" +msgstr "нульовий розділ має ненульовий тип\n" + +#: src/elflint.c:3724 +#, c-format +msgid "zeroth section has nonzero flags\n" +msgstr "нульовий розділ має ненульові прапорці\n" + +#: src/elflint.c:3726 +#, c-format +msgid "zeroth section has nonzero address\n" +msgstr "нульовий розділ має ненульову адресу\n" + +#: src/elflint.c:3728 +#, c-format +msgid "zeroth section has nonzero offset\n" +msgstr "нульовий розділ має ненульове зміщення\n" + +#: src/elflint.c:3730 +#, c-format +msgid "zeroth section has nonzero align value\n" +msgstr "нульовий розділ має ненульове значення вирівнювання\n" + +#: src/elflint.c:3732 +#, c-format +msgid "zeroth section has nonzero entry size value\n" +msgstr "нульовий розділ має ненульове значення розміру запису\n" + +#: src/elflint.c:3735 +#, c-format +msgid "" +"zeroth section has nonzero size value while ELF header has nonzero shnum " +"value\n" +msgstr "" +"нульовий розділ має ненульове значення розміру, хоча заголовок ELF ман " +"ненульове значення shnum\n" + +#: src/elflint.c:3739 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in shstrndx\n" +msgstr "" +"нульовий розділ має ненульове значення компонування, хоча у заголовку ELF " +"немає сигналу переповнення у shstrndx\n" + +#: src/elflint.c:3743 +#, c-format +msgid "" +"zeroth section has nonzero link value while ELF header does not signal " +"overflow in phnum\n" +msgstr "" +"нульовий розділ має ненульове значення компонування, хоча у заголовку ELF " +"немає сигналу переповнення у phnum\n" + +#: src/elflint.c:3761 +#, c-format +msgid "cannot get section header for section [%2zu] '%s': %s\n" +msgstr "не вдалося отримати заголовок розділу [%2zu] «%s»: %s\n" + +#: src/elflint.c:3770 +#, c-format +msgid "section [%2zu]: invalid name\n" +msgstr "розділ [%2zu]: некоректна назва\n" + +#: src/elflint.c:3797 +#, c-format +msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n" +msgstr "" +"розділ [%2d] «%s» належить до помилкового типу: мав бути %s, маємо %s\n" + +#: src/elflint.c:3814 +#, c-format +msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n" +msgstr "розділ [%2zu] «%s» має помилкові прапорці: мало бути %s, маємо %s\n" + +#: src/elflint.c:3832 +#, c-format +msgid "" +"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n" +msgstr "" +"розділ [%2zu] «%s» має помилкові прапорці: мало бути %s, можливо, %s, але " +"маємо %s\n" + +#: src/elflint.c:3849 +#, c-format +msgid "section [%2zu] '%s' present in object file\n" +msgstr "у об’єктному файлі виявлено розділ [%2zu] «%s»\n" + +#: src/elflint.c:3855 src/elflint.c:3887 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n" +msgstr "" +"у розділ [%2zu] «%s» встановлено прапорець SHF_ALLOC, але немає придатного " +"до завантаження сегмента\n" + +#: src/elflint.c:3860 src/elflint.c:3892 +#, c-format +msgid "" +"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable " +"segments\n" +msgstr "" +"у розділі [%2zu] «%s» не встановлено прапорець SHF_ALLOC, але є придатні до " +"завантаження сегменти\n" + +#: src/elflint.c:3868 +#, c-format +msgid "" +"section [%2zu] '%s' is extension section index table in non-object file\n" +msgstr "" +"розділ [%2zu] «%s» є таблицею-покажчиком розділу розширень у файлі, який не " +"є об’єктним\n" + +#: src/elflint.c:3911 +#, c-format +msgid "section [%2zu] '%s': size not multiple of entry size\n" +msgstr "розділ [%2zu] «%s»: розмір не є кратним до розміру запису\n" + +#: src/elflint.c:3916 +#, c-format +msgid "cannot get section header\n" +msgstr "не вдалося отримати заголовок розділу\n" + +#: src/elflint.c:3926 +#, c-format +msgid "section [%2zu] '%s' has unsupported type %d\n" +msgstr "розділ [%2zu] «%s» належить до непідтримуваного типу %d\n" + +#: src/elflint.c:3946 +#, c-format +msgid "" +"section [%2zu] '%s' contains invalid processor-specific flag(s) %#\n" +msgstr "" +"розділ [%2zu] «%s» містить некоректні специфічні для процесора прапорці " +"%#\n" + +#: src/elflint.c:3956 +#, c-format +msgid "section [%2zu] '%s' contains unknown flag(s) %#\n" +msgstr "розділ [%2zu] «%s» містить невідомі прапорці %#\n" + +#: src/elflint.c:3964 +#, c-format +msgid "section [%2zu] '%s': thread-local data sections address not zero\n" +msgstr "" +"розділ [%2zu] «%s»: адреса розділів локальних даних потоків не є нульовою\n" + +#: src/elflint.c:3974 +#, c-format +msgid "section [%2zu] '%s': allocated section cannot be compressed\n" +msgstr "" +"розділ [%2zu] «%s»: розміщений у пам'яті розділ не може бути стиснений\n" + +#: src/elflint.c:3979 +#, c-format +msgid "section [%2zu] '%s': nobits section cannot be compressed\n" +msgstr "розділ [%2zu] «%s»: розділ nobits не може бути стиснений\n" + +#: src/elflint.c:3985 +#, c-format +msgid "" +"section [%2zu] '%s': compressed section with no compression header: %s\n" +msgstr "розділ [%2zu] «%s»: стиснений розділ без заголовка стиснення: %s\n" + +#: src/elflint.c:3991 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in link value\n" +msgstr "" +"розділ [%2zu] «%s»: некоректне посилання на розділ у значенні компонування\n" + +#: src/elflint.c:3996 +#, c-format +msgid "section [%2zu] '%s': invalid section reference in info value\n" +msgstr "" +"розділ [%2zu] «%s»: некоректне посилання на розділ у значенні відомостей\n" + +#: src/elflint.c:4003 +#, c-format +msgid "section [%2zu] '%s': strings flag set without merge flag\n" +msgstr "розділ [%2zu] «%s»: встановлено прапорець strings без прапорця merge\n" + +#: src/elflint.c:4008 +#, c-format +msgid "section [%2zu] '%s': merge flag set but entry size is zero\n" +msgstr "" +"розділ [%2zu] «%s»: встановлено прапорець merge, але розмір запису є " +"нульовим\n" + +#: src/elflint.c:4027 +#, c-format +msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n" +msgstr "розділ [%2zu] «%s» має неочікуваний тип %d для виконуваного розділу\n" + +#: src/elflint.c:4036 +#, c-format +msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n" +msgstr "розділ [%2zu] «%s» у файлах debuginfo має належати до типу NOBITS\n" + +#: src/elflint.c:4043 +#, c-format +msgid "section [%2zu] '%s' is both executable and writable\n" +msgstr "розділ [%2zu] «%s» є одночасно виконуваним і придатним до запису\n" + +#: src/elflint.c:4074 +#, c-format +msgid "" +"section [%2zu] '%s' not fully contained in segment of program header entry " +"%d\n" +msgstr "" +"розділ [%2zu] «%s» не повністю міститься у сегменті запису заголовка " +"програми %d\n" + +#: src/elflint.c:4084 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d\n" +msgstr "" +"розділ [%2zu] «%s» належить до типу NOBITS, але його читання виконується з " +"файла у сегментів запису заголовка програми %d\n" + +#: src/elflint.c:4110 +#, c-format +msgid "" +"section [%2zu] '%s' has type NOBITS but is read from the file in segment of " +"program header entry %d and file contents is non-zero\n" +msgstr "" +"розділ [%2zu] «%s» належить до типу NOBITS, але його читання виконується з " +"файла у сегментів запису заголовка програми %d, а вміст файла є ненульовим\n" + +#: src/elflint.c:4121 +#, c-format +msgid "" +"section [%2zu] '%s' has not type NOBITS but is not read from the file in " +"segment of program header entry %d\n" +msgstr "" +"розділ [%2zu] «%s» не належить до типу NOBITS, але його читання не " +"виконується з файла у сегментів запису заголовка програми %d\n" + +#: src/elflint.c:4132 +#, c-format +msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n" +msgstr "розділ [%2zu] «%s» є виконуваним у невиконуваному сегменті %d\n" + +#: src/elflint.c:4142 +#, c-format +msgid "section [%2zu] '%s' is writable in unwritable segment %d\n" +msgstr "" +"розділ [%2zu] «%s» є придатним до запису у непридатному до запису сегменті " +"%d\n" + +#: src/elflint.c:4152 +#, c-format +msgid "" +"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n" +msgstr "" +"розділ [%2zu] «%s»: встановлено прапорець alloc, але розділ не перебуває у " +"жодному завантаженому сегменті\n" + +#: src/elflint.c:4158 +#, c-format +msgid "" +"section [%2zu] '%s': ELF header says this is the section header string table " +"but type is not SHT_TYPE\n" +msgstr "" +"розділ [%2zu] «%s»: заголовок ELF повідомляє про те, що це таблиця рядків " +"заголовка розділу, але ця таблиця не належить до типу SHT_TYPE\n" + +#: src/elflint.c:4166 +#, c-format +msgid "" +"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n" +msgstr "" +"розділ [%2zu] «%s»: придатні до пересування файли не можуть містити " +"динамічних таблиць символів\n" + +#: src/elflint.c:4217 +#, c-format +msgid "more than one version symbol table present\n" +msgstr "виявлено більше за одну таблицю символів версій\n" + +#: src/elflint.c:4240 +#, c-format +msgid "INTERP program header entry but no .interp section\n" +msgstr "існує запис заголовка програми INTERP, але не розділ .interp\n" + +#: src/elflint.c:4251 +#, c-format +msgid "" +"loadable segment [%u] is executable but contains no executable sections\n" +msgstr "" +"придатний до завантаження сегмент [%u] є виконуваним, але не містить " +"виконуваних розділів\n" + +#: src/elflint.c:4257 +#, c-format +msgid "loadable segment [%u] is writable but contains no writable sections\n" +msgstr "" +"придатний до завантаження розділ [%u] є придатним до запису, але не містить " +"придатних до запису розділів\n" + +#: src/elflint.c:4268 +#, c-format +msgid "" +"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section " +"exist\n" +msgstr "" +"немає розділу .gnu.versym, хоча існує розділ .gnu.versym_d або .gnu." +"versym_r\n" + +#: src/elflint.c:4281 +#, c-format +msgid "duplicate version index %d\n" +msgstr "дублікат індексу версії %d\n" + +#: src/elflint.c:4295 +#, c-format +msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n" +msgstr "" +"існує розділ .gnu.versym, але немає розділу .gnu.versym_d або .gnu.versym_r\n" + +#: src/elflint.c:4344 +#, c-format +msgid "phdr[%d]: unknown core file note type % at offset %\n" +msgstr "" +"phdr[%d]: невідомий тип нотатки файла core % за зміщенням %\n" + +#: src/elflint.c:4348 +#, c-format +msgid "" +"section [%2d] '%s': unknown core file note type % at offset %zu\n" +msgstr "" +"розділ [%2d] «%s»: невідомий тип нотатки файла core % за зміщенням " +"%zu\n" + +#: src/elflint.c:4397 +#, c-format +msgid "" +"phdr[%d]: unknown object file note type % with owner name '%s' at " +"offset %zu\n" +msgstr "" +"phdr[%d]: невідомий тип нотатки у файлі об'єктів, %, із іменем " +"власника «%s» за зміщенням %zu\n" + +#: src/elflint.c:4402 +#, c-format +msgid "" +"section [%2d] '%s': unknown object file note type % with owner name " +"'%s' at offset %zu\n" +msgstr "" +"розділ [%2d] «%s»: невідомий тип нотатки у файлі об'єктів, %, із " +"іменем власника «%s» за зміщенням %zu\n" + +#: src/elflint.c:4421 +#, c-format +msgid "phdr[%d]: no note entries defined for the type of file\n" +msgstr "phdr[%d]: для цього типу файлів не визначено записів нотаток\n" + +#: src/elflint.c:4441 +#, c-format +msgid "phdr[%d]: cannot get content of note section: %s\n" +msgstr "phdr[%d]: не вдалося отримати вміст розділу нотаток: %s\n" + +#: src/elflint.c:4444 +#, c-format +msgid "phdr[%d]: extra % bytes after last note\n" +msgstr "phdr[%d]: зайві % байтів після останнього запису нотатки\n" + +#: src/elflint.c:4465 +#, c-format +msgid "section [%2d] '%s': no note entries defined for the type of file\n" +msgstr "" +"розділ [%2d] «%s»: для цього типу файлів не визначено записів нотаток\n" + +#: src/elflint.c:4472 +#, c-format +msgid "section [%2d] '%s': cannot get content of note section\n" +msgstr "розділ [%2d] «%s»: не вдалося отримати вміст розділу нотаток\n" + +#: src/elflint.c:4475 +#, c-format +msgid "section [%2d] '%s': extra % bytes after last note\n" +msgstr "" +"розділ [%2d] «%s»: додаткові % байтів після останньої нотатки\n" + +#: src/elflint.c:4493 +#, c-format +msgid "" +"only executables, shared objects, and core files can have program headers\n" +msgstr "" +"заголовки програм можуть бути лише у виконуваних файлів, об’єктних файлів " +"спільного використання або файлів core\n" + +#: src/elflint.c:4508 +#, c-format +msgid "cannot get program header entry %d: %s\n" +msgstr "не вдалося отримати запис заголовка програми %d: %s\n" + +#: src/elflint.c:4518 +#, c-format +msgid "program header entry %d: unknown program header entry type %#\n" +msgstr "" +"запис заголовка програми %d: невідомий тип запису заголовка програми " +"%#\n" + +#: src/elflint.c:4529 +#, c-format +msgid "more than one INTERP entry in program header\n" +msgstr "більше за один запис INTERP у заголовку програми\n" + +#: src/elflint.c:4537 +#, c-format +msgid "more than one TLS entry in program header\n" +msgstr "більше за один запис TLS у заголовку програми\n" + +#: src/elflint.c:4544 +#, c-format +msgid "static executable cannot have dynamic sections\n" +msgstr "у статичному виконуваному файлі не може бути динамічних розділів\n" + +#: src/elflint.c:4558 +#, c-format +msgid "dynamic section reference in program header has wrong offset\n" +msgstr "" +"посилання на динамічний розділ у заголовку програми має помилкове зміщення\n" + +#: src/elflint.c:4561 +#, c-format +msgid "dynamic section size mismatch in program and section header\n" +msgstr "" +"розміри динамічного розділу у заголовку програми та у заголовку розділу не " +"збігаються\n" + +#: src/elflint.c:4571 +#, c-format +msgid "more than one GNU_RELRO entry in program header\n" +msgstr "більше за один запис GNU_RELRO у заголовку програми\n" + +#: src/elflint.c:4592 +#, c-format +msgid "loadable segment GNU_RELRO applies to is not writable\n" +msgstr "" +"придатний до завантаження сегмент, до якого звертається GNU_RELRO, " +"непридатний до запису\n" + +#: src/elflint.c:4603 +#, c-format +msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n" +msgstr "" +"прапорці придатного до завантаження сегмента [%u] не відповідають прапорцям " +"GNU_RELRO [%u]\n" + +#: src/elflint.c:4610 +#, c-format +msgid "" +"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n" +msgstr "" +"прапорці GNU_RELRO [%u] не є підмножиною прапорців завантажуваного сегмента " +"[%u]\n" + +#: src/elflint.c:4619 src/elflint.c:4642 +#, c-format +msgid "%s segment not contained in a loaded segment\n" +msgstr "сегмент %s не міститься у завантаженому сегменті\n" + +#: src/elflint.c:4648 +#, c-format +msgid "program header offset in ELF header and PHDR entry do not match" +msgstr "зміщення заголовка програми у заголовку ELF і запис PHDR не збігаються" + +#: src/elflint.c:4675 +#, c-format +msgid "call frame search table reference in program header has wrong offset\n" +msgstr "" +"посилання на таблицю вікон викликів у заголовку програми має помилкове " +"зміщення\n" + +#: src/elflint.c:4678 +#, c-format +msgid "call frame search table size mismatch in program and section header\n" +msgstr "" +"розміри таблиці пошуку вікон виклику у заголовку програми та у заголовку " +"розділу не збігаються\n" + +#: src/elflint.c:4691 +#, c-format +msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n" +msgstr "існує PT_GNU_EH_FRAME, хоча немає розділу .eh_frame_hdr\n" + +#: src/elflint.c:4699 +#, c-format +msgid "call frame search table must be allocated\n" +msgstr "таблицю пошуку вікон викликів має бути розміщено у пам’яті\n" + +#: src/elflint.c:4702 +#, c-format +msgid "section [%2zu] '%s' must be allocated\n" +msgstr "розділ [%2zu] «%s» має бути розміщено у пам’яті\n" + +#: src/elflint.c:4706 +#, c-format +msgid "call frame search table must not be writable\n" +msgstr "таблиця пошуку вікон викликів не повинна бути придатною до запису\n" + +#: src/elflint.c:4709 +#, c-format +msgid "section [%2zu] '%s' must not be writable\n" +msgstr "розділ [%2zu] «%s» не повинен бути придатним до запису\n" + +#: src/elflint.c:4714 +#, c-format +msgid "call frame search table must not be executable\n" +msgstr "таблиця пошуку вікон викликів не повинна бути придатною до виконання\n" + +#: src/elflint.c:4717 +#, c-format +msgid "section [%2zu] '%s' must not be executable\n" +msgstr "розділ [%2zu] «%s» не повинен бути придатним до виконання\n" + +#: src/elflint.c:4728 +#, c-format +msgid "program header entry %d: file size greater than memory size\n" +msgstr "запис заголовка програми %d: розмір файла перевищує об’єм пам’яті\n" + +#: src/elflint.c:4735 +#, c-format +msgid "program header entry %d: alignment not a power of 2\n" +msgstr "запис заголовка програми %d: значення вирівнювання не є степенем 2\n" + +#: src/elflint.c:4738 +#, c-format +msgid "" +"program header entry %d: file offset and virtual address not module of " +"alignment\n" +msgstr "" +"запис заголовка програми %d: зміщення у файлі і віртуальна адреса не " +"співвідносяться з вирівнюванням\n" + +#: src/elflint.c:4751 +#, c-format +msgid "" +"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME " +"program header entry" +msgstr "" +"виконуваний модуль/DSO з розділом .eh_frame_hdr не містить запису заголовка " +"програми PT_GNU_EH_FRAME" + +#: src/elflint.c:4785 +#, c-format +msgid "cannot read ELF header: %s\n" +msgstr "не вдалося прочитати заголовок ELF: %s\n" + +#: src/elflint.c:4797 +#, fuzzy, c-format +msgid "cannot create backend for ELF file\n" +msgstr "не вдалося створити файл" + +#: src/elflint.c:4818 +#, c-format +msgid "text relocation flag set but not needed\n" +msgstr "" +"встановлено прапорець пересування тексту, але такий прапорець не потрібен\n" + +#: src/findtextrel.c:60 +msgid "Input Selection:" +msgstr "Вибір параметрів виводу даних:" + +#: src/findtextrel.c:61 +msgid "Prepend PATH to all file names" +msgstr "Додавати ШЛЯХ до всіх назв файлів" + +#: src/findtextrel.c:63 +msgid "Use PATH as root of debuginfo hierarchy" +msgstr "Використовувати ШЛЯХ як кореневий каталог для ієрархії debuginfo" + +#. Short description of program. +#: src/findtextrel.c:70 +msgid "Locate source of text relocations in FILEs (a.out by default)." +msgstr "Шукає джерело пересуваного тексту у ФАЙЛАХ (типово, a.out)." + +#. Strings for arguments in help texts. +#: src/findtextrel.c:74 src/nm.c:108 src/objdump.c:71 src/size.c:80 +#: src/strings.c:87 src/strip.c:101 +msgid "[FILE...]" +msgstr "[ФАЙЛ...]" + +#: src/findtextrel.c:222 +#, c-format +msgid "cannot get ELF header '%s': %s" +msgstr "не вдалося отримати заголовок ELF «%s»: %s" + +#: src/findtextrel.c:233 +#, c-format +msgid "'%s' is not a DSO or PIE" +msgstr "«%s» не є DSO або PIE" + +#: src/findtextrel.c:253 +#, c-format +msgid "getting get section header of section %zu: %s" +msgstr "отримання заголовка розділу get розділу %zu: %s" + +#: src/findtextrel.c:277 +#, c-format +msgid "cannot read dynamic section: %s" +msgstr "не вдалося прочитати динамічний розділ: %s" + +#: src/findtextrel.c:298 +#, c-format +msgid "no text relocations reported in '%s'" +msgstr "у «%s» не виявлено пересувань тексту" + +#: src/findtextrel.c:310 +#, c-format +msgid "while reading ELF file" +msgstr "під час спроби читання файла ELF" + +#: src/findtextrel.c:314 +#, c-format +msgid "cannot get program header count: %s" +msgstr "не вдалося отримати кількість заголовків програми: %s" + +#: src/findtextrel.c:325 src/findtextrel.c:342 +#, c-format +msgid "cannot get program header index at offset %zd: %s" +msgstr "не вдалося отримати індекс заголовка програми за зміщенням %zd: %s" + +#: src/findtextrel.c:406 +#, c-format +msgid "cannot get symbol table section %zu in '%s': %s" +msgstr "не вдалося отримати таблицю символів розділу %zu у «%s»: %s" + +#: src/findtextrel.c:427 src/findtextrel.c:450 +#, c-format +msgid "cannot get relocation at index %d in section %zu in '%s': %s" +msgstr "" +"не вдалося отримати пересування за індексом %d у розділі %zu у «%s»: %s" + +#: src/findtextrel.c:516 +#, c-format +msgid "%s not compiled with -fpic/-fPIC\n" +msgstr "%s не зібрано з -fpic/-fPIC\n" + +#: src/findtextrel.c:570 +#, c-format +msgid "" +"the file containing the function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"файл, що містить функцію «%s», не було зібрано з параметрами -fpic/-fPIC\n" + +#: src/findtextrel.c:577 src/findtextrel.c:597 +#, c-format +msgid "" +"the file containing the function '%s' might not be compiled with -fpic/-" +"fPIC\n" +msgstr "" +"файл, що містить функцію «%s», ймовірно, не було зібрано з параметрами -" +"fpic/-fPIC\n" + +#: src/findtextrel.c:585 +#, c-format +msgid "" +"either the file containing the function '%s' or the file containing the " +"function '%s' is not compiled with -fpic/-fPIC\n" +msgstr "" +"файл, що містить функцію «%s», або файл, що містить функцію «%s», зібрано " +"без параметрів -fpic/-fPIC\n" + +#: src/findtextrel.c:605 +#, c-format +msgid "" +"a relocation modifies memory at offset %llu in a write-protected segment\n" +msgstr "" +"пересування призводить до зміни запису пам’яті за зміщенням %llu у " +"захищеному від запису сегменті\n" + +#: src/nm.c:66 src/strip.c:70 +msgid "Output selection:" +msgstr "Вибір виводу:" + +#: src/nm.c:67 +msgid "Display debugger-only symbols" +msgstr "Показувати лише діагностичні символи" + +#: src/nm.c:68 +msgid "Display only defined symbols" +msgstr "Показувати лише визначені символи" + +#: src/nm.c:71 +msgid "Display dynamic symbols instead of normal symbols" +msgstr "Показувати динамічні символи замість звичайних символів" + +#: src/nm.c:72 +msgid "Display only external symbols" +msgstr "Показувати лише зовнішні символи" + +#: src/nm.c:73 +msgid "Display only undefined symbols" +msgstr "Показувати лише невизначені символи" + +#: src/nm.c:75 +msgid "Include index for symbols from archive members" +msgstr "Включити покажчик для символів з елементів архіву" + +#: src/nm.c:77 src/size.c:54 +msgid "Output format:" +msgstr "Формат виводу:" + +#: src/nm.c:79 +msgid "Print name of the input file before every symbol" +msgstr "Виводити перед кожним символом назву вхідного файла" + +#: src/nm.c:82 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The " +"default is `sysv'" +msgstr "" +"Використовувати формат виводу ФОРМАТ. ФОРМАТом може бути «bsd», «sysv» або " +"«posix». Типовим форматом є «sysv»" + +#: src/nm.c:84 +msgid "Same as --format=bsd" +msgstr "Те саме, що і --format=bsd" + +#: src/nm.c:85 +msgid "Same as --format=posix" +msgstr "Те саме, що і --format=posix" + +#: src/nm.c:86 src/size.c:60 +msgid "Use RADIX for printing symbol values" +msgstr "Використовувати ОСНОВУ числення для виводу символьних значень" + +#: src/nm.c:87 +msgid "Mark special symbols" +msgstr "Позначати спеціальні символи" + +#: src/nm.c:89 +msgid "Print size of defined symbols" +msgstr "Вивести розмір визначених символів" + +#: src/nm.c:91 src/size.c:68 src/strip.c:75 src/unstrip.c:69 +msgid "Output options:" +msgstr "Параметри виводу:" + +#: src/nm.c:92 +msgid "Sort symbols numerically by address" +msgstr "Числове впорядкування символів за адресою" + +#: src/nm.c:94 +msgid "Do not sort the symbols" +msgstr "Не впорядковувати символи" + +#: src/nm.c:95 +msgid "Reverse the sense of the sort" +msgstr "Змінити порядок на протилежний" + +#: src/nm.c:98 +msgid "Decode low-level symbol names into source code names" +msgstr "Визначати за низькорівневими назвами символів назви у початковому коді" + +#. Short description of program. +#: src/nm.c:105 +msgid "List symbols from FILEs (a.out by default)." +msgstr "Показати список символів з ФАЙЛів (типово з a.out)." + +#: src/nm.c:116 src/objdump.c:79 +msgid "Output formatting" +msgstr "Форматування виводу" + +#: src/nm.c:140 src/objdump.c:103 src/size.c:105 src/strip.c:133 +#, c-format +msgid "%s: INTERNAL ERROR %d (%s): %s" +msgstr "%s: ВНУТРІШНЯ ПОМИЛКА %d (%s): %s" + +#: src/nm.c:381 src/nm.c:393 src/size.c:288 src/size.c:297 src/size.c:308 +#: src/strip.c:2763 +#, c-format +msgid "while closing '%s'" +msgstr "під час закриття «%s»" + +#: src/nm.c:403 src/objdump.c:280 src/strip.c:818 +#, c-format +msgid "%s: File format not recognized" +msgstr "%s: не вдалося розпізнати формат файла" + +#. Note: 0 is no valid offset. +#: src/nm.c:443 +msgid "" +"\n" +"Archive index:\n" +msgstr "" +"\n" +"Покажчик архіву:\n" + +#: src/nm.c:452 +#, c-format +msgid "invalid offset %zu for symbol %s" +msgstr "некоректне зміщення %zu для символу %s" + +#: src/nm.c:457 +#, c-format +msgid "%s in %s\n" +msgstr "%s у %s\n" + +#: src/nm.c:465 +#, c-format +msgid "cannot reset archive offset to beginning" +msgstr "не вдалося відновити зміщення початку архіву" + +#: src/nm.c:490 src/objdump.c:328 +#, c-format +msgid "%s%s%s: file format not recognized" +msgstr "%s%s%s: не вдалося розпізнати формат файла" + +#: src/nm.c:705 +#, c-format +msgid "cannot create search tree" +msgstr "не вдалося створити дерево пошуку" + +#: src/nm.c:746 src/nm.c:1239 src/objdump.c:782 src/readelf.c:637 +#: src/readelf.c:1451 src/readelf.c:1602 src/readelf.c:1803 src/readelf.c:2009 +#: src/readelf.c:2199 src/readelf.c:2377 src/readelf.c:2453 src/readelf.c:2719 +#: src/readelf.c:2795 src/readelf.c:2882 src/readelf.c:3480 src/readelf.c:3530 +#: src/readelf.c:3600 src/readelf.c:11339 src/readelf.c:12533 +#: src/readelf.c:12744 src/readelf.c:12813 src/size.c:398 src/size.c:470 +#: src/strip.c:1084 +#, c-format +msgid "cannot get section header string table index" +msgstr "не вдалося визначити індекс заголовка розділу у таблиці рядків" + +#. We always print this prolog. +#: src/nm.c:771 +#, c-format +msgid "" +"\n" +"\n" +"Symbols from %s:\n" +"\n" +msgstr "" +"\n" +"\n" +"Символи з %s:\n" +"\n" + +#. The header line. +#: src/nm.c:774 +#, c-format +msgid "" +"%*s%-*s %-*s Class Type %-*s %*s Section\n" +"\n" +msgstr "" +"%*s%-*s %-*s Клас Тип %-*s %*s Розділ\n" +"\n" + +#: src/nm.c:776 +#, fuzzy +#| msgid " Name: " +msgctxt "sysv" +msgid "Name" +msgstr "Назва: " + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:778 +msgctxt "sysv" +msgid "Value" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:780 +msgctxt "sysv" +msgid "Size" +msgstr "" + +#. TRANS: the "sysv|" parts makes the string unique. +#: src/nm.c:782 +msgctxt "sysv" +msgid "Line" +msgstr "" + +#: src/nm.c:1250 +#, c-format +msgid "%s: entry size in section %zd `%s' is not what we expect" +msgstr "%s: розмір запису у розділі %zd «%s» не є очікуваним" + +#: src/nm.c:1255 +#, c-format +msgid "%s: size of section %zd `%s' is not multiple of entry size" +msgstr "%s: розмір розділу %zd «%s» не є кратним до розміру запису" + +#: src/nm.c:1336 +#, c-format +msgid "%s: entries (%zd) in section %zd `%s' is too large" +msgstr "%s: записи (%zd) у розділі %zd, «%s» є завеликим" + +#. XXX Add machine specific object file types. +#: src/nm.c:1572 +#, c-format +msgid "%s%s%s%s: Invalid operation" +msgstr "%s%s%s%s: некоректна дія" + +#: src/nm.c:1622 +#, c-format +msgid "%s%s%s: no symbols" +msgstr "%s%s%s: немає символів" + +#: src/objdump.c:52 +msgid "Mode selection:" +msgstr "Вибір режиму:" + +#: src/objdump.c:53 +msgid "Display relocation information." +msgstr "Показати інформацію про пересування." + +#: src/objdump.c:55 +msgid "Display the full contents of all sections requested" +msgstr "Показати весь вміст всіх вказаних розділів" + +#: src/objdump.c:57 +msgid "Display assembler code of executable sections" +msgstr "Показати код асемблера виконуваних розділів" + +#: src/objdump.c:59 +msgid "Output content selection:" +msgstr "Вибір виведених даних:" + +#: src/objdump.c:61 +msgid "Only display information for section NAME." +msgstr "Показати інформацію лише з розділу НАЗВА." + +#. Short description of program. +#: src/objdump.c:67 +msgid "Show information from FILEs (a.out by default)." +msgstr "Показати інформацію з ФАЙЛів (типово a.out)." + +#: src/objdump.c:218 src/readelf.c:582 +msgid "No operation specified.\n" +msgstr "Не вказано дії.\n" + +#: src/objdump.c:258 src/objdump.c:270 +#, c-format +msgid "while close `%s'" +msgstr "під час закриття «%s»" + +#: src/objdump.c:363 src/readelf.c:2104 src/readelf.c:2296 +msgid "INVALID SYMBOL" +msgstr "НЕКОРЕКТНИЙ СИМВОЛ" + +#: src/objdump.c:378 src/readelf.c:2138 src/readelf.c:2332 +msgid "INVALID SECTION" +msgstr "НЕКОРЕКТНИЙ РОЗДІЛ" + +#: src/objdump.c:498 +#, c-format +msgid "" +"\n" +"RELOCATION RECORDS FOR [%s]:\n" +"%-*s TYPE VALUE\n" +msgstr "" +"\n" +"ЗАПИСИ ПЕРЕМІЩЕННЯ ДЛЯ [%s]:\n" +"%-*s ТИП ЗНАЧЕННЯ\n" + +#: src/objdump.c:501 +msgid "OFFSET" +msgstr "ЗМІЩЕННЯ" + +#: src/objdump.c:566 +#, c-format +msgid "Contents of section %s:\n" +msgstr "Вміст розділу %s:\n" + +#: src/objdump.c:687 +#, c-format +msgid "cannot disassemble" +msgstr "не вдалося дизасемблювати" + +#: src/objdump.c:760 +#, fuzzy, c-format +msgid "cannot create backend for elf file" +msgstr "не вдалося створити файл" + +#. Short description of program. +#: src/ranlib.c:63 +msgid "Generate an index to speed access to archives." +msgstr "Створювати покажчик для пришвидшення доступу до архівів." + +#. Strings for arguments in help texts. +#: src/ranlib.c:66 +msgid "ARCHIVE" +msgstr "АРХІВ" + +#: src/ranlib.c:102 +#, c-format +msgid "Archive name required" +msgstr "Слід вказати назву архіву" + +#: src/ranlib.c:166 +#, c-format +msgid "'%s' is no archive" +msgstr "«%s» не є архівом" + +#: src/ranlib.c:201 +#, c-format +msgid "error while freeing sub-ELF descriptor: %s" +msgstr "помилка під час спроби вивільнення дескриптора під-ELF: %s" + +#: src/readelf.c:97 +msgid "ELF input selection:" +msgstr "Вибір вихідних даних ELF:" + +#: src/readelf.c:99 +msgid "" +"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data" +msgstr "" +"Використовувати вказаний за іменем РОЗДІЛ (типово .gnu_debugdata) як " +"(стиснені) вхідні дані ELF" + +#: src/readelf.c:102 +msgid "" +"Used with -w to find the skeleton Compile Units in FILE associated with the " +"Split Compile units in a .dwo input file" +msgstr "" +"Використовується з -w для пошуку основи компільованих модулів у ФАЙЛі, " +"пов'язаному із модулями розділеної компіляції у вхідному файлі .dwo" + +#: src/readelf.c:104 +msgid "ELF output selection:" +msgstr "Вибір виводу ELF:" + +#: src/readelf.c:106 +msgid "All these plus -p .strtab -p .dynstr -p .comment" +msgstr "Все це плюс -p .strtab -p .dynstr -p .comment" + +#: src/readelf.c:107 +msgid "Display the dynamic segment" +msgstr "Показувати динамічний сегмент" + +#: src/readelf.c:108 +msgid "Display the ELF file header" +msgstr "Показувати заголовок файла ELF" + +#: src/readelf.c:110 +msgid "Display histogram of bucket list lengths" +msgstr "Показати гістограму довжин списку блоків" + +#: src/readelf.c:111 +msgid "Display the program headers" +msgstr "Показувати заголовки програми" + +#: src/readelf.c:113 +msgid "Display relocations" +msgstr "Показувати пересування" + +#: src/readelf.c:114 +msgid "Display the section groups" +msgstr "Показувати групи розділів" + +#: src/readelf.c:115 +msgid "Display the sections' headers" +msgstr "Показувати заголовки розділів" + +#: src/readelf.c:118 +msgid "Display the symbol table sections" +msgstr "Показати розділи таблиці символів" + +#: src/readelf.c:120 +msgid "Display (only) the dynamic symbol table" +msgstr "Показувати (лише) динамічну таблицю символів" + +#: src/readelf.c:121 +msgid "Display versioning information" +msgstr "Показувати відомості щодо версії" + +#: src/readelf.c:122 +msgid "Display the ELF notes" +msgstr "Показувати нотатки ELF" + +#: src/readelf.c:124 +msgid "Display architecture specific information, if any" +msgstr "Показувати специфічні для архітектури дані, якщо такі буде виявлено" + +#: src/readelf.c:126 +msgid "Display sections for exception handling" +msgstr "Показувати розділи для обробки виключень" + +#: src/readelf.c:128 +msgid "Additional output selection:" +msgstr "Додатковий вибір виводу:" + +#: src/readelf.c:130 +msgid "" +"Display DWARF section content. SECTION can be one of abbrev, addr, aranges, " +"decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, " +"ranges, pubnames, str, macinfo, macro or exception" +msgstr "" +"Показати вміст розділу DWARF. Значенням РОЗДІЛ може бути abbrev, addr, " +"aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, " +"decodedline, ranges, pubnames, str, macinfo, macro або exception" + +#: src/readelf.c:134 +msgid "Dump the uninterpreted contents of SECTION, by number or name" +msgstr "" +"Створити дамп даних РОЗДІЛ, які не вдалося інтерпретувати, за номером або " +"назвами" + +#: src/readelf.c:136 +msgid "Print string contents of sections" +msgstr "Виводити вміст рядків розділів" + +#: src/readelf.c:139 +msgid "Display the symbol index of an archive" +msgstr "Показувати покажчик символів архіву" + +#: src/readelf.c:141 +msgid "Output control:" +msgstr "Керування виводом:" + +#: src/readelf.c:143 +msgid "Do not find symbol names for addresses in DWARF data" +msgstr "Не шукати назви символів для адрес у даних DWARF" + +#: src/readelf.c:145 +msgid "" +"Display just offsets instead of resolving values to addresses in DWARF data" +msgstr "Показати лише зміщення, а не визначені значення адреси у даних DWARF" + +#: src/readelf.c:147 +msgid "Ignored for compatibility (lines always wide)" +msgstr "Ігнорується з міркувань сумісності (рядки завжди широкі)" + +#: src/readelf.c:149 +msgid "" +"Show compression information for compressed sections (when used with -S); " +"decompress section before dumping data (when used with -p or -x)" +msgstr "" +"Показати дані щодо стискання для стиснених розділів (якщо використано з -S); " +"розпакувати розділ до створення дампу даних (якщо використано з -p або -x)" + +#. Short description of program. +#: src/readelf.c:154 +msgid "Print information from ELF file in human-readable form." +msgstr "Виводити відомості з файла ELF у придатному для читання форматі." + +#. Look up once. +#: src/readelf.c:350 +msgid "yes" +msgstr "так" + +#: src/readelf.c:351 +msgid "no" +msgstr "ні" + +#: src/readelf.c:550 +#, c-format +msgid "Unknown DWARF debug section `%s'.\n" +msgstr "Невідомий діагностичний розділ DWARF «%s».\n" + +#: src/readelf.c:621 src/readelf.c:732 +#, c-format +msgid "cannot generate Elf descriptor: %s" +msgstr "не вдалося створити дескриптор Elf: %s" + +#: src/readelf.c:628 src/readelf.c:955 src/strip.c:1179 +#, c-format +msgid "cannot determine number of sections: %s" +msgstr "не вдалося визначити кількість розділів: %s" + +#: src/readelf.c:646 src/readelf.c:1265 src/readelf.c:1475 +#, c-format +msgid "cannot get section: %s" +msgstr "не вдалося отримати розділ: %s" + +#: src/readelf.c:655 src/readelf.c:1272 src/readelf.c:1483 src/readelf.c:12764 +#: src/unstrip.c:397 src/unstrip.c:428 src/unstrip.c:489 src/unstrip.c:610 +#: src/unstrip.c:631 src/unstrip.c:671 src/unstrip.c:887 src/unstrip.c:1222 +#: src/unstrip.c:1349 src/unstrip.c:1373 src/unstrip.c:1429 src/unstrip.c:1470 +#: src/unstrip.c:1663 src/unstrip.c:1814 src/unstrip.c:1957 src/unstrip.c:2056 +#, c-format +msgid "cannot get section header: %s" +msgstr "не вдалося отримати заголовок розділу: %s" + +#: src/readelf.c:663 +#, c-format +msgid "cannot get section name" +msgstr "не вдалося отримати назву розділу" + +#: src/readelf.c:672 src/readelf.c:6636 src/readelf.c:10611 src/readelf.c:10713 +#: src/readelf.c:10891 +#, c-format +msgid "cannot get %s content: %s" +msgstr "не вдалося отримати дані %s: %s" + +#: src/readelf.c:688 +#, c-format +msgid "cannot create temp file '%s'" +msgstr "не вдалося створити файл тимчасових даних «%s»" + +#: src/readelf.c:697 +#, c-format +msgid "cannot write section data" +msgstr "не вдалося записати дані розділу" + +#: src/readelf.c:703 src/readelf.c:720 src/readelf.c:749 +#, c-format +msgid "error while closing Elf descriptor: %s" +msgstr "помилка під час спроби закриття дескриптора Elf: %s" + +#: src/readelf.c:710 +#, c-format +msgid "error while rewinding file descriptor" +msgstr "помилка під час повернення до початкового значення дескриптора файла" + +#: src/readelf.c:744 +#, c-format +msgid "'%s' is not an archive, cannot print archive index" +msgstr "«%s» не є архівом, виведення покажчика архіву неможливе" + +#: src/readelf.c:848 +#, c-format +msgid "cannot stat input file" +msgstr "не вдалося отримати дані з вхідного файла за допомогою stat" + +#: src/readelf.c:850 +#, c-format +msgid "input file is empty" +msgstr "вхідний файл є порожнім" + +#: src/readelf.c:852 +#, c-format +msgid "failed reading '%s': %s" +msgstr "не вдалося прочитати «%s»: %s" + +#: src/readelf.c:881 +#, c-format +msgid "No such section '%s' in '%s'" +msgstr "У «%2$s» немає розділу «%1$s»" + +#: src/readelf.c:940 +#, c-format +msgid "cannot read ELF header: %s" +msgstr "не вдалося прочитати заголовок ELF: %s" + +#: src/readelf.c:948 +#, c-format +msgid "cannot create EBL handle" +msgstr "не вдалося створити дескриптор EBL" + +#: src/readelf.c:961 +#, c-format +msgid "cannot determine number of program headers: %s" +msgstr "не вдалося визначити кількість заголовків програми: %s" + +#: src/readelf.c:993 +#, c-format +msgid "cannot read ELF: %s" +msgstr "не вдалося прочитати ELF: %s" + +#: src/readelf.c:1054 +msgid "NONE (None)" +msgstr "NONE (Немає)" + +#: src/readelf.c:1055 +msgid "REL (Relocatable file)" +msgstr "REL (Придатний до пересування файл)" + +#: src/readelf.c:1056 +msgid "EXEC (Executable file)" +msgstr "EXEC (Виконуваний файл)" + +#: src/readelf.c:1057 +msgid "DYN (Shared object file)" +msgstr "DYN (Файл об’єктів спільного використання)" + +#: src/readelf.c:1058 +msgid "CORE (Core file)" +msgstr "CORE (Файл ядра)" + +#: src/readelf.c:1063 +#, c-format +msgid "OS Specific: (%x)\n" +msgstr "ОС-специфічне: (%x)\n" + +#. && e_type <= ET_HIPROC always true +#: src/readelf.c:1065 +#, c-format +msgid "Processor Specific: (%x)\n" +msgstr "Специфічне для процесора: (%x)\n" + +#: src/readelf.c:1075 +msgid "" +"ELF Header:\n" +" Magic: " +msgstr "" +"Заголовок ELF:\n" +" Magic: " + +#: src/readelf.c:1079 +#, c-format +msgid "" +"\n" +" Class: %s\n" +msgstr "" +"\n" +" Клас: %s\n" + +#: src/readelf.c:1084 +#, c-format +msgid " Data: %s\n" +msgstr " Дані: %s\n" + +#: src/readelf.c:1090 +#, c-format +msgid " Ident Version: %hhd %s\n" +msgstr " Версія Ident: %hhd %s\n" + +#: src/readelf.c:1092 src/readelf.c:1114 +msgid "(current)" +msgstr "(поточний)" + +#: src/readelf.c:1096 +#, c-format +msgid " OS/ABI: %s\n" +msgstr " ОС/ABI: %s\n" + +#: src/readelf.c:1099 +#, c-format +msgid " ABI Version: %hhd\n" +msgstr " Версія ABI: %hhd\n" + +#: src/readelf.c:1102 +msgid " Type: " +msgstr " Тип: " + +#: src/readelf.c:1107 +#, c-format +msgid " Machine: %s\n" +msgstr " Архітектура: %s\n" + +#: src/readelf.c:1109 +#, c-format +msgid " Machine: : 0x%x\n" +msgstr " Архітектура: <невідома>: 0x%x\n" + +#: src/readelf.c:1112 +#, c-format +msgid " Version: %d %s\n" +msgstr " Версія: %d %s\n" + +#: src/readelf.c:1116 +#, c-format +msgid " Entry point address: %#\n" +msgstr " Адреса вхідної точки: %#\n" + +#: src/readelf.c:1119 +#, c-format +msgid " Start of program headers: % %s\n" +msgstr " Початок заголовків програм: % %s\n" + +#: src/readelf.c:1120 src/readelf.c:1123 +msgid "(bytes into file)" +msgstr "(байтів у файл)" + +#: src/readelf.c:1122 +#, c-format +msgid " Start of section headers: % %s\n" +msgstr " Початок заголовків розділів: % %s\n" + +#: src/readelf.c:1125 +#, c-format +msgid " Flags: %s\n" +msgstr " Прапорці: %s\n" + +#: src/readelf.c:1128 +#, c-format +msgid " Size of this header: % %s\n" +msgstr " Розмір цього заголовка: % %s\n" + +#: src/readelf.c:1129 src/readelf.c:1132 src/readelf.c:1149 +msgid "(bytes)" +msgstr "(байтів)" + +#: src/readelf.c:1131 +#, c-format +msgid " Size of program header entries: % %s\n" +msgstr " Розмір записів заголовка програми: % %s\n" + +#: src/readelf.c:1134 +#, c-format +msgid " Number of program headers entries: %" +msgstr " Кількість записів заголовків програми: %" + +#: src/readelf.c:1141 +#, c-format +msgid " (% in [0].sh_info)" +msgstr " (% у [0].sh_info)" + +#: src/readelf.c:1144 src/readelf.c:1161 src/readelf.c:1175 +msgid " ([0] not available)" +msgstr " ([0] недоступний)" + +#: src/readelf.c:1148 +#, c-format +msgid " Size of section header entries: % %s\n" +msgstr " Розмір записів заголовків розділів: % %s\n" + +#: src/readelf.c:1151 +#, c-format +msgid " Number of section headers entries: %" +msgstr " Кількість записів заголовків розділів: %" + +#: src/readelf.c:1158 +#, c-format +msgid " (% in [0].sh_size)" +msgstr " (% у [0].sh_size)" + +#. We managed to get the zeroth section. +#: src/readelf.c:1171 +#, c-format +msgid " (% in [0].sh_link)" +msgstr " (% у [0].sh_link)" + +#: src/readelf.c:1179 +#, c-format +msgid "" +" Section header string table index: XINDEX%s\n" +"\n" +msgstr "" +" Індекс заголовка розділу у таблиці рядків: XINDEX%s\n" +"\n" + +#: src/readelf.c:1183 +#, c-format +msgid "" +" Section header string table index: %\n" +"\n" +msgstr "" +" Індекс заголовка розділу у таблиці рядків: %\n" +"\n" + +#: src/readelf.c:1230 src/readelf.c:1440 +#, c-format +msgid "cannot get number of sections: %s" +msgstr "не вдалося отримати кількість розділів: %s" + +#: src/readelf.c:1233 +#, c-format +msgid "" +"There are %zd section headers, starting at offset %#:\n" +"\n" +msgstr "" +"Виявлено %zd заголовків розділів, зміщення початку — %#:\n" +"\n" + +#: src/readelf.c:1242 +#, c-format +msgid "cannot get section header string table index: %s" +msgstr "не вдалося визначити індекс заголовка розділу у таблиці рядків: %s" + +#: src/readelf.c:1245 +msgid "Section Headers:" +msgstr "Заголовки розділів:" + +#: src/readelf.c:1248 +msgid "" +"[Nr] Name Type Addr Off Size ES Flags Lk " +"Inf Al" +msgstr "" +"[№ ] Назва Тип Адр Змі Розмір ES Прап Lk " +"Інф Al" + +#: src/readelf.c:1250 +msgid "" +"[Nr] Name Type Addr Off Size ES " +"Flags Lk Inf Al" +msgstr "" +"[№ ] Назва Тип Адр Змі Розмір ES " +"Прап Lk Інф Al" + +#: src/readelf.c:1255 +msgid " [Compression Size Al]" +msgstr " [Стискання Розмір Ал]" + +#: src/readelf.c:1257 +msgid " [Compression Size Al]" +msgstr " [Стискання Розмір Ал]" + +#: src/readelf.c:1335 +#, c-format +msgid "bad compression header for section %zd: %s" +msgstr "помилковий заголовок стиснення для розділу %zd: %s" + +#: src/readelf.c:1346 +#, c-format +msgid "bad gnu compressed size for section %zd: %s" +msgstr "помилкове значення стисненого розміру gnu для розділу %zd: %s" + +#: src/readelf.c:1364 +msgid "Program Headers:" +msgstr "Заголовки програми:" + +#: src/readelf.c:1366 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align" +msgstr "" +" Тип Зміщен ВіртАдр ФізАдр РозмФайл РозмПам Пра Вирів" + +#: src/readelf.c:1369 +msgid "" +" Type Offset VirtAddr PhysAddr FileSiz " +"MemSiz Flg Align" +msgstr "" +" Тип Зміщен ВіртАдр ФізАдр " +"РозмФайлРозмПам Пра Вирів" + +#: src/readelf.c:1426 +#, c-format +msgid "\t[Requesting program interpreter: %s]\n" +msgstr "\t[Запит щодо інтерпретатора програми: %s]\n" + +#: src/readelf.c:1453 +msgid "" +"\n" +" Section to Segment mapping:\n" +" Segment Sections..." +msgstr "" +"\n" +" Відображення розділів на сегмент:\n" +" Розділи сегмента..." + +#: src/readelf.c:1464 src/unstrip.c:2115 src/unstrip.c:2157 src/unstrip.c:2164 +#, c-format +msgid "cannot get program header: %s" +msgstr "не вдалося отримати заголовок програми: %s" + +#: src/readelf.c:1610 +#, c-format +msgid "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Група розділів COMDAT [%2zu] «%s» з підписом «%s» містить %zu запис:\n" +msgstr[1] "" +"\n" +"Група розділів COMDAT [%2zu] «%s» з підписом «%s» містить %zu записи:\n" +msgstr[2] "" +"\n" +"Група розділів COMDAT [%2zu] «%s» з підписом «%s» містить %zu записів:\n" + +#: src/readelf.c:1615 +#, c-format +msgid "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n" +msgid_plural "" +"\n" +"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n" +msgstr[0] "" +"\n" +"Група розділів [%2zu] «%s» з підписом «%s» містить %zu запис:\n" +msgstr[1] "" +"\n" +"Група розділів [%2zu] «%s» з підписом «%s» містить %zu записи:\n" +msgstr[2] "" +"\n" +"Група розділів [%2zu] «%s» з підписом «%s» містить %zu записів:\n" + +#: src/readelf.c:1623 +msgid "" +msgstr "<НЕКОРЕКТНИЙ СИМВОЛ>" + +#: src/readelf.c:1637 +msgid "" +msgstr "<НЕКОРЕКТНИЙ РОЗДІЛ>" + +#: src/readelf.c:1660 src/readelf.c:2387 src/readelf.c:3496 src/readelf.c:12635 +#: src/readelf.c:12642 src/readelf.c:12686 src/readelf.c:12693 +msgid "Couldn't uncompress section" +msgstr "Не вдалося розпакувати розділ" + +#: src/readelf.c:1665 src/readelf.c:2392 src/readelf.c:3501 +#, c-format +msgid "cannot get section [%zd] header: %s" +msgstr "не вдалося отримати заголовок розділу [%zd]: %s" + +#: src/readelf.c:1809 src/readelf.c:2459 src/readelf.c:2725 src/readelf.c:2801 +#: src/readelf.c:3105 src/readelf.c:3179 src/readelf.c:5409 +#, c-format +msgid "invalid sh_link value in section %zu" +msgstr "некоректне значення sh_link у розділі %zu" + +#: src/readelf.c:1812 +#, c-format +msgid "" +"\n" +"Dynamic segment contains %lu entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Dynamic segment contains %lu entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Динамічний сегмент містить %lu запис:\n" +" Адр: %#0* Зміщення: %#08 Пос. на розділ: [%2u] '%s'\n" +msgstr[1] "" +"\n" +"Динамічний сегмент містить %lu записи:\n" +" Адр: %#0* Зміщення: %#08 Пос. на розділ: [%2u] '%s'\n" +msgstr[2] "" +"\n" +"Динамічний сегмент містить %lu записів:\n" +" Адр: %#0* Зміщення: %#08 Пос. на розділ: [%2u] '%s'\n" + +#: src/readelf.c:1822 +msgid " Type Value\n" +msgstr " Тип Значення\n" + +#: src/readelf.c:1846 +#, c-format +msgid "Shared library: [%s]\n" +msgstr "Спільна бібліотека: [%s]\n" + +#: src/readelf.c:1851 +#, c-format +msgid "Library soname: [%s]\n" +msgstr "Назва so бібліотеки: [%s]\n" + +#: src/readelf.c:1856 +#, c-format +msgid "Library rpath: [%s]\n" +msgstr "Rpath бібліотеки: [%s]\n" + +#: src/readelf.c:1861 +#, c-format +msgid "Library runpath: [%s]\n" +msgstr "Runpath бібліотеки: [%s]\n" + +#: src/readelf.c:1881 +#, c-format +msgid "% (bytes)\n" +msgstr "% (байт)\n" + +#: src/readelf.c:1994 src/readelf.c:2184 +#, c-format +msgid "" +"\n" +"Invalid symbol table at offset %#0\n" +msgstr "" +"\n" +"Некоректна таблиця символів за зміщенням %#0\n" + +#: src/readelf.c:2012 src/readelf.c:2202 +#, c-format +msgid "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0 " +"contains %d entries:\n" +msgstr[0] "" +"\n" +"Розділ пересування [%2zu] «%s» для розділу [%2u] «%s» за зміщенням " +"%#0 містить %d запис:\n" +msgstr[1] "" +"\n" +"Розділ пересування [%2zu] «%s» для розділу [%2u] «%s» за зміщенням " +"%#0 містить %d записи:\n" +msgstr[2] "" +"\n" +"Розділ пересування [%2zu] «%s» для розділу [%2u] «%s» за зміщенням " +"%#0 містить %d записів:\n" + +#. The .rel.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#. The .rela.dyn section does not refer to a specific section but +#. instead of section index zero. Do not try to print a section +#. name. +#: src/readelf.c:2027 src/readelf.c:2217 +#, c-format +msgid "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Relocation section [%2u] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Розділ пересування [%2u] «%s» за зміщенням %#0 містить %d запис:\n" +msgstr[1] "" +"\n" +"Розділ пересування [%2u] «%s» за зміщенням %#0 містить %d записи:\n" +msgstr[2] "" +"\n" +"Розділ пересування [%2u] «%s» за зміщенням %#0 містить %d записів:\n" + +#: src/readelf.c:2037 +msgid " Offset Type Value Name\n" +msgstr " Зміщення Тип Значення Назва\n" + +#: src/readelf.c:2039 +msgid " Offset Type Value Name\n" +msgstr " Зміщення Тип Значення Назва\n" + +#: src/readelf.c:2092 src/readelf.c:2103 src/readelf.c:2116 src/readelf.c:2137 +#: src/readelf.c:2149 src/readelf.c:2283 src/readelf.c:2295 src/readelf.c:2309 +#: src/readelf.c:2331 src/readelf.c:2344 +msgid "" +msgstr "<НЕКОРЕКТНЕ ПЕРЕМІЩЕННЯ>" + +#: src/readelf.c:2227 +msgid " Offset Type Value Addend Name\n" +msgstr " Зміщення Тип Значення Назва додатка\n" + +#: src/readelf.c:2229 +msgid " Offset Type Value Addend Name\n" +msgstr "" +" Зміщення Тип Значення Назва додатка\n" + +#: src/readelf.c:2467 +#, c-format +msgid "" +"\n" +"Symbol table [%2u] '%s' contains %u entry:\n" +msgid_plural "" +"\n" +"Symbol table [%2u] '%s' contains %u entries:\n" +msgstr[0] "" +"\n" +"Таблиця символів [%2u] «%s» містить %u запис:\n" +msgstr[1] "" +"\n" +"Таблиця символів [%2u] «%s» містить %u записи:\n" +msgstr[2] "" +"\n" +"Таблиця символів [%2u] «%s» містить %u записів:\n" + +#: src/readelf.c:2472 +#, c-format +msgid " %lu local symbol String table: [%2u] '%s'\n" +msgid_plural " %lu local symbols String table: [%2u] '%s'\n" +msgstr[0] " %lu лок. символ Таблиця символів: [%2u] «%s»\n" +msgstr[1] " %lu лок. символи Таблиця символів: [%2u] «%s»\n" +msgstr[2] " %lu лок. символів Таблиця символів: [%2u] «%s»\n" + +#: src/readelf.c:2480 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " №№ Знач. Роз. Тип Зв’яз Вид. Інд Назва\n" + +#: src/readelf.c:2482 +msgid " Num: Value Size Type Bind Vis Ndx Name\n" +msgstr " №№ Знач. Роз. Тип Зв’яз Вид. Інд Назва\n" + +#: src/readelf.c:2502 +#, c-format +msgid "%5u: %0* %6 %-7s %-6s %-9s %6s %s" +msgstr "%5u: %0* %6 %-7s %-6s %-9s %6s %s" + +#: src/readelf.c:2595 +#, c-format +msgid "bad dynamic symbol" +msgstr "помилковий динамічний символ" + +#: src/readelf.c:2680 +msgid "none" +msgstr "немає" + +#: src/readelf.c:2697 +msgid "| " +msgstr "| <невідомо>" + +#: src/readelf.c:2728 +#, c-format +msgid "" +"\n" +"Version needs section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version needs section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Розділ потреби у версіях [%2u] «%s», що містить %d запис:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" +msgstr[1] "" +"\n" +"Розділ потреби у версіях [%2u] «%s», що містить %d записи:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" +msgstr[2] "" +"\n" +"Розділ потреби у версіях [%2u] «%s», що містить %d записів:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" + +#: src/readelf.c:2749 +#, c-format +msgid " %#06x: Version: %hu File: %s Cnt: %hu\n" +msgstr " %#06x: Версія: %hu Файл: %s Кть: %hu\n" + +#: src/readelf.c:2762 +#, c-format +msgid " %#06x: Name: %s Flags: %s Version: %hu\n" +msgstr " %#06x: Назва: %s Прап: %s Версія: %hu\n" + +#: src/readelf.c:2805 +#, c-format +msgid "" +"\n" +"Version definition section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Version definition section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Розділ визначення версії [%2u] «%s», що містить %d запис:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" +msgstr[1] "" +"\n" +"Розділ визначення версії [%2u] «%s», що містить %d записи:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" +msgstr[2] "" +"\n" +"Розділ визначення версії [%2u] «%s», що містить %d записів:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" + +#: src/readelf.c:2833 +#, c-format +msgid " %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n" +msgstr " %#06x: Версія: %hd Прап.: %s Індекс: %hd К-ть: %hd Назва: %s\n" + +#: src/readelf.c:2848 +#, c-format +msgid " %#06x: Parent %d: %s\n" +msgstr " %#06x: батьківський %d: %s\n" + +#. Print the header. +#: src/readelf.c:3109 +#, c-format +msgid "" +"\n" +"Version symbols section [%2u] '%s' contains %d entry:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgid_plural "" +"\n" +"Version symbols section [%2u] '%s' contains %d entries:\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'" +msgstr[0] "" +"\n" +"Розділ символів версій [%2u] «%s», що містить %d запис:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»" +msgstr[1] "" +"\n" +"Розділ символів версій [%2u] «%s», що містить %d записи:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»" +msgstr[2] "" +"\n" +"Розділ символів версій [%2u] «%s», що містить %d записів:\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»" + +#: src/readelf.c:3137 +msgid " 0 *local* " +msgstr " 0 *локальний* " + +#: src/readelf.c:3142 +msgid " 1 *global* " +msgstr " 1 *загальний* " + +#: src/readelf.c:3184 +#, c-format +msgid "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"bucket):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgid_plural "" +"\n" +"Histogram for bucket list length in section [%2u] '%s' (total of %d " +"buckets):\n" +" Addr: %#0* Offset: %#08 Link to section: [%2u] '%s'\n" +msgstr[0] "" +"\n" +"Гістограма довжин списків блоків у розділі [%2u] «%s» (загальні дані за %d " +"блоком):\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" +msgstr[1] "" +"\n" +"Гістограма довжин списків блоків у розділі [%2u] «%s» (загальні дані за %d " +"блоками):\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" +msgstr[2] "" +"\n" +"Гістограма довжин списків блоків у розділі [%2u] «%s» (загальні дані за %d " +"блоками):\n" +" Адр.: %#0* Зміщ.: %#08 Посилання на розділ: [%2u] «%s»\n" + +#: src/readelf.c:3206 +#, no-c-format +msgid " Length Number % of total Coverage\n" +msgstr " Довжина Номер % від загал. Покриття\n" + +#: src/readelf.c:3208 +#, c-format +msgid " 0 %6 %5.1f%%\n" +msgstr " 0 %6 %5.1f%%\n" + +#: src/readelf.c:3215 +#, c-format +msgid "%7d %6 %5.1f%% %5.1f%%\n" +msgstr "%7d %6 %5.1f%% %5.1f%%\n" + +#: src/readelf.c:3228 +#, c-format +msgid "" +" Average number of tests: successful lookup: %f\n" +"\t\t\t unsuccessful lookup: %f\n" +msgstr "" +" Середня кількість тестів: успішний пошук: %f\n" +"\t\t\t неуспішний пошук: %f\n" + +#: src/readelf.c:3246 src/readelf.c:3310 src/readelf.c:3376 +#, c-format +msgid "cannot get data for section %d: %s" +msgstr "не вдалося отримати дані для розділу %d: %s" + +#: src/readelf.c:3254 +#, c-format +msgid "invalid data in sysv.hash section %d" +msgstr "некоректні дані у розділі sysv.hash %d" + +#: src/readelf.c:3283 +#, c-format +msgid "invalid chain in sysv.hash section %d" +msgstr "некоректний ланцюжок у розділі sysv.hash %d" + +#: src/readelf.c:3318 +#, c-format +msgid "invalid data in sysv.hash64 section %d" +msgstr "некоректні дані у розділі sysv.hash64 %d" + +#: src/readelf.c:3349 +#, c-format +msgid "invalid chain in sysv.hash64 section %d" +msgstr "некоректний ланцюжок у розділі sysv.hash64 %d" + +#: src/readelf.c:3385 +#, c-format +msgid "invalid data in gnu.hash section %d" +msgstr "некоректні дані у розділі gnu.hash %d" + +#: src/readelf.c:3452 +#, c-format +msgid "" +" Symbol Bias: %u\n" +" Bitmask Size: %zu bytes %%% bits set 2nd hash shift: %u\n" +msgstr "" +" Відхилення символу: %u\n" +" Розмір бітової маски: %zu байтів %%% встановлених бітів зсув " +"2-го хешу: %u\n" + +#: src/readelf.c:3541 +#, c-format +msgid "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entry:\n" +msgid_plural "" +"\n" +"Library list section [%2zu] '%s' at offset %#0 contains %d entries:\n" +msgstr[0] "" +"\n" +"Розділ списку бібліотек [%2zu] «%s» за зміщенням %#0 містить %d " +"запис:\n" +msgstr[1] "" +"\n" +"Розділ списку бібліотек [%2zu] «%s» за зміщенням %#0 містить %d " +"записи:\n" +msgstr[2] "" +"\n" +"Розділ списку бібліотек [%2zu] «%s» за зміщенням %#0 містить %d " +"записів:\n" + +#: src/readelf.c:3555 +msgid "" +" Library Time Stamp Checksum Version " +"Flags" +msgstr "" +" Бібліотека Часовий штамп Версія суми " +"Прапорці" + +#: src/readelf.c:3614 +#, c-format +msgid "" +"\n" +"Object attributes section [%2zu] '%s' of % bytes at offset " +"%#0:\n" +msgstr "" +"\n" +"Розділ атрибутів об’єктів [%2zu] «%s» з % байтів за зміщенням " +"%#0:\n" + +#: src/readelf.c:3631 +msgid " Owner Size\n" +msgstr " Власник Розмір\n" + +#: src/readelf.c:3655 +#, c-format +msgid " %-13s %4\n" +msgstr " %-13s %4\n" + +#. Unknown subsection, print and skip. +#: src/readelf.c:3694 +#, c-format +msgid " %-4u %12\n" +msgstr " %-4u %12\n" + +#. Tag_File +#: src/readelf.c:3699 +#, c-format +msgid " File: %11\n" +msgstr " Файл: %11\n" + +#: src/readelf.c:3748 +#, c-format +msgid " %s: %, %s\n" +msgstr " %s: %, %s\n" + +#: src/readelf.c:3751 +#, c-format +msgid " %s: %\n" +msgstr " %s: %\n" + +#: src/readelf.c:3754 +#, c-format +msgid " %s: %s\n" +msgstr " %s: %s\n" + +#: src/readelf.c:3764 +#, c-format +msgid " %u: %\n" +msgstr " %u: %\n" + +#: src/readelf.c:3767 +#, c-format +msgid " %u: %s\n" +msgstr " %u: %s\n" + +#: src/readelf.c:3837 +#, c-format +msgid "sprintf failure" +msgstr "помилка sprintf" + +#: src/readelf.c:4319 +msgid "empty block" +msgstr "порожній блок" + +#: src/readelf.c:4322 +#, c-format +msgid "%zu byte block:" +msgstr "%zu-байтовий блок:" + +#: src/readelf.c:4800 +#, c-format +msgid "%*s[%2] %s \n" +msgstr "%*s[%2] %s <ОБРІЗАНО>\n" + +#: src/readelf.c:4867 +#, c-format +msgid "%s %# used with different address sizes" +msgstr "%s %# використано з різними розмірами адрес" + +#: src/readelf.c:4874 +#, c-format +msgid "%s %# used with different offset sizes" +msgstr "%s %# використано з різними розмірами зміщень" + +#: src/readelf.c:4881 +#, c-format +msgid "%s %# used with different base addresses" +msgstr "%s %# використано з різними базовими адресами" + +#: src/readelf.c:4888 +#, c-format +msgid "%s %# used with different attribute %s and %s" +msgstr "%s %# використано з різними атрибутами, %s і %s" + +#: src/readelf.c:4988 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] <НЕВИКОРИСТОВУВАНІ ДАНІ У РЕШТІ РОЗДІЛУ>\n" + +#: src/readelf.c:4996 +#, c-format +msgid " [%6tx] ... % bytes ...\n" +msgstr " [%6tx] <НЕВИКОРИСТОВУВАНІ ДАНІ> ... % байтів ...\n" + +#: src/readelf.c:5099 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [ Code]\n" +msgstr "" +"\n" +"Розділ DWARF [%2zu] «%s» зі зміщенням %#:\n" +" [ Код]\n" + +#: src/readelf.c:5107 +#, c-format +msgid "" +"\n" +"Abbreviation section at offset %:\n" +msgstr "" +"\n" +"Розділ скорочень за зміщенням %:\n" + +#: src/readelf.c:5120 +#, c-format +msgid " *** error while reading abbreviation: %s\n" +msgstr " *** помилка під час читання скорочення: %s\n" + +#: src/readelf.c:5136 +#, c-format +msgid " [%5u] offset: %, children: %s, tag: %s\n" +msgstr " [%5u] зміщення: %, дочірній: %s, мітка: %s\n" + +#: src/readelf.c:5169 src/readelf.c:5478 src/readelf.c:5645 src/readelf.c:6030 +#: src/readelf.c:6646 src/readelf.c:8386 src/readelf.c:9075 src/readelf.c:9548 +#: src/readelf.c:9799 src/readelf.c:9965 src/readelf.c:10352 +#: src/readelf.c:10412 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Розділ DWARF [%2zu] «%s» зі зміщенням %#:\n" + +#: src/readelf.c:5182 +#, c-format +msgid "cannot get .debug_addr section data: %s" +msgstr "не вдалося отримати дані розділу .debug_addr: %s" + +#: src/readelf.c:5282 src/readelf.c:5306 src/readelf.c:5690 src/readelf.c:9120 +#, c-format +msgid " Length: %8\n" +msgstr " Довжина: %8\n" + +#: src/readelf.c:5284 src/readelf.c:5321 src/readelf.c:5703 src/readelf.c:9133 +#, c-format +msgid " DWARF version: %8\n" +msgstr " версія DWARF: %8\n" + +#: src/readelf.c:5285 src/readelf.c:5330 src/readelf.c:5712 src/readelf.c:9142 +#, c-format +msgid " Address size: %8\n" +msgstr " Розмір адреси: %8\n" + +#: src/readelf.c:5287 src/readelf.c:5340 src/readelf.c:5722 src/readelf.c:9152 +#, c-format +msgid " Segment size: %8\n" +msgstr "" +" Розмір сегмента: %8\n" +"\n" + +#: src/readelf.c:5325 src/readelf.c:5707 src/readelf.c:9137 src/readelf.c:10544 +#, c-format +msgid "Unknown version" +msgstr "Невідома версія" + +#: src/readelf.c:5335 src/readelf.c:5548 src/readelf.c:5717 src/readelf.c:9147 +#, c-format +msgid "unsupported address size" +msgstr "непідтримуваний розмір адреси" + +#: src/readelf.c:5346 src/readelf.c:5559 src/readelf.c:5727 src/readelf.c:9157 +#, c-format +msgid "unsupported segment size" +msgstr "непідтримуваний розмір сегмента" + +#: src/readelf.c:5399 src/readelf.c:5473 +#, c-format +msgid "cannot get .debug_aranges content: %s" +msgstr "не вдалося отримати дані get .debug_aranges: %s" + +#: src/readelf.c:5414 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entry:\n" +msgid_plural "" +"\n" +"DWARF section [%2zu] '%s' at offset %# contains %zu entries:\n" +msgstr[0] "" +"\n" +"Розділ DWARF [%2zu] «%s» за зміщенням %# містить %zu запис:\n" +msgstr[1] "" +"\n" +"Розділ DWARF [%2zu] «%s» за зміщенням %# містить %zu записи:\n" +msgstr[2] "" +"\n" +"Розділ DWARF [%2zu] «%s» за зміщенням %# містить %zu записів:\n" + +#: src/readelf.c:5445 +#, c-format +msgid " [%*zu] ???\n" +msgstr " [%*zu] ???\n" + +#: src/readelf.c:5447 +#, c-format +msgid "" +" [%*zu] start: %0#*, length: %5, CU DIE offset: %6\n" +msgstr "" +" [%*zu] початок: %0#*, довжина: %5, зміщення CU DIE: " +"%6\n" + +#: src/readelf.c:5491 src/readelf.c:8413 +#, c-format +msgid "" +"\n" +"Table at offset %zu:\n" +msgstr "" +"\n" +"Таблиця за зміщенням %zu:\n" + +#: src/readelf.c:5495 src/readelf.c:5671 src/readelf.c:6670 src/readelf.c:8424 +#: src/readelf.c:9101 +#, c-format +msgid "invalid data in section [%zu] '%s'" +msgstr "некоректні дані у розділі [%zu] «%s»" + +#: src/readelf.c:5511 +#, c-format +msgid "" +"\n" +" Length: %6\n" +msgstr "" +"\n" +" Довжина: %6\n" + +#: src/readelf.c:5523 +#, c-format +msgid " DWARF version: %6\n" +msgstr " версія DWARF: %6\n" + +#: src/readelf.c:5527 +#, c-format +msgid "unsupported aranges version" +msgstr "непідтримувана версія aranges" + +#: src/readelf.c:5538 +#, c-format +msgid " CU offset: %6\n" +msgstr " зміщення CU: %6\n" + +#: src/readelf.c:5544 +#, c-format +msgid " Address size: %6\n" +msgstr " Розмір адреси: %6\n" + +#: src/readelf.c:5555 +#, c-format +msgid "" +" Segment size: %6\n" +"\n" +msgstr "" +" Розмір сегмента: %6\n" +"\n" + +#: src/readelf.c:5610 +#, c-format +msgid " %zu padding bytes\n" +msgstr " %zu байтів доповнення\n" + +#: src/readelf.c:5654 +#, c-format +msgid "cannot get .debug_rnglists content: %s" +msgstr "не вдалося отримати вміст .debug_rnglists: %s" + +#: src/readelf.c:5677 src/readelf.c:9107 +#, c-format +msgid "" +"Table at Offset 0x%:\n" +"\n" +msgstr "" +"Таблиця за зміщенням 0x%:\n" +"\n" + +#: src/readelf.c:5732 src/readelf.c:9162 +#, c-format +msgid " Offset entries: %8\n" +msgstr " Записи зміщення: %8\n" + +#: src/readelf.c:5748 src/readelf.c:9178 +#, c-format +msgid " Unknown CU base: " +msgstr " Невідома основа CU: " + +#: src/readelf.c:5750 src/readelf.c:9180 +#, c-format +msgid " CU [%6] base: " +msgstr " Основа CU [%6]: " + +#: src/readelf.c:5756 src/readelf.c:9186 +#, c-format +msgid " Not associated with a CU.\n" +msgstr " Не пов'язано із CU.\n" + +#: src/readelf.c:5767 src/readelf.c:9197 +#, c-format +msgid "too many offset entries for unit length" +msgstr "забагато записів зсуву для довжини модуля" + +#: src/readelf.c:5771 src/readelf.c:9201 +#, c-format +msgid " Offsets starting at 0x%:\n" +msgstr " Зміщення, що починаються з 0x%:\n" + +#: src/readelf.c:5823 +#, c-format +msgid "invalid range list data" +msgstr "некоректні дані списку діапазонів" + +#: src/readelf.c:6008 src/readelf.c:9526 +#, c-format +msgid "" +" %zu padding bytes\n" +"\n" +msgstr "" +" %zu байтів доповнення\n" +"\n" + +#: src/readelf.c:6025 +#, c-format +msgid "cannot get .debug_ranges content: %s" +msgstr "не вдалося отримати дані .debug_ranges: %s" + +#: src/readelf.c:6061 src/readelf.c:9581 +#, c-format +msgid "" +"\n" +" Unknown CU base: " +msgstr "" +"\n" +" Невідома основа CU: " + +#: src/readelf.c:6063 src/readelf.c:9583 +#, c-format +msgid "" +"\n" +" CU [%6] base: " +msgstr "" +"\n" +" Основа CU [%6]: " + +#: src/readelf.c:6072 src/readelf.c:9609 src/readelf.c:9635 +#, c-format +msgid " [%6tx] \n" +msgstr " [%6tx] <НЕКОРЕКТНІ ДАНІ>\n" + +#: src/readelf.c:6097 src/readelf.c:9719 +#, fuzzy +msgid "base address" +msgstr " встановити адресу у значення " + +#: src/readelf.c:6107 src/readelf.c:9729 +#, c-format +msgid " [%6tx] empty list\n" +msgstr " [%6tx] порожній список\n" + +#: src/readelf.c:6367 +msgid " \n" +msgstr " <НЕКОРЕКТНІ ДАНІ>\n" + +#: src/readelf.c:6624 +#, c-format +msgid "cannot get ELF: %s" +msgstr "не вдалося отримати ELF: %s" + +#: src/readelf.c:6642 +#, c-format +msgid "" +"\n" +"Call frame information section [%2zu] '%s' at offset %#:\n" +msgstr "" +"\n" +"Розділ відомостей щодо вікна викликів [%2zu] «%s» за зміщенням %#:\n" + +#: src/readelf.c:6692 +#, c-format +msgid "" +"\n" +" [%6tx] Zero terminator\n" +msgstr "" +"\n" +" [%6tx] нульовий переривач\n" + +#: src/readelf.c:6793 src/readelf.c:6947 +#, c-format +msgid "invalid augmentation length" +msgstr "некоректна довжина збільшення" + +#: src/readelf.c:6808 +msgid "FDE address encoding: " +msgstr "Кодування адреси FDE: " + +#: src/readelf.c:6814 +msgid "LSDA pointer encoding: " +msgstr "Кодування вказівника LSDA: " + +#: src/readelf.c:6924 +#, c-format +msgid " (offset: %#)" +msgstr " (зміщення: %#)" + +#: src/readelf.c:6931 +#, c-format +msgid " (end offset: %#)" +msgstr " (зміщення від кінця: %#)" + +#: src/readelf.c:6968 +#, c-format +msgid " %-26sLSDA pointer: %#\n" +msgstr " %-26sвказівник LSDA: %#\n" + +#: src/readelf.c:7053 +#, c-format +msgid "DIE [%] cannot get attribute code: %s" +msgstr "DIE [%] не вдалося отримати код атрибута: %s" + +#: src/readelf.c:7063 +#, c-format +msgid "DIE [%] cannot get attribute form: %s" +msgstr "DIE [%] не вдалося отримати форму атрибута: %s" + +#: src/readelf.c:7085 +#, c-format +msgid "DIE [%] cannot get attribute '%s' (%s) value: %s" +msgstr "DIE [%] не вдалося отримати значення атрибута «%s» (%s): %s" + +#: src/readelf.c:7415 +#, c-format +msgid "invalid file (%): %s" +msgstr "некоректний файл (%): %s" + +#: src/readelf.c:7419 +#, c-format +msgid "no srcfiles for CU [%]" +msgstr "немає srcfiles для CU [%]" + +#: src/readelf.c:7423 +#, c-format +msgid "couldn't get DWARF CU: %s" +msgstr "не вдалося отримати CU DWARF: %s" + +#: src/readelf.c:7738 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" [Offset]\n" +msgstr "" +"\n" +"Розділ DWARF [%2zu] «%s» за зміщенням %#:\n" +" [Зміщення]\n" + +#: src/readelf.c:7788 +#, c-format +msgid "cannot get next unit: %s" +msgstr "не вдалося отримати наступний модуль: %s" + +#: src/readelf.c:7808 +#, c-format +msgid "" +" Type unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +" Type signature: %#, Type offset: %# [%]\n" +msgstr "" +" Модуль типів за зміщенням %:\n" +" Версія: %, Зміщення розділу скорочень: %, Розмір адреси: " +"%, Розмір зміщення: %\n" +" Підпис типу: %#, Зміщення типу: %# [%]\n" + +#: src/readelf.c:7820 +#, c-format +msgid "" +" Compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Модуль компіляції за зміщенням %:\n" +" Версія: %, Зміщення розділу скорочень: %, Адреса: %, " +"Зміщення: %\n" + +#: src/readelf.c:7830 src/readelf.c:7993 +#, c-format +msgid " Unit type: %s (%)" +msgstr " Тип модуля: %s (%)" + +#: src/readelf.c:7857 +#, c-format +msgid "unknown version (%d) or unit type (%d)" +msgstr "невідома версія (%d) або тип модуля (%d)" + +#: src/readelf.c:7886 +#, c-format +msgid "cannot get DIE offset: %s" +msgstr "не вдалося отримати зміщення DIE: %s" + +#: src/readelf.c:7895 +#, c-format +msgid "cannot get tag of DIE at offset [%] in section '%s': %s" +msgstr "" +"не вдалося отримати мітку DIE за зміщенням [%] у розділі «%s»: %s" + +#: src/readelf.c:7933 +#, c-format +msgid "cannot get next DIE: %s\n" +msgstr "не вдалося визначити наступний DIE: %s\n" + +#: src/readelf.c:7941 +#, c-format +msgid "cannot get next DIE: %s" +msgstr "не вдалося визначити наступний DIE: %s" + +#: src/readelf.c:7985 +#, c-format +msgid "" +" Split compilation unit at offset %:\n" +" Version: %, Abbreviation section offset: %, Address size: " +"%, Offset size: %\n" +msgstr "" +" Модуль розділеної компіляції за зміщенням %:\n" +" Версія: %, Зміщення розділу скорочень: %, Адреса: %, " +"Зміщення: %\n" + +#: src/readelf.c:8037 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +"\n" +msgstr "" +"\n" +"Розділ DWARF [%2zu] «%s» зі зміщенням %#:\n" +"\n" + +#: src/readelf.c:8369 +#, c-format +msgid "unknown form: %s" +msgstr "невідома форма: %s" + +#: src/readelf.c:8400 +#, c-format +msgid "cannot get line data section data: %s" +msgstr "не вдалося отримати дані розділу лінійних даних: %s" + +#. Print what we got so far. +#: src/readelf.c:8502 +#, c-format +msgid "" +"\n" +" Length: %\n" +" DWARF version: %\n" +" Prologue length: %\n" +" Address size: %zd\n" +" Segment selector size: %zd\n" +" Min instruction length: %\n" +" Max operations per instruction: %\n" +" Initial value if 'is_stmt': %\n" +" Line base: %\n" +" Line range: %\n" +" Opcode base: %\n" +"\n" +"Opcodes:\n" +msgstr "" +"\n" +" Довжина: %\n" +" Версія DWARF: %\n" +" Довжина вступу: %\n" +" Розмір адреси: %zd\n" +" Розмір селектора сегментів: %zd\n" +" Мінімальна довж. інстр.: %\n" +" Макс. к-ть операцій на інструкцію: %\n" +" Поч. значення, якщо «is_stmt»: %\n" +" Основа рядків: %\n" +" Діапазон рядків: %\n" +" Основа кодів операцій: %\n" +"\n" +"Коди операцій:\n" + +#: src/readelf.c:8524 +#, c-format +msgid "cannot handle .debug_line version: %u\n" +msgstr "не вдалося обробити версію .debug_line: %u\n" + +#: src/readelf.c:8532 +#, c-format +msgid "cannot handle address size: %u\n" +msgstr "не вдалося обробити розмір адреси: %u\n" + +#: src/readelf.c:8540 +#, c-format +msgid "cannot handle segment selector size: %u\n" +msgstr "не вдалося обробити розмір селектора сегментів: %u\n" + +#: src/readelf.c:8550 +#, c-format +msgid "invalid data at offset %tu in section [%zu] '%s'" +msgstr "некоректні дані зі зміщенням %tu у розділі [%zu] «%s»" + +#: src/readelf.c:8565 +#, c-format +msgid " [%*] %hhu argument\n" +msgid_plural " [%*] %hhu arguments\n" +msgstr[0] " [%*] %hhu аргумент\n" +msgstr[1] " [%*] %hhu аргументи\n" +msgstr[2] " [%*] %hhu аргументів\n" + +#: src/readelf.c:8576 +msgid "" +"\n" +"Directory table:" +msgstr "" +"\n" +"Таблиця каталогу:" + +#: src/readelf.c:8582 src/readelf.c:8659 +#, c-format +msgid " [" +msgstr " [" + +#: src/readelf.c:8653 +msgid "" +"\n" +"File name table:" +msgstr "" +"\n" +" Таблиця назв файлів:" + +#: src/readelf.c:8714 +msgid " Entry Dir Time Size Name" +msgstr " Запис Кат Час Розмір Назва" + +#: src/readelf.c:8753 +#, fuzzy +msgid "" +"\n" +"No line number statements." +msgstr "" +"\n" +"Оператори номерів рядків:" + +#: src/readelf.c:8757 +msgid "" +"\n" +"Line number statements:" +msgstr "" +"\n" +"Оператори номерів рядків:" + +#: src/readelf.c:8777 +#, c-format +msgid "invalid maximum operations per instruction is zero" +msgstr "некоректну кількість операцій на інструкцію прирівняно до нуля" + +#: src/readelf.c:8811 +#, c-format +msgid " special opcode %u: address+%u = " +msgstr " спеціальний код операції %u: адреса+%u = " + +#: src/readelf.c:8815 +#, c-format +msgid ", op_index = %u, line%+d = %zu\n" +msgstr ", індекс_оп = %u, рядок%+d = %zu\n" + +#: src/readelf.c:8818 +#, c-format +msgid ", line%+d = %zu\n" +msgstr ", рядок%+d = %zu\n" + +#: src/readelf.c:8836 +#, c-format +msgid " extended opcode %u: " +msgstr " розширений код операції %u: " + +#: src/readelf.c:8841 +msgid " end of sequence" +msgstr " кінець послідовності" + +#: src/readelf.c:8859 +#, c-format +msgid " set address to " +msgstr " встановити адресу у значення " + +#: src/readelf.c:8887 +#, c-format +msgid " define new file: dir=%u, mtime=%, length=%, name=%s\n" +msgstr "" +" визначення нового файла: dir=%u, mtime=%, довжина=%, назва=" +"%s\n" + +#: src/readelf.c:8901 +#, c-format +msgid " set discriminator to %u\n" +msgstr " встановити розрізнення для %u\n" + +#. Unknown, ignore it. +#: src/readelf.c:8906 +msgid " unknown opcode" +msgstr " невідомий код операції" + +#. Takes no argument. +#: src/readelf.c:8918 +msgid " copy" +msgstr " копія" + +#: src/readelf.c:8929 +#, c-format +msgid " advance address by %u to " +msgstr " збільшення адреси на %u до " + +#: src/readelf.c:8933 src/readelf.c:8994 +#, c-format +msgid ", op_index to %u" +msgstr ", op_index до %u" + +#: src/readelf.c:8945 +#, c-format +msgid " advance line by constant %d to %\n" +msgstr " просувати рядок на сталу %d до %\n" + +#: src/readelf.c:8955 +#, c-format +msgid " set file to %\n" +msgstr " встановити файл у %\n" + +#: src/readelf.c:8966 +#, c-format +msgid " set column to %\n" +msgstr " встановити значення стовпчика %\n" + +#: src/readelf.c:8973 +#, c-format +msgid " set '%s' to %\n" +msgstr " встановити «%s» у %\n" + +#. Takes no argument. +#: src/readelf.c:8979 +msgid " set basic block flag" +msgstr " встановити прапорець базового блоку" + +#: src/readelf.c:8990 +#, c-format +msgid " advance address by constant %u to " +msgstr " збільшити адресу на сталу величину %u до " + +#: src/readelf.c:9010 +#, c-format +msgid " advance address by fixed value %u to \n" +msgstr " збільшити адресу на фіксовану величину %u до \n" + +#. Takes no argument. +#: src/readelf.c:9020 +msgid " set prologue end flag" +msgstr " встановити прапорець кінця вступу" + +#. Takes no argument. +#: src/readelf.c:9025 +msgid " set epilogue begin flag" +msgstr " встановити прапорець початку епілогу" + +#: src/readelf.c:9035 +#, c-format +msgid " set isa to %u\n" +msgstr " встановити isa у %u\n" + +#. This is a new opcode the generator but not we know about. +#. Read the parameters associated with it but then discard +#. everything. Read all the parameters for this opcode. +#: src/readelf.c:9044 +#, c-format +msgid " unknown opcode with % parameter:" +msgid_plural " unknown opcode with % parameters:" +msgstr[0] " невідомий код операції з % параметром:" +msgstr[1] " невідомий код операції з % параметрами:" +msgstr[2] " невідомий код операції з % параметрами:" + +#: src/readelf.c:9084 +#, c-format +msgid "cannot get .debug_loclists content: %s" +msgstr "не вдалося отримати вміст .debug_loclists: %s" + +#: src/readelf.c:9250 +#, fuzzy, c-format +msgid " \n" +msgstr " <НЕКОРЕКТНІ ДАНІ>\n" + +#: src/readelf.c:9290 +#, c-format +msgid "invalid loclists data" +msgstr "некоректні дані loclists" + +#: src/readelf.c:9543 +#, c-format +msgid "cannot get .debug_loc content: %s" +msgstr "не вдалося отримати вміст .debug_loc: %s" + +#: src/readelf.c:9756 src/readelf.c:10800 +msgid " \n" +msgstr " <НЕКОРЕКТНІ ДАНІ>\n" + +#: src/readelf.c:9811 src/readelf.c:9974 +#, c-format +msgid "cannot get macro information section data: %s" +msgstr "не вдалося отримати дані розділу відомостей щодо макросів: %s" + +#: src/readelf.c:9891 +#, c-format +msgid "%*s*** non-terminated string at end of section" +msgstr "%*s*** незавершений рядок наприкінці розділу" + +#: src/readelf.c:9914 +#, c-format +msgid "%*s*** missing DW_MACINFO_start_file argument at end of section" +msgstr "%*s*** пропущено аргумент DW_MACINFO_start_file наприкінці розділу" + +#: src/readelf.c:10015 +#, c-format +msgid " Offset: 0x%\n" +msgstr " Зміщення: 0x%\n" + +#: src/readelf.c:10027 +#, c-format +msgid " Version: %\n" +msgstr " Версія: %\n" + +#: src/readelf.c:10033 src/readelf.c:10920 +#, c-format +msgid " unknown version, cannot parse section\n" +msgstr " невідома версія, не вдалося обробити розділ\n" + +#: src/readelf.c:10040 +#, c-format +msgid " Flag: 0x%" +msgstr " Прапорець: 0x%" + +#: src/readelf.c:10069 +#, c-format +msgid " Offset length: %\n" +msgstr " Довжина зміщення: %\n" + +#: src/readelf.c:10077 +#, c-format +msgid " .debug_line offset: 0x%\n" +msgstr " зміщення .debug_line: 0x%\n" + +#: src/readelf.c:10102 +#, c-format +msgid " extension opcode table, % items:\n" +msgstr " таблиця кодів операцій розширень, записів — %:\n" + +#: src/readelf.c:10109 +#, c-format +msgid " [%]" +msgstr " [%]" + +#: src/readelf.c:10121 +#, c-format +msgid " % arguments:" +msgstr " % аргументів:" + +#: src/readelf.c:10136 +#, c-format +msgid " no arguments." +msgstr " немає аргументів." + +#: src/readelf.c:10337 +#, c-format +msgid " [%5d] DIE offset: %6, CU DIE offset: %6, name: %s\n" +msgstr "" +" [%5d] зміщення DIE: %6, зміщення CU DIE: %6, назва: %s\n" + +#: src/readelf.c:10381 +#, c-format +msgid "" +"\n" +"DWARF section [%2zu] '%s' at offset %#:\n" +" %*s String\n" +msgstr "" +"\n" +"Розділ DWARF [%2zu] «%s» зі зміщенням %#:\n" +" %*s Рядок\n" + +#. TRANS: the debugstr| prefix makes the string unique. +#: src/readelf.c:10386 +msgctxt "debugstr" +msgid "Offset" +msgstr "" + +#: src/readelf.c:10396 +#, c-format +msgid " *** error, missing string terminator\n" +msgstr " *** помилка, пропущено роздільник рядків\n" + +#: src/readelf.c:10425 +#, c-format +msgid "cannot get .debug_str_offsets section data: %s" +msgstr "не вдалося отримати дані розділу .debug_str_offsets: %s" + +#: src/readelf.c:10524 +#, c-format +msgid " Length: %8\n" +msgstr " Довжина: %8\n" + +#: src/readelf.c:10526 +#, c-format +msgid " Offset size: %8\n" +msgstr " Розмір зсуву: %8\n" + +#: src/readelf.c:10540 +#, c-format +msgid " DWARF version: %8\n" +msgstr " версія DWARF: %8\n" + +#: src/readelf.c:10549 +#, c-format +msgid " Padding: %8\n" +msgstr " Заповнення: %8\n" + +#: src/readelf.c:10603 +#, c-format +msgid "" +"\n" +"Call frame search table section [%2zu] '.eh_frame_hdr':\n" +msgstr "" +"\n" +"Розділ таблиці пошуку вікон виклику [%2zu] '.eh_frame_hdr':\n" + +#: src/readelf.c:10705 +#, c-format +msgid "" +"\n" +"Exception handling table section [%2zu] '.gcc_except_table':\n" +msgstr "" +"\n" +"Розділ таблиці обробки виключень [%2zu] '.gcc_except_table':\n" + +#: src/readelf.c:10728 +#, c-format +msgid " LPStart encoding: %#x " +msgstr " Кодування LPStart: %#x " + +#: src/readelf.c:10740 +#, c-format +msgid " TType encoding: %#x " +msgstr " Кодування TType: %#x " + +#: src/readelf.c:10755 +#, c-format +msgid " Call site encoding: %#x " +msgstr " Кодування місця виклику:%#x " + +#: src/readelf.c:10768 +msgid "" +"\n" +" Call site table:" +msgstr "" +"\n" +" Таблиця місця виклику:" + +#: src/readelf.c:10782 +#, c-format +msgid "" +" [%4u] Call site start: %#\n" +" Call site length: %\n" +" Landing pad: %#\n" +" Action: %u\n" +msgstr "" +" [%4u] Поч. місця виклику: %#\n" +" Довж. місця виклику: %\n" +" Місце застосування: %#\n" +" Дія: %u\n" + +#: src/readelf.c:10855 +#, c-format +msgid "invalid TType encoding" +msgstr "некоректне кодування TType" + +#: src/readelf.c:10882 +#, c-format +msgid "" +"\n" +"GDB section [%2zu] '%s' at offset %# contains % bytes :\n" +msgstr "" +"\n" +"Розділ GDB [%2zu] «%s» за зміщенням %# містить % байтів:\n" + +#: src/readelf.c:10911 +#, c-format +msgid " Version: %\n" +msgstr " Версія: %\n" + +#: src/readelf.c:10929 +#, c-format +msgid " CU offset: %#\n" +msgstr " зміщення CU: %#\n" + +#: src/readelf.c:10936 +#, c-format +msgid " TU offset: %#\n" +msgstr " зміщення TU: %#\n" + +#: src/readelf.c:10943 +#, c-format +msgid " address offset: %#\n" +msgstr " зміщення адреси: %#\n" + +#: src/readelf.c:10950 +#, c-format +msgid " symbol offset: %#\n" +msgstr " зміщення символу: %#\n" + +#: src/readelf.c:10957 +#, c-format +msgid " constant offset: %#\n" +msgstr " стале зміщення: %#\n" + +#: src/readelf.c:10971 +#, c-format +msgid "" +"\n" +" CU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Список CU зі зміщенням %# містить %zu записів:\n" + +#: src/readelf.c:10996 +#, c-format +msgid "" +"\n" +" TU list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Список TU зі зміщенням %# містить %zu записів:\n" + +#: src/readelf.c:11025 +#, c-format +msgid "" +"\n" +" Address list at offset %# contains %zu entries:\n" +msgstr "" +"\n" +" Список адрес зі зміщенням %# містить %zu записів:\n" + +#: src/readelf.c:11057 +#, c-format +msgid "" +"\n" +" Symbol table at offset %# contains %zu slots:\n" +msgstr "" +"\n" +" Таблиця символів за зміщенням %# містить %zu позицій:\n" + +#: src/readelf.c:11195 +#, c-format +msgid "cannot get debug context descriptor: %s" +msgstr "не вдалося отримати дескриптор контексту зневаджування: %s" + +#: src/readelf.c:11563 src/readelf.c:12190 src/readelf.c:12301 +#: src/readelf.c:12359 +#, c-format +msgid "cannot convert core note data: %s" +msgstr "не вдалося перетворити дані запису ядра: %s" + +#: src/readelf.c:11926 +#, c-format +msgid "" +"\n" +"%*s... ..." +msgstr "" +"\n" +"%*s... <повторюється %u разів> ..." + +#: src/readelf.c:12438 +msgid " Owner Data size Type\n" +msgstr " Власник Розм. даних Тип\n" + +#: src/readelf.c:12466 +#, c-format +msgid " %-13.*s %9 %s\n" +msgstr " %-13.*s %9 %s\n" + +#: src/readelf.c:12518 +#, c-format +msgid "cannot get content of note: %s" +msgstr "не вдалося отримати вміст нотатки: %s" + +#: src/readelf.c:12552 +#, c-format +msgid "" +"\n" +"Note section [%2zu] '%s' of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Розділ записів (note) [%2zu] «%s» з % байтів за зміщенням " +"%#0:\n" + +#: src/readelf.c:12575 +#, c-format +msgid "" +"\n" +"Note segment of % bytes at offset %#0:\n" +msgstr "" +"\n" +"Сегмент записів з % байтів за зміщенням %#0:\n" + +#: src/readelf.c:12622 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no data to dump.\n" +msgstr "" +"\n" +"У розділі [%zu] «%s» не міститься даних для створення дампу.\n" + +#: src/readelf.c:12649 src/readelf.c:12700 +#, c-format +msgid "cannot get data for section [%zu] '%s': %s" +msgstr "не вдалося отримати дані для розділу [%zu] «%s»: %s" + +#: src/readelf.c:12654 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes at offset %#0:\n" +msgstr "" +"\n" +"Шіст. дамп розділу [%zu] «%s», % байтів за зміщенням %#0:\n" + +#: src/readelf.c:12659 +#, c-format +msgid "" +"\n" +"Hex dump of section [%zu] '%s', % bytes (%zd uncompressed) at offset " +"%#0:\n" +msgstr "" +"\n" +"Шіст. дамп розділу [%zu] «%s», % байтів (%zd нестиснено) за " +"зміщенням %#0:\n" + +#: src/readelf.c:12673 +#, c-format +msgid "" +"\n" +"Section [%zu] '%s' has no strings to dump.\n" +msgstr "" +"\n" +"У розділі [%zu] «%s» не міститься рядків для створення дампу.\n" + +#: src/readelf.c:12705 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes at offset %#0:\n" +msgstr "" +"\n" +"Розділ рядків [%zu] «%s» містить % байтів за зміщенням %#0:\n" + +#: src/readelf.c:12710 +#, c-format +msgid "" +"\n" +"String section [%zu] '%s' contains % bytes (%zd uncompressed) at " +"offset %#0:\n" +msgstr "" +"\n" +"Рядок розділу [%zu] «%s» містить % байти (%zd нестиснено) на " +"зміщенні %#0:\n" + +#: src/readelf.c:12759 +#, c-format +msgid "" +"\n" +"section [%lu] does not exist" +msgstr "" +"\n" +"розділу [%lu] не існує" + +#: src/readelf.c:12789 +#, c-format +msgid "" +"\n" +"section '%s' does not exist" +msgstr "" +"\n" +"розділу «%s» не існує" + +#: src/readelf.c:12846 +#, c-format +msgid "cannot get symbol index of archive '%s': %s" +msgstr "не вдалося отримати покажчик символів архіву «%s»: %s" + +#: src/readelf.c:12849 +#, c-format +msgid "" +"\n" +"Archive '%s' has no symbol index\n" +msgstr "" +"\n" +"У архіві «%s» немає покажчика символів\n" + +#: src/readelf.c:12853 +#, c-format +msgid "" +"\n" +"Index of archive '%s' has %zu entries:\n" +msgstr "" +"\n" +"Покажчик архіву «%s» містить %zu записів:\n" + +#: src/readelf.c:12871 +#, c-format +msgid "cannot extract member at offset %zu in '%s': %s" +msgstr "не вдалося видобути елемент за зміщенням %zu у «%s»: %s" + +#: src/readelf.c:12876 +#, c-format +msgid "Archive member '%s' contains:\n" +msgstr "Елемент архіву «%s» містить:\n" + +#: src/size.c:56 +msgid "" +"Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. The default " +"is `bsd'" +msgstr "" +"Використовувати формат виводу ФОРМАТ. ФОРМАТом може бути «bsd» або «sysv». " +"Типовим є значення «bsd»" + +#: src/size.c:58 +msgid "Same as `--format=sysv'" +msgstr "Те саме, що і «--format=sysv»" + +#: src/size.c:59 +msgid "Same as `--format=bsd'" +msgstr "Те саме, що і «--format=bsd»" + +#: src/size.c:62 +msgid "Same as `--radix=10'" +msgstr "Те саме, що і «--radix=10»" + +#: src/size.c:63 +msgid "Same as `--radix=8'" +msgstr "Те саме, що і «--radix=8»" + +#: src/size.c:64 +msgid "Same as `--radix=16'" +msgstr "Те саме, що і «--radix=16»" + +#: src/size.c:66 +msgid "Similar to `--format=sysv' output but in one line" +msgstr "Вивід даних у форматі, подібному до «--format=sysv», але у один рядок" + +#: src/size.c:70 +msgid "Print size and permission flags for loadable segments" +msgstr "" +"Вивести розмір і прапорці прав доступу для придатних до завантаження " +"сегментів" + +#: src/size.c:71 +msgid "Display the total sizes (bsd only)" +msgstr "Показувати загальні розміри (лише bsd)" + +#. Short description of program. +#: src/size.c:76 +msgid "List section sizes of FILEs (a.out by default)." +msgstr "Показати розміри розділів ФАЙЛів (типово a.out)." + +#: src/size.c:240 +#, c-format +msgid "Invalid format: %s" +msgstr "Некоректний формат: %s" + +#: src/size.c:251 +#, c-format +msgid "Invalid radix: %s" +msgstr "Некоректна основа числення: %s" + +#: src/size.c:310 +#, c-format +msgid "%s: file format not recognized" +msgstr "%s: не вдалося розпізнати формат файла" + +#: src/size.c:328 +msgctxt "bsd" +msgid "text" +msgstr "" + +#: src/size.c:329 +msgctxt "bsd" +msgid "data" +msgstr "" + +#: src/size.c:330 +msgctxt "bsd" +msgid "bss" +msgstr "" + +#: src/size.c:331 +msgctxt "bsd" +msgid "dec" +msgstr "" + +#: src/size.c:332 +msgctxt "bsd" +msgid "hex" +msgstr "" + +#: src/size.c:333 +msgctxt "bsd" +msgid "filename" +msgstr "" + +#: src/size.c:418 src/size.c:560 +#, c-format +msgid " (ex %s)" +msgstr " (прикл. %s)" + +#: src/size.c:420 +#, fuzzy +#| msgid "invalid section" +msgctxt "sysv" +msgid "section" +msgstr "некоректний розділ" + +#: src/size.c:421 +msgctxt "sysv" +msgid "size" +msgstr "" + +#: src/size.c:422 +msgctxt "sysv" +msgid "addr" +msgstr "" + +#: src/size.c:451 src/size.c:454 src/size.c:457 +msgctxt "sysv" +msgid "Total" +msgstr "" + +#: src/size.c:482 +#, c-format +msgid "cannot get section header" +msgstr "не вдалося отримати заголовок розділу" + +#: src/size.c:585 +msgid "(TOTALS)\n" +msgstr "(ЗАГАЛОМ)\n" + +#: src/stack.c:487 +#, c-format +msgid "-p PID should be a positive process id." +msgstr "PID у -p PID має бути додатним значенням ідентифікатора процесу." + +#: src/stack.c:493 +#, c-format +msgid "Cannot open core file '%s'" +msgstr "Не вдалося відкрити файл дампу ядра «%s»" + +#: src/stack.c:553 +#, c-format +msgid "-n MAXFRAMES should be 0 or higher." +msgstr "MAXFRAMES у -n має бути значенням рівним 0 або більшим." + +#: src/stack.c:565 +#, c-format +msgid "-e EXEC needs a core given by --core." +msgstr "Для -e EXEC слід вказати ядро за допомогою --core." + +#: src/stack.c:569 +#, c-format +msgid "-1 needs a thread id given by -p." +msgstr "-1 слід передати ідентифікатор потоку виконання, заданого -p." + +#: src/stack.c:573 +#, c-format +msgid "One of -p PID or --core COREFILE should be given." +msgstr "Слід вказати -p PID або --core COREFILE." + +#: src/stack.c:645 +msgid "Show stack of process PID" +msgstr "Вивести стек PID процесу" + +#: src/stack.c:647 +msgid "Show stack found in COREFILE" +msgstr "Вивести стек, знайдений у COREFILE" + +#: src/stack.c:648 +msgid "(optional) EXECUTABLE that produced COREFILE" +msgstr "(необов’язковий) EXECUTABLE, яким створено COREFILE" + +#: src/stack.c:652 +msgid "Output selection options:" +msgstr "Параметри вибору виведених даних:" + +#: src/stack.c:654 +msgid "Additionally show frame activation" +msgstr "Додатково вивести активацію вікна" + +#: src/stack.c:656 +msgid "Additionally try to lookup DWARF debuginfo name for frame address" +msgstr "" +"Додатково спробувати визначити назву файла даних діагностики DWARF для " +"адреси вікна" + +#: src/stack.c:659 +msgid "" +"Additionally show inlined function frames using DWARF debuginfo if available " +"(implies -d)" +msgstr "" +"Додатково вивести вікна вбудованих функцій за допомогою даних діагностики " +"DWARF, якщо такі є (використовується і -d)" + +#: src/stack.c:661 +msgid "Additionally show module file information" +msgstr "Додатково вивести дані щодо файла модуля" + +#: src/stack.c:663 +msgid "Additionally show source file information" +msgstr "Додатково вивести дані щодо файла початкового коду" + +#: src/stack.c:665 +msgid "" +"Show all additional information (activation, debugname, inlines, module and " +"source)" +msgstr "" +"Вивести усі додаткові дані (активацію, назву у системі діагностики, " +"вбудовані функції, модуль і початковий файл)" + +#: src/stack.c:667 +msgid "Do not resolve address to function symbol name" +msgstr "Не розгортати адресу до назви символу функції" + +#: src/stack.c:669 +msgid "Show raw function symbol names, do not try to demangle names" +msgstr "" +"Вивести назви символів функцій без обробки, не намагатися розшифрувати назви" + +#: src/stack.c:671 +msgid "Show module build-id, load address and pc offset" +msgstr "Виводити ідентифікатор збирання, адресу завантаження та зсув модуля" + +#: src/stack.c:673 +msgid "Show the backtrace of only one thread" +msgstr "Виводити зворотне трасування лише одного потоку" + +#: src/stack.c:675 +msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)" +msgstr "" +"Виводити не більше MAXFRAMES на потік виконання (типове значення 256, 0 — не " +"обмежувати)" + +#: src/stack.c:677 +msgid "Show module memory map with build-id, elf and debug files detected" +msgstr "" +"Вивести карту пам’яті модуля із виявленими ідентифікатором збирання, elf та " +"файлами діагностичних даних" + +#: src/stack.c:685 +msgid "" +"Print a stack for each thread in a process or core file.\n" +"\n" +"Program exits with return code 0 if all frames were shown without any " +"errors. If some frames were shown, but there were some non-fatal errors, " +"possibly causing an incomplete backtrace, the program exits with return code " +"1. If no frames could be shown, or a fatal error occurred the program exits " +"with return code 2. If the program was invoked with bad or missing " +"arguments it will exit with return code 64." +msgstr "" +"Вивести стек для кожного потоку у процесі або файлі дампу ядра.\n" +"\n" +"Програма завершує роботу з кодом виходу 0, якщо усі вікна було виведено без " +"помилок. Якщо деякі вікна було показано, але сталися некритичні помилки, " +"ймовірно спричинені неповними даними зворотного трасування, програма " +"завершує роботу з кодом повернення 1. Якщо не вдалося вивести жодного вікна " +"або сталася критична помилка, програма виходить з кодом повернення 2. Якщо " +"програму було викликано з помилковими або пропущеними аргументами, програма " +"завершить роботу з кодом виходу 64." + +#: src/stack.c:760 +#, c-format +msgid "Couldn't show any frames." +msgstr "Не вдалося вивести жодного вікна." + +#: src/strings.c:65 +msgid "Output Selection:" +msgstr "Вибір виводу:" + +#: src/strings.c:66 +msgid "Scan entire file, not only loaded sections" +msgstr "Шукати у всьому файлі, а не лише у завантажених розділах" + +#: src/strings.c:68 +msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed" +msgstr "" +"Буде виведено лише послідовності з не менше, ніж MIN-LEN символів, що " +"завершуються на NUL" + +#: src/strings.c:69 +msgid "" +"Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, " +"{B,L} = 32-bit" +msgstr "" +"Визначення розмірності та порядку бітів символів: s = 7-бітові, S = 8-" +"бітові, {b,l} = 16-бітові, {B,L} = 32-бітові" + +#: src/strings.c:73 +msgid "Print name of the file before each string." +msgstr "Виводити назву файла перед кожним рядком." + +#: src/strings.c:75 +msgid "Print location of the string in base 8, 10, or 16 respectively." +msgstr "Виводити адресу рядка за основами 8, 10 та 16, відповідно." + +#: src/strings.c:76 +msgid "Alias for --radix=o" +msgstr "Замінник --radix=o" + +#. Short description of program. +#: src/strings.c:83 +msgid "Print the strings of printable characters in files." +msgstr "Вивести рядки файлів з символів, придатних для друку." + +#: src/strings.c:256 src/strings.c:291 +#, c-format +msgid "invalid value '%s' for %s parameter" +msgstr "некоректне значення «%s» параметра %s" + +#: src/strings.c:302 +#, c-format +msgid "invalid minimum length of matched string size" +msgstr "некоректна мінімальна довжина розмірності рядка для порівняння" + +#: src/strings.c:585 +#, c-format +msgid "lseek failed" +msgstr "помилка lseek" + +#: src/strings.c:602 src/strings.c:666 +#, c-format +msgid "re-mmap failed" +msgstr "помилка повторного використання mmap" + +#: src/strings.c:639 +#, c-format +msgid "mprotect failed" +msgstr "помилка mprotect" + +#: src/strings.c:728 +#, c-format +msgid "Skipping section %zd '%s' data outside file" +msgstr "Пропускаємо дані %zd «%s» поза файлом" + +#: src/strip.c:71 +msgid "Place stripped output into FILE" +msgstr "Вивести дані після вилучення до ФАЙЛа" + +#: src/strip.c:72 +msgid "Extract the removed sections into FILE" +msgstr "Видобути вилучені розділи до ФАЙЛа" + +#: src/strip.c:73 +msgid "Embed name FILE instead of -f argument" +msgstr "Вбудувати назву ФАЙЛа замість аргументу -f" + +#: src/strip.c:77 +msgid "Remove all debugging symbols" +msgstr "Вилучити всі символи зневаджування" + +#: src/strip.c:81 +msgid "Remove section headers (not recommended)" +msgstr "Вилучити заголовки розділів (не рекомендовано)" + +#: src/strip.c:83 +msgid "Copy modified/access timestamps to the output" +msgstr "Скопіювати часові позначки зміни/доступу до виведених даних" + +#: src/strip.c:85 +msgid "" +"Resolve all trivial relocations between debug sections if the removed " +"sections are placed in a debug file (only relevant for ET_REL files, " +"operation is not reversible, needs -f)" +msgstr "" +"Розв’язати всі очевидні пересування між діагностичними розділами, якщо " +"вилучені розділи було розташовано у діагностичному файлі (стосується лише " +"файлів ET_REL, скасувати дію неможливо, потребує параметра -f)" + +#: src/strip.c:87 +msgid "" +"Similar to --reloc-debug-sections, but resolve all trivial relocations " +"between debug sections in place. No other stripping is performed (operation " +"is not reversible, incompatible with -f, -g, --remove-comment and --remove-" +"section)" +msgstr "" +"Подібний до --reloc-debug-sections, або усі тривіальні переміщення між " +"розділами діагностики вирішуються на місці. Додаткове очищення не " +"виконується (дію неможливо скасувати, параметр несумісний із -f, -g, --" +"remove-comment та --remove-section)" + +#: src/strip.c:89 +msgid "Remove .comment section" +msgstr "Вилучити розділ .comment" + +#: src/strip.c:90 +msgid "" +"Remove the named section. SECTION is an extended wildcard pattern. May be " +"given more than once. Only non-allocated sections can be removed." +msgstr "" +"Вилучити іменований розділ. РОЗДІЛ є розширеним взірцем із символами-" +"замінниками. Можна вказувати декілька розділів. Може бути вилучено лише " +"нерозміщені у пам'яті розділи." + +#: src/strip.c:91 +msgid "" +"Keep the named section. SECTION is an extended wildcard pattern. May be " +"given more than once." +msgstr "" +"Зберегти іменований розділ. РОЗДІЛ є розширеним взірцем із символами-" +"замінниками. Можна вказувати декілька розділів." + +#. Short description of program. +#: src/strip.c:98 +msgid "Discard symbols from object files." +msgstr "Відкинути символи з об’єктних файлів" + +#: src/strip.c:247 +#, c-format +msgid "--reloc-debug-sections used without -f" +msgstr "--reloc-debug-sections використано без -f" + +#: src/strip.c:253 +#, c-format +msgid "" +"--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --" +"remove-section" +msgstr "" +"--reloc-debug-sections-only є несумісним із -f, -g, --remove-comment та --" +"remove-section" + +#: src/strip.c:267 +#, c-format +msgid "Only one input file allowed together with '-o' and '-f'" +msgstr "" +"Разом з «-o» або «-f» можна використовувати лише один файл вхідних даних" + +#: src/strip.c:290 +#, c-format +msgid "-f option specified twice" +msgstr "параметр -f вказано двічі" + +#: src/strip.c:299 +#, c-format +msgid "-F option specified twice" +msgstr "параметр -F вказано двічі" + +#: src/strip.c:362 +#, c-format +msgid "cannot both keep and remove .comment section" +msgstr "неможливо одночасно зберегти і вилучити розділ .comment" + +#: src/strip.c:481 +#, c-format +msgid "bad relocation" +msgstr "помилкове пересування" + +#: src/strip.c:747 src/strip.c:771 +#, c-format +msgid "cannot stat input file '%s'" +msgstr "не вдалося отримати дані з вхідного файла «%s» за допомогою stat" + +#: src/strip.c:761 +#, c-format +msgid "while opening '%s'" +msgstr "під час спроби відкриття «%s»" + +#: src/strip.c:799 +#, c-format +msgid "%s: cannot use -o or -f when stripping archive" +msgstr "" +"%s: не можна використовувати -o або -f під час вилучення додаткового вмісту " +"архіву" + +#. We would like to support ar archives, but currently it just +#. doesn't work at all since we call elf_clone on the members +#. which doesn't really support ar members. +#. result = handle_ar (fd, elf, NULL, fname, +#. preserve_dates ? tv : NULL); +#. +#: src/strip.c:811 +#, c-format +msgid "%s: no support for stripping archive" +msgstr "%s: підтримки вилучення додаткового вмісту з архіву не передбачено" + +#: src/strip.c:1047 +#, c-format +msgid "cannot open EBL backend" +msgstr "не вдалося відкрити канал сервера EBL" + +#: src/strip.c:1092 +#, c-format +msgid "cannot get number of phdrs" +msgstr "не вдалося отримати кількість phdr" + +#: src/strip.c:1106 src/strip.c:1149 +#, c-format +msgid "cannot create new ehdr for file '%s': %s" +msgstr "не вдалося створити ehdr для файла «%s»: %s" + +#: src/strip.c:1116 src/strip.c:1159 +#, c-format +msgid "cannot create new phdr for file '%s': %s" +msgstr "не вдалося створити phdr для файла «%s»: %s" + +#: src/strip.c:1240 +#, c-format +msgid "illformed file '%s'" +msgstr "помилкове форматування файла «%s»" + +#: src/strip.c:1250 +#, c-format +msgid "Cannot remove allocated section '%s'" +msgstr "Неможливо вилучити розміщений у пам'яті розділ «%s»" + +#: src/strip.c:1259 +#, c-format +msgid "Cannot both keep and remove section '%s'" +msgstr "Неможливо одночасно зберегти та вилучити розділ «%s»" + +#: src/strip.c:1624 src/strip.c:1739 +#, c-format +msgid "while generating output file: %s" +msgstr "під час спроби створення файла з виведеними даними: %s" + +#: src/strip.c:1688 +#, c-format +msgid "%s: error while updating ELF header: %s" +msgstr "%s: помилка під час оновлення заголовка ELF: %s" + +#: src/strip.c:1697 +#, c-format +msgid "%s: error while getting shdrstrndx: %s" +msgstr "%s: помилка під час отримання shdrstrndx: %s" + +#: src/strip.c:1705 src/strip.c:2550 +#, c-format +msgid "%s: error updating shdrstrndx: %s" +msgstr "%s: помилка під час оновлення shdrstrndx: %s" + +#: src/strip.c:1722 +#, c-format +msgid "while preparing output for '%s'" +msgstr "під час приготування виведених даних для «%s»" + +#: src/strip.c:1784 src/strip.c:1847 +#, c-format +msgid "while create section header section: %s" +msgstr "під час створення розділу заголовка розділу: %s" + +#: src/strip.c:1793 +#, c-format +msgid "cannot allocate section data: %s" +msgstr "не вдалося розмістити дані розділу: %s" + +#: src/strip.c:1859 +#, c-format +msgid "while create section header string table: %s" +msgstr "під час створення таблиці рядків заголовка розділу: %s" + +#: src/strip.c:1866 +#, c-format +msgid "no memory to create section header string table" +msgstr "недостатньо пам'яті для створення таблиці рядків заголовка розділу" + +#: src/strip.c:2079 +#, c-format +msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]" +msgstr "" +"Неможливо вилучити символ [%zd] з розміщеної у пам'яті таблиці символів [%zd]" + +#: src/strip.c:2466 src/strip.c:2574 +#, c-format +msgid "while writing '%s': %s" +msgstr "під час запису «%s»: %s" + +#: src/strip.c:2477 +#, c-format +msgid "while creating '%s'" +msgstr "під час спроби створення «%s»" + +#: src/strip.c:2500 +#, c-format +msgid "while computing checksum for debug information" +msgstr "під час обчислення контрольної суми для діагностичних даних" + +#: src/strip.c:2541 +#, c-format +msgid "%s: error while creating ELF header: %s" +msgstr "%s: помилка під час створення заголовка ELF: %s" + +#: src/strip.c:2559 +#, c-format +msgid "%s: error while reading the file: %s" +msgstr "%s: помилка під час читання файла: %s" + +#: src/strip.c:2599 src/strip.c:2619 +#, c-format +msgid "while writing '%s'" +msgstr "під час спроби запису «%s»" + +#: src/strip.c:2656 src/strip.c:2663 +#, c-format +msgid "error while finishing '%s': %s" +msgstr "помилка під час завершення «%s»: %s" + +#: src/strip.c:2680 src/strip.c:2756 +#, c-format +msgid "cannot set access and modification date of '%s'" +msgstr "не вдалося встановити права доступу та дату зміни «%s»" + +#: src/unstrip.c:66 +msgid "Match MODULE against file names, not module names" +msgstr "" +"Встановити відповідність МОДУЛЯ назвам файлів, а не назвам модулів names" + +#: src/unstrip.c:67 +msgid "Silently skip unfindable files" +msgstr "Пропустити незнайдені файли без додаткових повідомлень" + +#: src/unstrip.c:70 +msgid "Place output into FILE" +msgstr "Вивести дані у ФАЙЛ" + +#: src/unstrip.c:72 +msgid "Create multiple output files under DIRECTORY" +msgstr "Створити декілька файлів виведених даних у КАТАЛОЗІ" + +#: src/unstrip.c:73 +msgid "Use module rather than file names" +msgstr "Використовувати назви модулів, а не файлів" + +#: src/unstrip.c:75 +msgid "Create output for modules that have no separate debug information" +msgstr "" +"Вивести дані для модулів, які не містять окремих діагностичних відомостей" + +#: src/unstrip.c:78 +msgid "Apply relocations to section contents in ET_REL files" +msgstr "Застосувати пересування до вмісту розділів у файлах ET_REL" + +#: src/unstrip.c:80 +msgid "Only list module and file names, build IDs" +msgstr "Вивести лише список назв модулів, файлів, побудувати ідентифікатори" + +#: src/unstrip.c:82 +msgid "Force combining files even if some ELF headers don't seem to match" +msgstr "" +"Примусово поєднати файли, навіть якщо буде встановлено невідповідність " +"якихось із заголовків ELF" + +#: src/unstrip.c:126 +#, c-format +msgid "-d option specified twice" +msgstr "параметр -d вказано двічі" + +#: src/unstrip.c:161 +#, c-format +msgid "only one of -o or -d allowed" +msgstr "можна використовувати лише один з параметрів: -o або -d" + +#: src/unstrip.c:170 +#, c-format +msgid "-n cannot be used with explicit files or -o or -d" +msgstr "" +"-n не можна використовувати з файлами, заданими явно, або параметрами -o і -d" + +#: src/unstrip.c:185 +#, c-format +msgid "output directory '%s'" +msgstr "каталог виведення даних «%s»" + +#: src/unstrip.c:194 +#, c-format +msgid "exactly two file arguments are required" +msgstr "як аргументи має бути вказано точно два файла" + +#: src/unstrip.c:200 +#, c-format +msgid "-m, -a, -R, and -i options not allowed with explicit files" +msgstr "" +"для файлів, заданих явно, не можна використовувати параметри -m, -a, -R і -i" + +#: src/unstrip.c:213 +#, c-format +msgid "-o or -d is required when using implicit files" +msgstr "" +"якщо використовуються файли, задані неявно, слід додавати параметр -o або -d" + +#: src/unstrip.c:236 +#, c-format +msgid "cannot create ELF header: %s" +msgstr "не вдалося створити заголовок ELF: %s" + +#: src/unstrip.c:240 +#, c-format +msgid "cannot get shdrstrndx:%s" +msgstr "не вдалося отримати shdrstrndx:%s" + +#: src/unstrip.c:244 src/unstrip.c:2086 +#, c-format +msgid "cannot get ELF header: %s" +msgstr "не вдалося отримати заголовок ELF: %s" + +#: src/unstrip.c:254 +#, c-format +msgid "cannot get new zero section: %s" +msgstr "не вдалося отримати новий нульовий розділ: %s" + +#: src/unstrip.c:257 +#, c-format +msgid "cannot update new zero section: %s" +msgstr "неможливо оновити новий нульовий розділ: %s" + +#: src/unstrip.c:261 +#, c-format +msgid "cannot copy ELF header: %s" +msgstr "не вдалося скопіювати заголовок ELF: %s" + +#: src/unstrip.c:265 src/unstrip.c:2104 src/unstrip.c:2147 +#, c-format +msgid "cannot get number of program headers: %s" +msgstr "не вдалося отримати кількість заголовків програми: %s" + +#: src/unstrip.c:270 src/unstrip.c:2108 +#, c-format +msgid "cannot create program headers: %s" +msgstr "не вдалося створити заголовки програми: %s" + +#: src/unstrip.c:276 +#, c-format +msgid "cannot copy program header: %s" +msgstr "не вдалося скопіювати заголовок програми: %s" + +#: src/unstrip.c:286 +#, c-format +msgid "cannot copy section header: %s" +msgstr "не вдалося скопіювати заголовок розділу: %s" + +#: src/unstrip.c:289 src/unstrip.c:1708 +#, c-format +msgid "cannot get section data: %s" +msgstr "не вдалося отримати дані розділу: %s" + +#: src/unstrip.c:291 src/unstrip.c:1710 +#, c-format +msgid "cannot copy section data: %s" +msgstr "не вдалося скопіювати дані розділу: %s" + +#: src/unstrip.c:319 +#, c-format +msgid "cannot create directory '%s'" +msgstr "не вдалося створити каталог «%s»" + +#: src/unstrip.c:393 src/unstrip.c:657 src/unstrip.c:691 src/unstrip.c:859 +#: src/unstrip.c:1750 +#, c-format +msgid "cannot get symbol table entry: %s" +msgstr "не вдалося отримати запис таблиці символів: %s" + +#: src/unstrip.c:409 src/unstrip.c:660 src/unstrip.c:681 src/unstrip.c:694 +#: src/unstrip.c:1771 src/unstrip.c:1966 src/unstrip.c:1990 +#, c-format +msgid "cannot update symbol table: %s" +msgstr "не вдалося оновити таблицю символів: %s" + +#: src/unstrip.c:419 +#, c-format +msgid "cannot update section header: %s" +msgstr "не вдалося оновити заголовок розділу: %s" + +#: src/unstrip.c:467 src/unstrip.c:481 +#, c-format +msgid "cannot update relocation: %s" +msgstr "не вдалося оновити пересування: %s" + +#: src/unstrip.c:580 +#, c-format +msgid "cannot get symbol version: %s" +msgstr "не вдалося отримати версію символу: %s" + +#: src/unstrip.c:593 +#, c-format +msgid "unexpected section type in [%zu] with sh_link to symtab" +msgstr "неочікуваний тип розділу у [%zu] з посиланням sh_link на symtab" + +#: src/unstrip.c:848 +#, c-format +msgid "cannot get symbol section data: %s" +msgstr "не вдалося отримати дані розділу символів: %s" + +#: src/unstrip.c:850 +#, c-format +msgid "cannot get string section data: %s" +msgstr "не вдалося отримати дані розділу рядків: %s" + +#: src/unstrip.c:867 +#, c-format +msgid "invalid string offset in symbol [%zu]" +msgstr "некоректне зміщення рядка у символі [%zu]" + +#: src/unstrip.c:1025 src/unstrip.c:1433 +#, c-format +msgid "cannot read section [%zu] name: %s" +msgstr "не вдалося прочитати назву розділу [%zu]: %s" + +#: src/unstrip.c:1040 +#, c-format +msgid "bad sh_link for group section: %s" +msgstr "помилкове значення sh_link для розділу груп: %s" + +#: src/unstrip.c:1046 +#, c-format +msgid "couldn't get shdr for group section: %s" +msgstr "не вдалося отримати shdr для розділу груп: %s" + +#: src/unstrip.c:1051 +#, c-format +msgid "bad data for group symbol section: %s" +msgstr "помилкові дані для розділу символів груп: %s" + +#: src/unstrip.c:1057 +#, c-format +msgid "couldn't get symbol for group section: %s" +msgstr "не вдалося отримати символ для розділу груп: %s" + +#: src/unstrip.c:1062 +#, c-format +msgid "bad symbol name for group section: %s" +msgstr "помилкова назва символу для розділу груп: %s" + +#: src/unstrip.c:1073 src/unstrip.c:1554 +#, c-format +msgid "cannot find matching section for [%zu] '%s'" +msgstr "не вдалося знайти відповідний розділ для [%zu] «%s»" + +#: src/unstrip.c:1118 src/unstrip.c:1137 src/unstrip.c:1175 +#, c-format +msgid "cannot read '.gnu.prelink_undo' section: %s" +msgstr "не вдалося прочитати розділ «.gnu.prelink_undo»: %s" + +#: src/unstrip.c:1155 +#, c-format +msgid "overflow with shnum = %zu in '%s' section" +msgstr "переповнення з shnum = %zu у розділі «%s»" + +#: src/unstrip.c:1166 +#, c-format +msgid "invalid contents in '%s' section" +msgstr "некоректний вміст розділу «%s»" + +#: src/unstrip.c:1337 src/unstrip.c:1353 src/unstrip.c:1634 src/unstrip.c:1925 +#, c-format +msgid "cannot add section name to string table: %s" +msgstr "не вдалося додати назву розділу до таблиці рядків: %s" + +#: src/unstrip.c:1362 +#, c-format +msgid "cannot update section header string table data: %s" +msgstr "не вдалося оновити дані заголовка розділу у таблиці рядків: %s" + +#: src/unstrip.c:1391 src/unstrip.c:1395 +#, c-format +msgid "cannot get section header string table section index: %s" +msgstr "" +"не вдалося визначити індекс розділу заголовка розділу у таблиці рядків: %s" + +#: src/unstrip.c:1399 src/unstrip.c:1403 src/unstrip.c:1649 +#, c-format +msgid "cannot get section count: %s" +msgstr "не вдалося отримати кількість розділів: %s" + +#: src/unstrip.c:1406 +#, c-format +msgid "more sections in stripped file than debug file -- arguments reversed?" +msgstr "" +"у очищеному файлі більше розділів ніж у файлі з даними для зневаджування — " +"помилковий порядок параметрів?" + +#: src/unstrip.c:1410 +#, c-format +msgid "no sections in stripped file" +msgstr "у очищеному файлі немає розділів" + +#: src/unstrip.c:1458 src/unstrip.c:1569 +#, c-format +msgid "cannot read section header string table: %s" +msgstr "не вдалося прочитати таблицю рядків заголовка розділу: %s" + +#: src/unstrip.c:1628 +#, c-format +msgid "cannot add new section: %s" +msgstr "не вдалося додати новий розділ: %s" + +#: src/unstrip.c:1758 +#, c-format +msgid "symbol [%zu] has invalid section index" +msgstr "символ [%zu] має некоректний індекс розділу" + +#: src/unstrip.c:1790 +#, c-format +msgid "group has invalid section index [%zd]" +msgstr "група містить некоректний індекс розділу [%zd]" + +#: src/unstrip.c:2065 +#, c-format +msgid "cannot read section data: %s" +msgstr "не вдалося прочитати дані розділу: %s" + +#: src/unstrip.c:2094 +#, c-format +msgid "cannot update ELF header: %s" +msgstr "не вдалося оновити заголовок ELF: %s" + +#: src/unstrip.c:2118 +#, c-format +msgid "cannot update program header: %s" +msgstr "не вдалося оновити заголовок програми: %s" + +#: src/unstrip.c:2123 src/unstrip.c:2206 +#, c-format +msgid "cannot write output file: %s" +msgstr "не вдалося записати файл виведених даних: %s" + +#: src/unstrip.c:2174 +#, c-format +msgid "DWARF data not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"Дані DWARF не скориговано відповідно до відхилення перед компонуванням; " +"спробуйте виправити це командою prelink -u" + +#: src/unstrip.c:2177 +#, c-format +msgid "" +"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u" +msgstr "" +"Дані DWARF у «%s» не скориговано відповідно до відхилення перед " +"компонуванням; спробуйте виправити це командою prelink -u" + +#: src/unstrip.c:2197 src/unstrip.c:2249 src/unstrip.c:2261 src/unstrip.c:2351 +#, c-format +msgid "cannot create ELF descriptor: %s" +msgstr "не вдалося створити дескриптор ELF: %s" + +#: src/unstrip.c:2235 +msgid "WARNING: " +msgstr "УВАГА: " + +#: src/unstrip.c:2237 +msgid ", use --force" +msgstr ", скористайтеся --force" + +#: src/unstrip.c:2265 +msgid "ELF header identification (e_ident) different" +msgstr "Різні ідентифікатори заголовків ELF (e_ident)" + +#: src/unstrip.c:2269 +msgid "ELF header type (e_type) different" +msgstr "Різні типи заголовків ELF (e_type)" + +#: src/unstrip.c:2273 +msgid "ELF header machine type (e_machine) different" +msgstr "Різні типи архітектур заголовків ELF (e_machine)" + +#: src/unstrip.c:2277 +msgid "stripped program header (e_phnum) smaller than unstripped" +msgstr "очищений заголовок програми (e_phnum) є меншим за неочищений" + +#: src/unstrip.c:2308 +#, c-format +msgid "cannot find stripped file for module '%s': %s" +msgstr "не вдалося знайти очищений файл для модуля «%s»: %s" + +#: src/unstrip.c:2312 +#, c-format +msgid "cannot open stripped file '%s' for module '%s': %s" +msgstr "не вдалося відкрити очищений файл «%s» для модуля «%s»: %s" + +#: src/unstrip.c:2327 +#, c-format +msgid "cannot find debug file for module '%s': %s" +msgstr "не вдалося знайти файл діагностичних даних для модуля «%s»: %s" + +#: src/unstrip.c:2331 +#, c-format +msgid "cannot open debug file '%s' for module '%s': %s" +msgstr "не вдалося відкрити файл діагностичних даних «%s» для модуля «%s»: %s" + +#: src/unstrip.c:2344 +#, c-format +msgid "module '%s' file '%s' is not stripped" +msgstr "у модулі «%s» файл «%s» не очищено strip" + +#: src/unstrip.c:2375 +#, c-format +msgid "cannot cache section addresses for module '%s': %s" +msgstr "не вдалося кешувати адреси розділів для модуля «%s»: %s" + +#: src/unstrip.c:2505 +#, c-format +msgid "no matching modules found" +msgstr "відповідних модулів не виявлено" + +#: src/unstrip.c:2515 +#, c-format +msgid "matched more than one module" +msgstr "встановлено відповідність декількох модулів" + +#: src/unstrip.c:2560 +msgid "" +"STRIPPED-FILE DEBUG-FILE\n" +"[MODULE...]" +msgstr "" +"ОЧИЩЕНИЙ-ФАЙЛ ФАЙЛ-DEBUG\n" +"[МОДУЛЬ...]" + +#: src/unstrip.c:2561 +msgid "" +"Combine stripped files with separate symbols and debug information.\n" +"\n" +"The first form puts the result in DEBUG-FILE if -o was not given.\n" +"\n" +"MODULE arguments give file name patterns matching modules to process.\n" +"With -f these match the file name of the main (stripped) file (slashes are " +"never special), otherwise they match the simple module names. With no " +"arguments, process all modules found.\n" +"\n" +"Multiple modules are written to files under OUTPUT-DIRECTORY, creating " +"subdirectories as needed. With -m these files have simple module names, " +"otherwise they have the name of the main file complete with directory " +"underneath OUTPUT-DIRECTORY.\n" +"\n" +"With -n no files are written, but one line to standard output for each " +"module:\n" +"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n" +"START and SIZE are hexadecimal giving the address bounds of the module. " +"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the " +"hexadecimal may be followed by @0xADDR giving the address where the ID " +"resides if that is known. FILE is the file name found for the module, or - " +"if none was found, or . if an ELF image is available but not from any named " +"file. DEBUGFILE is the separate debuginfo file name, or - if no debuginfo " +"was found, or . if FILE contains the debug information." +msgstr "" +"Комбінувати очищені файли з окремими даними щодо символів та діагностичними " +"даними.\n" +"\n" +"За використання першої форми команди, результати буде виведено до ФАЙЛА-" +"DEBUG, якщо не файл виведених даних не вказано параметром -o.\n" +"\n" +"За допомогою аргументів МОДУЛЬ можна вказати шаблони назв файлів модулів, " +"які слід обробити.\n" +"З -f ці назви модулів відповідатимуть назві основного (очищеного strip) " +"файла (похилі риски не є спеціальними символами), якщо ж -f не вказано, " +"назви вважатимуться простими назвами модулів. Якщо аргументів не буде " +"вказано, програма обробить всі знайдені модулі.\n" +"\n" +"Вказані модулі буде записано до файлів у КАТАЛОЗІ-ВИВОДУ, зі створенням, за " +"потреби, підкаталогів. З параметром -m файли виведених даних " +"створюватимуться за назвами модулів, якщо ж цього параметра вказано не буде, " +"програма створюватиме файл з назвою основного файла у основному КАТАЛОЗІ-" +"ВИВОДУ.\n" +"\n" +"Якщо буде вказано параметр -n, дані до файлів не виводитимуться, програма " +"виведе для кожного модуля до стандартного виводу такі дані:\n" +"\tПОЧАТОК+РОЗМІР ІДЕНТИФІКАТОР-ЗБИРАННЯ ФАЙЛ ФАЙЛ-DEBUG НАЗВА-МОДУЛЯ\n" +"ПОЧАТОК і РОЗМІР буде виведено як шістнадцяткові числа у межах адресного " +"простору модуля. ІДЕНТИФІКАТОР-ЗБИРАННЯ — це шістнадцяткове число, що " +"відповідає бітам ідентифікатора збирання, або «-», якщо ідентифікатор " +"невідомий; за шістнадцятковим числом може слідувати @0xАДРЕСА, яка вказує " +"місце розташування ідентифікатора, якщо воно відоме. ФАЙЛ відповідає назві " +"файла, знайденого для модуля, або «-», якщо файл не знайдено, і «.», якщо " +"вдалося знайти образ ELF, але без жодного файла з назвою. ФАЙЛ-DEBUG — назва " +"окремого файла діагностичних даних або «-», якщо файла діагностичних даних " +"не вдалося знайти, і «.», якщо ФАЙЛ сам містить діагностичні дані." + +#. Short description of program. +#: debuginfod/debuginfod-find.c:42 +msgid "Request debuginfo-related content from debuginfods listed in $" +msgstr "" + +#. Strings for arguments in help texts. +#: debuginfod/debuginfod-find.c:46 +msgid "" +"debuginfo BUILDID\n" +"debuginfo PATH\n" +"executable BUILDID\n" +"executable PATH\n" +"source BUILDID /FILENAME\n" +"source PATH /FILENAME\n" +msgstr "" + +#: tests/backtrace.c:436 +msgid "Run executable" +msgstr "Запустити виконуваний файл" + +#: tests/dwflmodtest.c:209 +msgid "Additionally show function names" +msgstr "Додатково вивести назви функцій" + +#: tests/dwflmodtest.c:210 +msgid "Show instances of inlined functions" +msgstr "Вивести екземпляри вбудованих функцій" + +#~ msgid "" +#~ " [%6tx] base address\n" +#~ " " +#~ msgstr "" +#~ " [%6tx] базова адреса\n" +#~ " " + +#, fuzzy +#~ msgid "%s: error getting zero section: %s" +#~ msgstr "%s: помилка під час читання файла: %s" + +#, fuzzy +#~ msgid "%s: error while updating zero section: %s" +#~ msgstr "%s: помилка під час читання файла: %s" + +#~ msgid "%s+%# <%s+%#>" +#~ msgstr "%s+%# <%s+%#>" + +#~ msgid "%s+%#0* <%s+%#>" +#~ msgstr "%s+%#0* <%s+%#>" + +#~ msgid "%# <%s+%#>" +#~ msgstr "%# <%s+%#>" + +#~ msgid "%#0* <%s+%#>" +#~ msgstr "%#0* <%s+%#>" + +#~ msgid "%s+%# <%s>" +#~ msgstr "%s+%# <%s>" + +#~ msgid "%s+%#0* <%s>" +#~ msgstr "%s+%#0* <%s>" + +#~ msgid "%# <%s>" +#~ msgstr "%# <%s>" + +#~ msgid "%#0* <%s>" +#~ msgstr "%#0* <%s>" + +#~ msgid "%s+%#" +#~ msgstr "%s+%#" + +#~ msgid "%s+%#0*" +#~ msgstr "%s+%#0*" + +#~ msgid " %s..%s (%)\n" +#~ msgstr " %s..%s (%)\n" + +#~ msgid " %s..%s\n" +#~ msgstr " %s..%s\n" + +#~ msgid " advance address by %u to %s, op_index to %u\n" +#~ msgstr " збільшення адреси на %u до %s, індекс_оп до %u\n" + +#~ msgid " advance address by constant %u to %s, op_index to %u\n" +#~ msgstr " збільшити адресу на сталу величину %u до %s, індекс_оп до %u\n" + +#~ msgid " [%6tx] %s..%s\n" +#~ msgstr " [%6tx] %s..%s\n" + +#~ msgid " %s..%s\n" +#~ msgstr " %s..%s\n" + +#~ msgid "cannot get DIE at offset % in section '%s': %s" +#~ msgstr "не вдалося отримати DIE за зміщенням % у розділі «%s»: %s" + +#~ msgid " [%6tx] %s..%s" +#~ msgstr " [%6tx] %s..%s" + +#~ msgid " %s..%s" +#~ msgstr " %s..%s" + +#~ msgid "vendor opcode not verified?" +#~ msgstr "код операції постачальника не перевірено?" + +#~ msgid "-R option supports only .comment section" +#~ msgstr "Для параметра -R передбачено підтримку лише розділу .comment" + +#~ msgid "Written by %s.\n" +#~ msgstr "Автор — %s.\n" + +#~ msgid "cannot allocate PLTREL section: %s" +#~ msgstr "не вдалося розмістити розділ PLTREL: %s" + +#~ msgid "cannot allocate GOT section: %s" +#~ msgstr "не вдалося розмістити розділ GOT: %s" + +#~ msgid "cannot allocate GOTPLT section: %s" +#~ msgstr "не вдалося розмістити розділ GOTPLT: %s" + +#~ msgid "initial-executable TLS relocation cannot be used " +#~ msgstr "" +#~ "не можна використовувати пересування TLS у початковому виконуваному файлі" + +#~ msgid "Input File Control:" +#~ msgstr "Керування файлом вхідних даних:" + +#~ msgid "Include whole archives in the output from now on." +#~ msgstr "Відтепер включати цілі архіви до виведених даних." + +#~ msgid "Stop including the whole archives in the output." +#~ msgstr "Припинити включення цілих архівів до вихідних даних." + +#~ msgid "FILE" +#~ msgstr "ФАЙЛ" + +#~ msgid "Start a group." +#~ msgstr "Почати групу." + +#~ msgid "End a group." +#~ msgstr "Завершити групу." + +#~ msgid "PATH" +#~ msgstr "ШЛЯХ" + +#~ msgid "Add PATH to list of directories files are searched in." +#~ msgstr "Додати ШЛЯХ до списку каталогів, у яких слід шукати файли." + +#~ msgid "Only set DT_NEEDED for following dynamic libs if actually used" +#~ msgstr "" +#~ "Встановлювати DT_NEEDED лише для наступних динамічних бібліотек, якщо він " +#~ "справді використовується" + +#~ msgid "Always set DT_NEEDED for following dynamic libs" +#~ msgstr "Завжди встановлювати DT_NEEDED для наступних динамічних бібліотек" + +#~ msgid "Ignore LD_LIBRARY_PATH environment variable." +#~ msgstr "Ігнорувати змінну середовища LD_LIBRARY_PATH." + +#~ msgid "Output File Control:" +#~ msgstr "Керування файлом виведених даних:" + +#~ msgid "Place output in FILE." +#~ msgstr "Вивести дані до ФАЙЛА." + +#~ msgid "Object is marked to not use default search path at runtime." +#~ msgstr "" +#~ "Об’єкт позначено, як таких, який не використовує типовий шлях пошуку під " +#~ "час запуску." + +#~ msgid "Same as --whole-archive." +#~ msgstr "Те саме, що --whole-archive." + +#~ msgid "" +#~ "Default rules of extracting from archive; weak references are not enough." +#~ msgstr "" +#~ "Типові правила видобування з архівів; слабкого посилання недостатньо." + +#~ msgid "Weak references cause extraction from archive." +#~ msgstr "Слабкі посилання спричиняють видобування з архіву." + +#~ msgid "Allow multiple definitions; first is used." +#~ msgstr "Дозволити декілька визначень. Використовуватиметься лише перше." + +#~ msgid "Disallow/allow undefined symbols in DSOs." +#~ msgstr "Заборонити/Дозволити невизначені символи у DSO." + +#~ msgid "Object requires immediate handling of $ORIGIN." +#~ msgstr "Об’єкт вимагає негайної обробки $ORIGIN." + +#~ msgid "Relocation will not be processed lazily." +#~ msgstr "Переміщення не буде оброблятися у лінивому режимі." + +#~ msgid "Object cannot be unloaded at runtime." +#~ msgstr "Об’єкт не можна вивантажувати під час запуску." + +#~ msgid "Mark object to be initialized first." +#~ msgstr "Позначити об’єкт, як такий, що потребує ініціалізації." + +#~ msgid "Enable/disable lazy-loading flag for following dependencies." +#~ msgstr "" +#~ "Увімкнути/Вимкнути прапорець лінивого завантаження для наведених нижче " +#~ "залежностей." + +#~ msgid "Mark object as not loadable with 'dlopen'." +#~ msgstr "" +#~ "Позначити об’єкт, як непридатний для завантаження за допомогою «dlopen»." + +#~ msgid "Ignore/record dependencies on unused DSOs." +#~ msgstr "Ігнорувати/Записувати залежності невикористаних DSO." + +#~ msgid "Generated DSO will be a system library." +#~ msgstr "Створена DSO буде системною бібліотекою." + +#~ msgid "ADDRESS" +#~ msgstr "АДРЕСА" + +#~ msgid "Set entry point address." +#~ msgstr "Встановити адресу точки входу." + +#~ msgid "Do not link against shared libraries." +#~ msgstr "Не компонувати з бібліотеками спільного використання." + +#~ msgid "Prefer linking against shared libraries." +#~ msgstr "" +#~ "Надавати перевагу компонуванню з бібліотеками спільного використання." + +#~ msgid "Export all dynamic symbols." +#~ msgstr "Експортувати всі динамічні символи." + +#~ msgid "Strip all symbols." +#~ msgstr "Вилучити всі символи." + +#~ msgid "Strip debugging symbols." +#~ msgstr "Вилучити символи зневаджування." + +#~ msgid "Assume pagesize for the target system to be SIZE." +#~ msgstr "" +#~ "Вважати розмір сторінки для системи призначення рівним значенню РОЗМІР." + +#~ msgid "Set runtime DSO search path." +#~ msgstr "Встановити шлях пошуку DSO під час запуску." + +#~ msgid "Set link time DSO search path." +#~ msgstr "Встановити шлях пошуку DSO під час компонування." + +#~ msgid "Generate dynamic shared object." +#~ msgstr "Створити динамічний об’єкт спільного використання." + +#~ msgid "Generate relocatable object." +#~ msgstr "Створити придатний для пересування об’єкт." + +#~ msgid "Causes symbol not assigned to a version be reduced to local." +#~ msgstr "" +#~ "Спричиняє перетворення символів, не прив’язаних до версії, на локальні." + +#~ msgid "Remove unused sections." +#~ msgstr "Вилучити невикористані розділи." + +#~ msgid "Don't remove unused sections." +#~ msgstr "Не вилучати невикористані розділи." + +#~ msgid "Set soname of shared object." +#~ msgstr "Встановити soname об’єкта спільного використання." + +#~ msgid "Set the dynamic linker name." +#~ msgstr "Встановити назву динамічного компонувальника." + +#~ msgid "Add/suppress addition indentifying link-editor to .comment section." +#~ msgstr "" +#~ "Додати/Придушити додавання ідентифікації редактора компонування до " +#~ "розділу .comment." + +#~ msgid "Create .eh_frame_hdr section" +#~ msgstr "Створити розділ .eh_frame_hdr" + +#~ msgid "Set hash style to sysv, gnu or both." +#~ msgstr "Встановити формат хешування у значення sysv, gnu або both." + +#~ msgid "Generate build ID note (md5, sha1 (default), uuid)." +#~ msgstr "" +#~ "Створити запису ідентифікатора збирання (md5, sha1 (типовий), uuid)." + +#~ msgid "Linker Operation Control:" +#~ msgstr "Керування роботою компонувальника:" + +#~ msgid "Verbose messages." +#~ msgstr "Докладні повідомлення." + +#~ msgid "Trace file opens." +#~ msgstr "Спостерігати за відкриттями файлів." + +#~ msgid "Trade speed for less memory usage" +#~ msgstr "Зменшити споживання пам’яті за рахунок швидкості" + +#~ msgid "LEVEL" +#~ msgstr "РІВЕНЬ" + +#~ msgid "Set optimization level to LEVEL." +#~ msgstr "Встановити рівень оптимізації РІВЕНЬ." + +#~ msgid "Use linker script in FILE." +#~ msgstr "Використати скрипт компонування у ФАЙЛі." + +#~ msgid "Select to get parser debug information" +#~ msgstr "Позначте, щоб отримати діагностичні дані обробника" + +#~ msgid "Read version information from FILE." +#~ msgstr "Прочитати відомості щодо версії з ФАЙЛа." + +#~ msgid "Set emulation to NAME." +#~ msgstr "Встановити режим емуляції на основі НАЗВИ." + +#~ msgid "Combine object and archive files." +#~ msgstr "Комбінує об’єктні файли і файли архівів." + +#~ msgid "[FILE]..." +#~ msgstr "[ФАЙЛ]..." + +#~ msgid "At least one input file needed" +#~ msgstr "Потрібен принаймні один файл вхідних даних" + +#~ msgid "error while preparing linking" +#~ msgstr "помилка під час приготування до компонування" + +#~ msgid "cannot open linker script '%s'" +#~ msgstr "не вдалося відкрити скрипт компонування «%s»" + +#~ msgid "-( without matching -)" +#~ msgstr "-( без відповідника -)" + +#~ msgid "only one option of -G and -r is allowed" +#~ msgstr "можна використовувати лише один з параметрів -G або -r" + +#~ msgid "more than one '-m' parameter" +#~ msgstr "декілька параметрів «-m»" + +#~ msgid "unknown option `-%c %s'" +#~ msgstr "невідомий параметр «-%c %s»" + +#~ msgid "invalid hash style '%s'" +#~ msgstr "некоректний формат хешування «%s»" + +#~ msgid "invalid build-ID style '%s'" +#~ msgstr "некоректний формат ідентифікатора збирання «%s»" + +#~ msgid "Invalid optimization level `%s'" +#~ msgstr "Некоректний рівень оптимізації «%s»" + +#~ msgid "nested -( -) groups are not allowed" +#~ msgstr "підтримки вкладених груп -( -) не передбачено" + +#~ msgid "-) without matching -(" +#~ msgstr "-) без відповідника -(" + +#~ msgid "unknown option '-%c %s'" +#~ msgstr "невідомий параметр «-%c %s»" + +#~ msgid "could not find input file to determine output file format" +#~ msgstr "" +#~ "не вдалося виявити файл вхідних даних для визначення формату файла " +#~ "вихідних даних" + +#~ msgid "try again with an appropriate '-m' parameter" +#~ msgstr "повторіть спробу з належним параметром «-m»" + +#~ msgid "cannot read version script '%s'" +#~ msgstr "не вдалося прочитати скрипт версій «%s»" + +#~ msgid "duplicate definition of '%s' in linker script" +#~ msgstr "повторне визначення «%s» у скрипті компонування" + +#~ msgid "cannot create string table" +#~ msgstr "не вдалося створити таблицю рядків" + +#~ msgid "cannot load ld backend library '%s': %s" +#~ msgstr "не вдалося завантажити бібліотеку сервера ld «%s»: %s" + +#~ msgid "cannot find init function in ld backend library '%s': %s" +#~ msgstr "не вдалося виявити функцію init у бібліотеці сервера ld «%s»: %s" + +#~ msgid "%s listed more than once as input" +#~ msgstr "%s вказано декілька разів як джерело даних" + +#~ msgid "%s (for -l%s)\n" +#~ msgstr "%s (для -l%s)\n" + +#~ msgid "%s (for DT_NEEDED %s)\n" +#~ msgstr "%s (для DT_NEEDED %s)\n" + +#~ msgid "Warning: type of `%s' changed from %s in %s to %s in %s" +#~ msgstr "Попередження: тип «%s» змінився з %s у %s на %s у %s" + +#~ msgid "" +#~ "Warning: size of `%s' changed from % in %s to % in %s" +#~ msgstr "" +#~ "Попередження: розмір «%s» змінено з % у %s на % у %s" + +#~ msgid "(%s+%#): multiple definition of %s `%s'\n" +#~ msgstr "(%s+%#): повторне визначення %s «%s»\n" + +#~ msgid "(%s+%#): first defined here\n" +#~ msgstr "(%s+%#): вперше визначено тут\n" + +#~ msgid "%s: cannot get section group data: %s" +#~ msgstr "%s: не вдалося отримати дані групи розділів: %s" + +#~ msgid "%s: section '%s' with group flag set does not belong to any group" +#~ msgstr "" +#~ "%s: розділ «%s» з встановленим прапорцем групи не належить жодній групі" + +#~ msgid "%s: section [%2d] '%s' is not in the correct section group" +#~ msgstr "%s: розділ [%2d] «%s» не належить до відповідної групи розділів" + +#~ msgid "%s: invalid ELF file (%s:%d)\n" +#~ msgstr "%s: некоректний файл ELF (%s:%d)\n" + +#~ msgid "%s: only files of type ET_REL might contain section groups" +#~ msgstr "%s: групи розділів можуть містити лише файли типу ET_REL" + +#~ msgid "%s: cannot determine signature of section group [%2zd] '%s': %s" +#~ msgstr "%s: не вдалося визначити підпис групи розділів [%2zd] «%s»: %s" + +#~ msgid "%s: cannot get content of section group [%2zd] '%s': %s'" +#~ msgstr "%s: не вдалося отримати вміст групи розділів [%2zd] «%s»: %s'" + +#~ msgid "" +#~ "%s: group member %zu of section group [%2zd] '%s' has too high index: " +#~ "%" +#~ msgstr "" +#~ "%s: елемент групи %zu групи розділів [%2zd] «%s» має надто високий " +#~ "індекс: %" + +#~ msgid "%s: section '%s' has unknown type: %d" +#~ msgstr "%s: розділ «%s» належить до невідомого типу: %d" + +#~ msgid "cannot get descriptor for ELF file (%s:%d): %s\n" +#~ msgstr "не вдалося отримати дескриптор файла ELF (%s:%d): %s\n" + +#~ msgid "cannot read archive `%s': %s" +#~ msgstr "не вдалося прочитати архів «%s»: %s" + +#~ msgid "file of type %s cannot be linked in\n" +#~ msgstr "файл типу %s не можна скомпонувати у\n" + +#~ msgid "%s: input file incompatible with ELF machine type %s\n" +#~ msgstr "%s: файл вхідних даних несумісний з типом архітектури ELF %s\n" + +#~ msgid "%s: cannot get section header string table index: %s\n" +#~ msgstr "" +#~ "%s: не вдалося отримати покажчик таблиці рядків заголовка розділу: %s\n" + +#~ msgid "cannot use DSO '%s' when generating relocatable object file" +#~ msgstr "" +#~ "не вдалося використати DSO «%s» під час створення придатного до " +#~ "пересування об’єктного файла" + +#~ msgid "input file '%s' ignored" +#~ msgstr "файл вхідних даних «%s» проігноровано" + +#~ msgid "undefined symbol `%s' in %s" +#~ msgstr "невизначений символ «%s» у %s" + +#~ msgid "cannot create ELF descriptor for output file: %s" +#~ msgstr "не вдалося створити дескриптор ELF для файла вихідних даних: %s" + +#~ msgid "could not create ELF header for output file: %s" +#~ msgstr "не вдалося створити заголовок ELF для файла виведених даних: %s" + +#~ msgid "cannot create section for output file: %s" +#~ msgstr "не вдалося створити розділ для файла вихідних даних: %s" + +#~ msgid "address computation expression contains variable '%s'" +#~ msgstr "вираз обчислення адреси містить змінну «%s»" + +#~ msgid "" +#~ "argument '%' of ALIGN in address computation expression is no " +#~ "power of two" +#~ msgstr "" +#~ "значення «%» ALIGN у виразі обчислення адреси не є степенем " +#~ "двійки" + +#~ msgid "cannot find entry symbol '%s': defaulting to %#0*" +#~ msgstr "" +#~ "не вдалося знайти символ запису «%s»: встановлено типове значення " +#~ "%#0*" + +#~ msgid "no entry symbol specified: defaulting to %#0*" +#~ msgstr "не вказано символу запису: встановлено типове значення %#0*" + +#~ msgid "cannot create GNU hash table section for output file: %s" +#~ msgstr "" +#~ "не вдалося створити розділ таблиці хешів GNU для файла вихідних даних: %s" + +#~ msgid "cannot create hash table section for output file: %s" +#~ msgstr "" +#~ "не вдалося створити розділ таблиці хешів для файла вихідних даних: %s" + +#~ msgid "cannot create build ID section: %s" +#~ msgstr "не вдалося створити розділу ідентифікатора збирання: %s" + +#~ msgid "cannot convert section data to file format: %s" +#~ msgstr "не вдалося перетворити дані розділу у формат файла: %s" + +#~ msgid "cannot convert section data to memory format: %s" +#~ msgstr "не вдалося перетворити дані розділу у формат вмісту пам’яті: %s" + +#~ msgid "cannot read enough data for UUID" +#~ msgstr "не вдалося прочитати достатньо даних для встановлення UUID" + +#~ msgid "cannot create symbol table for output file: %s" +#~ msgstr "не вдалося створити таблицю символів для файла вихідних даних: %s" + +#~ msgid "section index too large in dynamic symbol table" +#~ msgstr "у таблиці динамічних символів покажчик є занадто великим" + +#~ msgid "cannot create versioning section: %s" +#~ msgstr "не вдалося створити розділ версій: %s" + +#~ msgid "cannot create dynamic symbol table for output file: %s" +#~ msgstr "" +#~ "не вдалося створити динамічну таблицю символів для файла вихідних даних: " +#~ "%s" + +#~ msgid "cannot create versioning data: %s" +#~ msgstr "не вдалося створити даних версії: %s" + +#~ msgid "cannot create section header string section: %s" +#~ msgstr "не вдалося створити розділ рядків заголовка розділу: %s" + +#~ msgid "cannot create section header string section" +#~ msgstr "не вдалося створити розділ рядків заголовка розділу" + +#~ msgid "cannot create program header: %s" +#~ msgstr "не вдалося створити заголовок програми: %s" + +#~ msgid "while determining file layout: %s" +#~ msgstr "під час визначення компонування файла: %s" + +#~ msgid "internal error: non-nobits section follows nobits section" +#~ msgstr "" +#~ "внутрішня помилка: небезбітовий розділ слідом за безбітовим розділом" + +#~ msgid "linker backend didn't specify function to relocate section" +#~ msgstr "у сервері компонування не визначено функції для розділу пересування" + +#~ msgid "while writing output file: %s" +#~ msgstr "під час запису файла вихідних даних: %s" + +#~ msgid "while finishing output file: %s" +#~ msgstr "під час закриття файла вихідних даних: %s" + +#~ msgid "cannot stat output file" +#~ msgstr "не вдалося обробити stat файл виводу даних" + +#~ msgid "WARNING: temporary output file overwritten before linking finished" +#~ msgstr "" +#~ "ПОПЕРЕДЖЕННЯ: файл тимчасового виводу даних було перезаписано до " +#~ "завершення компонування" + +#~ msgid "no machine specific '%s' implementation" +#~ msgstr "не специфічна для архітектури реалізація «%s»" + +#~ msgid "mode for segment invalid\n" +#~ msgstr "режим сегмента є некоректним\n" + +#~ msgid "while reading version script '%s': %s at line %d" +#~ msgstr "під час читання скрипту версій «%s»: %s у рядку %d" + +#~ msgid "" +#~ "symbol '%s' is declared both local and global for unnamed version '%s'" +#~ msgstr "" +#~ "символ «%s» оголошено локально і на загальному рівні для версії без назви " +#~ "«%s»" + +#~ msgid "symbol '%s' is declared both local and global for version '%s'" +#~ msgstr "" +#~ "символ «%s» оголошено локально і на загальному рівні для версії «%s»" + +#~ msgid "default visibility set as local and global" +#~ msgstr "типову видимість визначено як локальну і загальну" + +#~ msgid "cannot get section header of section %Zu: %s" +#~ msgstr "не вдалося отримати заголовок розділу %Zu: %s" + +#, fuzzy +#~ msgid "cannot attach to core" +#~ msgstr "не вдалося створити дерево пошуку" + +#~ msgid "'%s' and '%s' do not seem to match" +#~ msgstr "«%s» і «%s» не відповідають одне одному" + +#~ msgid "unknown tag %hx" +#~ msgstr "невідомий теґ %hx" + +#~ msgid "unknown user tag %hx" +#~ msgstr "невідомий теґ користувача %hx" + +#~ msgid "unknown attribute %hx" +#~ msgstr "невідомий атрибут %hx" + +#~ msgid "unknown user attribute %hx" +#~ msgstr "невідомий атрибут користувача %hx" + +#~ msgid "" +#~ "\n" +#~ "\n" +#~ "Symbols from %s[%s]:\n" +#~ "\n" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "Символи з %s[%s]:\n" +#~ "\n" + +#~ msgid "%s %s differ: section header" +#~ msgstr "%s %s diff: заголовок розділу" diff --git a/src/ChangeLog b/src/ChangeLog new file mode 100644 index 00000000..2c7be185 --- /dev/null +++ b/src/ChangeLog @@ -0,0 +1,5270 @@ +2021-05-12 Dmitry V. Levin + + * elfcompress.c (process_file): Return 1 instead of -1 in case of an + error. + + * elfcompress.c (process_file): Remove redundant assignment in case of + "Nothing to do". + + * elfcompress.c (process_file): Set res to 0 in case of "Nothing to do". + +2021-04-19 Martin Liska + + * elfclassify.c (run_classify): Use startswith. + * elfcompress.c (process_file): Likewise. + * nm.c (show_symbols_sysv): Likewise. + * readelf.c (print_debug): Likewise. + (handle_notes_data): Likewise. + (dump_data_section): Likewise. + (print_string_section): Likewise. + * strip.c (remove_debug_relocations): Likewise. + +2021-04-03 Mark Wielaard + + * nm.c (show_symbols): close dwfl_fd if dwfl_begin fails. + +2021-04-03 Mark Wielaard + + * unstrip.c (handle_output_dir_module): Free output_file when done. + +2021-04-03 Mark Wielaard + + * ar.c (do_oper_insert): Always close newfd. + +2021-03-03 Mark Wielaard + + * readelf.c (handle_symtab): Sanity check verneed vna_next, + vn_next and verdef vd_next offsets. + +2021-03-02 Timm Bäder + + * elfcompress.c (process_file): Remove cleanup() function and + replace it with a cleanup label at the end of the function. + Initialize res to -1. + +2021-02-17 Timm Bäder + + * elfcompress.c (process_file): Move get_sections function... + (get_section): ...to top-level static function taking an + sections array and shnum. + +2021-02-17 Timm Bäder + + * elfcompress.c (process_file): Move get_section function... + (get_section): ...to top-level static function taking an + sections array. + +2021-02-17 Timm Bäder + + * elfcompress.c (process_file): Move set_section function... + (set_section): ...to top-level static function taking a + section array. + +2021-02-17 Timm Bäder + + * unstrip.c (handle_implicit_modules): Inline the next function + in three places. This is simply dwfl_getmodules with match_module + callback providing mmi. + +2021-02-17 Timm Bäder + + * unstrip.c (handle_explicit_files): Move warn function... + (warn): ...here as top-level static function taking stripped, + unstripped files and force flag as extra arguments. + +2021-02-17 Timm Bäder + + * unstrip.c (copy_elided_sections): Inline find_unalloc_section + function into calling location. The sec pointer is set to NULL + before the if-else statement and only set when match is found. + +2021-02-17 Timm Bäder + + * unstrip.c (find_alloc_sections_prelink): Move check_match to... + (check_match): Adjusted to return whether there was no match, + which indicates a failure. So callers are adjusted to or the + result into a local fail boolean. + +2021-02-17 Timm Bäder + + * unstrip.c (adjust_relocs): Move adjust_reloc function to... + (adjust_reloc): ... here as static top-level function taking + a map array and size as extra arguments. + +2021-02-17 Timm Bäder + + * elflint.c (check_attributes): Rename and move left function... + (buffer_left): ...as static toplevel function taking both an + Elf_Data pointer argument and the unsigned char pointer p. + +2021-02-17 Timm Bäder + + * elflint.c (check_attributes): Rename and move pos function... + (buffer_pos): ...as static toplevel function taking an extra + Elf_Data pointer argument. + +2021-02-12 Mark Wielaard + + * readelf.c (print_debug_units): Type DIE offset is from start CU. + +2021-02-12 Mark Wielaard + + * readelf.c (attr_callback): Don't handle blocks as expression + blocks for DWARF version 4 or higher. + +2021-02-03 Timm Bäder + + * ar.c (do_oper_extract): Extract should_truncate_fname function + to... + (should_truncate_fname): ...here. New file scope function taking + size_t pointer to be read and/or set. + +2021-02-02 Timm Bäder + + * readelf.c (print_debug_line_section): Remove unnecessary + show_op_index variable, replace with (op_index > 0). + +2021-01-08 Timm Bäder + + * readelf.c (print_cfa_program): Lift regname function to... + (regname): ...here. New file scope function add ebl and regnamebuf + as arguments. + +2021-01-08 Timm Bäder + + * readelf.c (print_attributes): Lift left function to... + (left): ...here. New file scope function taking Elf_Data and char + pointers. + +2021-01-08 Timm Bäder + + * readelf.c (handle_core_registers): Lift same_set function to... + (same_set): ...here. New file scope function adding regs and + maxnreg arguments. + +2021-01-08 Timm Bäder + + * readelf.c (parse_opt): Lift add_dump_section function to... + (add_dump_section): ...here. New top level function. Added key + argument. + +2021-01-08 Timm Bäder + + * arlib-argp.c (help_filter): Lift text_for_default function to... + (text_for_default): ... here. New file scope function taking text + as argument. + +2021-01-08 Timm Bäder + + * addr2line.c (handle_address): Move show_note and show_int up to + file scope. + (show_note: New static inline function. + (show_int): Likewise. + +2021-01-08 Timm Bäder + + * strip.c (handle_elf): Remove no_symtab_updates function and + calls inside the switch statement. Add checks and (possibly) + continue, before switch statement is called. + +2021-01-08 Timm Bäder + + * strip.c (handle_elf): Move inlined update_section_size function + to... + (update_section_size): ...here. New static function that takes as + extra arguments the Elf_Scn, debug_elf, section cnt and fname. + +2021-01-08 Timm Bäder + + * strip.c (remove_debug_relocations): Rewrite inlined relocate + function to file static. Do R_*_NONE, reloc_simple_type and + ebl_debug_scn_p checks before calling new relocate function. + (relocate): New file static function from + remove_debug_relocate. Remove R_*_NONE, reloc_simple_type and + ebl_debugscn_p checks. + +2021-01-08 Timm Bäder + + * strip.c (handle_elf): Expand inlined function check_preserved. + +2021-01-12 Mark Wielaard + + * elflint.c (EXTRA_SHFLAGS): New define. + (check_sections): Use EXTRA_SHFLAGS. Add SHF_GNU_RETAIN to + ALL_SH_FLAGS. + +2020-12-31 Sergei Trofimovich + + * elflint.c (section_flags_string): Add NEWFLAG for GNU_RETAIN, + ORDERED and EXCLUDE. + +2020-12-31 Sergei Trofimovich + + * elflint.c (section_flags_string): Update cp pointer after + snprintf for unknown flags. + +2020-12-16 Érico Nogueira + + * readelf.c (qsort_r): Use qsort for improved portability. + +2020-12-20 Dmitry V. Levin + + * .gitignore: New file. + +2020-12-12 Mark Wielaard + + * elflint.c (check_sections): Handle SHF_GNU_RETAIN. + * readelf.c (print_shdr): Likewise. + +2020-12-16 Dmitry V. Levin + + * *.c: Replace gettext(...) with _(...). + + * unstrip.c (_): Remove. + +2020-12-15 Mark Wielaard + + * elflint.c (check_symtab): Always print symbol name (if known) + in error messages. + +2020-12-12 Dmitry V. Levin + + * ar.c (write_member, do_oper_insert): Fix spelling typo in comment. + * elfclassify.c (issue, elf_issue, is_unstripped): Likewise. + * elfcompress.c (process_file): Likewise. + * elflint.c (be_quiet, check_gnu_hash): Likewise. + * readelf.c (print_phdr, handle_gnu_hash, + dwarf_locexpr_opcode_string): Likewise. + * size.c (totals_class): Likewise. + * strings.c (read_elf): Likewise. + * strip.c (handle_elf): Likewise. + + * readelf.c (print_debug_addr_section): Fix spelling typo in error + diagnostics. + * strip.c (options): Fix spelling typos in argp help text. + * strings.c (options): Likewise. + * stack.c (options): Likewise. + +2020-11-01 Érico N. Rolim + + * unstrip.c (make_directories): Use ACCESSPERMS for mkdir. + (handle_file): Use DEFFILEMODE for open with O_CREAT for ET_REL + files, ACCESSPERMS otherwise. + +2020-11-01 Érico N. Rolim + + * Makefile.am (nm_LDADD): Add obstack_LIBS. + (ranlib_LDADD): Likewise. + (ar_LDADD): Likewise. + +2020-10-27 Érico N. Rolim + + * unstrip.c (make_directories): Use strndup, not strndupa. + +2020-09-28 Mark Wielaard + + * readelf.c (next_listptr_offset): Take idx as pointer, to be updated + and use new Dwarf_Off as offset to match. + (listptr_attr): New function. + (print_debug_loclists_section): Check for DW_AT_GNU_locviews to show + view pairs. + (print_debug_loc_section): Adjust next_listptr_offset call. + +2020-09-03 Mark Wielaard + + * readelf.c (print_cfa_program): Take ehdr as argument. Use it to + recognize DW_CFA_AARCH64_negate_ra_state. + (print_debug_frame_section): Pass ehdr to print_cfa_program. + (print_debug): Don't warn if we dump frames, but cannot get dbg. + +2020-09-01 Mark Wielaard + + * readelf.c (print_debug_ranges_section): Base address entry can + be first. + (print_debug_loc_section): Likewise. + +2020-09-04 Mark Wielaard + + * elflint.c (special_sections): Add .debug_line_str. + +2020-08-26 Mark Wielaard + + * readelf.c (print_debug_line_section): It is not an error if there + are no line number statements at the end of a debug line section. + +2020-07-19 Mark Wielaard + + * elfclassify.c (process_current_path): Handle fwrite failing. + +2020-07-05 Mark Wielaard + + * stack.c (module_callback): Don't assert if dwfl_module_info fails. + * unstrip.c (adjust_relocs): Produce a proper error when HAS + section has inconsistent size or entsize. + (match_module): Don't assert if dwfl_module_info fails. + +2020-06-16 Mark Wielaard + + * ar.c (do_oper_extract): Split large if statement. Call fchown + before fchmod and explicitly ignore the return value. + (do_oper_delete): Likewise. + (do_oper_insert): Likewise. + * ranlib.c (handle_file): Likewise. + +2020-06-16 Mark Wielaard + + * elflint.c (check_elf_header): Explicitly check and ignore + any error from elf_compress. + +2020-06-07 Mark Wielaard + + * nm.c (sort_by_name_strtab): Replace by... + (sort_by_name_elf): New static Elf pointer and ... + (sort_by_name_ndx): New static size_t index. + (sort_by_name): Use elf_strptr to get symbol string. + (show_symbols): Set sort_by_name_elf and sort_by_name_ndx. + +2020-06-06 Mark Wielaard + + * nm.c (show_symbols_sysv): Skip no name and STT_FILE symbols. + When not printing address and size pad strings. Strip "GNU_" + prefix from binding name. + (class_type_char): Use 'V' for weak symbols, 'C' for common + symbols and 'T' for weak functions. + (show_symbols_posix): Skip STT_FILE symbols. Don't print value and + size when undefined. + +2020-06-04 Mark Wielaard + + * elflint.c (check_program_header): Remove PT_GNU_PROPERTY define. + +2020-05-14 Mark Wielaard + + * size.c (show_bsd): Set printf format based on radix. + +2020-05-09 Mark Wielaard + + * elflint.c (process_elf_file): Error out if ebl_openbackend fails. + * objdump.c (handle_elf): Likewise. + * nm.c (handle_elf): Likewise. Move full name string construction + forward, so it can be used in the error message. + +2020-04-17 Mark Wielaard + + * readelf.c (print_debug): Check .gnu.debuglto_ prefix. + +2020-04-16 Mark Wielaard + + * elflint.c (check_sections): Mask out SHF_EXCLUDE from processor + specific section flags when --gnu is given. + +2020-02-08 Mark Wielaard + + * elflint.c (check_program_header): Handle PT_GNU_PROPERTY. + +2020-02-07 Mark Wielaard + + * elflint.c (check_symtab): Check st_info isn't too big. + +2020-01-16 Mark Wielaard + + * nm.c (show_symbols_sysv): Iterate over all symbols starting + at index zero. + +2019-11-26 Mark Wielaard + + * Makefile.am (BUILD_STATIC): Add libraries needed for libdw. + +2019-10-26 Mark Wielaard + + * unstrip.c (collect_symbols): Check symbol strings are + terminated. + +2019-10-18 Mark Wielaard + + * unstrip.c (adjust_relocs): Set versym data d_size to the actual + size allocated. + +2019-10-20 Mark Wielaard + + * unstrip.c (copy_elided_sections): Set and check max_off. + +2019-10-21 Mark Wielaard + + * unstrip.c (adjust_relocs): Add map_size argument and check ndx + against it. + (adjust_all_relocs): Add map_size argument and pass it to + adjust_relocs. + (add_new_section_symbols): Call adjust_all_relocs with symndx_map + size. + (collect)symbols): Check sym and string data can be found. + (compare_symbols_output): Call error when (different) symbols are + equal. + (new_shstrtab): Make unstripped_strent array one larger. Check + stripped_shnum isn't zero. + (copy_elided_sections): Add ndx_sec_num as size of ndx_section + array. Check sh_link and sh_info are not larger than ndx_sec_num. + Allocate symbols and symndx_map arrays on heap, not stack. Pass + map sizes to adjust_all_relocs. + +2019-09-28 Dmitry V. Levin + + * elflint.c (main): When an input file cannot be opened, + include its name into the error diagnostics. + * readelf.c (main): Likewise. + +2019-09-02 Mark Wielaard + + * readelf.c (PRINT_DYNSYM_TABLE): New argp key value. + (argp_opt): Add syn-sym. + (print_dynsym_table): New static bool. + (parse_opt): Handle PRINT_DYNSYM_TABLE. + (process_elf_file): Check print_dynsym_table. + +2019-08-27 Mark Wielaard + + * readelf.c (for_each_section_argument): Call (*dump) also for + section numbers. + +2019-08-26 Mark Wielaard + + * nm.c (show_symbols): Remember nentries_orig and check before + freeing sym_mem. + +2019-07-05 Omar Sandoval + + * Makefile.am: Remove -ldl. + (elflint_LDADD): Add $(libdw). + (elfcmp_LDADD): Add $(libdw). + (objdump_LDADD): Add $(libdw). + +2019-08-26 Mark Wielaard + + * readelf (options): Add OPTION_ARG_OPTIONAL "SECTION" for notes. + (notes_section): New global variable. + (parse_opt): Set notes_section. + (handle_notes): Check if notes_section is set. + +2019-07-26 Florian Weimer + Mark Wielaard + + * Makefile.am (bin_PROGRAMS): Add elfclassify. + (elfclassify_LDADD): New variable. + * elfclassify.c: New tool. + +2019-07-13 Mao Han + + * elflint.c: Add C-SKY. + +2019-06-28 Mark Wielaard + + * readelf.c (print_ehdr): Use dwelf_elf_e_machine_string instead of + ebl->name. If unknown print hex value. + +2019-06-25 Mark Wielaard + + * stack.c (parse_opt): Fix dwfl_core_file_attach error message. + +2019-06-18 Mark Wielaard + + * strip.c (handle_elf): Use elf_begin ELF_C_WRITE, instead of + ELF_C_WRITE_MMAP. + +2019-05-10 Mark Wielaard + + * readelf.c (struct attrcb_args): Rename die to dies. + (attr_callback): Get current current die using dies[level]. + Handle DW_AT_discr_list as block, not as constant. + (print_debug_units): pass dies, not dies[level] as args. + +2019-05-09 Mark Wielaard + + * readelf.c (cleanup_list): New function. + (main): Call cleanup_list for dump_data_sections and string_sections. + +2019-04-28 Mark Wielaard + + * unstrip.c (add_new_section_symbols): Call ELF_CHECK after + gelf_getsymshndx. + (new_shstrtab): Call ELF_CHECK after gelf_getshdr. + +2019-04-28 Mark Wielaard + + * size.c (show_sysv): Call INTERNAL_ERROR if gelf_getshdr + returns NULL. + (show_sysv_one_line): Call error with EXIT_FAILURE if + gelf_getshdr returns NULL. + +2019-04-28 Mark Wielaard + + * nm.c (show_symbols_sysv): Check gelf_getshdr doesn't return + NULL. Simplify naming of invalid sections, don't use alloca. + +2019-04-28 Mark Wielaard + + * elfcmp.c (main): Check shdr1 and shdr2 are not NULL. + +2019-04-03 Mark Wielaard + + * readelf.c (attr_callback): Print DW_AT_data_member_location as + decimal offset, not hex number. + +2019-03-29 Mark Wielaard + + * readelf.c (print_debug_macinfo_section): Check cus[0] is not the + sentinel. + +2019-03-27 Mark Wielaard + + * strip.c (handle_elf): Assert that symbol section number exists. + +2019-01-24 Mark Wielaard + + * strip.c (handle_elf): Fix check test for SHN_XINDEX symbol. + +2019-01-22 Mark Wielaard + + * readelf.c (print_debug_line_section): Check we are not at end of + line data when reading parameters for unknown opcodes. + +2019-01-20 Mark Wielaard + + * readelf.c (print_debug_line_section): Check terminating NUL byte + for dir and file tables. + +2019-01-16 Mark Wielaard + + * readelf (handle_core_note): Pass desc to ebl_core_note. + +2018-11-10 Mark Wielaard + + * elflint.c (check_program_header): Allow PT_GNU_EH_FRAME segment + to be matched against SHT_X86_64_UNWIND section. + +2018-11-09 Mark Wielaard + + * strip.c (remove_debug_relocations): Check if section is gnu + compressed and decompress and recompress it. + +2018-11-12 Mark Wielaard + + * elflint.c (check_note_data): Recognize NT_GNU_BUILD_ATTRIBUTE_OPEN + and NT_GNU_BUILD_ATTRIBUTE_OPEN. + * readelf.c (handle_notes_data): Handle + ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX. Pass nhdr.n_namesz to + ebl_object_note. + +2018-11-11 Mark Wielaard + + * readelf.c (handle_notes_data): Pass n_descsz to + ebl_object_note_type_name. + * elflint.c (check_note_data): Recognize NT_VERSION, add owner + name to unknown note error. + +2018-10-20 Mark Wielaard + + * readelf.c (process_elf_file): Use dwelf_elf_begin to open pure_elf. + +2018-10-26 Mark Wielaard + + * strip.c (OPT_RELOC_DEBUG_ONLY): New define. + (options): Add reloc-debug-sections-only. + (reloc_debug_only): New static bool. + (main): Check reloc_debug_only is the only strip option used. + (parse_opt): Handle OPT_RELOC_DEBUG_ONLY. + (handle_debug_relocs): New function. + (handle_elf): Add local variables lastsec_offset and lastsec_size. + Handle reloc_debug_only. + +2018-10-24 Mark Wielaard + + * strip.c (handle_elf): Extract code to update shdrstrndx into... + (update_shdrstrndx): ... this new function. + +2018-10-24 Mark Wielaard + + * strip.c (handle_elf): Extract code into separate functions... + (secndx_name): ... new function. + (get_xndxdata): Likewise. + (remove_debug_relocations): Likewise. + +2018-10-24 Mark Wielaard + + * strip.c (handle_elf): Always copy over phdrs if there are any + and check phnum instead of e_type to determine whether to move + allocated sections. + +2018-11-02 Mark Wielaard + + * unstrip.c (copy_elf): Add ELF_CHECK to make sure gelf_getehdr () + doesn't return NULL. + +2018-10-18 Mark Wielaard + + * elflint.c (check_note_data): Recognize NT_GNU_PROPERTY_TYPE_0. + (check_note): Use p_align to pass either ELF_T_NHDR or ELF_T_NHDR8 to + elf_getdata_rawchunk. + * readelf (handle_notes): Likewise. + +2018-10-24 Mark Wielaard + + * addr2line.c (print_addrsym): Use elf_getshdrstrndx instead of + Ehdr field. + +2018-10-24 Mark Wielaard + + * readelf.c (section_name): Remove ehdr argument, lookup shstrndx. + (print_debug_abbrev_section): Don't pass ehdr. + (print_debug_addr_section): Likewise. + (print_decoded_aranges_section): Likewise. + (print_debug_aranges_section): Likewise. + (print_debug_rnglists_section): Likewise. + (print_debug_ranges_section): Likewise. + (print_debug_units): Likewise. + (print_decoded_line_section): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loclists_section): Likewise. + (print_debug_loc_section): Likewise. + (print_debug_macinfo_section): Likewise. + (print_debug_macro_section): Likewise. + (print_debug_pubnames_section): Likewise. + (print_debug_str_section): Liekwise. + (print_debug_str_offsets_section): Likewise. + (print_gdb_index_section): Likewise. + +2018-10-16 Mark Wielaard + + * readelf.c (print_debug_frame_section): Make sure readp is never + greater than cieend. + +2018-10-19 Mark Wielaard + + * dwfl_module_getdwarf.c (adjust_relocs): Check sh_entsize is not + zero. + (add_new_section_symbols): Likewise. + (copy_elided_sections): Likewise. + +2018-10-18 Mark Wielaard + + * size.c (handle_ar): Only close elf if prefix was NULL. + +2018-10-18 Mark Wielaard + + * arlib.c (arlib_add_symbols): Check that sh_entsize is not zero. + +2018-10-14 Mark Wielaard + + * ar.c (do_oper_extract): Assume epoch if ar_date is bogus. + +2018-10-14 Mark Wielaard + + * findtextrel.c (process_file): Check that sh_entsize is not zero. + +2018-10-13 Mark Wielaard + + * readelf.c (print_debug_macro_section): Use elf_getdata. Print + decoded flag string. + +2018-10-19 Mark Wielaard + + * unstrip.c (copy_elided_sections): Renumber group section indexes. + +2018-10-12 Mark Wielaard + + * strip.c (handle_elf): Don't remove SHF_GROUP flag from sections. + Skip group section flag when renumbering section indexes. + * unstrip.c (struct section): Add sig field. + (compare_unalloc_sections): Take and use sig1 and sig2 as arguments. + (compare_sections): Pass signatures to compare_unalloc_sections. + (get_group_sig): New function. + (find_alloc_sections_prelink): Set signature. + (copy_elided_sections): Likewise and pass them on. + (find_unalloc_section): Take and pass signatures. + +2018-10-02 Andreas Schwab + + * strip.c (handle_elf): Handle ADD/SUB relocation. + +2018-09-13 Mark Wielaard + + * readelf.c (print_shdr): Get number of section with elf_getshdrnum. + (print_phdr): Likewise. + +2018-09-13 Mark Wielaard + + * strip.c (handle_elf): Check against shstrndx, not e_shstrndx. + Explicitly set shdrstrndx for debug file. + * unstrip.c (copy_elf): Explicitly copy shstrndx. + (find_alloc_sections_prelink): Document shnum usage. + +2018-09-13 Mark Wielaard + + * elflint.c (check_elf_header): Use shnum instead of e_shnum for all + checks. + (check_symtab): Use shstrndx instead of e_shstrndx to get section + names. + +2018-09-13 Mark Wielaard + + * elfcmp.c (main): Get, check and shdrstrndx for section names. + +2018-09-12 Mark Wielaard + + * elfcmp.c (main): Call ebl_section_strip_p without ehdr. + * strip.c (handle_elf): Likewise. + +2018-09-12 Mark Wielaard + + * elflint.c (check_symtab): Call ebl_check_special_symbol without + ehdr. + +2018-07-30 Mark Wielaard + + * strip.c (handle_elf): Track allocated/unallocated sections seen. Set + section offset of unallocated sections after handling all allocated + sections. + +2018-08-18 Mark Wielaard + + * readelf.c (print_debug_aranges_section): Make sure there is enough + data to read the header segment size. + +2018-08-18 Mark Wielaard + + * elflint.c (check_sysv_hash): Calculate needed size using unsigned + long long int to prevent overflow. + (check_sysv_hash64): Calculate maxwords used separately before + comparison to prevent overflow. + +2018-07-24 Mark Wielaard + + * unstrip.c (compare_unalloc_sections): Also compare sh_size. + +2018-07-21 Mark Wielaard + + * unstrip.c (adjust_all_relocs): Skip SHT_GROUP sections. + +2018-07-21 Mark Wielaard + + * elfcompress.c (get_sections): New function. + (process_file): Check whether section needs to change. Don't rewrite + file if no section data needs changing. + (main): Update 'force' help text. + +2018-07-21 Mark Wielaard + + * elfcompress.c (process_file): Swap fchmod and fchown calls. + +2018-07-04 Mark Wielaard + + * readelf.c (print_debug_addr_section): Rename index var to uidx. + (attr_callback): Rename index var to word. + (print_debug_str_offsets_section): Rename index var to uidx. + +2018-07-04 Ross Burton + + * addr2line.c: Remove error.h include. + * ar.c: Likewise. + * arlib.c: Likewise and add system.h include. + * arlib2.c: Likewise. + * elfcmp.c: Likewise. + * elfcompress.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * stack.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2018-06-25 Mark Wielaard + + * readelf.c (print_decoded_line_section): Use dwarf_next_lines + instead of dwarf_nextcu. + (print_debug_line_section): Don't explicitly lookup CU. + +2018-06-15 Mark Wielaard + + * readelf.c (attr_callback): Only print block as expressions if it + isn't DW_FORM_data16. + +2018-06-12 Mark Wielaard + + * readelf.c (print_form_data): Check we have 4, not 2, bytes + available for DW_FORM_block4. + +2018-06-12 Mark Wielaard + + * readelf.c (print_form_data): Don't increase strreadp after use. + Do increase readp for DW_FORM_strx[1234]. + +2018-06-16 Mark Wielaard + + * readelf.c (print_debug_loc_section): Make sure next_off doesn't + overflow d_buf. + +2018-06-13 Mark Wielaard + + * readelf.c (die_type_sign_bytes): New function. + (attr_callback): Recognized DW_FORM_implicit_cost as signed. Use + die_type_sign_bytes to lookup the signedness and size of const + values. + +2018-06-11 Mark Wielaard + + * readelf.c (print_form_data): Don't reuse readp and readendp when + reading str_offsets section. + +2018-06-10 Mark Wielaard + + * readelf.c (print_form_data): Don't cast value to ptrdiff_t, cast + ptrdiff_t to size_t. + +2018-06-08 Mark Wielaard + + * readelf.c (print_debug_rnglists_section): Calculate max_entries + instead of needed bytes to prevent overflowing. Always print + max_entries (but not more). + (print_debug_loclists_section): Likewise. + +2018-06-08 Mark Wielaard + + * readelf.c (print_debug_line_section): Stop printing directories + and files when we are at the end of the unit data. + +2018-06-07 Mark Wielaard + + * readelf.c (format_result): Removed. + (format_result_size): Removed. + (format_dwarf_addr): Renamed to... + (print_dwarf_addr): ...this. Simply call printf, don't setup buffer, + don't call sprintf. + (print_ops): Use print_dwarf_addr instead of format_dwarf_addr. + (print_debug_addr_section): Likewise. + (print_debug_aranges_section): Likewise. + (print_debug_rnglists_section): Likewise. + (print_debug_ranges_section): Likewise. + (print_debug_frame_section): Likewise. + (attr_callback): Likewise. + (print_decoded_line_section): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loclists_section): Likewise. + (print_debug_loc_section): Likewise. + (print_gdb_index_section): Likewsie. + +2018-06-05 Mark Wielaard + + * readelf.c (print_debug_addr_section): Set unit_length always to + (next_unitp - readp) in case we don't have a real header. + +2018-06-05 Mark Wielaard + + * readelf.c (print_debug_loc_section): Set begin to idx when failing + to read the start address if DW_LLE_GNU_start_end_entry. + +2018-06-05 Mark Wielaard + + * readelf.c (handle_sysv_hash): Don't leak lengths array when + detecting an invalid chain. + (handle_sysv_hash64): Likewise. + +2018-06-05 Mark Wielaard + + * readelf.c (print_debug_macro_section): Extend vendor array by one + to include max DW_MACRO_hi_user opcode. + +2018-06-07 Mark Wielaard + + * readelf.c (main): Lookup "no" for no_str. + (print_debug_abbrev_section): Use yes_str and no_str. + (print_form_data): Likewise. + +2018-06-04 Mark Wielaard + + * readelf (format_result): New static char pointer. + (format_result_size): New static size_t. + (format_dwarf_addr): Calculate max string size, reuse format_result + if possible, otherwise realloc. Use sprintf on result, not asprintf. + (print_ops): Don't free format_dwarf_addr, make sure result is + printed before calling format_dwarf_addr again. + (print_debug_addr_section): Likewise. + (print_debug_aranges_section): Likewise. + (print_debug_rnglists_section): Likewise. + (print_debug_ranges_section): Likewise. + (print_debug_frame_section): Likewise. + (attr_callback): Likewise. + (print_decoded_line_section): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loclists_section): Likewise. + (print_debug_loc_section): Likewise. + (print_gdb_index_section): Likewsie. + +2018-06-04 Mark Wielaard + + * readelf.c (yes_str): New static char pointer. + (no_str): Likewise. + (main): Set yes_str and no_str using gettext. + (attr_callback): Use yes_str and no_str instead of calling gettext. + +2018-06-04 Mark Wielaard + + * readelf.c (main): Call __fsetlocking (stdout, FSETLOCKING_BYCALLER). + +2018-05-31 Mark Wielaard + + * readelf.c (print_debug_units): Print the dwo name and id when + unable to find a .dwo file. + +2018-05-31 Mark Wielaard + + * readelf.c (enum section_e): Make section_types not an alias of + section_info. + (section_all): Add section_types. + (parse_opt): Add both section_info and section_types for "info" + and "info+". + (print_debug_units): Don't be silent for debug_types. + +2018-05-31 Mark Wielaard + + * readelf.c (attr_callback): Only register section_loc when not + looking at a split dwarf from a skeleton. + +2018-05-30 Mark Wielaard + + * readelf.c (print_debug_loc_section): Use correct listptr for + locview attribute. + +2018-05-31 Mark Wielaard + + * readelf.c (print_debug_units): Check offset against -1 not ~0ul. + +2018-05-29 Mark Wielaard + + * readelf.c (print_debug_loc_section): Handle GNU DebugFission list + entries. + +2018-05-29 Mark Wielaard + + * readelf.c (print_debug): Record and reset section_info status in + implicit_debug_sections and print_debug_sections. + +2018-05-28 Mark Wielaard + + * readelf.c (print_debug_units): Turn "Could not find split compile + unit" into an Warning instead of an error. + +2018-04-29 Mark Wielaard + + * readelf.c (parse_opt): Request implicit section_info for "str". + (known_stroffbases): New static variable. + (attr_callbackattr_callback): Handle DW_AT_str_offets_base. + (print_debug_str_offsets_section): New function. + (print_debug): Handle .debug_str_offsets as section_str. Reset + known_stroffbases. + +2018-04-27 Mark Wielaard + + * readelf.c (options): Add addr. + (enum section_e): Add section_addr. + (section_all): Add section_addr. + (parse_opt): Parse "addr". + (known_addrbases): New static variable. + (get_listptr): New function. + (print_debug_addr_section): Likewise. + (attr_callback): Handle DW_AT_addr_base and DW_AT_GNU_addr_base. + (print_debug): Add NEW_SECTION (addr). Reset known_addrbases. + +2018-04-07 Mark Wielaard + + * readelf.c (attr_callback): Handle DW_FORM_loclistx and + DW_AT_segment. + +2018-04-12 Mark Wielaard + + * readelf.c (dwarf_loc_list_encoding_string): New functions. + (dwarf_loc_list_encoding_name): Likewise. + (known_loclistptr): Renamed and split in two... + (known_locsptr): this and ... + (known_loclistsptr): this. + (listptr_base): Split out... + (cudie_base): ...this. + (is_split_dwarf): New function. + (attr_callback): Handle DW_AT_loclists_base and notice sec_offset + in correct list. + (print_debug_rnglists_section): Use spit_dwarf_cu_base. + (print_debug_loclists_section): New function. + (print_debug_loc_section): Use known_locsptr instead of + known_loclistptr. + (print_debug): Recognize .debug_loclists. Reset known_locsptr and + known_loclistsptr. + +2018-05-25 Mark Wielaard + + * readelf.c (DWARF_SKELETON): New constant. + (do_not_close_dwfl): New bool. + (options): Add dwarf-skeleton. + (dwarf_skeleton): New static variable. + (parse_opt): Handle DWARF_SKELETON, set dwarf_skeleton. + (create_dwfl): New function, with code extracted from... + (process_file): ...here. Check do_not_close_dwfl. + (is_split_darf): New function. + (getone_dwflmod): Likewise. + (print_debug): Use new functions to find skeleton DWARF file to use + when inspecting .dwo split DWARF file. + +2018-04-11 Mark Wielaard + + * readelf.c (dwarf_range_list_encoding_string): New function. + (dwarf_range_list_encoding_name): Likewise. + (known_rnglistptr): New static variable. + (listptr_cu): New function. + (print_debug_rnglists_section): Likewise. + (attr_callback): Call notice_listptr for DW_AT_ranges. Handle + DW_AT_rnglists_base. Handle DW_FORM_rnglistx. DW_AT_start_scope + can also have a rnglist. + (print_debug_units): Do (silently) scan split DWARF also for + debug_ranges before DWARF5 to catch all rangelistptrs. + (print_debug): Recognize .debug_rnglists. Reset known_rnglistptr. + +2018-01-21 Mark Wielaard + + * readelf.c (get_indexed_addr): New function. + (print_ops): Handle DW_OP_addrx, DW_OP_GNU_addr_index, + DW_OP_constx, DW_OP_GNU_const_index separately and resolve + address. + (attr_callback): Print index and address for + DW_FORM_GNU_addr_index and DW_FORM_addrx[1234]. + +2018-01-19 Mark Wielaard + + * readelf.c (options): Add info+. + (show_split_units): New static boolean defaulting to false. + (parse_opt): For all (no arg) --debug-dump set show_split_units + to yes. For "info+" enable section_info and show_split_units. + (attrcb_args): Add is_split field. + (attr_callback): Use is_split to format DIE offsets differently. + (print_debug_units): Likewise. Get subdie (type or split) only + when needed. When not silent reiterate over split DIEs when + found. + +2018-05-15 Mark Wielaard + + * readelf.c (print_debug_units): Print unit type and id for any + unit type that has it even when version < 5. + +2018-05-14 Mark Wielaard + + * readelf.c (print_ops): Handle DW_OP_GNU_addr_index and + DW_OP_GNU_const_index. + (attr_callback): Handle DW_FORM_GNU_addr_index as DW_FORM_addrx. + Handle DW_FORM_GNU_str_index as DW_FORM_constx. Add as_hex_id. + Handle DW_AT_GNU_dwo_id as_hex_id. + (print_form_data): Handle DW_FORM_GNU_str_index as DW_FORM_strx. + +2018-05-12 Mark Wielaard + + * readelf.c (print_debug): Also recognize .dwo section name variants. + +2018-05-15 Dmitry V. Levin + + * elflint.c (check_elf_header): Fix typo in error diagnostics. + +2018-05-15 Mark Wielaard + + * readelf.c (print_form_data): Cast comparisons against offset_len to + ptrdiff_t. + (print_debug_line_section): Print uint64_t as PRIu64. + +2018-05-11 Mark Wielaard + + * readelf.c (print_debug_macro_section): Use libdw_valid_user_form. + Use print_form_data for strx and sup strings. + +2018-05-09 Mark Wielaard + + * readelf.c (dwarf_line_content_description_string): New function. + (dwarf_line_content_description_name): Likewise. + (print_bytes): Likewise. + (print_form_data): Likewise. Based on code taken from... + (print_debug_macro_section): ...here. Now calls print_form_data + and str_offsets_base_off. + (print_debug_line_section): Parse DWARF5 header, directory and file + name tables. + +2018-05-12 Mark Wielaard + + * addr2line.c (main): Add fflush (stdout) after handle_address () + when reading from stdin. + +2018-04-24 Mark Wielaard + + * readelf.c (print_debug_aranges_section): Try elf_rawdata if no + sectiondata. + (print_debug_ranges_section): Likewise. + (print_debug_frame_section): Likewise. + (print_debug_line_section): Likewise. Check for data == NULL. + (print_debug_loc_section): Likewise. + (print_debug_macinfo_section): Likewise. + (print_debug_macro_section): Likewise. + +2018-04-28 Mark Wielaard + + * readelf.c (print_debug): If .debug_info is needed implicitly by + then handle it first before handling any other debug section. + (parse_opt): Set implicit_debug_sections to section_info when + showing all debug sections. + +2018-05-05 Mark Wielaard + + * readelf.c (attr_callback): Handle DW_FORM_ref_sup4 and + DW_FORM_ref_sup8 as references. + +2018-04-24 Mark Wielaard + + * readelf.c (print_debug_str_section): Take raw section data. Don't + use dwarf_getstring, but determine start and end of string from + offset and section data directly. + (print_debug): Handle ".debug_line_str" like ".debug_str". + +2018-04-19 Andreas Schwab + + * elflint.c (valid_e_machine): Add EM_RISCV. + +2018-04-16 Mark Wielaard + + * readelf.c (print_debug_line_section). In advance_pc, advance + using op_addr_advance, not op_advance. + +2018-04-14 Mark Wielaard + + * readelf.c (attr_callback): Only show errors when not silent. + +2018-03-23 Mark Wielaard + + * readelf.c (attr_callback): Handle DW_FORM_strx[1234]. + +2018-03-22 Mark Wielaard + + * readelf.c (attr_callback): Handle DW_FORM_addrx[1234]. + +2018-03-28 Mark Wielaard + + * readelf.c (handle_sysv_hash): Break bucket chain after nchain + entries are found. + (handle_sysv_hash64): Likewise. + +2018-03-27 Mark Wielaard + + * readelf.c (attr_callback): Print dwarf_dieoffset as %PRIx64, + not %zx. + +2018-03-20 Mark Wielaard + + * readelf.c (attr_callback): Report error when DW_AT_decl_file or + DW_AT_call_file cannot be resolved. + +2018-03-06 Mark Wielaard + + * readelf.c (print_ops): Handle DW_OP_addrx, DW_OP_constx, + DW_OP_implicit_pointer, DW_OP_entry_value, DW_OP_const_type, + DW_OP_regval_type, DW_OP_deref_type, DW_OP_xderef_type, + DW_OP_convert, DW_OP_reinterpret. + +2018-03-01 Mark Wielaard + + * readelf.c (struct listptr): Add attr field. + (compare_listptr): Warn when two listptrs for the same offset have + different attributes. + (notice_listptr): Take attr as argument and add it to listptr. + (skip_listptr_hole): New attr argument. + (next_listptr_offset): New function. + (print_debug_ranges_section): Pass NULL attr to skip_listptr_hole. + (attr_callback): Handle DW_AT_GNU_locviews. Call notice_listptr with + attr. + (print_debug_loc_section): Keep track of which attr is associated with + a listptr. If the attr is DW_AT_GNU_locview print view pairs till the + next listptr offset. + +2018-02-09 Mark Wielaard + + * elflint.c (check_group): Make sure we can read a complete + element when iterating over the group. + +2018-02-09 Mark Wielaard + + * readelf.c (attr_callback): Handle DW_FORM_data16 as Dwarf_Block. + +2018-02-09 Mark Wielaard + + * readelf.c (print_debug_abbrev_section): Print the value of a + DW_FORM_implicit_const using dwarf_getabbrevattr_data. + (attr_callback): Handle DW_FORM_implicit_const. + +2018-01-30 Mark Wielaard + + * readelf.c (dwarf_unit_string): New function. + (dwarf_unit_name): Likewise. + (print_debug_units): Use dwarf_get_units and dwarf_cu_die instead + of dwarf_next_unit. Print unit type, id and subdie if available. + +2018-02-09 Joshua Watt + + * addr2line.c (handle_address): Use FALLTHROUGH macro instead of + comment. + * elfcompress.c (parse_opt): Likewise. + * elflint.c (check_dynamic): Likewise. + (check_sections): Likewise. + (check_note_data): Likewise. + * objdump.c (parse_opt): Likewise. + * readelf.c (parse_opt): Likewise. + (attr_callback): Likewise. + (handle_auxv_note): Likewise. + * strings.c (parse_opt): Likewise. + * backtrace.c (callback_verify): Likewise. + +2018-01-25 Mark Wielaard + + * readelf.c (print_debug_ranges_section): Initialize cu to last_cu. + (print_debug_loc_section): Likewise. + +2018-01-01 Mark Wielaard + + * readelf.c (attr_callback): Use dwarf_form_name for unknown forms. + (print_debug_macro_section): Print form using dwarf_form_name. + +2017-12-28 Mark Wielaard + + * readelf.c (print_debug_units): Print DIE offset in error message + as hex. + +2017-12-18 Mark Wielaard + + * readelf.c (handle_notes_data): Don't use EXIT_FAILURE in error. + Adjust error message depending on whether or not we got data. + +2017-12-07 Mark Wielaard + + * readelf.c (print_ops): Update data pointer and print arguments + to DW_OP_call2 and DW_OP_call4 as DIE offsets. + +2017-11-29 Mark Wielaard + + * readelf.c (argp_options): Add "section-groups", 'g'. + +2017-11-29 Mark Wielaard + + * readelf.c (print_debug_loc_section): Print CU base and unresolved + addresses. Adjust formatting. + +2017-11-29 Mark Wielaard + + * readelf.c (print_debug_ranges_section): Print CU base and unresolved + addresses. Adjust formatting. + +2017-11-29 Mark Wielaard + + * readelf.c (attr_callback): Set valuestr to resolved file name + for DW_AT_decl_file and DW_AT_call_file. + +2017-11-29 Mark Wielaard + + * readelf.c (print_debug_units): Print abbrev code after DIE tag. + +2017-11-29 Mark Wielaard + + * readelf.c (print_ops): Use only2 space for index. re-indent +5 + for DW_OP_GNU_entry_value. + +2017-11-21 Mark Wielaard + + * readelf.c (attr_callback): Print attribute name and form in error + message. If only the value cannot be retrieved/resolved don't abort. + +2017-10-03 Mark Wielaard + + * readelf.c (attr_callback): Print DIE offset in error messages. + +2017-11-03 Mark Wielaard + + * readelf.c (print_ops): Handle DW_OP_GNU_variable_value. Print + referenced DIE as offset. + +2017-09-10 Mark Wielaard + + * ar.c (do_oper_delete): Remove DEBUG conditional check. + (no0print): Return bool. Check snprintf return value. + (do_oper_insert): Initialize elf. Remove DEBUG conditional check. + Check no0print calls succeed. Explicitly elf_end found elfs. + (do_oper_extract): Make sure we don't create an empty variable + length array. + +2017-09-01 Mark Wielaard + + * stack.c (main): Replace \v in doc string with \n\n. + * unstrip.c (main): Likewise. + +2017-05-04 Ulf Hermann + + * stack.c: Print pid_t using %lld. + +2017-08-18 Ulf Hermann + + * readelf.c: Hardcode the signal numbers for non-linux systems. + +2017-07-26 Mark Wielaard + + * readelf.c (print_debug_macro_section): Accept either version 4 or + version 5. Use DW_MACRO names instead of DW_MACRO_GNU names. Add + minimal support for DW_MACRO_define_sup, DW_MACRO_undef_sup, + DW_MACRO_import_sup, DW_MACRO_define_strx and DW_MACRO_undef_strx. + +2017-07-26 Mark Wielaard + + * readelf.c (dwarf_defaulted_string): New function. + (dwarf_defaulted_name): Likewise. + (attr_callback): Use dwarf_defaulted_name to get value of + DW_AT_defaulted. + +2017-07-20 Mark Wielaard + + * strip.c (handle_elf): Deal with data marker symbols pointing to + debug sections (they can be removed). + +2017-07-14 Mark Wielaard + + * strip (OPT_KEEP_SECTION): New define. + (options): Add documentation for remove-section. Add keep-section. + (struct section_pattern): New data type. + (keep_secs, remove_secs): New globals. + (add_pattern, free_sec_patterns, free_patterns, section_name_matches): + New functions. + (main): Call free_patterns. + (parse_opt): Handle 'R' and OPT_KEEP_SECTION. Check remove_comment + on ARGP_KEY_SUCCESS. + (handle_elf): Handle and sanity check keep_secs and remove_secs. + +2017-06-07 Mark Wielaard + + * strip.c (handle_elf): Introduce new handle_elf boolean. Use it to + determine whether to create an output and/or debug file. Remove new + output file on error. + +2017-06-06 Mark Wielaard + + * strip.c (handle_elf): Assume e_shstrndx section can be removed. + +2017-04-20 Ulf Hermann + + * readelf.c: Include strings.h. + +2017-04-20 Ulf Hermann + + * unstrip.c: Check shnum for 0 before subtracting from it. + +2017-04-20 Ulf Hermann + + * readelf.c: Replace YESSTR and NOSTR with gettext ("yes") and + gettext ("no"), respectively. + +2017-04-05 Mark Wielaard + + * elflint.c (check_elf_header): Decompress all sections. + +2017-03-28 Mark Wielaard + + * elflint (check_group): Don't check if there is no flag word. + +2017-03-27 Mark Wielaard + + * elflint.c (check_elf_header): Sanity check phnum and shnum. + +2017-03-27 Mark Wielaard + + * elflint.c (check_sysv_hash): Return early if section size is + too small. + (check_sysv_hash64): Likewise. + (check_hash): Calculate expect_entsize to check section size. + +2017-03-27 Mark Wielaard + + * elflint.c (check_symtab_shndx): Check data->d_size. + +2017-03-24 Mark Wielaard + + * elfcmp.c (main): If n_namesz == 0 then the note name data is the + empty string. + * readelf.c (handle_notes_data): Likewise. + +2017-03-24 Mark Wielaard + + * readelf.c (handle_gnu_hash): Check inner < max_nsyms before + indexing into chain array. + +2017-02-16 Ulf Hermann + + * addr2line.c: Include printversion.h + * ar.c: Likewise. + * elflint.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * stack.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * elfcmp.c: Include printversion.h, remove system.h include. + * elfcompress.c: Likewise. + * findtextrel.c: Likewise. + * unstrip.c: Likewise. + +2017-02-14 Ulf Hermann + + * nm.c: Include color.h. + * objdump.c: Likewise. + +2016-12-24 Mark Wielaard + + * Makefile.am (findtextrel_LDADD): Add $(libeu). + (addr2line_LDADD): Likewise. + (elfcmp_LDADD): Likewise. + * addr2line.c (print_version): Removed. + * ar.c (print_version): Likewise. + * elfcmp.c (print_version): Likewise. + * elfcompress.c (print_version): Likewise. + * elflint.c (print_version): Likewise. + * findtextrel.c (print_version): Likewise. + * nm.c (print_version): Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * stack.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2016-11-17 Mark Wielaard + + * readelf.c (options): Add optional arg SECTION for symbols. + (symbol_table_section): New static variable. + (parse_opt): Set symbol_table_section on 's'. + (print_symtab): Filter on symbol_table_section name is set. + +2016-11-10 Mark Wielaard + + * ar.c (write_member): Make sure tmpbuf is large enough to contain + a starting '/' and ending '\0' char. + (do_oper_insert): Likewise. + * arlib.c (arlib_finalize): Format tmpbuf as PRId32 decimal. + +2016-11-02 Mark Wielaard + + * addr2line.c (handle_address): Add fallthrough comment. + * elfcompress.c (parse_opt): Adjust fallthrough comment. + * elflint.c (parse_opt): Add missing break after 'd' case. + (check_sections): Add fallthrough comments. + * objdump.c (parse_opt): Add explantion for fallthrough comment. + +2016-10-22 Kevin Cernekee + + * unstrip.c: Fix "invalid string offset" error caused by using the + unstripped .symtab with the stripped .strtab. + +2016-10-11 Akihiko Odaki + + * arlib.c: Remove system.h include, add libeu.h include. + * arlib2.c: Remove sys/param.h include. + * elfcompress.c: Add libeu.h include. + * elflint.c: Remove sys/param.h include, add libeu.h include. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Remove sys/param.h include. + * strings.c: Likewise, add libeu.h include. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2016-10-06 Mark Wielaard + + * strip.c (handle_elf): Don't remove real symbols from allocated + symbol tables. + +2016-08-25 Mark Wielaard + + * strip.c (handle_elf): Recompress with ELF_CHF_FORCE. + +2016-08-06 Mark Wielaard + + * strip.c (handle_elf): Uncompress and recompress relocation target + section if necessary. + +2016-07-08 Mark Wielaard + + * Makefile.am (strip_LDADD): Add libdw. + * elfcompress.c (process_file): Use dwelf_strtab functions instead of + ebl_strtab. + * strip.c (handle_elf): Likewise. + * unstrip.c (new_shstrtab): Likewise. + +2016-07-06 Mark Wielaard + + * elf32-i386.script, i386_ld.c, ld.c, ld.h, ldgeneric.c, ldlex.l, + ldscript.y, libld_elf_i386.map, none_ld.c, sectionhash.c, + sectionhash.h, symbolhash.c, symbolhash.h, unaligned.h, + versionhash.c, versionhash.h, xelf.h: Removed. + * Makefile.am (YACC): Removed. + (AM_YFLAGS): Removed. + (AM_LFLAGS): Removed. + (native_ld): Removed. + (base_cpu): Removed. + (bin_PROGRAMS): Removed ld. + (ld_dsos): Removed. + (ld_SOURCES): Removed. + (noinst_LIBRARIES): Only libar.a. + (EXTRA_DIST): Just arlib.h and debugpred.h. + (ld_LDADD): Removed. + (ld_LDFLAGS): Removed. + (ldlex.o): Removed. + (ldscript.h): Removed. + (libld*): Removed. + (CLEANFILES): Just *.gconv. + (MAINTAINERCLEANFILES): Removed. + +2016-07-06 Mark Wielaard + + * unstrip.c (copy_elided_sections): Use unstripped_strent[] from + index zero, instead of one. + +2016-06-28 Richard Henderson + + * elflint.c (valid_e_machine): Add EM_BPF. + +2016-04-11 David Abdurachmanov + + * elfcmp.c (main): Fix self-comparison error with GCC 6. + +2016-03-21 Mark Wielaard + + * nm.c (show_symbols): Check for malloc size argument overflow. + +2016-02-13 Mark Wielaard + + * readelf.c (print_scngrp): Call error when gelf_getshdr fails. + (print_symtab): Likewise. + (handle_hash): Likewise. + (dump_data_section): Print a warning if decompressing fails. + (print_string_section): Likewise. + +2016-02-13 Mark Wielaard + + * elfcompress.c (parse_opt): Don't fallthrough after processing -q. + +2016-02-12 Mark Wielaard + + * strip.c (handle_elf): Correct elf_assert shndxdata check. + +2016-02-09 Mark Wielaard + + * readelf.c (read_encoded): Move up. + (print_cfa_program): Add encoding argument. Use it for read_encoded + when reading DW_CFA_set_loc op. + (print_debug_frame_section): Pass fde_encoding to print_cfa_program. + +2016-02-09 Mark Wielaard + + * elflint.c (compare_hash_gnu_hash): Check hash sh_entsize against + sizeof (Elf64_Xword). Correct invalid sh_entsize error message + section idx and name. + +2016-01-13 Mark Wielaard + + * elflint.c (check_elf_header): Recognize ELFOSABI_FREEBSD. + +2016-01-08 Mark Wielaard + + * elfcompress.c (compress_section): Use %zu to print size_t. + * readelf.c (print_shdr): Use %zx to print size_t. + +2015-12-16 Mark Wielaard + + * elfcompress.c: New file. + * Makefile.am (bin_PROGRAMS): Add elfcompress. + (elfcompress_LDADD): New variable. + +2015-12-18 Mark Wielaard + + * elflint.c (section_flags_string): Add NEWFLAG COMPRESSED. + (check_sections): SHF_COMPRESSED can be on any special section. + SHF_COMPRESSED is a valid section flag. SHF_COMPRESSED cannot + be used together with SHF_ALLOC or with SHT_NOBITS. Should have + a valid Chdr. + +2015-10-20 Mark Wielaard + + * readelf.c (options): Expand -z help text. + (dump_data_section): Check whether we need and can decompress section + data and call elf_rawzdata if so, + (print_string_section): Likewise. + (elf_contains_chdrs): New function. + (process_elf_file): Rename print_unrelocated to print_unchanged, + use elf_contains_chdrs. + (print_scngrp): Check whether section is compressed before use. + (print_symtab): Likewise. + (handle_hash): Likewise. + +2015-10-16 Mark Wielaard + + * readelf.c (argp_option): Describe --decompress,-z. + (print_decompress): New bool. + (parse_opt): Handle -z. + (elf_ch_type_name): New function. + (print_shdr): Print section compress information. + +2015-12-31 Mark Wielaard + + * elflint.c (check_symtab): Add _edata and _end (plus extra underscore + variants) to to the list of possibly dangling symbols. + +2015-12-02 Mark Wielaard + + * nm.c (process_file): Accept fd and pass it on. + (handle_elf): Likewise. + (find_no_debuginfo): New. + (struct getdbg): Likewise. + (getdbg_dwflmod): Likewise. + (show_symbols): Take fd. If the file is ET_REL use libdwfl to get + the relocated Dwarf. + +2015-12-02 Mark Wielaard + + * nm.c (get_local_names): Check for duplicates in local_root tree. + +2015-12-02 Mark Wielaard + + * unstrip.c (struct data_list): New. + (new_data_list): Likewise. + (record_new_data): Likewise. + (free_new_data): Likewise. + (adjust_relocs): Call record_new_data. + (add_new_section_symbols): Likewise. + (copy_elided_sections): Call free_new_data. + +2015-12-01 Mark Wielaard + + * elfcmp.c (main): Close ebl1 and ebl2 backends. + +2015-10-16 Mark Wielaard + + * Makefile.am [BUILD_STATIC](libdw): Add -lz. + [BUILD_STATIC](libelf): Likewise. + +2015-10-16 Mark Wielaard + + * elflint.c (check_symtab): Don't check TLS symbol value against TLS + phdr offset in debuginfo files. + (check_sections): Don't try to match section offsets to phdrs offsets + in debuginfo files. + +2015-10-16 Mark Wielaard + + * elflint.c (check_reloc_shdr): Reject only desthdrs if they have both + SHF_MERGE and SHF_STRINGS set. + +2015-10-13 Jose E. Marchesi + + * elflint.c (check_sections): Do not rely on + ebl_check_special_section when checking debuginfo files. Also + check that the type of WE sections in debuginfo files is NOBITS. + +2015-10-13 Mark Wielaard + + * elflint.c (check_program_header): Check relro flags are a subset + of the load segment if they don't fully overlap. + +2015-10-07 Mark Wielaard + + * Makefile.am (ldlex_no_Wstack_usage): New. + * ldlex.l ([RWX]): Make cnt unsigned. + +2015-10-09 Josh Stone + + * elflint.c (main): Replace stat64 and fstat64 with stat and fstat. + * readelf.c (process_file): Likewise. + (process_elf_file): Replace off64_t with off_t. + * findtextrel.c (process_file): Replace open64 with open. + * ld.c (main): Replace sizeof (off64_t) with 8. + * strings.c: Replace off64_t with off_t throughout. + (main): Replace stat64 and fstat64 with stat and fstat. + (map_file): Replace mmap64 with mmap. + (read_block): Likewise, and replace lseek64 with lseek. + * strip.c (handle_elf): Replace ftruncate64 with ftruncate. + (process_file): Replace stat64 and fstat64 with stat and fstat. + * unstrip.c (parse_opt): Replace stat64 with stat. + (handle_file): Replace open64 with open. + (open_file): Likewise. + +2015-10-08 Chih-Hung Hsieh + + * ld.c (determine_output_format): Move recursive nested + function "try" to file scope. + +2015-10-04 Mark Wielaard + + * strip.c (handle_elf): Only sanity check section symbols to not + kept discarded sections if we are creating a debug file. + +2015-10-07 Mark Wielaard + + * unstrip.c (MAX): Removed. + (find_alloc_sections_prelink): Allocate exact amount of bytes for + shdrs. + +2015-10-05 Chih-Hung Hsieh + + * unstrip.c (find_alloc_sections_prelink): Do not allocate + on stack union types with variable length arrays; use xmalloc + for such dynamic sized objects. + * readelf.c (handle_core_item): Likewise, but use alloca + for small variable size data object and add assert(count < 128). + +2015-10-05 Josh Stone + + * Makefile.am (libld_elf_i386.so): Add AM_V_CCLD silencer. + (.deps/none_ld.Po): Always silence the dummy command. + (make-debug-archive): Add AM_V_GEN and AM_V_at silencers. + +2015-10-02 Mark Wielaard + + * unstrip.c (copy_elided_sections): Use SH_INFO_LINK_P, not just + SHF_INFO_LINK. + +2015-10-02 Mark Wielaard + + * strip.c (handle_elf): Don't move around allocated NOBITS sections. + Don't just mark the section header string table as unused. + * unstrip.c (copy_elided_sections): Add header names to strtab if + shstrndx equals the symtab strtabndx. + +2015-09-22 Mark Wielaard + + * strip.c (cleanup_debug): Remove old-style function definitions. + +2015-09-09 Chih-Hung Hsieh + + * readelf.c (print_debug_exception_table): Initialize variable before + it is used, because compiler does not know that error never returns. + (dump_arhive_index): Likewise. + +2015-09-04 Chih-Hung Hsieh + + * elflint.c (check_group): Replace %Z length modifier with %z. + (check_note_data): Likewise. + * findtextrel.c (process_file): Likewise. + * readelf.c (handle_dynamic): Likewise. + (handle_symtab): Likewise. + (handle_verneed): Likewise. + (handle_verdef): Likewise. + (handle_versym): Likewise. + (print_hash_info): Likewise. + (print_decoded_aranges_section): Likewise. + (print_debug_aranges_section): Likewise. + (print_debug_line_section): Likewise. + (hex_dump): Likewise. + (dump_data_section): Likewise. + (print_string_section): Likewise. + (dump_archive_index): Likewise. + * unstrip.c (adjust_relocs): Likewise. + (collect_symbols): likewise. + (get_section_name): Likewise. + (find_alloc_sections_prelink): Likewise. + (copy_elided_sections): Likewise. + * ldscript.y (add_id_list): Add missing '%s'. + +2015-09-03 Mark Wielaard + + * readelf.c (handle_core_item): Handle right shift >= 32 bits. + +2015-08-11 Mark Wielaard + + * elflint.c (check_sections): When gnuld and a NOBITS section falls + inside a segment make sure any ELF file contents is zero. + +2015-07-29 Mark Wielaard + + * unstrip.c (sections_flags_match): New function. + (sections_match): Use sections_flags_match. + (find_alloc_sections_prelink): Only clear matched sections if there + is an undo section. + (copy_elided_sections): Add SHF_INFO_LINK to shdr_mem.sh_flags if + necessary. + +2015-06-27 Pino Toscano + + * src/strings.c: Define MAP_POPULATE if not defined already. + +2015-06-27 Mark Wielaard + + * nm.c (show_symbols): First call elf_getdata, then allocate memory. + +2015-06-18 Mark Wielaard + + * findtextrel.c (process_file): Free segments after use. + +2015-06-18 Mark Wielaard + + * readelf.c (print_phdr): Make sure phdr2_mem lifetime/scope equals + phdr2 pointer. + +2015-06-18 Mark Wielaard + + * readelf.c (handle_gnu_hash): Free lengths on invalid_data. + +2015-06-18 Mark Wielaard + + * elflint.c (check_symtab): Only check the PT_TLS phdr if it actually + exists. Warn otherwise. + +2015-06-18 Mark Wielaard + + * nm.c (show_symbols): Check sizeof (sym_mem[0]), not GElf_Sym to + known whether or not we stack allocated memory. + +2015-06-18 Mark Wielaard + + * strings.c (readelf): Use "" if we cannot retrieve section + name. + +2015-06-09 Mark Wielaard + + * addr2line.c (print_dwarf_function): Always free scopes before + returning. + +2015-06-09 Mark Wielaard + + * strip.c (handle_ar): Mark as unused. + (process_file): Produce an error when trying to handle an ar. + +2015-05-30 Mark Wielaard + + * elfcmp.c (main): Only call memcmp when d_size != 0. + +2015-05-23 Mark Wielaard + + * Makefile.am: Define ldgeneric, readelf, nm, size, strip, elflint, + findtextrel, elfcmp objdump, ranlib, ar and unstrip no_Wstack_usage. + +2015-05-21 Mark Wielaard + + * addr2line.c (handle_address): Set scopes to NULL after free. + +2015-05-20 Mark Wielaard + + * addr2line.c (OPT_PRETTY): New constant define. + (argp_option): Add "pretty-print". + (pretty): New static bool. + (parse_opt): Set pretty. + (print_dwarf_function): Adjust output when pretty is set. + (print_addrsym): Likewise. + (handle_address): Likewise. + +2015-05-20 Mark Wielaard + + * Makefile.am (addr2line_LDADD): Add demanglelib. + * addr2line.c (argp_option): Move demangle under output format. + (demangle): New static bool. + (demangle_buffer_len): New static size_t. + (demangle_buffer): New static char *. + (main): free demangle_buffer. + (parse_opt): Set demangle. + (symname): New static function. + (get_diename): Use symname. + (print_dwarf_function): Likewise. + (print_addrsym): Likewise. + (handle_address): Likewise. + +2015-05-20 Mark Wielaard + + * addr2line.c (argp_option): Add "addresses", 'a'. + (print_addresses): New static bool. + (parse_opt): Set print_addresses. + (get_addr_width): New static function. + (handle_address): Print address if print_addresses is true. + +2015-05-20 Mark Wielaard + + * addr2line.c (handle_address): Call strtoumax with base 16. Make + sure all input has been processed. + +2015-05-20 Mark Wielaard + + * addr2line (argp_option): Group 'section' under "Input format + options". + +2015-05-12 Mark Wielaard + + * strip.c (debug_fd): New static variable. + (tmp_debug_fname): Likewise. + (cleanup_debug): New function using the above to clean up temporary + debug file. + (INTERNAL_ERROR): Call cleanup_debug. + (handle_elf): Use debug_fd and tmp_debug_fname statics and call + cleanup_debug before any error. Use output_fname instead of fname in + error messages when it exists (-o was given). SHT_NOBITS sections + can also be moved freely even if SHF_ALLOC is set. Add various + sanity checks. Use elf_assert instead of plain assert. + +2015-05-08 Mark Wielaard + + * nm.c (show_symbols): Call gelf_fsize with EV_CURRENT. + * strip.c (handle_elf): Likewise. + +2015-05-06 Mark Wielaard + + * elflint.c (check_gnu_hash): Return early when 2nd hash function + shift too big. Check there is enough data available. Make sure + bitmask_words is not zero. + (check_verdef): Use Elf64_Word for shdr->sh_info cnt. + (check_verneed): Likewise. + (check_attributes): Break when vendor name isn't terminated. + Add overflow check for subsection_len. + +2015-05-05 Mark Wielaard + + * nm.c (show_symbols): Handle dwarf_linesrc returning NULL. + +2015-05-04 Max Filippov + + * ar.c (do_oper_extract): Replace struct timeval with struct timespec + and futimes with futimens. + * strip.c (process_file): Replace struct timeval with struct timespec. + (handle_elf, handle_ar): Replace struct timeval with struct timespec + in prototype. Replace futimes with futimens. + +2015-05-04 Max Filippov + + * addr2line.c (main): Drop mtrace() call and #include . + * ar.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * size.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2015-05-04 Anthony G. Basile + + * Makefile.am (readelf_LDADD, nm_LDADD, size_LDADD, strip_LDADD) + (ld_LDADD, elflint_LDADD, findtextrel_LDADD, addr2line_LDADD) + (elfcmp_LDADD, objdump_LDADD, ranlib_LDADD, strings_LDADD) + (ar_LDADD, unstrip_LDADD, stack_LDADD): Append $(argp_LDADD). + +2015-03-22 Mark Wielaard + + * readelf.c (print_debug_frame_section): Cast start to Dwarf_Off + before subtracting cie_id. And cast cie_offset to Dwarf_Off before + comparison. + +2015-03-22 Mark Wielaard + + * readelf.c (print_gdb_index_section): Check all offsets used + against section d_size. + +2015-03-17 Mark Wielaard + + * readelf.c (print_debug): Don't return, but always use dummy_dbg. + +2015-03-17 Mark Wielaard + + * readelf.c (print_gdb_index_section): Add overflow checking for + dataend checks. + +2015-03-14 Mark Wielaard + + * nm.c (INTERNAL_ERROR): Remove __DATE__. + * objdump.c (INTERNAL_ERROR): Likewise. + * size.c (INTERNAL_ERROR): Likewise. + * strip.c (INTERNAL_ERROR): Likewise. + +2015-03-18 Petr Machata + + * readelf.c (dwarf_tag_string, dwarf_attr_string) + (dwarf_form_string, dwarf_lang_string, dwarf_inline_string) + (dwarf_encoding_string, dwarf_access_string) + (dwarf_visibility_string, dwarf_virtuality_string) + (dwarf_identifier_case_string, dwarf_calling_convention_string) + (dwarf_ordering_string, dwarf_discr_list_string) + (dwarf_locexpr_opcode_string): Adjust uses of know-dwarf.h macros + to match the API changes. + +2015-03-09 Mark Wielaard + + * elflint.c (compare_hash_gnu_hash): Correct gnu_symbias usage. + +2015-01-03 Mark Wielaard + + * elfcmp (main): Check section name is not NULL. Check sh_entsize + is not zero for symbol tables. Check phdrs are not NULL. + (search_for_copy_reloc): Check sh_entsize is not zero. + +2014-12-30 Mark Wielaard + + * elflint.c (check_scn_group): Check d_buf and name are not NULL. + (is_rel_dyn): Check d is not NULL. Check shdr->sh_entsize is not + zero. + (check_dynamic): Check strshdr is not NULL. Check d_tag is positive. + (check_symtab_shndx): Check symshdr and data->d_buf are not NULL. + Check shdr and symshdr sh_entsize are not zero. + (check_gnu_hash): Make sure maskidx is smaller than bitmask_words. + Check symshdr->sh_entsize is not zero. Check data->d_buf is not + NULL. + (compare_hash_gnu_hash): Check sections d_buf are not NULL. + Check section data is large enough. Use gnu_symbias. + (check_group): Check section val is valid. + (has_copy_reloc): Check sh_entsize is not zero. + (check_versym): Likewise. + (unknown_dependency_p): Likewise. + (check_verneed): Break on invalid ref or offset. Don't assert. + Report error when next offset is zero, but more vers expected. + (check_verdef): Likewise. + (check_attributes): Make sure d_buf is not NULL. + (check_note): Likewise. + (check_note_section): Likewise. + (check_program_header): Make sure section name is not NULL. + +2014-12-26 Mark Wielaard + + * strings.c (read_elf): Produce error when section data falls outside + file. + +2014-12-26 Mark Wielaard + + * nm.c (show_symbols): Guard against divide by zero in error check. + Add section index number in error message. + +2014-12-26 Mark Wielaard + + * nm.c (handle_ar): Skip over /SYM64/ entries. + +2014-12-26 Mark Wielaard + + * nm.c (handle_ar): Break on arsym with invalid offset. + +2014-12-20 Mark Wielaard + + * readelf.c (print_debug_macinfo_section): Mark cus sentinel files + as -1 non-existent. Check macoff against sentinel cus. + +2014-12-20 Mark Wielaard + + * readelf.c (print_debug_exception_table): Add max_action overflow + check. Check action_table_end before reading slib128. Check + max_ar_filter underflow. + +2014-12-18 Ulrich Drepper + + * Makefile.am: Suppress output of textrel_check command. + +2014-12-17 Mark Wielaard + + * readelf.c (print_cfa_program): Add bounds check before each op that + takes at least one argument. + +2014-12-16 Mark Wielaard + + * readelf.c (print_decoded_line_section): Print dwarf_errmsg if + dwarf_onesrcline or dwarf_linesrc fails. + +2014-12-16 Mark Wielaard + + * readelf.c (print_debug_line_section): Correct overflow check for + unit_length. + (print_debug_aranges_section): Correct overflow check for length. + +2014-12-15 Mark Wielaard + + * readelf.c (notice_listptr): Return false if offset doesn't fit + in 61-bits. + (attr_callback): Warn if loclist or rangelist offset doesn't fit. + +2014-12-15 Mark Wielaard + + * readelf.c (print_ops): Don't assert when addr_size or ref_size + is not 4 or 8, just report invalid data. + +2014-12-15 Mark Wielaard + + * readelf.c (print_gdb_index_section): Add more bounds checks. + +2014-12-15 Mark Wielaard + + * readelf.c (print_debug_line_section): Check there is enough room + for DW_LNE_set_address argument. Make sure there is enough room + for the the initial unit_length. + +2014-12-14 Mark Wielaard + + * elflint.c (check_attributes): Call get_uleb128 with end pointer. + * readelf.c (print_attributes): Likewise. + (print_ops): Likewise and also for get_sleb128. + (print_cfa_program): Likewise and add more readp bounds checks. + (read_encoded): Likewise. + (print_debug_frame_section): Likewise. + (print_debug_line_section): Likewise. + (print_debug_macinfo_section): Likewise. + (print_debug_macro_section): Likewise. + (print_debug_exception_table): Likewise. + +2014-12-16 Mark Wielaard + + * elfcmp.c (compare_Elf32_Word): Make sure (unsigned) Elf32_Word + difference doesn't wrap around before returning as int. + +2014-12-11 Mark Wielaard + + * readelf.c (print_debug_exception_table): Check TType base offset + and Action table are sane. + +2014-12-11 Mark Wielaard + + * readelf.c (print_debug_frame_section): Check number of augmentation + chars to print. + +2014-12-09 Mark Wielaard + + * readelf.c (handle_file_note): Check count fits data section and + doesn't overflow fptr. + +2014-12-08 Mark Wielaard + + * readelf.c (print_debug_exception_table): Report invalid data if + action table doesn't immediately follow call site table. + +2014-12-10 Josh Stone + + * addr2line.c (get_diename): New, get linkage_name or name. + * addr2line.c (print_dwarf_function): Use get_diename. + * addr2line.c (handle_address): Likewise. + * addr2line.c (print_diesym): Removed. + +2014-12-10 Josh Stone + + * addr2line.c (handle_address): Find the proper inline parents. + +2014-12-07 Mark Wielaard + + * readelf.c (print_debug_line_section): max_ops_per_instr cannot + be zero. + +2014-12-07 Mark Wielaard + + * readelf.c (print_ops): Handle zero ref_size for DW_OP_call_ref + and DW_OP_GNU_implicit_pointer. + +2014-12-04 Mark Wielaard + + * objdump.c (show_relocs_x): Make sure destshdr exists. + (show_relocs_rel): Don't rely on shdr->sh_entsize, use gelf_fsize. + (show_relocs_rela): Likewise. + (show_relocs): Make sure destshdr, symshdr and symdata exists. + +2014-11-30 Mark Wielaard + + * readelf.c (handle_sysv_hash64): Fix overflow check. + +2014-11-28 Mark Wielaard + + * readelf.c (handle_relocs_rel): Don't reuse destshdr to store + section header of a relocation against a STT_SECTION symbol. Use + a new local variable secshdr. + (handle_relocs_rela): Likewise. + +2014-11-26 Mark Wielaard + + * readelf.c (print_debug_aranges_section): Cast Dwarf_Word length + to ptrdiff_t for comparison. + +2014-11-24 Mark Wielaard + + * readelf.c (print_debug_line_section): Check line_range is not zero + before usage. + +2014-11-23 Mark Wielaard + + * readelf.c (print_debug_aranges_section): Check length to catch + nexthdr overflow. + +2014-11-21 Mark Wielaard + + * readelf.c (print_attributes): Guard against empty section. + Document attribute format. Break when vendor name isn't terminated. + Add overflow check for subsection_len. Handle both gnu and non-gnu + attribute tags. + +2014-11-22 Mark Wielaard + + * elflint.c (check_sections): Call ebl_bss_plt_p without ehdr. + * findtextrel.c (process_file): Use elf_getphdrnum. + * readelf.c (process_elf_file): Remove redundant ehdr->e_phoff check. + (print_phdr): Check phnum. + * size.c (show_segments): Use elf_getphdrnum. + * strip.c (handle_elf): Likewise. + * unstrip.c (copy_elf): Likewise. + (copy_elided_sections): Likewise. + (handle_file): Likewise. + +2014-11-18 Mark Wielaard + + * readelf.c (print_cfa_program): Fix sanity check of DW_FORM_block + length. + +2014-11-17 Mark Wielaard + + * readelf.c (handle_verneed): Check vna_next and vn_next exist. + (handle_verdef): Check vda_next and vd_next exist. + (handle_versym): Check vd_next, vna_next and vn_next exist. + Check vername and filename are not NULL before use. + +2014-11-17 Mark Wielaard + + * elfcmp.c (main): Check section names are NULL before use. + * objdump.c (section_match): Likewise. + * size.c (show_sysv): Likewise. + +2014-11-17 Mark Wielaard + + * readelf.c (print_debug_frame_section): Warn if ptr_size is not 4 + or 8 instead of just calling print_cfa_program. + +2014-11-16 Mark Wielaard + + * readelf (process_elf_file): Set phnum to zero if there aren't + actually any pheaders. + (print_phdr): Check there actually is a phdr. + +2014-11-16 Mark Wielaard + + * readelf.c (print_cfa_program): Check block len before calling + print_ops. + +2014-11-14 Mark Wielaard + + * readelf.c (print_debug_frame_section): Sanity Check CIE + unit_length and augmentationlen. + +2014-11-14 Mark Wielaard + + * readelf.c (handle_versym): Check def == NULL before use. + +2014-11-08 Mark Wielaard + + * readelf.c (handle_versym): Initialize vername and filename array + elements. + +2014-11-07 Mark Wielaard + + * readelf.c (handle_sysv_hash): Sanity check section contents. + (handle_sysv_hash64): Likewise. + (handle_gnu_hash): Likewise. + +2014-09-14 Petr Machata + + * readelf.c (handle_relocs_rela): Typo fix, test DESTSHDR properly. + +2014-09-12 Petr Machata + + * readelf.c (encoded_ptr_size): In the switch statement, change + magic constants 3 and 4 to DW_EH_PE_* counterparts. Still accept + 0. Print diagnostic for anything else. + +2014-08-25 Josh Stone + + * Makefile.am: Prevent premature @AR@ replacement in a sed expression. + +2014-07-04 Menanteau Guy + Mark Wielaard + + * elflint (check_symtab): Add ".TOC." to the list of possibly + dangling symbols because of sourceware PR13621. + +2014-06-14 Mark Wielaard + + * elflint (check_symtab): Use ebl_func_addr_mask on st_value. + +2014-05-27 Mark Wielaard + + * readelf.c (print_debug): Skip section if name is NULL. + +2014-05-26 Mark Wielaard + + * readelf.c (handle_relocs_rela): Print header like handle_relocs_rel + does, when sh_info == 0. + +2014-05-26 Mark Wielaard + + * unstrip.c (find_alloc_sections_prelink): Allow non-split .bss + section when sh_size of the original and undo .bss section are equal. + +2014-05-26 Mark Wielaard + + * unstrip.c (options): Add --force, -F. + (struct arg_info): Add bool force. + (parse_opt): Handle 'F', set force. + (handle_explicit_files): Add force argument, add warn function, + separate check ehdr field checks, use warn. + (handle_dwfl_module): Add force argument, pass on to + handle_explicit_files. + (handle_output_dir_module): Add force argument, pass on to + handle_dwfl_module. + (handle_implicit_modules): Pass info->force to handle_dwfl_module and + handle_output_dir_module. + (main): Pass info.force to handle_explicit_files. + +2014-05-19 Mark Wielaard + + * elflint.c (check_reloc_shdr): Check ebl_check_reloc_target_type. + +2014-05-01 Mark Wielaard + + * readelf.c (find_no_debuginfo): Call dwfl_standard_find_debuginfo + if looking for alternate debug file. + +2014-04-11 Mark Wielaard + + * Makefile.am (AM_CPPFLAGS): Add -I libdwelf. + +2014-04-22 Mark Wielaard + + * readelf.c (handle_core_item): Make sure variable length array + contains at least enough space for terminating zero char. + +2014-04-22 Mark Wielaard + + * readelf.c (print_gdb_index_section): Use unsigned int for 31 bits + left shift. + +2014-03-13 Mark Wielaard + + * Makefile.am: Remove no_mudflap.os. Remove libmudflap from all + LDADD lines. + * strings.c (process_chunk): Remove _MUDFLAP condition. + +2014-04-09 Mark Wielaard + + * readelf.c (print_debug_aranges_section): Don't get the raw section + data, use the possibly decompressed .[z]debug sectiondata. + (print_debug_ranges_section): Likewise. + (print_debug_frame_section): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loc_section): Likewise. + (print_debug_macinfo_section): Likewise. + (print_debug_macro_section): Likewise. + +2014-04-10 Mark Wielaard + + * readelf.c (buf_read_ulong): Pass actual long size to convert. + +2014-03-05 Mark Wielaard + + * readelf.c (attr_callback): Print DW_FORM_sdata values as signed + numbers. + +2014-02-24 Mark Wielaard + + * readelf (print_phdr): Check there is a SHT_PROGBITS section at the + offset given by p_offsets for a PT_INTERP segment before trying to + display the interpreter string. + +2014-02-07 Mark Wielaard + + * readelf.c (print_phdr): Check phdr->p_filesz and make sure + interpreter string is zero terminated before calling printf. + +2014-01-22 Mark Wielaard + + * Makefile.am (nm_no_Wformat): Removed. + (size_no_Wformat): Likewise. + (strings_no_Wformat): Likewise. + (addr2line_no_Wformat): Likewise. + * size.c (show_sysv): Use fmtstr directly as literal in printf. + (show_sysv_one_line): Likewise. + * strings.c (locfmt): Removed. + (radix): New static enum. + (parse_opt): Set radix, not locfmt. + (process_chunk_mb): Use fmtstr directly as literal in printf based + on radix. + (process_chunk): Likewise. + * nm.c (show_symbols_sysv): Use fmtstr directly as literal in printf. + (show_symbols_bsd): Likewise. + (show_symbols_posix): Likewise. + +2014-01-21 Mark Wielaard + + * stack.c (show_inlines): New static boolean. + (print_frame): New function split out from... + (print_frames): ..here. If show_inlines is true and we found a + DIE for the frame address, call print_inline_frames otherwise + call print_frame. Keep track of and track frame_nr. + (print_inline_frames): New function. + (parse_opt): Handle '-i'. + (main): Add 'i' to options. + +2014-01-27 Mark Wielaard + + * stack.c (maxframes): Initialize to 256. + (main): Document new default in options. Document magic number + used in frames.allocated initialization. + +2014-01-20 Mark Wielaard + + * stack.c (show_debugname): New static boolean. + (die_name): New function. + (print_frames): If show_debugname is true set symname to the + first function-like DIE with a name in scope for the address in + the debuginfo. + (parse_opt): Handle '-d'. + (main): Add 'd' to options. + +2014-01-20 Mark Wielaard + + * addr2line.c (handle_address): Initialize scopes to NULL. + +2014-01-17 Roland McGrath + + * strip.c (handle_elf): Check for bogus values in sh_link, sh_info, + st_shndx, e_shstrndx, and SHT_GROUP or SHT_SYMTAB_SHNDX data. + Don't use assert on input values, instead bail with "illformed" error. + +2014-01-17 Roland McGrath + + * readelf.c (handle_dynamic, handle_symtab): Check for bogus sh_link. + (handle_verneed, handle_verdef, handle_versym, handle_hash): Likewise. + (handle_scngrp): Check for bogus sh_info. + +2014-01-17 Jakub Jelinek + + * elflint.c (section_name): Return "" instead of + crashing on invalid section name. + (check_symtab, is_rel_dyn, check_rela, check_rel, check_dynamic, + check_symtab_shndx, check_hash, check_versym): Robustify. + (check_hash): Don't check entries beyond end of section. + (check_note): Don't crash if gelf_rawchunk fails. + +2014-01-17 Petr Machata + + * readelf.c (handle_dynamic, handle_relocs_rel) + (handle_relocs_rela, handle_versym, print_liblist): + Use gelf_fsize instead of relying on shdr->sh_entsize. + +2014-01-14 Mark Wielaard + + * readelf.c (print_debug_macro_section): Clear vendor array before + use. + +2014-01-15 Jan Kratochvil + + Fix corruption of non-C++ symbols by the demangler. + * nm.c (show_symbols_sysv, show_symbols_bsd, show_symbols_posix) + (show_symbols): Check for _Z. + * stack.c (print_frames) : Check for _Z. + +2014-01-02 Mark Wielaard + + * stack.c (show_raw): Declare unconditionally. + (parse_opt): Handle '-r' unconditionally. + (main): Show "raw" option even without USE_DEMANGLE. + +2014-01-02 Mark Wielaard + + * stack.c (print_frames): Print 0x before build-id hex-offset. + +2014-01-02 Mark Wielaard + + * stack.c (maxframes): Increase to 2048. + (struct frames): Add allocated field. + (frame_callback): If frames used is frames allocated, realloc. + (print_frames): Show an error if maxframes has been reached. + (parse_opt): Allow -n 0 for unlimited frames. + (main): Document -n 0 and new default 2048 frames. Allocate initial + number of frames with malloc. + +2013-12-30 Mark Wielaard + + * stack.c (parse_opt): Explicitly call dwfl_linux_proc_attach + or dwfl_core_file_attach and check for errors. + +2013-12-28 Mark Wielaard + + * stack.c (print_frames): Remove address width code and use... + (get_addr_width): ...this new function. + (show_modules): New static boolean. + (module_callback): New static function. + (parse_opt): Handle '-l'. + (main): Add 'l' to options. If show_modules then use dwfl_getmodules + with module_callback to show all detected modules and possible + build_id, elf and dwarf files. + +2013-12-27 Mark Wielaard + + * stack.c (frames_shown): New static boolean. + (EXIT_OK,EXIT_ERROR,EXIT_BAD,EXIT_USAGES): New defines. + (frame_callback): Return -1 on error. Don't print error. + (print_frames): Add arguments, tid, dwflerr and what. Print tid. + If there was an error report it with address and module if possible. + Record whether any frames were actually printed. + (thread_callback): Collect tid and err, pass it to print_frames. + (parse_opt): Use EXIT_BAD for errors. On ARGP_KEY_END print errno + if dwfl_linux_proc_report returned it. Check whether we are properly + attached with dwfl_pid. + (main): Document exit status. Don't report DWARF_CB_ABORT from + callbacks as error. Pass real errors to print_frames. Return + EXIT_BAD if no frames could be shown. Return EXIT_ERROR if there + were any non-fatal errors. + +2013-12-23 Mark Wielaard + + * Makefile.am (stack_LDADD): Add demanglelib. + * stack.c (show_quiet): New static boolean, default false. + (show_raw): Likewise. + (demangle_buffer_len): New static size_t. + (demangle_buffer): New static char *. + (print_frames): Don't resolve pc name if show_quiet. Demangle name + unless show_raw. + (parse_opt): Handle '-q' and '-r'. + (main): Add 'q' and 'r' to options. Free demangle_buffer. + +2013-12-23 Mark Wielaard + + * stack.c (OPT_DEBUGINFO): New define. + (OPT_COREFILE): Likewise. + (pid): New static. + (core_fd): Likewise. + (core): Likewise. + (exec): Likewise. + (debuginfo_path): Likewise. + (parse_opt): Handle '-p', '--core', '-e' and '--debuginfo-path'. + Do argument sanity checking. Setup Dwfl. + (main): Add 'p', 'core', 'e' and 'debuginfo-path' to options. + Remove argp_child children, simplify argp doc, remove custom + usage message and construction of dwfl with dwfl_standard_argp. + Use pid directly as tid. close core and core_fd if opened. Print + pid of process or core. + +2013-12-23 Mark Wielaard + + * stack.c (show_build_id): New static boolean. + (print_frames): Print module build-id, load address and pc offset + if show_build_id is true. + (parse_opt): Handle '-b'. + (main): Add -b to options. + +2013-12-22 Mark Wielaard + + * stack.c (maxframes): New static unsigned. Initialize to 64. + (struct frame): New struct. + (struct frames): Likewise. + (dwfl): New static Dwfl pointer. + (frame_callback): Use arg as struct frames and fill it next frame. + Return DWARF_CB_ABORT when maxframes has been reached. Move + printing of frame to... + (print_frames): ...here. New function. + (thread_callback): Use arg as struct frames and set frames to zero. + Call print_frames. + (parse_opt): Handle '-n'. + (main): Add -n to options. Allocate frames using maxframes. Pass + frames to frame_callback and thread_callback. + +2013-12-20 Mark Wielaard + + * stack.c (show_one_tid): New static boolean. + (parse_opt): Handle '-1'. + (main): Add -1 to options. Call dwfl_getthread_frames when + show_one_tid is true. + +2013-12-18 Mark Wielaard + + * addr2line.c (options): Add symbol-sections, 'x'. + (show_symbol_sections): New static bool. + (parse_opt): Handle 'x'. + (print_addrsym): Use dwfl_module_addrinfo value.r + Also show section of address with show_symbol_sections. + (find_symbol): Use dwfl_module_getsym_info and set value. + (handle_address): Request value and use it instead of sym.st_value. + * readelf.c (format_dwarf_addr): Use dwfl_module_addrinfo to get + name and offset. + +2013-12-17 Masatake YAMATO + Mark Wielaard + + * stack.c (show_activation, show_module, show_source): New variables. + (parse_opt): Set show_activation if -a option is given. + Set show_module if -m option is given. Set show_source if -s option + is given. Set all show booleans when -v option is given. + (main): Added `-a', `-m', `-s', and `-v' to the help message. + (frame_callback): Print module and source file information. + +2013-11-25 Petr Machata + + * elflint.c (valid_e_machine): Add EM_AARCH64. + +2013-11-14 Petr Machata + + * readelf.c (handle_core_item) <'h'>: New branch for handling + fields that shouldn't be displayed. + +2013-11-10 Mark Wielaard + + * stack.c: Use ARGP_PROGRAM_VERSION_HOOK_DEF and + ARGP_PROGRAM_BUG_ADDRESS_DEF. + (print_version): New function. + +2013-11-09 Mark Wielaard + + * arlib.c (arlib_init): Call snprintf before using the result + with memcpy. + (arlib_finalize): Likewise. + * nm.c (show_symbols_sysv): Don't modify cnt inside assert. + +2013-11-07 Jan Kratochvil + + * Makefile.am (bin_PROGRAMS): Add stack. + (stack_LDADD): New. + * stack.c: New file. + +2013-11-05 Mark Wielaard + + * readelf.c (print_debug_ranges_section): Cast address to size_t + before comparison. + (print_debug_loc_section): Likewise. + +2013-10-18 Mark Wielaard + + * ar.c (main): Correct operation check when instance_specifed is set. + +2013-09-26 Petr Machata + + * readelf.c (handle_file_note): New function. + (handle_notes_data): Call it to handle NT_FILE notes. + +2013-09-26 Petr Machata + + * readelf.c (handle_siginfo_note): New function. + (handle_notes_data): Call it to handle NT_SIGINFO notes. + (buf_read_int, buf_read_ulong, buf_has_data): New functions. + +2013-08-13 Mark Wielaard + + * addr2line.c (options): Add "inlines", 'i'. + (show_inlines): New bool. + (parse_opt): Handle 'i'. + (print_diesym): New static function. + (print_src): New function taking code from... + (handle_address): here. Call print_src. Print inlines. + +2013-08-12 Mark Wielaard + + * addr2line.c (main): If there is a newline char at end of buf, + then remove it. + +2013-07-05 Mark Wielaard + + * readelf.c (print_ops): Take CU as argument, use it to print + parameter_ref DIE offset. + (struct listptr): Replace base field with cu. + (listptr_base): New function. + (compare_listptr): Use listptr_base. + (notice_listptr): Take CU as argument. + (skip_listptr_hole): Likewise. + (print_debug_ranges_section): Pass NULL as CU to skip_listptr_hole. + (print_cfa_program): Pass NULL as CU to print_ops. + (struct attrcb_args): Replace cu_base field with cu. + (attr_callback): Pass cu not cu_base to notice_listptr. + (print_debug_units): Don't calculate base, just set cu. + (print_debug_loc_section): Pass cu to skip_listptr_hole and + print_ops. + +2013-05-06 Mark Wielaard + + * readelf.c (print_ops): Format first DW_OP_GNU_implicit_pointer + argument as DIE offset. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2013-03-25 Mark Wielaard + + * readelf.c (argp_options): Add decodedline. + (decodedline): New boolean initialized to false. + (parse_opt): Set decodedline when arg is decodedline. + (print_decoded_line_section): New function. + (print_debug_line_section): Call print_decoded_line_section when + decodedline is true. + +2013-03-25 Mark Wielaard + + * readelf.c (argp_option): Add decodedaranges. + (decodedaranges): New boolean initialized to false. + (parse_opt): Set decodedaranges when arg is decodedaranges. + (print_debug_aranges_section): Reimplemented and original + implementation renamed to... + (print_decoded_aranges_section): this. + +2013-03-25 Mark Wielaard + + * readelf.c (attrcb_args): Add Dwarf_Die. + (attr_callback): When highpc is in constant form also print as + address. + (print_debug_units): Set args.die. + +2013-03-19 Mark Wielaard + + * readelf.c (print_gdb_index_section): Free format_dwarf_addr results. + +2013-03-18 Mark Wielaard + + * readelf.c (print_gdb_index_section): Accept version 8. + +2013-03-01 Mark Wielaard + + * findtextrel.c (process_file): Release ELF and close file when not + text relocations are found. + * strip.c (handle_elf): Track memory used for .debuglink section data + and free when done. + +2013-02-24 Mark Wielaard + + * elflint.c (check_symtab): Add __bss_start__ to the list of symbols + allowed to have out of section values because of GNU ld bugs. + +2013-02-06 Mark Wielaard + + * elflint.c (check_symtab): Add __bss_start and __TMC_END__ to the + list of symbols allowed to have out of section values because of + GNU ld bugs in either .symtab or .dynsym, but only when they are + zero sized. + +2013-01-24 Mark Wielaard + + * readelf.c (argp_option): Add unresolved-address-offsets, U. + (print_unresolved_addresses): New static. + (parse_opt): Handle 'U', set print_unprocessed_values. + (format_dwarf_addr): Take and handle new raw argument. + (print_ops): Call format_dwarf_addr with raw offset values. + (print_debug_ranges_section): Likewise. + (print_debug_frame_section): Likewise. + (attr_callback): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loc_section): Likewise. + (print_gdb_index_section): Likewise. + +2013-01-18 Mark Wielaard + + * readelf.c (struct listptr): Add base Dwarf_Addr field. + (compare_listptr): Warn for same offset with different base. + (notice_listptr): Take base argument and set it. + (skip_listptr_hole): Likewise. + (struct attrcb_args): Removed unused cu_offset field. + Add cu_base Dwarf_Addr field. + (attr_callback): Call notice_listptr with cbargs->cu_base. + (print_debug_units): Set args.cu_base. + (print_debug_ranges_section): Get base and use for format_dwarf_addr. + (print_debug_loc_section): Likewise. + +2013-01-29 Jan Kratochvil + + * readelf.c (handle_core_items): Limit special repeated items handling + to single-item formats '\n', 'b' and 'B', assert OFFSET 0 there. + +2012-12-18 Mark Wielaard + + * readelf.c (ELF_INPUT_SECTION): New argp key value. + (argp_option): Add elf-section. + (elf_input_section): New static. + (parse_opt): Handle ELF_INPUT_SECTION and set elf_input_section. + (open_input_section): New function. + (process_file): Call open_input_section if elf_input_section set. + +2013-01-13 David Abdurachmanov + + ar.c (do_oper_delete): Fix num passed to memset. + +2012-12-21 Mark Wielaard + + * readelf.c (print_debug_frame_section): Adjust FDE start address + if pcrel before feeding it to format_dwarf_addr. + +2012-12-21 Mark Wielaard + + * addr2line.c (main): Call dwfl_end. + +2012-12-11 Roland McGrath + + * nm.c (show_symbols_sysv): Fix size passed to snprintf for invalid + sh_name case. + Reported by David Abdurachmanov . + +2012-10-16 Mark Wielaard + + * readelf.c (print_ops): DW_OP_skip and DW_OP_bra targets are + calculated beginning after the operand and 2-byte constant. + +2012-10-12 Jan Kratochvil + + * readelf.c (ITEM_WRAP_COLUMN, REGISTER_WRAP_COLUMN): Merge to ... + (WRAP_COLUMN): ... here. + (print_core_item): Remove parameter format_max. Update function + comment. Replace FORMAT_MAX by the real output width. + (handle_core_item): Remove the FORMAT_MAX values in TYPES, DO_TYPE, + calls of print_core_item, remove variable maxfmt, change + ITEM_WRAP_COLUMN to WRAP_COLUMN. + (handle_core_register): Remove the FORMAT_MAX values in TYPES, BITS, + calls of print_core_item, change REGISTER_WRAP_COLUMN to WRAP_COLUMN. + +2012-10-11 Jan Kratochvil + + * readelf.c (handle_core_item) : Make run an outer block variable. + Increase run only if LASTBIT != 0. Print last element only if RUN > 0. + +2012-08-27 Mark Wielaard + + * readelf.c (print_debug_macro_section): Print offset as PRIx64. + +2012-08-27 Mark Wielaard + + * readelf.c (register_info): Handle loc == NULL. + +2012-08-22 Jeff Kenton + + * elflint.c (valid_e_machine): Add EM_TILEGX and EM_TILEPRO. + +2012-08-16 Mark Wielaard + + * readelf.c (dwarf_tag_name): Renamed from dwarf_tag_string. + Uses new dwarf_tag_string or adds ??? or lo_user+%#x when + appropriate. + (dwarf_attr_name): Likewise. + (dwarf_form_name): Likewise. + (dwarf_lang_name): Likewise. + (dwarf_inline_name): Likewise. + (dwarf_encoding_name): Likewise. + (dwarf_access_name): Likewise. + (dwarf_visibility_name): Likewise. + (dwarf_virtuality_name): Likewise. + (dwarf_identifier_case_name): Likewise. + (dwarf_calling_convention_name): Likewise. + (dwarf_ordering_name): Likewise. + (dwarf_discr_list_name): Likewise. + (print_ops): Remove KNOWN. Use dwarf_locexpr_opcode_string. + (attr_callback): Call new dwarf_foobar_name instead of old + dwarf_foobar_string functions. + (dwarf_tag_string): New function using known-dwarf.h macros. + (dwarf_attr_string): Likewise. + (dwarf_form_string): Likewise. + (dwarf_lang_string): Likewise. + (dwarf_inline_string): Likewise. + (dwarf_encoding_string): Likewise. + (dwarf_access_string): Likewise. + (dwarf_visibility_string): Likewise. + (dwarf_virtuality_string): Likewise. + (dwarf_identifier_case_string): Likewise. + (dwarf_calling_convention_string): Likewise. + (dwarf_ordering_string): Likewise. + (dwarf_discr_list_string): Likewise. + (dwarf_locexpr_opcode_string): Likewise. + +2012-06-27 Mark Wielaard + + * readelf.c (dwarf_form_string): Handle DW_FORM_GNU_ref_alt and + DW_FORM_GNU_strp_alt. + (attr_callback): Likewise. + +2012-07-30 Petr Machata + + * nm.c (show_symbols_bsd): Reorder arguments in {S,}FMTSTRS (and + corresponding printf) so that those that are referenced by only + one of the formatting strings are at the end. + +2012-07-29 Mark Wielaard + + * readelf.c (dwarf_lang_string): Use DW_LANG_ObjC, not DW_LANG_Objc. + (print_ops): Use known[op], not op_name, for DW_OP_GNU_parameter_ref. + +2012-07-19 Mark Wielaard + + * readelf.c (print_ops): Handle DW_OP_GNU_parameter_ref. + +2012-07-11 Mark Wielaard + + * readelf.c (options): Add macro to help of debug-dump. + (section_e): Add section_macro. + (section_all): Add section_macro. + (parse_opt): Handle macro. + (print_debug_macro_section): New function. + (print_debug): Add NEW_SECTION (macro). + +2012-07-10 Mark Wielaard + + * readelf.c (print_gdb_index_section): Add version 7 support. + Keep track of cu_nr. Print kind and static/global flag for each + symbol. When a symbol is in the TU list add 'T'. + +2012-06-26 Mark Wielaard + + * readelf.c (dwarf_attr_string): Add DW_AT_GNU_macros. + +2012-06-22 Mark Wielaard + + * readelf.c (print_ops): Cast printf PRIu/x64 arguments to uint64_t + for gcc 4.7 -Wformat. + +2012-05-09 Roland McGrath + + * elflint (check_sections): Allow zero sized sections at (filesz) end + of segment. And make check overflow-proofed. + +2012-04-24 Mark Wielaard + + * readelf.c (print_ops): Add DW_OP_GNU_push_tls_address, + DW_OP_GNU_uinit and DW_OP_GNU_encoded_addr. + +2012-03-28 Roland McGrath + + * elflint.c (special_sections): Accept SHF_INFO_LINK for reloc sections. + +2012-03-28 Mark Wielaard + + * readelf.c (print_debug_abbrev_section): Check there is Dwarf + section data. + (print_debug_str_section): Likewise. + +2012-03-21 Mark Wielaard + + * readelf.c (print_gdb_index_section): Accept version 6. + +2012-01-31 Mark Wielaard + + * readelf.c (attr_callback): Don't special case DW_FORM_sec_offset. + +2012-01-21 Ulrich Drepper + + * addr2line.c: Update copyright year. + * ar.c: Likewise. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + + * nm.c (argp_children): Define. + (argp): Hook up argp_children. + (handle_ar): Optimize puts call. + (show_symbols_bsd): Use positional parameters to also print color + codes. Don't print STT_FILE symbols. + * objdump.c (options): Improve help text. + (argp_children): Define. + (argp): Hook up argp_children. + (disasm_info): Add elements for color codes. + (disasm_output): Print color codes as well. + (show_disasm): Set up disasm_info data for callback. + +2012-01-20 Roland McGrath + + * arlib-argp.c (arlib_deterministic_output): Initialize from + configured value. + (help_filter): New function. + (argp): Use it. + + * ar.c (main): Handle oper_none as usage error. + + * arlib-argp.c (options, parse_opt): Grok -U as inverse of -D. + + * ranlib.c (argp): Use arlib_argp_children. + + * arlib.c (arlib_init): Obey arlib_deterministic_output. + + * arlib-argp.c: New file. + * Makefile.am (libar_a_SOURCES): Add it. + * arlib.h (arlib_deterministic_output, arlib_argp_children): + Declare new variables. + * ar.c (deterministic_output): Variable removed. + (do_oper_insert): Use arlib_deterministic_output instead. + (options, parse_opt): Don't handle -D here. Add group numbers. + (argp): Use arlib_argp_children. + +2011-12-20 Roland McGrath + + * readelf.c (print_debug): Initialize DUMMY_DBG.elf. + Reported by Karel Klic . + +2011-11-05 Roland McGrath + + * ar.c (deterministic_output): New flag variable. + (options, parse_opt): Grok -D to set it. + (do_oper_insert): When set, use zero from mtime, uid, and gid. + + * ar.c (do_oper_insert): Fix check on elf_rawfile return value. + +2011-10-04 Marek Polacek + + * readelf.c (register_info): Assume the right size of an array. + +2011-10-03 Ulrich Drepper + + * nm.c: Recognize option --mark-special. Still recognize --mark-weak + but don't show it in help anymore. + (mark_special): Renamed from mark_weak. + (parse_opt): Adjust. + (class_type_char): Take additional parameters for ELF file and ELF + header. Treat TLS symbols like objects. + In case of D symbols, show u for unique symbols, R for symbols in + read-only sections, B for symbols in BSS sections. + (show_symbols_bsd): Take additional parameters for ELF file and ELF + header. Adjust for class_type_char change. Show TLS symbols with + @ after them in case --mark-special is selected. + (show_symbols_posix): Likewise. + (show_symbols): Adjust calls to show_symbols_bsd and + show_symbols_posix. + (show_symbols_sysv): Avoid printing address and size for undefined + symbols. Don't print initial special entry and section entries. + +2011-10-02 Ulrich Drepper + + * Makefile.am (demanglelib): Define. + (nm_LDADD): Add demanglelib. + * nm.c (options): Add -C option. + (demangle): Define as global variable. + (parse_opt): Recognize -C. + (show_symbols_sysv): Handle demangling. + (show_symbols_bad): Likewise. + (show_symbols_posix): Likewise. + (show_symbols): Likewise. + +2011-07-09 Roland McGrath + + * readelf.c (options, parse_opt): Grok -W/--wide and ignore it. + + * ar.c (parse_opt): Grok -u. + +2011-05-30 Mark Wielaard + + * strip.c (relocate): Make offset check overflow-proof. + +2011-05-23 Mark Wielaard + + * strip.c (relocate): Take new arguments is_rela to indicate + whether the relocation is from a SHT_REL or SHT_RELA section. + Relocate against any debug section symbol, not just STT_SECTION + symbols. For SHT_REL relocations, fetch addend from offset and + add it to symbol value if not zero. + +2011-05-23 Mark Wielaard + + * strip.c (OPT_RELOC_DEBUG): New option. + (argp_option): Add new --reloc-debug-sections option. + (main): Check new option. + (parse_opt): Likewise. + (handle_elf): Remove any relocations between debug sections + in ET_REL for the debug file when requested. + +2011-05-18 Mark Wielaard + + * strip.c (handle_elf): Make sure all sections of a removed group + section are removed too. Don't discard SHT_GROUP sections, copy + section table before it gets modified. Section group signature + symbols don't have to be retained. + +2011-05-16 Jakub Jelinek + + * readelf.c (print_ops): Handle DW_OP_GNU_const_type, + DW_OP_GNU_regval_type, DW_OP_GNU_deref_type, DW_OP_GNU_convert + and DW_OP_GNU_reinterpret. + +2011-05-17 Mark Wielaard + + * readelf.c (dwarf_tag_string): Fixup DW_TAG_GNU_call_site and + DW_TAG_GNU_call_site_parameter return strings. + +2011-05-11 Marek Polacek + + * nm.c (show_symbols_sysv): Remove unused if/else, remove + unused `prefix' and `fname' parameters. + +2011-05-07 Marek Polacek + + * unstrip.c (compare_sections_nonrel): Mark this function as static. + +2011-04-26 Mark Wielaard + + * readelf.c (handle_notes_data): Call ebl_object_note_type_name + with note name. + +2011-04-14 Mark Wielaard + + * readelf.c (options): Add gdb_index. + (section_e): Define section_gdb_index. + (parse_opt): Recognize gdb_index debug-dump argument. + (print_gdb_index_section): New function. + (print_debug): Add gdb_index to debug_sections. + +2011-03-24 Petr Machata + + * readelf.c (print_debug_line_section): Emit initial space for all + opcode lines. Print offset in front of each opcode. + +2011-03-22 Marek Polacek + + * readelf.c (handle_dynamic): Don't segfault at DT_PLTREL case. + +2011-03-22 Mark Wielaard + + * readelf.c (dwarf_tag_string): Support DW_TAG_GNU_call_site + and DW_TAG_GNU_call_site_parameter. + (dwarf_attr_string): Support DW_AT_GNU_call_site_value, + DW_AT_GNU_call_site_data_value, + DW_AT_GNU_call_site_target, + DW_AT_GNU_call_site_target_clobbered, + DW_AT_GNU_tail_call, + DW_AT_GNU_all_tail_call_sites, + DW_AT_GNU_all_call_sites, + and DW_AT_GNU_all_source_call_sites. + (print_ops): Handle DW_OP_GNU_entry_value. + (attr_callback): Handle DW_AT_GNU_call_site_value, + DW_AT_GNU_call_site_data_value, + DW_AT_GNU_call_site_target, + and DW_AT_GNU_call_site_target_clobbered. + +2011-03-10 Mark Wielaard + + * elflint.c (check_symtab): Use ebl_check_st_other_bits. + +2011-02-27 Jan Kratochvil + + * readelf.c (reset_listptr): Clear TABLE->TABLE. + +2011-02-25 Mark Wielaard + + * readelf.c (dwarf_attr_string): Add DW_AT_GNU_* handling. + (dwarf_form_string): Properly format and return unknown form. + +2011-02-23 Roland McGrath + + * readelf.c (section_name): New function. + (print_debug_abbrev_section): Use it instead of constant. + (print_debug_aranges_section): Likewise. + (print_debug_ranges_section): Likewise. + (print_debug_units): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loc_section): Likewise. + (print_debug_macinfo_section): Likewise. + (print_debug_pubnames_section): Likewise. + (print_debug_str_section): Likewise. + (print_debug) [USE_ZLIB]: Match .zdebug_* sections too. + (print_debug_abbrev_section): Use decoded d_size, not sh_size. + (print_debug_str_section): Likewise. + + * readelf.c (dwarf_attr_string): Grok DW_AT_GNU_odr_signature. + +2011-02-11 Roland McGrath + + * elfcmp.c (verbose): New variable. + (options, parse_opt): Grok -l/--verbose to set it. + (main): Under -l, keep going after first difference. + + * elfcmp.c (ignore_build_id): New variable. + (options, parse_opt): Grok --ignore-build-id to set it. + (main): For SHT_NOTE sections, compare note details rather than raw + bytes. Under --ignore-build-id, don't complain about differing build + ID contents if lengths match. + +2011-02-08 Roland McGrath + + * ldscript.y (filename_id_star): Remove unused variable. + + * unstrip.c (copy_elided_sections): Remove unused variable. + + * elflint.c (check_dynamic): Remove unused variables. + + * elflint.c (check_symtab): Warn about missing xndx section only once. + + * ldgeneric.c (check_for_duplicate2): Remove unused variable. + +2011-01-06 Roland McGrath + + * strip.c (handle_elf): Under --strip-sections, remove all + non-allocated sections and never generate .gnu_debuglink. + +2011-01-04 Roland McGrath + + * strip.c (remove_shdrs): New variable. + (options, parse_opt): Grok --strip-sections to set it. + (handle_elf): When that's set, truncate off .shstrtab and shdrs. + +2010-11-10 Roland McGrath + + * findtextrel.c (process_file): Don't assume order of sections. + Reported by Mike Hommey . + +2010-07-26 Roland McGrath + + * readelf.c (print_ops): Handle DW_OP_GNU_implicit_pointer. + +2010-08-30 Roland McGrath + + Print .debug_loc/.debug_ranges with cognizance of actual DIE uses. + * readelf.c (parse_opt): Add section_info to implicit_debug_sections + for ranges, loc. + (struct listptr, struct listptr_table): New types. + (compare_listptr, reset_listptr, sort_listptr): New functions. + (notice_listptr, skip_listptr_hole): New functions. + (struct attrcb_args): Add silent member. + (attr_callback): Call notice_listptr for loclistptr and rangelistptr. + Suppress output if silent, but still call notice_listptr. + (print_debug_units): Suppress output if section_info not requested. + (print_debug_loc_section): Call sort_listptr, skip_listptr_hole. + (print_debug_ranges_section): Likewise. + (print_debug): Call reset_listptr on both tables. + + * readelf.c (print_debug_ranges_section): Print empty list. + (print_debug_loc_section): Likewise. + + * readelf.c (print_debug_loc_section): Check for bogus length + before calling print_ops. + (print_ops): Check harder for bogus data that would read off end. + +2010-08-11 Roland McGrath + + * readelf.c (for_each_section_argument): Process all sections with + matching name, not just the first. + +2010-07-26 Roland McGrath + + * readelf.c (print_ops): Take new argument for CU version. + Fix DW_OP_call_ref decoding to depend on it. + (print_debug_loc_section): Update caller. + (print_cfa_program): Take new argument, pass it down. + (print_debug_frame_section): Update caller. + (struct attrcb_args): New member version. + (print_debug_units): Initialize it. + +2010-07-02 Roland McGrath + + * readelf.c (print_debug_frame_section): Use format_dwarf_addr for + initial_location. + +2010-06-30 Roland McGrath + + * strings.c (main): Use STDIN_FILENO, not STDOUT_FILENO. + Ignore st_size for a non-S_ISREG file descriptor. + (read_block): Move assert after no-mmap bail-out. + (read_block_no_mmap): Fix size calculations for moving buffer remnant. + +2010-06-22 Roland McGrath + + * readelf.c (print_debug_line_section): Fix braino in DW_LNS_set_isa. + +2010-06-21 Roland McGrath + + * readelf.c (dwarf_tag_string): Handle new v4 tags. + (dwarf_attr_string): Add new attributes. + (dwarf_tag_string): Handle DW_TAG_GNU_*. + + * readelf.c (print_ops): Use 64-bit types for LEB128 operands. + (print_cfa_program): Likewise. + +2010-06-20 Roland McGrath + + * readelf.c (print_debug_units): New function, broken out of ... + (print_debug_info_section): ... here. Call it. + (print_debug_types_section): New function. + (enum section_e): Add section_types alias for section_info. + (print_debug): Add types to the sections table. + + * readelf.c (print_debug_frame_section): Handle version 4 format. + + * readelf.c (print_debug_line_section): Handle version 4 format. + +2010-06-14 Roland McGrath + + * unstrip.c (copy_elided_sections): Make sure all sections' data have + been read in before we write anything out. + +2010-06-04 Roland McGrath + + * unstrip.c (update_shdr): New function. + (update_sh_size): Call it instead of gelf_update_shdr. + (adjust_relocs, add_new_section_symbols): Likewise. + (new_shstrtab, copy_elided_sections): Likewise. + + * unstrip.c (copy_elided_sections): Bail if stripped file has more + sections than unstripped file, rather than getting confused later. + +2010-06-01 Roland McGrath + + * readelf.c (dwarf_form_string): Handle DWARF 4 forms. + (attr_callback): Handle DW_FORM_flag_present, DW_FORM_exprloc, + DW_FORM_sec_offset, DW_FORM_ref_sig8. + + * readelf.c (print_debug): Don't bail if libdw setup fails. + Suppress complaint if we only want .eh_frame anyway. + +2010-05-28 Ulrich Drepper + + * readelf.c (attr_callback): Also print form information. + +2010-05-19 Roland McGrath + + * addr2line.c (find_symbol): Short-circuit on empty name. + (handle_address): Handle SYMBOL with no +OFFSET. + +2010-05-08 Roland McGrath + + * readelf.c (print_ops): Take new arg OFFSET_SIZE. + Use that for DW_OP_call_ref, not ADDRSIZE. + (print_cfa_program): Update caller. + (struct attrcb_args): Add offset_size field. + (attr_callback): Use it for print_ops call. + (print_debug_info_section): Initialize it. + (print_ops): Likewise. + +2010-04-14 Roland McGrath + + * readelf.c (handle_core_item): Fix bitmask printing. + +2010-04-06 Roland McGrath + + * ld.c (options): Fix some typos in messages. + * elflint.c (check_scn_group, check_group): Likewise. + * ldscript.y (add_id_list): Likewise. + * readelf.c (print_hash_info): Add xgettext:no-c-format magic comment + before translated string containing a literal %. + +2010-02-26 Roland McGrath + + * readelf.c (process_file): Don't leak an fd in failure case. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + + * readelf.c (print_debug_frame_section): Add a cast to avoid sign + mismatch in comparison. + +2010-02-02 Roland McGrath + + * readelf.c (print_encoding_base): Handle DW_EH_PE_absptr (zero). + (read_encoded): Likewise. + (print_debug_frame_section): Check for bogus augmentation length. + For P augmentation, use read_encoded, print the encoding description, + and use hex for unsigned values. + +2010-01-15 Roland McGrath + + * ar.c: Include . + * elflint.c: Likewise. + * readelf.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise + +2010-01-07 Roland McGrath + + * readelf.c (print_ehdr): Handle PN_XNUM. + (phnum): New static variable. + (process_elf_file): Set it with elf_getphdrnum. + (print_phdr): Use phnum instead of EHDR->e_phnum. + (print_dynamic, handle_notes): Likewise. + (handle_relocs_rel, handle_relocs_rela): Likewise. + + * elfcmp.c (main): Use elf_getshdrnum and elf_getphdrnum. + + * elflint.c (phnum): New static variable. + (check_elf_header): Set it, handling PN_XNUM. + Use that in place of EHDR->e_phnum throughout. + (check_symtab, check_reloc_shdr, check_dynamic): Likewise. + (unknown_dependency_p, check_sections, check_program_header): Likewise. + +2010-01-05 Roland McGrath + + * readelf.c (dwarf_attr_string): Match DW_AT_GNU_vector and + DW_AT_GNU_template_name. + +2010-01-04 Roland McGrath + + * readelf.c (handle_notes_data): Grab NT_AUXV only for name "CORE". + (handle_core_note): Pass NHDR and NAME to ebl_core_note. + (handle_core_item): Handle .format of '\n' as \n-separated strings. + + * readelf.c (implicit_debug_sections): New variable. + (parse_opt): Set it instead of print_debug_sections for -a. + OR them together for print_debug check. + (print_debug): OR them together for section check. + + * readelf.c (options): Repartition into set implied by -a and others. + Correct -a text to match reality. + + * readelf.c (struct section_argument): Add bool member 'implicit'. + (parse_opt): Set it for -a cases, clear it for -x args. + (for_each_section_argument): Don't complain about a missing section by + name if it's implicit. + +2009-11-16 Roland McGrath + + * readelf.c (print_string_section): Punt SHT_NOBITS like empty + sections, just as dump_data_section already does. + +2009-09-21 Ulrich Drepper + + * elflint.c (special_sections): Allow MERGE and STRINGS flags to be + set for .comment section. + Patch by Mark Wielaard . + +2009-09-08 Roland McGrath + + * ar.c (main): Fix typo in message format. + +2009-08-21 Roland McGrath + + * readelf.c (attr_callback): Use print_block only when we don't use + print_ops. + +2009-08-14 Roland McGrath + + * ar.c (do_oper_extract): Use pathconf instead of statfs. + +2009-08-01 Ulrich Drepper + + * debugpred.h: Add two most const. + +2009-07-26 Mark Wielaard + + * elflint.c (check_note_data): Recognize NT_GNU_GOLD_VERSION. + +2009-07-25 Mark Wielaard + + * Makefile.am (addr2line_LDADD): Add $(libelf). + +2009-07-24 Roland McGrath + + * readelf.c (print_block): New function. + (print_ops): Use it. + (attr_callback): Use it for DW_FORM_block* forms. + +2009-07-20 Mark Wielaard + + * readelf.c (print_ops): Add handling of DW_OP_implicit_value + and DW_OP_stack_value. + +2009-07-14 Ulrich Drepper + + * elflint.c (check_elf_header): Allow Linux ABI. + (check_symtab): Handle STB_GNU_UNIQUE. + +2009-07-08 Mark Wielaard + + * readelf.c (attr_callback): Handle DW_Form constants for + DW_AT_data_member_location. + +2009-07-06 Roland McGrath + + * readelf.c (register_info): New function. Handle unknown register #s. + (print_cfa_program): Use it. + (handle_core_register, handle_core_registers): Likewise. + +2009-06-28 Roland McGrath + + * readelf.c (print_address_names): New static variable. + (options, parse_opt): Grok -N/--numeric-addresses to clear it. + (format_dwarf_addr): Don't look up name if !print_address_names. + +2009-06-13 Ulrich Drepper + + * ldgeneric.c: Don't use deprecated libelf functions. + * nm.c: Likewise. + * objdump.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + * ld.h: Fix up comment. + +2009-06-01 Ulrich Drepper + + * readelf.c (print_relocs): Expect ELF header argument and pass on + to handle_relocs_rel* functions. Adjust caller. + (handle_relocs_rel): Add ELF header argument. Add special case for + the IRELATIVE relocations in statically linked executables. + (handle_relocs_rela): Likewise. + +2009-04-29 Ulrich Drepper + + * elflint.c (check_symtab): Add tests of st_other field. + +2009-04-23 Ulrich Drepper + + * Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS). + +2009-04-20 Roland McGrath + + * addr2line.c (print_dwarf_function): Honor -s and -A for file names + of inline call sites. + + * addr2line.c (just_section): New variable. + (adjust_to_section): New function, broken out of ... + (handle_address): ... here. + (options, parse_opt): Add -j/--section=NAME to set it. + +2009-04-15 Roland McGrath + + * readelf.c (print_debug_frame_section): Check for DW_CIE_ID_64 in + 64-bit format header, DW_CIE_ID_32 in 32-bit format header. + +2009-04-14 Roland McGrath + + * readelf.c (print_attributes): Treat SHT_ARM_ATTRIBUTES on EM_ARM + like SHT_GNU_ATTRIBUTES. + + * readelf.c (handle_core_registers): Fix error message. + + * strip.c (handle_elf: check_preserved): Don't note any change when + .debug_data is already filled from a previous pass. + +2009-02-05 Ulrich Drepper + + * objdump.c (show_relocs_x): Minor cleanups. + + * readelf.c (print_cfa_program): Correct a few labels. + Print first DW_CFA_expression and DW_CFA_val_expression parameter + as register. + +2009-02-01 Ulrich Drepper + + * objdump.c (show_relocs_rel, show_relocs_rela): Split common parts + into ... + (show_relocs_x): ...here. New function. + (show_relocs): Better spacing in output. + + * objdump.c (show_relocs_rela): Show offsets as signed values. + + * ar.c (main): Fix recognition of invalid modes for a, b, i modifiers. + Improve some error messages. + Use program_invocation_short_name instead of AR macro. + * Makefile.am (CFLAGS_ar): Remove. + * elflint.c (parse_opt): ARGP_HELP_EXIT_ERR does nothing for argp_help. + * objdump.c (parse_opt): Likewise. + * readelf.c (parse_opt): Likewise. + +2009-01-27 Roland McGrath + + * readelf.c (print_ops): Notice short length, don't overrun buffer + (still need to fix LEB128). + + * readelf.c (print_ops): Fix DW_OP_call[24] decoding. + + * readelf.c (print_ops): Print (empty)\n when LEN == 0. + +2009-01-24 Ulrich Drepper + + * readelf.c (print_debug_frame_section): Fix computation of vma_base + for PC-relative mode. + +2009-01-23 Ulrich Drepper + + * size.c (process_file): When handling archive, close file descriptor + here. For unknown file format also close file descriptor. + (handle_ar): Don't close file descriptor here. + + * readelf.c (parse_opt): Move code to add to dump_data_sections and + string_sections list in local function add_dump_section. Adjust 'x' + key handling. For 'a' key add .strtab, .dynstr, and .comment section + to string_sections list. + +2009-01-22 Roland McGrath + + * readelf.c (print_phdr): Don't print section mapping when no sections. + + * Makefile.am (AM_CFLAGS): Pass -Wno-format for *_no_Wformat. + + * readelf.c (print_debug_frame_section): Initialize IS_SIGNED to false + and reset it only for the 'true' cases. + + * Makefile.am (addr2line_no_Wformat): New variable. + + * readelf.c (print_debug_frame_section): Use t instead of j formats + for ptrdiff_t OFFSET. + +2009-01-21 Ulrich Drepper + + * elflint.c (check_program_header): Fix typo in .eh_frame_hdr section + test. Handle debuginfo files. + (check_exception_data): First sanity test. + +2009-01-17 Ulrich Drepper + + * readelf.c (print_debug_exception_table): Show target of ar_disp + field. + + * elflint.c (check_program_header): Add most consistency checks for + PT_GNU_EH_FRAME entry. + + * addr2line.c: Use ARGP_PROGRAM_VERSION_HOOK_DEF and + ARGP_PROGRAM_BUG_ADDRESS_DEF. + * ar.c: Likewise. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2009-01-16 Ulrich Drepper + + * elflint.c (check_program_header): Check that PT_GNU_EH_FRAME entry + matches .eh_frame_hdr section, if it is available. Also check that + the segment is allocated, not writable, not executable. + + * readelf.c: Add -e option. Dump exception and unwind related + sections. Add -e to -a. + (print_encoding_base): Handle DW_EH_PE_omit. + (print_debug_exception_table): Beginning of support. + (print_debug): Hook up print_debug_exception_table for + .gcc_except_table sections. + + * readelf.c (print_debug_frame_section): Some fixes for last change. + +2009-01-15 Ulrich Drepper + + * readelf.c (print_encoding): Now a toplevel function. + (print_relinfo): Likewise. + (print_encoding_base): Broken out of print_debug_frame_section. + (print_debug_frame_section): Print different header for .eh_frame + sections. Fix recognition of matching CIEs in .debug_frame sections. + Print absolute offset for PC-relative FDE locations. Don't print + table header for FDEs if the table is empty. + (read_encoded): New function. + (print_debug_frame_hdr_section): New function. + (print_debug): Hook up print_debug_frame_hdr_section for .eh_frame_hdr + sections. + + * readelf.c (handle_relocs_rel): Print section number. + (print_debug_abbrev_section): Likewise. + (print_debug_aranges_section): Likewise. + (print_debug_ranges_section): Likewise. + (print_debug_info_section): Likewise. + (print_debug_line_section): Likewise. + (print_debug_loc_section): Likewise. + (print_debug_macinfo_section): Likewise. + (print_debug_pubnames_section): Likewise. + (print_debug_str_section): Likewise. + +2009-01-10 Ulrich Drepper + + * strings.c (read_block): Fix typo in error message string. + +2009-01-07 Ulrich Drepper + + * ld.c (ld_new_searchdir): Fix adding to search path list. + +2009-01-06 Ulrich Drepper + + * readelf.c: Implement call frame debug section dumping. + +2009-01-05 Roland McGrath + + * elfcmp.c: Exit with status 2 for errors (like cmp, diff, grep). + Status 1 (aka EXIT_FAILURE) is only for completed OK but not equal. + +2009-01-01 Ulrich Drepper + + * addr2line.c: Update copyright year. + * ar.c: Likewise. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2008-12-11 Roland McGrath + + * nm.c (sym_name): New function. + (show_symbols_sysv): Use it in place of elf_strptr. + (show_symbols_bsd, show_symbols_posix): Likewise. + Fixes RHBZ#476136. + + * nm.c (show_symbols_sysv): Use an alloca'd backup section name when + elf_strptr fails. + +2008-12-02 Roland McGrath + + * readelf.c (count_dwflmod, process_file): Don't presume encoding of + nonzero OFFSET argument to dwfl_getmodules. + +2008-08-07 Roland McGrath + + * addr2line.c (main): Pass string to handle_address. + (see_one_module): New function, subroutine of handle_address. + (find_symbol): Likewise. + (handle_address): Take string argument rather than address. + Convert plain number, or handle strings like "(section)+offset" + or "symbol+offset". + +2008-08-01 Roland McGrath + + * readelf.c (handle_core_item): Handle 'B' type for 1-origin bitset. + For 'b' and 'B', print or ~ rather than 1/0 string. + + * readelf.c (convert): Take new argument SIZE. + (handle_core_register, handle_core_item): Update callers. + (handle_core_item): Take new arg REPEATED_SIZE. + (handle_core_items): Special case for a singleton item, + let handle_core_item handle repeats if it wants to. + + * readelf.c (handle_core_items): Give abridged output + for identical groups repeated more than twice. + +2008-07-04 Roland McGrath + + * readelf.c (handle_core_items): Handle ELF_T_ADDR. + +2008-04-10 Roland McGrath + + * strip.c (handle_elf): Don't keep sections that kept symbol tables + refer to. Instead, just be sure to preserve the original symbol + table in the debug file so those symbols go with their sections and + can be elided from the stripped version of the symbol table. + + * strip.c (handle_elf): When a discarded section kept in the debug + file refers to a nondiscard section via sh_link/sh_info, preserve + that nondiscarded section unmodified in the debug file as well. + Skip adjustment of discarded sections symbol table references when + that symbol table is copied in this way. + + * elflint.c (check_symtab): Don't crash from missing symbol names + after diagnosing bogus strtab. + + * strip.c (handle_elf): Cosmetic cleanup in special section contents + adjustment for symtab changes. + +2008-03-31 Roland McGrath + + * elflint.c (check_sections): Add checks on SHF_EXECINSTR sections: + must be SHT_PROGBITS, must not be SHF_WRITE. Let backend hook + excuse a special section. + +2008-03-27 Roland McGrath + + * elflint.c (check_sections): Check that executability and writability + of sections is reflected in segment p_flags. + +2008-03-26 Roland McGrath + + * elflint.c (check_program_header): Accept PT_GNU_RELRO p_flags + that matches its PT_LOAD's p_flags &~ PF_W. On sparc, PF_X really + is valid in RELRO. + +2008-02-29 Roland McGrath + + * readelf.c (print_attributes): Add a cast. + * elflint.c (check_attributes): Likewise. + + * unaligned.h (add_8ubyte_unaligned): Cast PTR argument for parity + with [UNALIGNED_ACCESS_CLASS == BYTE_ORDER] definition. + (add_4ubyte_unaligned, add_2ubyte_unaligned): Likewise. + +2008-02-03 Ulrich Drepper + + * i386_ld.c (elf_i386_count_relocations): Implement R_386_TLS_GD + when linked into executable. + (elf_i386_create_relocations): Likewise. + +2008-02-20 Roland McGrath + + * readelf.c (print_attributes): New function. + (process_elf_file): Call it under -A. + + * elflint.c (check_attributes): Implement it for real. + +2008-02-19 Roland McGrath + + * elflint.c (special_sections): Handle .gnu.attributes section. + (check_sections): Likewise. + (check_attributes): New function. + +2008-02-10 Roland McGrath + + * elfcmp.c (main): Ignore sh_offset differences in non-SHF_ALLOC + sections and ET_REL files. + +2008-02-02 Ulrich Drepper + + * elf32-i386.script: Add .eh_frame_hdr, .tdata, and .tbss sections. + * i386_ld.c (elf_i386_count_relocations): Handle R_386_TLS_LDO_32 + and R_386_TLS_LE. + (elf_i386_create_relocations): Likewise. + * ld.h (struct ld_state): Add need_tls, tls_start, and tls_tcb + elements. + * ldgeneric.c (add_section): If TLS section is used, set need_tls flag. + (ld_generic_create_outfile): Add PT_TLS entry to program header. + Fix generation of PT_GNU_STACK entry. + +2008-02-01 Ulrich Drepper + + * ld.c (replace_args): Prevent loop over replacements if the parameter + is only two characters long. + + * ld.c: Recognize sha1 argument for --build-id parameter. + * ldgeneric.c (create_build_id_section): Handle sha1. + (compute_hash_sum): New function. Broken out of compute_build_id. + Take hash function and context as parameters. + (compute_build_id): Use compute_hash_sum for md5 and the new sha1 + implementation. + +2008-01-31 Ulrich Drepper + + * elf32-i386.script: Add .note.ABI-tag and .note.gnu.build-id sections. + * ld.c: Recognize --build-id command line parameter. + * ld.h: Define scn_dot_note_gnu_build_id. + (struct ld_state): Add build_id and buildidscnidx elements. + * ldgeneric.c: Implement --build-id command line parameter. + * ldlex.l (ID): Recognize - as valid character after the first one. + +2008-01-29 Ulrich Drepper + + * ld.c (replace_args): New function. + (main): Use it to rewrite old-style parameters. + + * elf32-i386.script: Add .gnu.hash section. + * ldgeneric.c (optimal_bucket_size): A tiny bit more efficient. + (fillin_special_symbol): Initialize st_size. + (sortfct_hashval): New function. + (create_gnu_hash): New function. + (create_hash): New function. + (ld_generic_create_outfile): Use the new functions to create the + hash tables. + + * elflint.c (check_gnu_hash): Fix index value printed in error message. + +2008-01-24 Ulrich Drepper + + * elflint.c (check_group): Check that signature symbol for section + group is not an empty string. + * ldgeneric.c: Remove magic assignment of indices in the dynsym + section. Start implementation of --hash-style. + * i386_ld.c: Likewise. + * ld.c: Recognize --hash-style. + * ld.h (struct scninfo): Add comdat_group. + Add additional parameter to finalize_plt callback. + +2008-01-22 Ulrich Drepper + + * ld.h (struct callbacks): Add initialize_gotplt. + (struct scnhead): Add scn_dot_gotplt. + (struct ld_state): Add gotpltscnidx. + * i386_ld.c (elf_i386_initialize_plt): Minor optimization. + (elf_i386_initialize_pltrel): Likewise. + (elf_i386_initialize_got): There is now a separate .got.plt, so + don't do the PLT-related work here. Initialize d_type. + (elf_i386_initialize_gotplt): New function. + (elf_i386_plt0): Use ud2a after indirect jump. + (elf_i386_pic_plt0_entry): Likewise. + (elf_i386_finalize_plt): Reference now .got.plt. + (elf_i386_count_relocations): For GOT entries which need no relocation + don't bump nrel_got. + (elf_i386_create_relocations): Also get .got.plt. Rewrite R-386_GOT32 + handling for split .got/.got.plt. + (elf_i386_ld_init): Initialize callbacks.initialize_gotplt. + * elf32-i386.script: Sort sections for security. There are no .got + input sections. Add .got.plt. + * ldgeneric.c (ld_generic_generate_sections): Add .got.plt section. + (ld_generic_create_outfile): Initialize .got.plt section. + Use .got.plt address for _GLOBAL_OFFSET_TABLE_ symbol and DT_PLTGOT. + +2008-01-19 Ulrich Drepper + + * i386_ld.c (elf_i386_count_relocations): PLT relocations for undefined + symbols are not carried over into statically linked output files. + Add dummy entries for more TLS relocations. + + * ld.c (options): Add long names for -( and -). + + * ldgeneric.c (check_definition): For newly found definitions don't + mark section as used if symbol is absolute. + (extract_from_archive): Only assign archive sequence number the first + time the archive is handled. Update ld_state.last_archive_used + if any symbol was used. Remove nround variable. + (file_process2): When using symbol from an archive, update + ld_state.group_start_archive, ld_state.archives, and + ld_state.tailarchives. + (ld_generic_file_process): If group is not handled anymore, after + freeing ELF handles for the archives, clear ld_state.archives and + *nextp. Fix wrong logic in recognizing first iteration of group + loop. When clearing flags, also clear ld_state.group_start_archive. + +2008-01-11 Ulrich Drepper + + * objdump.c (show_disasm): Adjust disassembler format string for + removal of %e. + +2008-01-04 Roland McGrath + + * readelf.c (handle_core_items): Take new arg DESCSZ; if nonzero, + a size greater than the items cover means multiple sets of items. + (handle_core_note): Update caller. + +2008-01-04 Roland McGrath + + * strip.c (handle_elf): Move SHDRIDX defn to silence gcc warning. + +2008-01-03 Roland McGrath + + * ld.h (linked_from_dso_p): Use __attribute__ ((__gnu_inline__)). + + * elflint.c (check_dynamic): Remove duplicate initializer. + +2008-01-02 Ulrich Drepper + + * addr2line.c: Update copyright year. + * ar.c: Likewise. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2007-12-30 Ulrich Drepper + + * objdump (show_disasm): Use %e after third parameter. + +2007-12-21 Ulrich Drepper + + * strip.c: Fix wrong parenthesis in a few branch predictions. + * strings.c: Likewise. + +2007-12-20 Ulrich Drepper + + * Makefile.am (DEFS): Add DEBUGPRED. + * addr2line.c: Include debugpred.h. + * ar.c: Likewise. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + * debugpred.h: New file. + + * readelf.c (handle_relocs_rel): Use elf_scnshndx. + (handle_relocs_rela): Likewise. + + * readelf.c: Add lots of likely/unlikely. + + * elflint.c: Minor cleanups. + +2007-11-19 Roland McGrath + + * readelf.c (print_ops): Handle all bad op codes gracefully. + Print their numbers instead of just ???. + +2007-11-09 Roland McGrath + + * readelf.c (attr_callback): Handle DW_AT_data_location. + Handle block forms to mean a DWARF expression for DW_AT_allocated, + DW_AT_associated, DW_AT_bit_size, DW_AT_bit_offset, DW_AT_bit_stride, + DW_AT_byte_size, DW_AT_byte_stride, DW_AT_count, DW_AT_lower_bound, + DW_AT_upper_bound. + +2007-10-20 Roland McGrath + + * unstrip.c (options): Update -R description. + (struct symbol): Put symbol details a union with a size_t pointer + `duplicate'. + (compare_symbols_output): Use null ->name as marker for discard + symbols, not zero *->map. + (copy_elided_sections): Record forwarding pointers for discarded + duplicates and fill SYMNDX_MAP elements through them. + + * readelf.c (process_file): Set offline_next_address to 0 at start. + (struct process_dwflmod_args): New type. + (process_dwflmod): Take args in it, pass fd to process_elf_file. + (process_file): Update caller; dup FD for passing to libdwfl. + (process_elf_file): Take new arg FD. For ET_REL file when + displaying data affected by libdwfl relocation, open a new Elf handle. + +2007-10-17 Roland McGrath + + * readelf.c (print_debug_line_section): For invalid data inside a + unit with plausible length, keep printing at the next unit boundary. + + * readelf.c (attr_callback): Use dwarf_formref_die, not dwarf_formref. + +2007-10-16 Roland McGrath + + * readelf.c (hex_dump): Fix rounding error in whitespace calculation. + +2007-10-15 Roland McGrath + + * make-debug-archive.in: New file. + * Makefile.am (EXTRA_DIST): Add it. + (make-debug-archive): New target. + (bin_SCRIPTS, CLEANFILES): Add it. + +2007-10-10 Roland McGrath + + * elflint.c (special_sections): Add new attrflag value exact_or_gnuld. + Use it to check MERGE|STRINGS for .debug_str. + (check_sections): Handle exact_or_gnuld. + +2007-10-08 Roland McGrath + + * readelf.c (handle_core_item): Handle 'T'|0x80 to indicate + 64-bit struct timeval with 32-bit tv_usec. + +2007-10-07 Roland McGrath + + * readelf.c (check_archive_index): New function. + (process_file): Call it. Change signature to take only fd and name. + Use libdwfl to open the file, then iterate on its modules (multiple + for an archive) to print file name and call process_elf_file. + (main): Update caller. Let process_file do elf_begin. + (count_dwflmod, process_dwflmod, find_no_debuginfo): New functions. + (process_elf_file): Take only Dwfl_Module * argument. + Don't print the file name here. + (print_debug_*_section): Take Dwfl_Module * argument. + (print_debug): Likewise. Update caller. + (format_dwarf_addr): New function. + (print_debug_ranges_section): Use it. + (attr_callback): Likewise. + (print_debug_line_section, print_debug_loc_section): Likewise. + + * readelf.c (print_debug_ranges_section): Translate all strings. + (print_debug_loc_section): Likewise. + + * unstrip.c (copy_elided_sections): Initialize SEC. + + * ar.c (do_oper_insert): Put trailing / on short names. + + * arlib.h (MAX_AR_NAME_LEN): Decrease by one. + + * arlib2.c (arlib_add_long_name): Adjust for header size. + + * arlib.c (arlib_finalize): Pad long name table to keep size even. + + * ar.c (do_oper_insert): Use write_retry for padding write. + + * ar.c (do_oper_insert): Initialize CUR_OFF in no_old case. + Unconditionally set FOUND[CNT]->elf when setting ->mem. + (remember_long_name): New function. + (do_oper_insert): Call it. Correctly use length of basename, + not original name. Don't store long name twice for new member. + +2007-10-06 Roland McGrath + + * elflint.c (check_note): Skip empty segment. + (check_note_section): Skip empty section. + + * unstrip.c (options, parse_opt, struct arg_info): Grok -R/--relocate. + (handle_output_dir_module, handle_implicit_modules): Pass it down. + (handle_dwfl_module): When set, use ET_REL already loaded by Dwfl. + (compare_alloc_sections): Take new arg REL, ignore address if true. + (compare_sections): Likewise, pass it down. + (compare_sections_rel, compare_sections_nonrel): New functions. + (find_alloc_sections_prelink, copy_elided_sections): Use them + instead of compare_sections. + (sections_match): New function, broken out of ... + (find_alloc_section): ... here. + (copy_elided_sections): Reorganize section match-up logic. + Use sections_match for SHF_ALLOC in ET_REL. + For ET_REL, let the nonzero sh_addr from the debug file dominate. + + * unstrip.c (add_new_section_symbols): Take new arg REL. + When true, do not update section symbol values. + (collect_symbols): Likewise. Update section symbols with address + of chosen output section, not original section. + (check_symtab_section_symbols, copy_elided_sections): Update callers. + + * unstrip.c (compare_alloc_sections): At the same address, preserve + original section order. + + * elflint.c (special_sections): Don't require MERGE|STRINGS for + .debug_str, it didn't always have them with older tools. + + * elflint.c (check_symtab, check_one_reloc): Ignore sh_addr in ET_REL. + +2007-10-05 Roland McGrath + + * elflint.c (check_symtab): Allow SHN_UNDEF _GLOBAL_OFFSET_TABLE_ in + ET_REL file. + + * elflint.c (check_symtab): For _GLOBAL_OFFSET_TABLE_, diagnose + SHN_UNDEF as "bad section". Use shndx value in messages. + + * elflint.c (special_sections): Add ".debug_str". Decrement namelen + for ".debug" so it matches as a prefix. + (IS_KNOWN_SPECIAL): New macro. + (check_sections): Use it for ".plt" match. Cite wrong SHT_NOBITS + type even under -d, for a .debug* or .shstrtab section. + + * readelf.c (print_ops): Use hex for address operand. + +2007-10-04 Roland McGrath + + * unstrip.c (copy_elided_sections): Initialize NDX_SECTION element for + .gnu_debuglink section to SHN_UNDEF. Drop STT_SECTION symbols for + sections mapped to SHN_UNDEF. + +2007-10-04 Ulrich Drepper + + * readelf.c (dump_archive_index): Avoid warning about uninitialized + variable with older glibc versions. + Add some branch prediction. + +2007-10-04 Roland McGrath + + * readelf.c (print_archive_index): New variable. + (options, parse_opt): Accept -c/--archive-index to set it. + (dump_archive_index): New function. + (process_file): Take new arg WILL_PRINT_ARCHIVE_INDEX. + Call dump_archive_index on archives if set. + (main): Update caller. + (any_control_option): Give it file scope, moved out of ... + (parse_opt): ... here. + +2007-10-03 Roland McGrath + + * unstrip.c (struct arg_info): Add `list' flag. + (options, parse_opt): Grok -n/--list to set it. + (list_module): New function. + (handle_implicit_modules): Call it under -n. + + * elflint.c (check_note_section): New function. + (check_sections): Call it for SHT_NOTE. + + * readelf.c (handle_notes): Use sections when available. + + * elflint.c (check_note_data): New function, broken out of ... + (check_note): ... here. Call it and elf_getdata_rawchunk. + + * readelf.c (handle_auxv_note): Take offset as argument, not buffer. + Use elf_getdata_rawchunk and gelf_getauxv. + (handle_notes_data): New function, broken out of ... + (handle_notes): ... here. Call it and elf_getdata_rawchunk. + +2007-10-01 Roland McGrath + + * readelf.c (hex_dump): Fix transposed subtraction generating spaces. + + * readelf.c (hex_dump): Fix line header to be hex instead of decimal. + +2007-09-10 Roland McGrath + + * readelf.c (options): Give -p optional argument, alias --string-dump. + (string_sections, string_sections_tail): New static variables. + (parse_opt): Set them when -p has an argument. + (print_string_section): New function, broken out of ... + (print_strings): ... here. Call it. + (dump_data_section): New function, broken out of ... + (dump_data): ... here. Call it. + (for_each_section_argument): New function, broken out of ... + (dump_data): ... here. Call it. + (dump_strings): New function. + +2007-08-31 Roland McGrath + + * readelf.c (print_strings): Typo fix. + +2007-08-23 Roland McGrath + + * readelf.c (printf_with_wrap): Function removed. + (REGISTER_WRAP_COLUMN): New macro. + (handle_core_register): Use print_core_item instead. + (struct register_info): New type. + (compare_registers, compare_register_sets): New functions. + (register_bitpos, compare_sets_by_info): New functions. + (handle_core_registers): Use those to segregate and sort registers + for display. + + * readelf.c (ITEM_WRAP_COLUMN): New macro. + (print_core_item): New function. + (handle_core_item): Use it instead of printf_with_wrap. + (compare_core_items, compare_core_item_groups): New functions. + (handle_core_items): Use them. Sort by group and force line breaks + between groups. + + * readelf.c (handle_core_registers, handle_core_items): New functions, + broken out of ... + (handle_core_note): ... here. Call them. + +2007-08-22 Roland McGrath + + * unstrip.c (new_shstrtab): New function, broken out of ... + (copy_elided_sections): ... here. + +2007-08-20 Roland McGrath + + Avoid local function trampolines in nm binary. + * nm.c (sort_by_address): Move to a static function instead of local + inside show_symbols. + (sort_by_name_strtab): New static variable. + (sort_by_name): Use it. Move to a static function instead of local + inside show_symbols. + (show_symbols): Set sort_by_name_strtab. + +2007-08-19 Roland McGrath + + * readelf.c (handle_auxv_note): New function. + (handle_notes): Call it. + + * readelf.c (printf_with_wrap, convert): New functions. + (handle_core_item, (handle_core_register): New functions. + (handle_notes): Call those with details from ebl_core_note. + +2007-08-12 Roland McGrath + + * elflint.c (check_note): Accept type 0 with name "Linux". + + * elflint.c (special_sections): Accept SHF_ALLOC for ".note". + + * elflint.c (section_flags_string): Return "none" for 0, not "". + +2007-08-11 Roland McGrath + + * elflint.c (check_note): Accept NT_GNU_HWCAP, NT_GNU_BUILD_ID. + +2007-08-04 Ulrich Drepper + + * readelf.c (hex_dump): Use isprint to determine whether to print + character itself or full stop character. + (dump_data): No need to check endp for NULL after strtol call. + +2007-08-03 Roland McGrath + + * readelf.c (print_string_sections): New variable. + (options, parse_opt): Handle --strings/-p to set it. + (print_strings): New function. + (process_elf_file): Call it under -p. + + * readelf.c (options): Add hidden aliases --segments, --sections, + as taken by binutils readelf. + +2007-08-01 Roland McGrath + + * readelf.c (dump_data_sections, dump_data_sections_tail): + New variables. + (options, parse_opt): Handle --hex-dump/-x, set them. + (hex_dump): New function. + (dump_data): New function, call it. + (process_elf_file): Call it. + +2007-07-25 Roland McGrath + + * addr2line.c (show_symbols): New variable. + (print_addrsym): New function. + (handle_address): Call it. + (options, parse_opt): Handle -S/--symbols. + +2007-06-05 Ulrich Drepper + + * addr2line.c: Update for latest autoconf header. + * ar.c: Likewise. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * ldgeneric.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + * unstrip.c: Likewise. + +2007-05-18 Roland McGrath + + * unstrip.c (copy_elided_sections): Match up non-NOBITS sections with + stripped file, so as not to duplicate a section copied in both. + + * strip.c (handle_elf): Keep SHT_NOTE section copies in the debug file. + +2007-05-17 Roland McGrath + + * unstrip.c (copy_elided_sections): Don't call gelf_newphdr for 0. + + * unstrip.c (handle_file): Tweak BIAS != 0 warning. + + * unstrip.c (handle_file): Take new arg CREATE_DIRS. If set, + call make_directories here. + (handle_explicit_files): Take new arg CREATE_DIRS, pass it down. + (handle_dwfl_module): Likewise. + (handle_implicit_modules): Update callers. + (handle_output_dir_module): Likewise. Don't do make_directories here. + + * unstrip.c (get_section_name): New function, broken out of ... + (copy_elided_sections): here. Update callers. + (find_alloc_section): Broken out of ... + (copy_elided_sections): ... here. Update caller. + (symtab_count_leading_section_symbols): Take new arg NEWSYMDATA, + update STT_SECTION symbols' st_value fields as a side effect. + (check_symtab_section_symbols): Update caller. + (add_new_section_symbols): Set st_value in symbols added. + (collect_symbols): Reset S->value for STT_SECTION symbols recorded. + Take new arg SPLIT_BSS. Adjust S->shndx recorded for symbols moved + from .bss to .dynbss. + (find_alloc_sections_prelink): New function. Associate debug file + allocated SHT_NOBITS shdrs with stripped moved by prelink via + .gnu.prelink_undo information. + (copy_elided_sections): Call it when we couldn't find every allocated + section. Don't use a debug file non-NOBITS section if SHF_ALLOC. + Take STRIPPED_EHDR arg instead of E_TYPE and PHNUM. + (handle_file): Update callers. + + * unstrip.c (copy_elided_sections): Ignore unfound unallocated section + named ".comment". + + * elflint.c (check_sections): Fix association of segments with + sections when p_memsz > p_filesz. + +2007-04-29 Roland McGrath + + * addr2line.c (options, main): Tweak argp group settings to fix + usage output. + +2007-04-28 Roland McGrath + + * strip.c (handle_elf): Update debug file's SHT_NOBITS sections' + sizes to match sections adjusted in the stripped file. + +2007-04-24 Roland McGrath + + * elfcmp.c (OPT_HASH_INEXACT): New macro. + (hash_inexact): New variable. + (options, parse_opt): Add --hash-inexact option to set it. + (hash_content_equivalent): New function. + (main): Call it for differing SHT_HASH sections under --hash-inexact. + +2007-04-23 Roland McGrath + + * unstrip.c: New file. + * Makefile.am (bin_PROGRAMS): Add it. + (unstrip_LDADD): New variable. + + * strip.c (options): Allow --output for -o. + +2007-02-15 Ulrich Drepper + + * readelf.c: Remove unused code. Add a few consts. + +2007-02-15 Roland McGrath + + * readelf.c (print_debug): Fix brainos in SHDR test. + +2007-02-05 Roland McGrath + + * ar.c: Include , since we use LONG_MAX. + +2007-02-05 Ulrich Drepper + + * ar.c: Add ugly hack to work around gcc complaining that we + ignore fchown's return value. + (do_oper_insert): Handle error when writing padding. + * ranlib.c: Add fchown complain work around. + + * arlib.c: Make symtab a global variable. Change all users. + * arlib2.c: Likewise. + * ranlib.c: Likewise. + * ar.c: Likewise. + * arlib.h: Declare it. + +2007-01-11 Roland McGrath + + * elflint.c (check_sections): Use ebl_machine_section_flag_check on + SHF_MASKPROC bits separately from generic sh_flags validation. + +2007-02-04 Ulrich Drepper + + * ar.c: New file. + * arlib.c: New file. + * arlib2.c: New file. + * arlib.h: New file. + * Makefile (noinst_LIBRARIES): Add libar. + (libar_a_SOURCES): Define. + (ar_LDADD): Define. + (CFLAGS_ar): Define. + * ranlib.c: Change to use arlib. + + * elflint.c (check_symtab): Work around GNU ld bug which omits + sections but not symbols in those sections. + +2007-01-10 Ulrich Drepper + + * addr2line.c: Update copyright year. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + +2006-12-09 Ulrich Drepper + + * elflint.c (compare_hash_gnu_hash): New function. Report if the + two hash tables have different content (module expected omission + of undefined symbols). + +2006-10-31 Roland McGrath + + * elflint.c (check_program_header): Don't complain about + p_filesz > p_memsz if p_memsz is zero and p_type is PT_NOTE. + +2006-09-19 Jakub Jelinek + + * strip.c (process_file): Disallow -f on archives. + +2006-10-09 Roland McGrath + + * Makefile.am (libld_elf_i386.so): Use $(LINK), not $(CC). + +2006-08-29 Roland McGrath + + * Makefile.am (MAINTAINERCLEANFILES): New variable. + + * readelf.c (handle_relocs_rel): Typo fix, test DESTSHDR properly. + Reported by Christian Aichinger . + + * elflint.c (valid_e_machine): Add EM_ALPHA. + Reported by Christian Aichinger . + +2006-08-08 Ulrich Drepper + + * elflint.c (check_dynamic): Don't require DT_HASH for DT_SYMTAB. + Keep track of which "high DT" entries are present. + Check that either old or GNU-style hash table is present. + If GNU-style hash table is used a symbol table is mandatory. + Check that if any prelink entry is present all of them are. + (check_gnu_hash): Only fail for undefined symbols in GNU-style hash + table if they don't refer to functions. + +2006-07-17 Roland McGrath + + * elflint.c (struct version_namelist): Use GElf_Versym for `ndx' field. + (add_version): Likewise for argument. + (check_versym): Cast constant to GElf_Versym for comparison. + +2006-07-12 Roland McGrath + + * readelf.c (handle_gnu_hash): Add casts for machines where + Elf32_Word != unsigned int. + +2006-07-12 Ulrich Drepper + + * elflint.c (check_sysv_hash64): Fix printf format. + +2006-07-11 Roland McGrath + + * addr2line.c (options): English fix in -f doc string. + + * addr2line.c (use_comp_dir): New variable. + (options, parse_opt): Grok -A/--absolute to set it. + (handle_address): If set, prepend dwfl_line_comp_dir results to + relative file names. + +2006-07-06 Ulrich Drepper + + * elflint.c: Adjust for latest new hash table format. + * readelf.c: Likewise. + + * elflint.c (check_versym): Ignore hidden bit when comparing version + numbers. + +2006-07-05 Ulrich Drepper + + * ldgeneric.c (ld_generic_create_outfile): Correctly recognize + discarded COMDAT symbols. + + * i386_ld.c (elf_i386_count_relocations): Lot of corrections. + (elf_i386_create_relocations): Likewise. + * ld.h (struct symbol): Add local and hidden bits. + * ld.c (create_special_section_symbol): These synthsized symbols + are local and hidden. + * ldgeneric.c (file_process2): Check whether input file matches + the emulation. + (fillin_special_symbol): Create symbols as local and/or hidden + if requested. + (ld_generic_create_outfile): Make local copy of symbol. + Don't hide global, defined symbols in dynamic symbol table unless + requested. Synthetic symbols have no version information. + + * elflint.c: Add support for checking 64-bit SysV-style hash tables. + * readelf.c: Add support for printing 64-bit SysV-style hash tables. + +2006-07-04 Ulrich Drepper + + * elflint.c (is_rel_dyn): Fix and extend DT_RELCOUNT/DT_RELACOUNT + testing. + +2006-07-03 Ulrich Drepper + + * elflint.c: Add testing of DT_GNU_HASH. + * readelf.c: Implement showing histogram for DT_GNU_HASH section. + + * Makefile.am: Add hacks to create dependency files for non-generic + linker. + +2006-06-12 Ulrich Drepper + + * ldgeneric.c (ld_generic_generate_sections): Don't create .interp + section if creating a DSO and no interpreter is given. + (ld_generic_create_outfile): Don't store reference to symbols in + discarded COMDAT groups. Don't create PHDR and INTERP program header + for DSO if no interpreter is specified. + (create_verneed_data): Pretty printing. + + * ldscript.y (content): If a DSO is created don't set default + interpreter from linker script. + + * i386_ld.c (elf_i386_count_relocations): Do not add relocations + for symbols in discarded COMDAT groups. + (elf_i386_create_relocations): Likewise. + * ld.h (struct scninfo): Add unused_comdat. + * ldgeneric.c (add_section): Also check group signature when + matching COMDAT sections. + (add_relocatable_file): Ignore symbols in COMDAT group which are + discarded. + + * elflint.c (check_one_reloc): For *_NONE relocs only check type + and symbol reference. + +2006-06-11 Ulrich Drepper + + * elflint.c (check_dynamic): Fix checking value of tags which are + offsets in the string section. Make sure DT_STRTAB points to the + section referenced in sh_link. + + * ld.c (options): Add headers. Add short option 'R' for '--rpath'. + + * ld.c: Recognize --eh-frame-hdr option. + * ld.h (struct ld_state): Add eh_frame_hdr field. + * ldgeneric.c (struct unw_eh_frame_hdr): Define. + + * ldgeneric.c (add_section): Use ebl_sh_flags_combine instead of + SH_FLAGS_COMBINE. + (add_relocatable_file): Minor optimization of last change. + (match_section): Don't preserve SHF_GROUP flag any longer. + +2006-06-10 Ulrich Drepper + + * ld.c (parse_z_option): Recognize execstack and noexecstack. + Handle record and ignore as position dependent options. + (parse_z_option_2): Handle ignore and record here. + * ld.h (struct ld_state): Add execstack field. + * ldgeneric.c (add_relocatable_file): Recognize .note.GNU-stack + sections. + (ld_generic_create_outfile): Fix program header creation in native + linker. Add PT_GNU_STACK program header. + +2006-06-09 Ulrich Drepper + + * i386_ld.c (elf_i386_finalize_plt): Don't change symbol table entries + for PLT entries if there is no local definition. + + * ld.c (parse_option): Handle -z ignore like --as-needed and + -z record like --no-as-needed. + * ld.h (struct ld_state): Remove ignore_unused_dsos field. + * ldgeneric.c (new_generated_scn): Always compute ndt_needed by + looping over DSOs. When deciding about adding DT_NEEDED entries + use ->as_needed instead of ignore_unused_dsos. + +2006-05-31 Ulrich Drepper + + * ld.c: Recognize --as-needed and --no-as-needed options. + * ld.h (struct usedfile): Add as_needed field. + (struct ld_state): Likewise. + * ldgeneric.c (ld_handle_filename_list): Copy as_needed flag from + the list. + * ldscript.y (filename_id_list): Split to correctly parse all + combinations. + (mark_as_needed): Fix loop. + +2006-05-28 Ulrich Drepper + + * addr2line.c (print_dwarf_function): Use unsigned type for lineno + and colno. + +2006-05-27 Ulrich Drepper + + * readelf.c (handle_relocs_rela): Better notations for addon value. + (print_ehdr): Distinguish e_ident[EI_VERSION] from e_version. + +2006-04-04 Ulrich Drepper + + * addr2line.c: Update copyright year. + * elfcmp.c: Likewise. + * elflint.c: Likewise. + * findtextrel.c: Likewise. + * ld.c: Likewise. + * nm.c: Likewise. + * objdump.c: Likewise. + * ranlib.c: Likewise. + * readelf.c: Likewise. + * size.c: Likewise. + * strings.c: Likewise. + * strip.c: Likewise. + +2006-03-09 Roland McGrath + + * Makefile.am (AM_LDFLAGS): New variable. + +2006-03-01 Roland McGrath + + * readelf.c (dwarf_tag_string, dwarf_attr_string): Update name tables + for dwarf.h changes matching 3.0 spec. + (dwarf_encoding_string, dwarf_lang_string, print_ops): Likewise. + +2005-12-04 Ulrich Drepper + + * elflint.c (check_one_reloc): If relocation section is not loaded, + don't check whether the relocations modify read-only sections or + loaded and unloaded sections. + +2005-11-28 Ulrich Drepper + + * elflint.c (check_one_reloc): Take additional parameters. Use + them to determine whether relocation is valid in this type of + file. DSOs and executables can contain relocation sections in + unloaded sections which just show the relocations the linker + applied. Adjust all callers. + (check_program_header): Check that PT_PHDR is loaded and that offset + matches the one in the ELF header. + +2005-10-26 Roland McGrath + + * nm.c (get_var_range): dwarf_getloclist -> dwarf_getlocation. + +2005-09-03 Ulrich Drepper + + * strip.c (handle_elf): Unify some error messages. + * ld.c (main): Likewise. + * ldgeneric.c (open_elf): Likewise. + * elfcmp.c (main): Likewise. + * elflint.c (check_elf_header): Likewise. + + * size.c (process_file): Fix typo in error message. + + * readelf.c: Lots of little cleanups. Use _unlocked functions. + +2005-09-02 Ulrich Drepper + + * strings.c (main): Reset elfmap variable after munmap call. + [_MUDFLAP] (map_file): Simplify mudflap debugging by not using mmap. + +2005-08-28 Ulrich Drepper + + * ranlib.c: Don't define pread_retry and write_retry here. + + * Makefile.an [BUILD_STATIC] (libdw): Add -ldl. + (CLEANFILES): Add *.gcno *.gcda *.gconv. + + * strings.c (process_chunk): Reorder expressions in conditional + (process_chunk_mb): Likewise. + + * strings.c: New file. + * Makefile.am (bin_PROGRAMS): Add strings. + (strings_no_Wstring): Define. + (strings_LDADD): Define. + +2005-08-27 Roland McGrath + + * addr2line.c (dwarf_diename_integrate): Function removed. + (print_dwarf_function): Use plain dwarf_diename. + +2005-08-24 Ulrich Drepper + + * elflint.c (check_versym): Versioned symbols should not have + local binding. + +2005-08-15 Ulrich Drepper + + * elflint.c (check_versym): Allow VER_NDX_LOCAL symbols to be + undefined. + + * Makefile.am: Add rules to build ranlib. + * ranlib.c: New file. + +2005-08-14 Roland McGrath + + * elflint.c (check_sections): Use ebl_section_type_name and allow any + sh_type it recognizes. + + * elflint.c (check_sections): Print unknown flags in hex, don't + truncate high bits. Print section number and name for unknown type. + +2005-08-13 Roland McGrath + + * elflint.c (check_program_header): Use ebl_segment_type_name and + allow any p_type it recognizes. Include p_type value in error + message for unknown type. + +2005-08-13 Ulrich Drepper + + * elflint.c (check_symtab): Simplify last change a bit. Pass ehdr + to ebl_check_special_symbol. + (check_sections): Pass ehdr to ebl_bss_plt_p. + +2005-08-12 Roland McGrath + + * elflint.c (check_symtab): Check that _GLOBAL_OFFSET_TABLE_ st_shndx + refers to the right section if it's not SHN_ABS. + Let ebl_check_special_symbol override _G_O_T_ value and size checks. + + * elflint.c (check_sections): Don't complain about a non-NOBITS + section taking no segment space, if it's sh_size is 0. + + * elflint.c (check_sections): Use ebl_bss_plt_p to see if .plt should + be PROGBITS or NOBITS. + + * elflint.c (check_symtab): Use ebl_check_special_symbol to override + standard st_value and st_size checks. + +2005-07-28 Roland McGrath + + * addr2line.c (options, parse_opt): Don't handle -e here. + (executable): Variable removed. + (argp_children): New static variable. + (argp): Use it. Make const. + (main): Fill in argp_children from dwfl_standard_argp (). + Let libdwfl handle file selection, pass Dwfl handle to handle_address. + (print_dwarf_function): New function. Try to figure out inline chain. + (elf_getname): Function removed, libdwfl does it for us. + (handle_address): Take Dwfl handle instead of Elf, Dwarf handles. + Use dwfl_module_addrname instead of elf_getname. + Use dwfl_module_getsrc and dwfl_lineinfo instead of libdw calls. + * Makefile.am (INCLUDES): Add libdwfl directory to path. + +2005-08-10 Ulrich Drepper + + * strip.c (parse_opt): STATE parameter is now used. + Various little cleanups. + + * readelf.c (print_debug_line_section): Correct fallout of renaming + of DW_LNS_set_epilog_begin. + +2005-08-08 Roland McGrath + + * strip.c (options, parse_opt): Grok -R .comment for compatibility + with binutils strip. Likewise -d, -S, as aliases for -g. + Likewise ignore -s/--strip-all. + +2005-08-07 Roland McGrath + + * strip.c (process_file): Open read-only when using a different output + file. + +2005-08-06 Ulrich Drepper + + * elflint.c (in_nobits_scn): New function. + (check_versym): Allow references for defined symbols against versions + of other DSOs also for symbols in nobits sections. + Move a few variables around. + + * Makefile.am (AM_CFLAGS): Avoid duplication. + Link with statis libs if BUILD_STATIC. + +2005-08-05 Ulrich Drepper + + * elflint.c: Many, many more tests. Mostly related to symbol + versioning. Those sections should now be completely checked. + + * readelf.c (print_dynamic): Use gelf_offscn. + +2005-08-04 Ulrich Drepper + + * elflint.c: Add lots more tests: more extension symbol table sanity, + versioning section tests, hash table tests. General cleanup. + +2005-08-02 Ulrich Drepper + + * objdump.c: New file. + * Makefile.am (bin_PROGRAMS): Add objdump. + (objdump_LDADD): Define. + + * elflint.c (check_reloc_shdr): New function split out from check_rela + and check_rel. + (check_one_reloc): New function. Likewise. + (check_rela): Use check_reloc_shdr and check_one_reloc. + (check_rel): Likewise. + (check_program_header): Check that PT_DYNAMIC entry matches .dynamic + section. + Add checks that relocations against read-only segments are flagged, + that the text relocation flag is not set unnecessarily, and that + relocations in one section are either against loaded or not-loaded + segments. + +2005-08-01 Ulrich Drepper + + * elfcmp.c (main): Ignore section count and section name string table + section index. + +2005-07-27 Roland McGrath + + * elfcmp.c: Include . + +2005-07-27 Ulrich Drepper + + * elfcmp.c: Print name and index of differing section. + +2005-07-24 Ulrich Drepper + + * elfcmp.c: Implement comparing gaps between sections. + +2005-07-23 Ulrich Drepper + + * elflint.c: Include libeblP.h instead of libebl.h. + * nm.c: Likewise. + * readelf.c: Likewise. + * elfcmp.c: Likewise. + + * elfcmp.c (main): Compare individual ELF header fields, excluding + e_shoff instead of the whole struct at once. + Use ebl_section_strip_p instead of SECTION_STRIP_P. + * strip.c: Use ebl_section_strip_p instead of SECTION_STRIP_P. + +2005-07-22 Ulrich Drepper + + * elfcmp.c (main): Take empty section into account when comparing + section content. + + * elflint.c (check_dynamic): Check that d_tag value is >= 0 before + using it. + +2005-07-21 Ulrich Drepper + + * elfcmp.c: New file. + * Makefile.am (bin_PROGRAMS): Add elfcmp. + (elfcmp_LDADD): Define. + + * elflint.c (check_rela): Check that copy relocations only reference + object symbols or symbols with unknown type. + (check_rel): Likewise. + +2005-06-08 Roland McGrath + + * readelf.c (print_ops): Add consts. + +2005-05-31 Roland McGrath + + * readelf.c (print_debug_abbrev_section): Don't bail after first CU's + abbreviations. Print a header line before each CU section. + + * readelf.c (print_debug_loc_section): Fix indentation for larger + address size. + +2005-05-30 Roland McGrath + + * readelf.c (print_debug_line_section): Print section offset of each + CU's table, so they are easy to find from seeing the stmt_list value. + + * readelf.c (dwarf_attr_string): Add all attributes in . + (attr_callback): Grok DW_AT_ranges and print offset in hex. + + * readelf.c (attr_callback): Add 2 to addrsize * 2 for %#0* format. + (print_debug_ranges_section, print_debug_loc_section): Likewise. + + * readelf.c (print_ops): Take different args for indentation control. + (attr_callback): Caller updated. + Grok several more block-form attributes as being location expressions. + For those same attributes with udata forms, format output differently + for location list offset. + (print_debug_loc_section): Implement it for real. + + * readelf.c (options): Mention ranges for --debug-dump. + (enum section_e): Add section_ranges. + (parse_opt): Grok "ranges" for -w/--debug-dump. + (print_debug_ranges_section): New function. + (print_debug): Handle .debug_ranges section. + +2005-05-30 Ulrich Drepper + + * readelf.c (handle_notes): At least x86-64 need not have the note + section values aligned to 8 bytes. + +2005-05-18 Ulrich Drepper + + * readelf.c (dwarf_tag_string): Add new tags. + +2005-05-08 Roland McGrath + + * strip.c (handle_elf): Don't translate hash and versym data formats, + elf_getdata already did it for us. + +2005-05-07 Ulrich Drepper + + * Makefile.am (findtextrel_LDADD): Add $(libmudflap). + (addr2line_LDADD): Likewise. + +2005-05-03 Roland McGrath + + * strip.c (handle_elf): Apply symbol table fixups to discarded + relocation sections when they are being saved in the debug file. + + * strip.c (handle_elf): Pass EHDR->e_ident[EI_DATA] to gelf_xlatetom + and gelf_xlatetof, not the native byte order. + + * strip.c (parse_opt): Give error if -f or -o is repeated. + (main): Exit if argp_parse returns nonzero. + + * strip.c (debug_fname_embed): New variable. + (options, parse_opt): New option -F to set it. + +2005-05-07 Ulrich Drepper + + * readelf.c (parse_opt): Make any_control_option variable + local. Simplify some tests. + +2005-05-03 Roland McGrath + + * strip.c (crc32_file): Function removed (now in ../lib). + +2005-05-03 Roland McGrath + + * elflint.c (is_debuginfo): New variable. + (options, parse_opt): New option --debuginfo/-d to set it. + (check_sections): If is_debuginfo, don't complain about SHT_NOBITS. + (check_note): If is_debuginfo, don't try to get note contents. + +2005-04-24 Ulrich Drepper + + * readelf.c (print_debug_abbrev_section): Don't print error when end of + section reached. + +2005-04-14 Ulrich Drepper + + * readelf.c (dwarf_encoding_string): New function. + (dwarf_inline_string): New function. + (dwarf_access_string): New function. + (dwarf_visibility_string): New function. + (dwarf_virtuality_string): New function. + (dwarf_identifier_case_string): New function. + (dwarf_calling_convention_string): New function. + (dwarf_ordering_string): New function. + (dwarf_discr_list_string): New function. + (attr_callback): Decode man more attribute values. + +2005-04-01 Ulrich Drepper + + * addr2line.c: Finish implementation of -f option. + +2005-03-29 Ulrich Drepper + + * addr2line.c: New file. + * Makefile.am (bin_PROGRAMS): Add addr2line. + Define addr2line_LDADD. + + * findtextrel.c: Use new dwarf_addrdie function. + + * findtextrel.c: Fix usage message and re-add accidentally removed + line. + +2005-03-28 Ulrich Drepper + + * findtextrel.c: New file. + * Makefile: Add rules to build findtextrel. + +2005-02-15 Ulrich Drepper + + * ldlex.l: Provide ECHO definition to avoid warning. + + * elflint.c (check_program_header): Fix typo in RELRO test. + + * Makefile.am (AM_CFLAGS): Add more warning options. + * elflint.c: Fix warnings introduced by the new warning options. + * i386_ld.c: Likewise. + * ld.c: Likewise. + * ld.h: Likewise. + * ldgeneric.c: Likewise. + * nm.c: Likewise. + * readelf.c: Likewise. + * sectionhash.c: Likewise. + * size.c: Likewise. + * string.c: Likewise. + +2005-02-05 Ulrich Drepper + + * Makefile.am: Check for text relocations in constructed DSOs. + + * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fmudflap. Link all apps + with -lmudflap. + + * ldscript.y: Add as_needed handling. + * ldlex.l: Recognize AS_NEEDED token. + * ld.h (struct filename_list): Add as_needed flag. + +2005-02-04 Ulrich Drepper + + * elflint.c (check_symtab): Correctly determine size of GOT section. + +2005-01-19 Ulrich Drepper + + * ld.c: Remove unnecessary more_help function. Print bug report + address using argp. + * strip.c: Likewise. + * size.c: Likewise. + * nm.c: Likewise. + * readelf.c: Likewise. + * elflint.c: Likewise. + + * elflint.c (main): Don't check for parameter problems here. + (parse_opt): Do it here, where we get informed about some of them + anyway. + + * readelf.c (main): Don't check for parameter problems here. + (parse_opt): Do it here, where we get informed about some of them + anyway. + +2005-01-11 Ulrich Drepper + + * strip.c: Update copyright year. + * readelf.c: Likewise. + * size.c: Likewise. + * nm.c: Likewise. + * ld.c: Likewise. + * elflint.c: Likewise. + + * elflint.c (check_symtab): Don't warn about wrong size for + _DYNAMIC and __GLOBAL_OFFSET_TABLE__ for --gnu-ld. + +2004-10-05 Ulrich Drepper + + * readelf.c (print_phdr): In section mapping, also indicate + sections in read-only segments. + +2004-09-25 Ulrich Drepper + + * readelf.c: Make compile with gcc 4.0. + * strip.c: Likewise. + +2004-08-16 Ulrich Drepper + + * strip.c (handle_elf): Rewrite dynamic memory handling to use of + allocate to work around gcc 3.4 bug. + +2004-01-25 Ulrich Drepper + + * ldlex.l (invalid_char): Better error message. + +2004-01-23 Ulrich Drepper + + * readelf.c: Print SHT_GNU_LIBLIST sections. + + * none_ld.c: New file. + +2004-01-21 Ulrich Drepper + + * Makefile.am: Enable building of machine specific linker. + +2004-01-20 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + + * i386_ld.c: Fix warnings gcc 3.4 spits out. + * ldgeneric.c: Likewise. + * ldscript.y: Likewise. + * readelf.c: Likewise. + * strip.c: Likewise. + + * readelf.c (print_debug_line_section): Determine address size + correctly. + +2004-01-19 Ulrich Drepper + + * readelf.c (print_phdr): Show which sections are covered by the + PT_GNU_RELRO entry. + + * elflint.c (check_program_header): Check PT_GNU_RELRO entry. + + * readelf.c (print_debug_macinfo_section): Implement. + +2004-01-18 Ulrich Drepper + + * readelf.c (print_debug_line_section): Implement. + +2004-01-17 Ulrich Drepper + + * src/elflint.c: Use PACKAGE_NAME instead of PACKAGE. + * src/ld.c: Likewise. + * src/nm.c: Likewise. + * src/readelf.c: Likewise. + * src/size.c: Likewise. + * src/strip.c: Likewise. + + * strip.c: Add a few more unlikely. Reduce scope of some variables. + + * Makefile.am: Support building with mudflap. + +2004-01-16 Ulrich Drepper + + * readelf.c (print_debug_info_section): Free dies memory. + + * readelf.c: Print .debug_info section content. + +2004-01-13 Ulrich Drepper + + * readelf.c (print_shdr): Add support for SHF_ORDERED and SHF_EXCLUDE. + +2004-01-12 Ulrich Drepper + + * readelf.c (print_debug_aranges): Implement using libdw. + +2004-01-11 Ulrich Drepper + + * nm.c: Adjust for Dwarf_Files type and dwarf_lineno interface change. + + * readelf.c: Use libdw instead of libdwarf. Not all of the old + behavior is available yet. + * Makefile.am: Link readelf with libdw. Remove libdwarf include path. + +2004-01-09 Ulrich Drepper + + * nm.c (get_local_names): Adjust call to dwarf_nextcu. + + * nm.c: Implement getting information about local variables. + +2004-01-07 Ulrich Drepper + + * nm.c: Read also debug information for local symbols. + +2004-01-05 Ulrich Drepper + + * nm.c: Shuffle dwarf handling code around so the maximum column + width can be computed ahead of printing. Avoid collection symbols + which are not printed anyway. + + * nm.c: Rewrite dwarf handling to use libdw. + * Makefile.am (AM_CFLAGS): Add -std parameter. + (INCLUDES): Find header in libdw subdir. + (nm_LDADD): Replace libdwarf with libdw. + + * elflint.c: Update copyright year. + * readelf.c: Likewise. + * size.c: Likewise. + * strip.c: Likewise. + * nm.c: Likewise. + +2003-12-31 Ulrich Drepper + + * strip.c (process_file): Close file before returning. + +2003-11-19 Ulrich Drepper + + * readelf.c (handle_dynamic): Make column for tag name wider. + +2003-09-29 Ulrich Drepper + + * readelf.c (handle_dynamic): Always terminate tag name with a space. + +2003-09-25 Ulrich Drepper + + * strip.c (process_file): Don't mmap the input file, we modify the + data structures and don't want the change end up on disk. + +2003-09-23 Jakub Jelinek + + * unaligned.h (union u_2ubyte_unaligned, + union u_4ubyte_unaligned, union u_8ubyte_unaligned): Add + packed attribute. + (add_2ubyte_unaligned, add_4ubyte_unaligned, + add_8ubyte_unaligned): Avoid nesting bswap_NN macros. + Read/store value through _ptr->u instead of *_ptr. + +2003-09-22 Ulrich Drepper + + * size.c (show_sysv): Change type of maxlen to int. + + * strip.c (handle_elf): Handle the 64-bit archs which is 64-bit + buckets. + + * i386_ld.c: Many many fixes and extensions. + * ld.c: Likewise. + * ldgeneric.c: Likewise. + +2003-08-16 Ulrich Drepper + + * ldgeneric.c (check_definition): Don't add symbol on dso_list if + the reference is from another DSO. + +2003-08-15 Ulrich Drepper + + * ldgeneric.c (find_entry_point): It is no fatal error if no entry + point is found when creating a DSO. + +2003-08-14 Ulrich Drepper + + * ld.c (main): Always call FLAG_UNRESOLVED. + * ldgeneric.c (ld_generic_flag_unresolved): Only complain about + undefined symbols if not creating DSO or ld_state.nodefs is not set. + +2003-08-13 Ulrich Drepper + + * Makefile.in: Depend on libebl.a, not libebl.so. + + * ld.c (main): Mark stream for linker script as locked by caller. + (read_version_script): Likewise. + * ldlex.c: Define fread and fwrite to _unlocked variant. + + * i386_ld.c (elf_i386_finalize_plt): Replace #ifdefs with uses of + target_bswap_32. + * unaligned.h: Define target_bswap_16, target_bswap_32, and + target_bswap_64. + (store_2ubyte_unaligned, store_4ubyte_unaligned, + store_8ubyte_unaligned): Define using new macros. + +2003-08-12 Ulrich Drepper + + * i386_ld.c (elf_i386_finalize_plt): Use packed structs to access + possibly unaligned memory. Support use of big endian machines. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..88d0ac8f --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,115 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 1996-2014, 2016 Red Hat, Inc. +## This file is part of elfutils. +## +## 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 3 of the License, or +## (at your option) any later version. +## +## elfutils 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, see . +## +include $(top_srcdir)/config/eu.am +DEFS += $(YYDEBUG) -DDEBUGPRED=@DEBUGPRED@ \ + -DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\" +AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \ + -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm + +AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw + +bin_PROGRAMS = readelf nm size strip elflint findtextrel addr2line \ + elfcmp objdump ranlib strings ar unstrip stack elfcompress \ + elfclassify + +noinst_LIBRARIES = libar.a + +libar_a_SOURCES = arlib.c arlib2.c arlib-argp.c + +EXTRA_DIST = arlib.h debugpred.h + +bin_SCRIPTS = make-debug-archive +EXTRA_DIST += make-debug-archive.in +CLEANFILES += make-debug-archive + +if BUILD_STATIC +libasm = ../libasm/libasm.a +libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) -ldl -lpthread +libelf = ../libelf/libelf.a -lz +else +libasm = ../libasm/libasm.so +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +endif +libebl = ../libebl/libebl.a ../backends/libebl_backends.a ../libcpu/libcpu.a +libeu = ../lib/libeu.a + +if DEMANGLE +demanglelib = -lstdc++ +endif + +# Bad, bad stack usage... +readelf_no_Wstack_usage = yes +nm_no_Wstack_usage = yes +size_no_Wstack_usage = yes +strip_no_Wstack_usage = yes +elflint_no_Wstack_usage = yes +findtextrel_no_Wstack_usage = yes +elfcmp_no_Wstack_usage = yes +objdump_no_Wstack_usage = yes +ranlib_no_Wstack_usage = yes +ar_no_Wstack_usage = yes +unstrip_no_Wstack_usage = yes + +readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) +nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS) \ + $(demanglelib) +size_LDADD = $(libelf) $(libeu) $(argp_LDADD) +strip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +elflint_LDADD = $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD) +findtextrel_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) +addr2line_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) $(demanglelib) +elfcmp_LDADD = $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD) +objdump_LDADD = $(libasm) $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD) +ranlib_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS) +strings_LDADD = $(libelf) $(libeu) $(argp_LDADD) +ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS) +unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) $(demanglelib) +elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +elfclassify_LDADD = $(libelf) $(libdw) $(libeu) $(argp_LDADD) + +installcheck-binPROGRAMS: $(bin_PROGRAMS) + bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if LD_LIBRARY_PATH=$(DESTDIR)$(libdir) \ + $(DESTDIR)$(bindir)/$$f $$opt > c$${pid}_.out 2> c$${pid}_.err \ + && test -n "`cat c$${pid}_.out`" \ + && test -z "`cat c$${pid}_.err`"; then :; \ + else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad + +CLEANFILES += *.gconv + +make-debug-archive: $(srcdir)/make-debug-archive.in + $(AM_V_GEN)UNSTRIP=$(bindir)/`echo unstrip | sed '$(transform)'`; \ + AR=$(bindir)/`echo ar | sed '$(transform)'`; \ + sed -e "s,[@]UNSTRIP[@],$$UNSTRIP,g" -e "s,[@]AR[@],$$AR,g" \ + -e "s%[@]PACKAGE_NAME[@]%$(PACKAGE_NAME)%g" \ + -e "s%[@]PACKAGE_VERSION[@]%$(PACKAGE_VERSION)%g" \ + $(srcdir)/make-debug-archive.in > $@.new + $(AM_V_at)chmod +x $@.new + $(AM_V_at)mv -f $@.new $@ diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 00000000..12695f9c --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,1100 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +bin_PROGRAMS = readelf$(EXEEXT) nm$(EXEEXT) size$(EXEEXT) \ + strip$(EXEEXT) elflint$(EXEEXT) findtextrel$(EXEEXT) \ + addr2line$(EXEEXT) elfcmp$(EXEEXT) objdump$(EXEEXT) \ + ranlib$(EXEEXT) strings$(EXEEXT) ar$(EXEEXT) unstrip$(EXEEXT) \ + stack$(EXEEXT) elfcompress$(EXEEXT) elfclassify$(EXEEXT) +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libar_a_AR = $(AR) $(ARFLAGS) +libar_a_LIBADD = +am_libar_a_OBJECTS = arlib.$(OBJEXT) arlib2.$(OBJEXT) \ + arlib-argp.$(OBJEXT) +libar_a_OBJECTS = $(am_libar_a_OBJECTS) +addr2line_SOURCES = addr2line.c +addr2line_OBJECTS = addr2line.$(OBJEXT) +am__DEPENDENCIES_1 = +@BUILD_STATIC_FALSE@am__DEPENDENCIES_2 = ../libelf/libelf.so +@BUILD_STATIC_TRUE@am__DEPENDENCIES_2 = ../libelf/libelf.a +@BUILD_STATIC_FALSE@am__DEPENDENCIES_3 = ../libdw/libdw.so +@BUILD_STATIC_TRUE@am__DEPENDENCIES_3 = ../libdw/libdw.a \ +@BUILD_STATIC_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +addr2line_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(libeu) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +ar_SOURCES = ar.c +ar_OBJECTS = ar.$(OBJEXT) +ar_DEPENDENCIES = libar.a $(am__DEPENDENCIES_2) $(libeu) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +elfclassify_SOURCES = elfclassify.c +elfclassify_OBJECTS = elfclassify.$(OBJEXT) +elfclassify_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ + $(libeu) $(am__DEPENDENCIES_1) +elfcmp_SOURCES = elfcmp.c +elfcmp_OBJECTS = elfcmp.$(OBJEXT) +elfcmp_DEPENDENCIES = $(libebl) $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) $(libeu) $(am__DEPENDENCIES_1) +elfcompress_SOURCES = elfcompress.c +elfcompress_OBJECTS = elfcompress.$(OBJEXT) +elfcompress_DEPENDENCIES = $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) $(libeu) $(am__DEPENDENCIES_1) +elflint_SOURCES = elflint.c +elflint_OBJECTS = elflint.$(OBJEXT) +elflint_DEPENDENCIES = $(libebl) $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) $(libeu) $(am__DEPENDENCIES_1) +findtextrel_SOURCES = findtextrel.c +findtextrel_OBJECTS = findtextrel.$(OBJEXT) +findtextrel_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(libeu) $(am__DEPENDENCIES_1) +nm_SOURCES = nm.c +nm_OBJECTS = nm.$(OBJEXT) +nm_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) $(libeu) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +objdump_SOURCES = objdump.c +objdump_OBJECTS = objdump.$(OBJEXT) +objdump_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) $(libeu) $(am__DEPENDENCIES_1) +ranlib_SOURCES = ranlib.c +ranlib_OBJECTS = ranlib.$(OBJEXT) +ranlib_DEPENDENCIES = libar.a $(am__DEPENDENCIES_2) $(libeu) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +readelf_SOURCES = readelf.c +readelf_OBJECTS = readelf.$(OBJEXT) +readelf_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) $(libeu) $(am__DEPENDENCIES_1) +size_SOURCES = size.c +size_OBJECTS = size.$(OBJEXT) +size_DEPENDENCIES = $(am__DEPENDENCIES_2) $(libeu) \ + $(am__DEPENDENCIES_1) +stack_SOURCES = stack.c +stack_OBJECTS = stack.$(OBJEXT) +stack_DEPENDENCIES = $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) $(libeu) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +strings_SOURCES = strings.c +strings_OBJECTS = strings.$(OBJEXT) +strings_DEPENDENCIES = $(am__DEPENDENCIES_2) $(libeu) \ + $(am__DEPENDENCIES_1) +strip_SOURCES = strip.c +strip_OBJECTS = strip.$(OBJEXT) +strip_DEPENDENCIES = $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) $(libeu) $(am__DEPENDENCIES_1) +unstrip_SOURCES = unstrip.c +unstrip_OBJECTS = unstrip.$(OBJEXT) +unstrip_DEPENDENCIES = $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) $(libeu) $(am__DEPENDENCIES_1) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/addr2line.Po ./$(DEPDIR)/ar.Po \ + ./$(DEPDIR)/arlib-argp.Po ./$(DEPDIR)/arlib.Po \ + ./$(DEPDIR)/arlib2.Po ./$(DEPDIR)/elfclassify.Po \ + ./$(DEPDIR)/elfcmp.Po ./$(DEPDIR)/elfcompress.Po \ + ./$(DEPDIR)/elflint.Po ./$(DEPDIR)/findtextrel.Po \ + ./$(DEPDIR)/nm.Po ./$(DEPDIR)/objdump.Po ./$(DEPDIR)/ranlib.Po \ + ./$(DEPDIR)/readelf.Po ./$(DEPDIR)/size.Po \ + ./$(DEPDIR)/stack.Po ./$(DEPDIR)/strings.Po \ + ./$(DEPDIR)/strip.Po ./$(DEPDIR)/unstrip.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libar_a_SOURCES) addr2line.c ar.c elfclassify.c elfcmp.c \ + elfcompress.c elflint.c findtextrel.c nm.c objdump.c ranlib.c \ + readelf.c size.c stack.c strings.c strip.c unstrip.c +DIST_SOURCES = $(libar_a_SOURCES) addr2line.c ar.c elfclassify.c \ + elfcmp.c elfcompress.c elflint.c findtextrel.c nm.c objdump.c \ + ranlib.c readelf.c size.c stack.c strings.c strip.c unstrip.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' \ + $(YYDEBUG) -DDEBUGPRED=@DEBUGPRED@ -DSRCDIR=\"$(shell cd \ + $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\" +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ + -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \ + -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) +CLEANFILES = *.gcno *.gcda make-debug-archive *.gconv +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw +noinst_LIBRARIES = libar.a +libar_a_SOURCES = arlib.c arlib2.c arlib-argp.c +EXTRA_DIST = arlib.h debugpred.h make-debug-archive.in +bin_SCRIPTS = make-debug-archive +@BUILD_STATIC_FALSE@libasm = ../libasm/libasm.so +@BUILD_STATIC_TRUE@libasm = ../libasm/libasm.a +@BUILD_STATIC_FALSE@libdw = ../libdw/libdw.so +@BUILD_STATIC_TRUE@libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) -ldl -lpthread +@BUILD_STATIC_FALSE@libelf = ../libelf/libelf.so +@BUILD_STATIC_TRUE@libelf = ../libelf/libelf.a -lz +libebl = ../libebl/libebl.a ../backends/libebl_backends.a ../libcpu/libcpu.a +libeu = ../lib/libeu.a +@DEMANGLE_TRUE@demanglelib = -lstdc++ + +# Bad, bad stack usage... +readelf_no_Wstack_usage = yes +nm_no_Wstack_usage = yes +size_no_Wstack_usage = yes +strip_no_Wstack_usage = yes +elflint_no_Wstack_usage = yes +findtextrel_no_Wstack_usage = yes +elfcmp_no_Wstack_usage = yes +objdump_no_Wstack_usage = yes +ranlib_no_Wstack_usage = yes +ar_no_Wstack_usage = yes +unstrip_no_Wstack_usage = yes +readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) +nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS) \ + $(demanglelib) + +size_LDADD = $(libelf) $(libeu) $(argp_LDADD) +strip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +elflint_LDADD = $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD) +findtextrel_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) +addr2line_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) $(demanglelib) +elfcmp_LDADD = $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD) +objdump_LDADD = $(libasm) $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD) +ranlib_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS) +strings_LDADD = $(libelf) $(libeu) $(argp_LDADD) +ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS) +unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) $(demanglelib) +elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) +elfclassify_LDADD = $(libelf) $(libdw) $(libeu) $(argp_LDADD) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libar.a: $(libar_a_OBJECTS) $(libar_a_DEPENDENCIES) $(EXTRA_libar_a_DEPENDENCIES) + $(AM_V_at)-rm -f libar.a + $(AM_V_AR)$(libar_a_AR) libar.a $(libar_a_OBJECTS) $(libar_a_LIBADD) + $(AM_V_at)$(RANLIB) libar.a + +addr2line$(EXEEXT): $(addr2line_OBJECTS) $(addr2line_DEPENDENCIES) $(EXTRA_addr2line_DEPENDENCIES) + @rm -f addr2line$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(addr2line_OBJECTS) $(addr2line_LDADD) $(LIBS) + +ar$(EXEEXT): $(ar_OBJECTS) $(ar_DEPENDENCIES) $(EXTRA_ar_DEPENDENCIES) + @rm -f ar$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ar_OBJECTS) $(ar_LDADD) $(LIBS) + +elfclassify$(EXEEXT): $(elfclassify_OBJECTS) $(elfclassify_DEPENDENCIES) $(EXTRA_elfclassify_DEPENDENCIES) + @rm -f elfclassify$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfclassify_OBJECTS) $(elfclassify_LDADD) $(LIBS) + +elfcmp$(EXEEXT): $(elfcmp_OBJECTS) $(elfcmp_DEPENDENCIES) $(EXTRA_elfcmp_DEPENDENCIES) + @rm -f elfcmp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfcmp_OBJECTS) $(elfcmp_LDADD) $(LIBS) + +elfcompress$(EXEEXT): $(elfcompress_OBJECTS) $(elfcompress_DEPENDENCIES) $(EXTRA_elfcompress_DEPENDENCIES) + @rm -f elfcompress$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfcompress_OBJECTS) $(elfcompress_LDADD) $(LIBS) + +elflint$(EXEEXT): $(elflint_OBJECTS) $(elflint_DEPENDENCIES) $(EXTRA_elflint_DEPENDENCIES) + @rm -f elflint$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elflint_OBJECTS) $(elflint_LDADD) $(LIBS) + +findtextrel$(EXEEXT): $(findtextrel_OBJECTS) $(findtextrel_DEPENDENCIES) $(EXTRA_findtextrel_DEPENDENCIES) + @rm -f findtextrel$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(findtextrel_OBJECTS) $(findtextrel_LDADD) $(LIBS) + +nm$(EXEEXT): $(nm_OBJECTS) $(nm_DEPENDENCIES) $(EXTRA_nm_DEPENDENCIES) + @rm -f nm$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(nm_OBJECTS) $(nm_LDADD) $(LIBS) + +objdump$(EXEEXT): $(objdump_OBJECTS) $(objdump_DEPENDENCIES) $(EXTRA_objdump_DEPENDENCIES) + @rm -f objdump$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(objdump_OBJECTS) $(objdump_LDADD) $(LIBS) + +ranlib$(EXEEXT): $(ranlib_OBJECTS) $(ranlib_DEPENDENCIES) $(EXTRA_ranlib_DEPENDENCIES) + @rm -f ranlib$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ranlib_OBJECTS) $(ranlib_LDADD) $(LIBS) + +readelf$(EXEEXT): $(readelf_OBJECTS) $(readelf_DEPENDENCIES) $(EXTRA_readelf_DEPENDENCIES) + @rm -f readelf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(readelf_OBJECTS) $(readelf_LDADD) $(LIBS) + +size$(EXEEXT): $(size_OBJECTS) $(size_DEPENDENCIES) $(EXTRA_size_DEPENDENCIES) + @rm -f size$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(size_OBJECTS) $(size_LDADD) $(LIBS) + +stack$(EXEEXT): $(stack_OBJECTS) $(stack_DEPENDENCIES) $(EXTRA_stack_DEPENDENCIES) + @rm -f stack$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(stack_OBJECTS) $(stack_LDADD) $(LIBS) + +strings$(EXEEXT): $(strings_OBJECTS) $(strings_DEPENDENCIES) $(EXTRA_strings_DEPENDENCIES) + @rm -f strings$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(strings_OBJECTS) $(strings_LDADD) $(LIBS) + +strip$(EXEEXT): $(strip_OBJECTS) $(strip_DEPENDENCIES) $(EXTRA_strip_DEPENDENCIES) + @rm -f strip$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(strip_OBJECTS) $(strip_LDADD) $(LIBS) + +unstrip$(EXEEXT): $(unstrip_OBJECTS) $(unstrip_DEPENDENCIES) $(EXTRA_unstrip_DEPENDENCIES) + @rm -f unstrip$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(unstrip_OBJECTS) $(unstrip_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +installcheck-binSCRIPTS: $(bin_SCRIPTS) + bad=0; pid=$$$$; list="$(bin_SCRIPTS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \ + for opt in --help --version; do \ + if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \ + 2>c$${pid}_.err &2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr2line.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arlib-argp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arlib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arlib2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfclassify.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfcmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfcompress.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elflint.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findtextrel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objdump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ranlib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readelf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/size.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strings.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unstrip.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(SCRIPTS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/addr2line.Po + -rm -f ./$(DEPDIR)/ar.Po + -rm -f ./$(DEPDIR)/arlib-argp.Po + -rm -f ./$(DEPDIR)/arlib.Po + -rm -f ./$(DEPDIR)/arlib2.Po + -rm -f ./$(DEPDIR)/elfclassify.Po + -rm -f ./$(DEPDIR)/elfcmp.Po + -rm -f ./$(DEPDIR)/elfcompress.Po + -rm -f ./$(DEPDIR)/elflint.Po + -rm -f ./$(DEPDIR)/findtextrel.Po + -rm -f ./$(DEPDIR)/nm.Po + -rm -f ./$(DEPDIR)/objdump.Po + -rm -f ./$(DEPDIR)/ranlib.Po + -rm -f ./$(DEPDIR)/readelf.Po + -rm -f ./$(DEPDIR)/size.Po + -rm -f ./$(DEPDIR)/stack.Po + -rm -f ./$(DEPDIR)/strings.Po + -rm -f ./$(DEPDIR)/strip.Po + -rm -f ./$(DEPDIR)/unstrip.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-binSCRIPTS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: installcheck-binPROGRAMS installcheck-binSCRIPTS + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/addr2line.Po + -rm -f ./$(DEPDIR)/ar.Po + -rm -f ./$(DEPDIR)/arlib-argp.Po + -rm -f ./$(DEPDIR)/arlib.Po + -rm -f ./$(DEPDIR)/arlib2.Po + -rm -f ./$(DEPDIR)/elfclassify.Po + -rm -f ./$(DEPDIR)/elfcmp.Po + -rm -f ./$(DEPDIR)/elfcompress.Po + -rm -f ./$(DEPDIR)/elflint.Po + -rm -f ./$(DEPDIR)/findtextrel.Po + -rm -f ./$(DEPDIR)/nm.Po + -rm -f ./$(DEPDIR)/objdump.Po + -rm -f ./$(DEPDIR)/ranlib.Po + -rm -f ./$(DEPDIR)/readelf.Po + -rm -f ./$(DEPDIR)/size.Po + -rm -f ./$(DEPDIR)/stack.Po + -rm -f ./$(DEPDIR)/strings.Po + -rm -f ./$(DEPDIR)/strip.Po + -rm -f ./$(DEPDIR)/unstrip.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-binSCRIPTS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am \ + installcheck-binPROGRAMS installcheck-binSCRIPTS installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-binSCRIPTS + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +installcheck-binPROGRAMS: $(bin_PROGRAMS) + bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if LD_LIBRARY_PATH=$(DESTDIR)$(libdir) \ + $(DESTDIR)$(bindir)/$$f $$opt > c$${pid}_.out 2> c$${pid}_.err \ + && test -n "`cat c$${pid}_.out`" \ + && test -z "`cat c$${pid}_.err`"; then :; \ + else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad + +make-debug-archive: $(srcdir)/make-debug-archive.in + $(AM_V_GEN)UNSTRIP=$(bindir)/`echo unstrip | sed '$(transform)'`; \ + AR=$(bindir)/`echo ar | sed '$(transform)'`; \ + sed -e "s,[@]UNSTRIP[@],$$UNSTRIP,g" -e "s,[@]AR[@],$$AR,g" \ + -e "s%[@]PACKAGE_NAME[@]%$(PACKAGE_NAME)%g" \ + -e "s%[@]PACKAGE_VERSION[@]%$(PACKAGE_VERSION)%g" \ + $(srcdir)/make-debug-archive.in > $@.new + $(AM_V_at)chmod +x $@.new + $(AM_V_at)mv -f $@.new $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/addr2line.c b/src/addr2line.c new file mode 100644 index 00000000..34945046 --- /dev/null +++ b/src/addr2line.c @@ -0,0 +1,819 @@ +/* Locate source files and line information for given addresses + Copyright (C) 2005-2010, 2012, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Values for the parameters which have no short form. */ +#define OPT_DEMANGLER 0x100 +#define OPT_PRETTY 0x101 /* 'p' is already used to select the process. */ + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Input format options:"), 2 }, + { "section", 'j', "NAME", 0, + N_("Treat addresses as offsets relative to NAME section."), 0 }, + + { NULL, 0, NULL, 0, N_("Output format options:"), 3 }, + { "addresses", 'a', NULL, 0, N_("Print address before each entry"), 0 }, + { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 }, + { "absolute", 'A', NULL, 0, + N_("Show absolute file names using compilation directory"), 0 }, + { "functions", 'f', NULL, 0, N_("Also show function names"), 0 }, + { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 }, + { "symbols-sections", 'x', NULL, 0, N_("Also show symbol and the section names"), 0 }, + { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 }, + { "inlines", 'i', NULL, 0, + N_("Show all source locations that caused inline expansion of subroutines at the address."), + 0 }, + { "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL, + N_("Show demangled symbols (ARG is always ignored)"), 0 }, + { "pretty-print", OPT_PRETTY, NULL, 0, + N_("Print all information on one line, and indent inlines"), 0 }, + + { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, + /* Unsupported options. */ + { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 }, + { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Locate source files and line information for ADDRs (in a.out by default)."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[ADDR...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +static struct argp_child argp_children[2]; /* [0] is set in main. */ + +/* Data structure to communicate with argp functions. */ +static const struct argp argp = +{ + options, parse_opt, args_doc, doc, argp_children, NULL, NULL +}; + + +/* Handle ADDR. */ +static int handle_address (const char *addr, Dwfl *dwfl); + +/* True when we should print the address for each entry. */ +static bool print_addresses; + +/* True if only base names of files should be shown. */ +static bool only_basenames; + +/* True if absolute file names based on DW_AT_comp_dir should be shown. */ +static bool use_comp_dir; + +/* True if line flags should be shown. */ +static bool show_flags; + +/* True if function names should be shown. */ +static bool show_functions; + +/* True if ELF symbol or section info should be shown. */ +static bool show_symbols; + +/* True if section associated with a symbol address should be shown. */ +static bool show_symbol_sections; + +/* If non-null, take address parameters as relative to named section. */ +static const char *just_section; + +/* True if all inlined subroutines of the current address should be shown. */ +static bool show_inlines; + +/* True if all names need to be demangled. */ +static bool demangle; + +/* True if all information should be printed on one line. */ +static bool pretty; + +#ifdef USE_DEMANGLE +static size_t demangle_buffer_len = 0; +static char *demangle_buffer = NULL; +#endif + +int +main (int argc, char *argv[]) +{ + int remaining; + int result = 0; + + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. This includes opening the modules. */ + argp_children[0].argp = dwfl_standard_argp (); + argp_children[0].group = 1; + Dwfl *dwfl = NULL; + (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl); + assert (dwfl != NULL); + + /* Now handle the addresses. In case none are given on the command + line, read from stdin. */ + if (remaining == argc) + { + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + + char *buf = NULL; + size_t len = 0; + ssize_t chars; + while (!feof_unlocked (stdin)) + { + if ((chars = getline (&buf, &len, stdin)) < 0) + break; + + if (buf[chars - 1] == '\n') + buf[chars - 1] = '\0'; + + result = handle_address (buf, dwfl); + fflush (stdout); + } + + free (buf); + } + else + { + do + result = handle_address (argv[remaining], dwfl); + while (++remaining < argc); + } + + dwfl_end (dwfl); + +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case ARGP_KEY_INIT: + state->child_inputs[0] = state->input; + break; + + case 'a': + print_addresses = true; + break; + + case 'b': + case 'C': + case OPT_DEMANGLER: + demangle = true; + break; + + case 's': + only_basenames = true; + break; + + case 'A': + use_comp_dir = true; + break; + + case 'f': + show_functions = true; + break; + + case 'F': + show_flags = true; + break; + + case 'S': + show_symbols = true; + break; + + case 'x': + show_symbols = true; + show_symbol_sections = true; + break; + + case 'j': + just_section = arg; + break; + + case 'i': + show_inlines = true; + break; + + case OPT_PRETTY: + pretty = true; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static const char * +symname (const char *name) +{ +#ifdef USE_DEMANGLE + // Require GNU v3 ABI by the "_Z" prefix. + if (demangle && name[0] == '_' && name[1] == 'Z') + { + int status = -1; + char *dsymname = __cxa_demangle (name, demangle_buffer, + &demangle_buffer_len, &status); + if (status == 0) + name = demangle_buffer = dsymname; + } +#endif + return name; +} + +static const char * +get_diename (Dwarf_Die *die) +{ + Dwarf_Attribute attr; + const char *name; + + name = dwarf_formstring (dwarf_attr_integrate (die, DW_AT_MIPS_linkage_name, + &attr) + ?: dwarf_attr_integrate (die, DW_AT_linkage_name, + &attr)); + + if (name == NULL) + name = dwarf_diename (die) ?: "??"; + + return name; +} + +static bool +print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) +{ + Dwarf_Addr bias = 0; + Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); + + Dwarf_Die *scopes; + int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); + if (nscopes <= 0) + return false; + + bool res = false; + for (int i = 0; i < nscopes; ++i) + switch (dwarf_tag (&scopes[i])) + { + case DW_TAG_subprogram: + { + const char *name = get_diename (&scopes[i]); + if (name == NULL) + goto done; + printf ("%s%c", symname (name), pretty ? ' ' : '\n'); + res = true; + goto done; + } + + case DW_TAG_inlined_subroutine: + { + const char *name = get_diename (&scopes[i]); + if (name == NULL) + goto done; + + /* When using --pretty-print we only show inlines on their + own line. Just print the first subroutine name. */ + if (pretty) + { + printf ("%s ", symname (name)); + res = true; + goto done; + } + else + printf ("%s inlined", symname (name)); + + Dwarf_Files *files; + if (dwarf_getsrcfiles (cudie, &files, NULL) == 0) + { + Dwarf_Attribute attr_mem; + Dwarf_Word val; + if (dwarf_formudata (dwarf_attr (&scopes[i], + DW_AT_call_file, + &attr_mem), &val) == 0) + { + const char *file = dwarf_filesrc (files, val, NULL, NULL); + unsigned int lineno = 0; + unsigned int colno = 0; + if (dwarf_formudata (dwarf_attr (&scopes[i], + DW_AT_call_line, + &attr_mem), &val) == 0) + lineno = val; + if (dwarf_formudata (dwarf_attr (&scopes[i], + DW_AT_call_column, + &attr_mem), &val) == 0) + colno = val; + + const char *comp_dir = ""; + const char *comp_dir_sep = ""; + + if (file == NULL) + file = "???"; + else if (only_basenames) + file = basename (file); + else if (use_comp_dir && file[0] != '/') + { + const char *const *dirs; + size_t ndirs; + if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 + && dirs[0] != NULL) + { + comp_dir = dirs[0]; + comp_dir_sep = "/"; + } + } + + if (lineno == 0) + printf (" from %s%s%s", + comp_dir, comp_dir_sep, file); + else if (colno == 0) + printf (" at %s%s%s:%u", + comp_dir, comp_dir_sep, file, lineno); + else + printf (" at %s%s%s:%u:%u", + comp_dir, comp_dir_sep, file, lineno, colno); + } + } + printf (" in "); + continue; + } + } + +done: + free (scopes); + return res; +} + +static void +print_addrsym (Dwfl_Module *mod, GElf_Addr addr) +{ + GElf_Sym s; + GElf_Off off; + const char *name = dwfl_module_addrinfo (mod, addr, &off, &s, + NULL, NULL, NULL); + if (name == NULL) + { + /* No symbol name. Get a section name instead. */ + int i = dwfl_module_relocate_address (mod, &addr); + if (i >= 0) + name = dwfl_module_relocation_info (mod, i, NULL); + if (name == NULL) + printf ("??%c", pretty ? ' ': '\n'); + else + printf ("(%s)+%#" PRIx64 "%c", name, addr, pretty ? ' ' : '\n'); + } + else + { + name = symname (name); + if (off == 0) + printf ("%s", name); + else + printf ("%s+%#" PRIx64 "", name, off); + + // Also show section name for address. + if (show_symbol_sections) + { + Dwarf_Addr ebias; + Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias); + if (scn != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + { + Elf *elf = dwfl_module_getelf (mod, &ebias); + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) >= 0) + printf (" (%s)", elf_strptr (elf, shstrndx, + shdr->sh_name)); + } + } + } + printf ("%c", pretty ? ' ' : '\n'); + } +} + +static int +see_one_module (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr start __attribute__ ((unused)), + void *arg) +{ + Dwfl_Module **result = arg; + if (*result != NULL) + return DWARF_CB_ABORT; + *result = mod; + return DWARF_CB_OK; +} + +static int +find_symbol (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr start __attribute__ ((unused)), + void *arg) +{ + const char *looking_for = ((void **) arg)[0]; + GElf_Sym *symbol = ((void **) arg)[1]; + GElf_Addr *value = ((void **) arg)[2]; + + int n = dwfl_module_getsymtab (mod); + for (int i = 1; i < n; ++i) + { + const char *symbol_name = dwfl_module_getsym_info (mod, i, symbol, + value, NULL, NULL, + NULL); + if (symbol_name == NULL || symbol_name[0] == '\0') + continue; + switch (GELF_ST_TYPE (symbol->st_info)) + { + case STT_SECTION: + case STT_FILE: + case STT_TLS: + break; + default: + if (!strcmp (symbol_name, looking_for)) + { + ((void **) arg)[0] = NULL; + return DWARF_CB_ABORT; + } + } + } + + return DWARF_CB_OK; +} + +static bool +adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl) +{ + /* It was (section)+offset. This makes sense if there is + only one module to look in for a section. */ + Dwfl_Module *mod = NULL; + if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 + || mod == NULL) + error (EXIT_FAILURE, 0, _("Section syntax requires" + " exactly one module")); + + int nscn = dwfl_module_relocations (mod); + for (int i = 0; i < nscn; ++i) + { + GElf_Word shndx; + const char *scn = dwfl_module_relocation_info (mod, i, &shndx); + if (unlikely (scn == NULL)) + break; + if (!strcmp (scn, name)) + { + /* Found the section. */ + GElf_Shdr shdr_mem; + GElf_Addr shdr_bias; + GElf_Shdr *shdr = gelf_getshdr + (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), + &shdr_mem); + if (unlikely (shdr == NULL)) + break; + + if (*addr >= shdr->sh_size) + error (0, 0, + _("offset %#" PRIxMAX " lies outside" + " section '%s'"), + *addr, scn); + + *addr += shdr->sh_addr + shdr_bias; + return true; + } + } + + return false; +} + +static void +print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu) +{ + const char *comp_dir = ""; + const char *comp_dir_sep = ""; + + if (only_basenames) + src = basename (src); + else if (use_comp_dir && src[0] != '/') + { + Dwarf_Attribute attr; + comp_dir = dwarf_formstring (dwarf_attr (cu, DW_AT_comp_dir, &attr)); + if (comp_dir != NULL) + comp_dir_sep = "/"; + } + + if (linecol != 0) + printf ("%s%s%s:%d:%d", + comp_dir, comp_dir_sep, src, lineno, linecol); + else + printf ("%s%s%s:%d", + comp_dir, comp_dir_sep, src, lineno); +} + +static int +get_addr_width (Dwfl_Module *mod) +{ + // Try to find the address width if possible. + static int width = 0; + if (width == 0 && mod != NULL) + { + Dwarf_Addr bias; + Elf *elf = dwfl_module_getelf (mod, &bias); + if (elf != NULL) + { + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr != NULL) + width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16; + } + } + if (width == 0) + width = 16; + + return width; +} + +static inline void +show_note (int (*get) (Dwarf_Line *, bool *), + Dwarf_Line *info, + const char *note) +{ + bool flag; + if ((*get) (info, &flag) == 0 && flag) + fputs (note, stdout); +} + +static inline void +show_int (int (*get) (Dwarf_Line *, unsigned int *), + Dwarf_Line *info, + const char *name) +{ + unsigned int val; + if ((*get) (info, &val) == 0 && val != 0) + printf (" (%s %u)", name, val); +} + +static int +handle_address (const char *string, Dwfl *dwfl) +{ + char *endp; + uintmax_t addr = strtoumax (string, &endp, 16); + if (endp == string || *endp != '\0') + { + bool parsed = false; + int i, j; + char *name = NULL; + if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2 + && string[i] == '\0') + parsed = adjust_to_section (name, &addr, dwfl); + switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j)) + { + default: + break; + case 1: + addr = 0; + j = i; + FALLTHROUGH; + case 2: + if (string[j] != '\0') + break; + + /* It was symbol[+offset]. */ + GElf_Sym sym; + GElf_Addr value = 0; + void *arg[3] = { name, &sym, &value }; + (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0); + if (arg[0] != NULL) + error (0, 0, _("cannot find symbol '%s'"), name); + else + { + if (sym.st_size != 0 && addr >= sym.st_size) + error (0, 0, + _("offset %#" PRIxMAX " lies outside" + " contents of '%s'"), + addr, name); + addr += value; + parsed = true; + } + break; + } + + free (name); + if (!parsed) + return 1; + } + else if (just_section != NULL + && !adjust_to_section (just_section, &addr, dwfl)) + return 1; + + Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); + + if (print_addresses) + { + int width = get_addr_width (mod); + printf ("0x%.*" PRIx64 "%s", width, addr, pretty ? ": " : "\n"); + } + + if (show_functions) + { + /* First determine the function name. Use the DWARF information if + possible. */ + if (! print_dwarf_function (mod, addr) && !show_symbols) + { + const char *name = dwfl_module_addrname (mod, addr); + name = name != NULL ? symname (name) : "??"; + printf ("%s%c", name, pretty ? ' ' : '\n'); + } + } + + if (show_symbols) + print_addrsym (mod, addr); + + if ((show_functions || show_symbols) && pretty) + printf ("at "); + + Dwfl_Line *line = dwfl_module_getsrc (mod, addr); + + const char *src; + int lineno, linecol; + + if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol, + NULL, NULL)) != NULL) + { + print_src (src, lineno, linecol, dwfl_linecu (line)); + if (show_flags) + { + Dwarf_Addr bias; + Dwarf_Line *info = dwfl_dwarf_line (line, &bias); + assert (info != NULL); + + show_note (&dwarf_linebeginstatement, info, " (is_stmt)"); + show_note (&dwarf_lineblock, info, " (basic_block)"); + show_note (&dwarf_lineprologueend, info, " (prologue_end)"); + show_note (&dwarf_lineepiloguebegin, info, " (epilogue_begin)"); + show_int (&dwarf_lineisa, info, "isa"); + show_int (&dwarf_linediscriminator, info, "discriminator"); + } + putchar ('\n'); + } + else + puts ("??:0"); + + if (show_inlines) + { + Dwarf_Addr bias = 0; + Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); + + Dwarf_Die *scopes = NULL; + int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); + if (nscopes < 0) + return 1; + + if (nscopes > 0) + { + Dwarf_Die subroutine; + Dwarf_Off dieoff = dwarf_dieoffset (&scopes[0]); + dwarf_offdie (dwfl_module_getdwarf (mod, &bias), + dieoff, &subroutine); + free (scopes); + scopes = NULL; + + nscopes = dwarf_getscopes_die (&subroutine, &scopes); + if (nscopes > 1) + { + Dwarf_Die cu; + Dwarf_Files *files; + if (dwarf_diecu (&scopes[0], &cu, NULL, NULL) != NULL + && dwarf_getsrcfiles (cudie, &files, NULL) == 0) + { + for (int i = 0; i < nscopes - 1; i++) + { + Dwarf_Word val; + Dwarf_Attribute attr; + Dwarf_Die *die = &scopes[i]; + if (dwarf_tag (die) != DW_TAG_inlined_subroutine) + continue; + + if (pretty) + printf (" (inlined by) "); + + if (show_functions) + { + /* Search for the parent inline or function. It + might not be directly above this inline -- e.g. + there could be a lexical_block in between. */ + for (int j = i + 1; j < nscopes; j++) + { + Dwarf_Die *parent = &scopes[j]; + int tag = dwarf_tag (parent); + if (tag == DW_TAG_inlined_subroutine + || tag == DW_TAG_entry_point + || tag == DW_TAG_subprogram) + { + printf ("%s%s", + symname (get_diename (parent)), + pretty ? " at " : "\n"); + break; + } + } + } + + src = NULL; + lineno = 0; + linecol = 0; + if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file, + &attr), &val) == 0) + src = dwarf_filesrc (files, val, NULL, NULL); + + if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line, + &attr), &val) == 0) + lineno = val; + + if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column, + &attr), &val) == 0) + linecol = val; + + if (src != NULL) + { + print_src (src, lineno, linecol, &cu); + putchar ('\n'); + } + else + puts ("??:0"); + } + } + } + } + free (scopes); + } + + return 0; +} + + +#include "debugpred.h" diff --git a/src/ar.c b/src/ar.c new file mode 100644 index 00000000..ab6098f0 --- /dev/null +++ b/src/ar.c @@ -0,0 +1,1576 @@ +/* Create, modify, and extract from archives. + Copyright (C) 2005-2012, 2016, 2017 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "arlib.h" + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Prototypes for local functions. */ +static int do_oper_extract (int oper, const char *arfname, char **argv, + int argc, long int instance); +static int do_oper_delete (const char *arfname, char **argv, int argc, + long int instance); +static int do_oper_insert (int oper, const char *arfname, char **argv, + int argc, const char *member); + + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Commands:"), 1 }, + { NULL, 'd', NULL, 0, N_("Delete files from archive."), 0 }, + { NULL, 'm', NULL, 0, N_("Move files in archive."), 0 }, + { NULL, 'p', NULL, 0, N_("Print files in archive."), 0 }, + { NULL, 'q', NULL, 0, N_("Quick append files to archive."), 0 }, + { NULL, 'r', NULL, 0, + N_("Replace existing or insert new file into archive."), 0 }, + { NULL, 't', NULL, 0, N_("Display content of archive."), 0 }, + { NULL, 'x', NULL, 0, N_("Extract files from archive."), 0 }, + + { NULL, 0, NULL, 0, N_("Command Modifiers:"), 2 }, + { NULL, 'o', NULL, 0, N_("Preserve original dates."), 0 }, + { NULL, 'N', NULL, 0, N_("Use instance [COUNT] of name."), 0 }, + { NULL, 'C', NULL, 0, + N_("Do not replace existing files with extracted files."), 0 }, + { NULL, 'T', NULL, 0, N_("Allow filename to be truncated if necessary."), + 0 }, + { NULL, 'v', NULL, 0, N_("Provide verbose output."), 0 }, + { NULL, 's', NULL, 0, N_("Force regeneration of symbol table."), 0 }, + { NULL, 'a', NULL, 0, N_("Insert file after [MEMBER]."), 0 }, + { NULL, 'b', NULL, 0, N_("Insert file before [MEMBER]."), 0 }, + { NULL, 'i', NULL, 0, N_("Same as -b."), 0 }, + { NULL, 'c', NULL, 0, N_("Suppress message when library has to be created."), + 0 }, + { NULL, 'P', NULL, 0, N_("Use full path for file matching."), 0 }, + { NULL, 'u', NULL, 0, N_("Update only older files in archive."), 0 }, + + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("Create, modify, and extract from archives."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[MEMBER] [COUNT] ARCHIVE [FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, arlib_argp_children, NULL, NULL +}; + + +/* What operation to perform. */ +static enum + { + oper_none, + oper_delete, + oper_move, + oper_print, + oper_qappend, + oper_replace, + oper_list, + oper_extract + } operation; + +/* Modifiers. */ +static bool verbose; +static bool preserve_dates; +static bool instance_specifed; +static bool dont_replace_existing; +static bool allow_truncate_fname; +static bool force_symtab; +static bool suppress_create_msg; +static bool full_path; +static bool update_newer; +static enum { ipos_none, ipos_before, ipos_after } ipos; + + +int +main (int argc, char *argv[]) +{ + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* For historical reasons the options in the first parameter need + not be preceded by a dash. Add it now if necessary. */ + if (argc > 1 && argv[1][0] != '-') + { + size_t len = strlen (argv[1]) + 1; + char *newp = alloca (len + 1); + newp[0] = '-'; + memcpy (&newp[1], argv[1], len); + argv[1] = newp; + } + + /* Parse and process arguments. */ + int remaining; + (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL); + + /* Tell the library which version we are expecting. */ + (void) elf_version (EV_CURRENT); + + /* Handle the [MEMBER] parameter. */ + const char *member = NULL; + if (ipos != ipos_none) + { + /* Only valid for certain operations. */ + if (operation != oper_move && operation != oper_replace) + error (1, 0, _("\ +'a', 'b', and 'i' are only allowed with the 'm' and 'r' options")); + + if (remaining == argc) + { + error (0, 0, _("\ +MEMBER parameter required for 'a', 'b', and 'i' modifiers")); + argp_help (&argp, stderr, ARGP_HELP_USAGE | ARGP_HELP_SEE, + program_invocation_short_name); + exit (EXIT_FAILURE); + } + + member = argv[remaining++]; + } + + /* Handle the [COUNT] parameter. */ + long int instance = -1; + if (instance_specifed) + { + /* Only valid for certain operations. */ + if (operation != oper_extract && operation != oper_delete) + error (1, 0, _("\ +'N' is only meaningful with the 'x' and 'd' options")); + + if (remaining == argc) + { + error (0, 0, _("COUNT parameter required")); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); + exit (EXIT_FAILURE); + } + + char *endp; + errno = 0; + if (((instance = strtol (argv[remaining], &endp, 10)) == LONG_MAX + && errno == ERANGE) + || instance <= 0 + || *endp != '\0') + error (1, 0, _("invalid COUNT parameter %s"), argv[remaining]); + + ++remaining; + } + + if ((dont_replace_existing || allow_truncate_fname) + && unlikely (operation != oper_extract)) + error (1, 0, _("'%c' is only meaningful with the 'x' option"), + dont_replace_existing ? 'C' : 'T'); + + /* There must at least be one more parameter specifying the archive. */ + if (remaining == argc) + { + error (0, 0, _("archive name required")); + argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name); + exit (EXIT_FAILURE); + } + + const char *arfname = argv[remaining++]; + argv += remaining; + argc -= remaining; + + int status; + switch (operation) + { + case oper_none: + error (0, 0, _("command option required")); + argp_help (&argp, stderr, ARGP_HELP_STD_ERR, + program_invocation_short_name); + status = 1; + break; + + case oper_list: + case oper_print: + status = do_oper_extract (operation, arfname, argv, argc, -1); + break; + + case oper_extract: + status = do_oper_extract (operation, arfname, argv, argc, instance); + break; + + case oper_delete: + status = do_oper_delete (arfname, argv, argc, instance); + break; + + case oper_move: + case oper_qappend: + case oper_replace: + status = do_oper_insert (operation, arfname, argv, argc, member); + break; + + default: + assert (! "should not happen"); + status = 1; + break; + } + + return status; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg __attribute__ ((unused)), + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'd': + case 'm': + case 'p': + case 'q': + case 'r': + case 't': + case 'x': + if (operation != oper_none) + { + error (0, 0, _("More than one operation specified")); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); + exit (EXIT_FAILURE); + } + + switch (key) + { + case 'd': + operation = oper_delete; + break; + case 'm': + operation = oper_move; + break; + case 'p': + operation = oper_print; + break; + case 'q': + operation = oper_qappend; + break; + case 'r': + operation = oper_replace; + break; + case 't': + operation = oper_list; + break; + case 'x': + operation = oper_extract; + break; + } + break; + + case 'a': + ipos = ipos_after; + break; + + case 'b': + case 'i': + ipos = ipos_before; + break; + + case 'c': + suppress_create_msg = true; + break; + + case 'C': + dont_replace_existing = true; + break; + + case 'N': + instance_specifed = true; + break; + + case 'o': + preserve_dates = true; + break; + + case 'P': + full_path = true; + break; + + case 's': + force_symtab = true; + break; + + case 'T': + allow_truncate_fname = true; + break; + + case 'u': + update_newer = true; + break; + + case 'v': + verbose = true; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +static int +open_archive (const char *arfname, int flags, int mode, Elf **elf, + struct stat *st, bool miss_allowed) +{ + int fd = open (arfname, flags, mode); + if (fd == -1) + { + if (miss_allowed) + return -1; + + error (EXIT_FAILURE, errno, _("cannot open archive '%s'"), + arfname); + } + + if (elf != NULL) + { + Elf_Cmd cmd = flags == O_RDONLY ? ELF_C_READ_MMAP : ELF_C_RDWR_MMAP; + + *elf = elf_begin (fd, cmd, NULL); + if (*elf == NULL) + error (EXIT_FAILURE, 0, _("cannot open archive '%s': %s"), + arfname, elf_errmsg (-1)); + + if (flags == O_RDONLY && elf_kind (*elf) != ELF_K_AR) + error (EXIT_FAILURE, 0, _("%s: not an archive file"), arfname); + } + + if (st != NULL && fstat (fd, st) != 0) + error (EXIT_FAILURE, errno, _("cannot stat archive '%s'"), + arfname); + + return fd; +} + + +static void +not_found (int argc, char *argv[argc], bool found[argc]) +{ + for (int i = 0; i < argc; ++i) + if (!found[i]) + printf (_("no entry %s in archive\n"), argv[i]); +} + + +static int +copy_content (Elf *elf, int newfd, off_t off, size_t n) +{ + size_t len; + char *rawfile = elf_rawfile (elf, &len); + + assert (off + n <= len); + + /* Tell the kernel we will read all the pages sequentially. */ + size_t ps = sysconf (_SC_PAGESIZE); + if (n > 2 * ps) + posix_madvise (rawfile + (off & ~(ps - 1)), n, POSIX_MADV_SEQUENTIAL); + + return write_retry (newfd, rawfile + off, n) != (ssize_t) n; +} + +static inline bool +should_truncate_fname (size_t *name_max) +{ + if (errno == ENAMETOOLONG && allow_truncate_fname) + { + if (*name_max == 0) + { + long int len = pathconf (".", _PC_NAME_MAX); + if (len > 0) + *name_max = len; + } + return *name_max != 0; + } + return false; +} + +static int +do_oper_extract (int oper, const char *arfname, char **argv, int argc, + long int instance) +{ + bool found[argc > 0 ? argc : 1]; + memset (found, '\0', sizeof (found)); + + size_t name_max = 0; + off_t index_off = -1; + size_t index_size = 0; + off_t cur_off = SARMAG; + + int status = 0; + Elf *elf; + int fd = open_archive (arfname, O_RDONLY, 0, &elf, NULL, false); + + if (hcreate (2 * argc) == 0) + error (EXIT_FAILURE, errno, _("cannot create hash table")); + + for (int cnt = 0; cnt < argc; ++cnt) + { + ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] }; + if (hsearch (entry, ENTER) == NULL) + error (EXIT_FAILURE, errno, + _("cannot insert into hash table")); + } + + struct stat st; + if (force_symtab) + { + if (fstat (fd, &st) != 0) + { + error (0, errno, _("cannot stat '%s'"), arfname); + close (fd); + return 1; + } + arlib_init (); + } + + Elf_Cmd cmd = ELF_C_READ_MMAP; + Elf *subelf; + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + if (strcmp (arhdr->ar_name, "/") == 0) + { + index_off = elf_getaroff (subelf); + index_size = arhdr->ar_size; + goto next; + } + if (strcmp (arhdr->ar_name, "//") == 0) + goto next; + + if (force_symtab) + { + arlib_add_symbols (elf, arfname, arhdr->ar_name, cur_off); + cur_off += (((arhdr->ar_size + 1) & ~((off_t) 1)) + + sizeof (struct ar_hdr)); + } + + bool do_extract = argc <= 0; + if (!do_extract) + { + ENTRY entry; + entry.key = arhdr->ar_name; + ENTRY *res = hsearch (entry, FIND); + if (res != NULL && (instance < 0 || instance-- == 0) + && !found[(char **) res->data - argv]) + found[(char **) res->data - argv] = do_extract = true; + } + + if (do_extract) + { + if (verbose) + { + if (oper == oper_print) + { + printf ("\n<%s>\n\n", arhdr->ar_name); + + /* We have to flush now because now we use the descriptor + directly. */ + fflush (stdout); + } + else if (oper == oper_list) + { + char datestr[100]; + struct tm *tp = localtime (&arhdr->ar_date); + if (tp == NULL) + { + time_t time = 0; + tp = localtime (&time); + } + + strftime (datestr, sizeof (datestr), "%b %e %H:%M %Y", tp); + + printf ("%c%c%c%c%c%c%c%c%c %u/%u %6ju %s %s\n", + (arhdr->ar_mode & S_IRUSR) ? 'r' : '-', + (arhdr->ar_mode & S_IWUSR) ? 'w' : '-', + (arhdr->ar_mode & S_IXUSR) + ? ((arhdr->ar_mode & S_ISUID) ? 's' : 'x') + : ((arhdr->ar_mode & S_ISUID) ? 'S' : '-'), + (arhdr->ar_mode & S_IRGRP) ? 'r' : '-', + (arhdr->ar_mode & S_IWGRP) ? 'w' : '-', + (arhdr->ar_mode & S_IXGRP) + ? ((arhdr->ar_mode & S_ISGID) ? 's' : 'x') + : ((arhdr->ar_mode & S_ISGID) ? 'S' : '-'), + (arhdr->ar_mode & S_IROTH) ? 'r' : '-', + (arhdr->ar_mode & S_IWOTH) ? 'w' : '-', + (arhdr->ar_mode & S_IXOTH) + ? ((arhdr->ar_mode & S_ISVTX) ? 't' : 'x') + : ((arhdr->ar_mode & S_ISVTX) ? 'T' : '-'), + arhdr->ar_uid, + arhdr->ar_gid, + (uintmax_t) arhdr->ar_size, + datestr, + arhdr->ar_name); + } + else + printf ("x - %s\n", arhdr->ar_name); + } + + if (oper == oper_list) + { + if (!verbose) + puts (arhdr->ar_name); + + goto next; + } + + size_t nleft; + char *data = elf_rawfile (subelf, &nleft); + if (data == NULL) + { + error (0, 0, _("cannot read content of %s: %s"), + arhdr->ar_name, elf_errmsg (-1)); + status = 1; + goto next; + } + + int xfd; + char tempfname[] = "XXXXXX"; + bool use_mkstemp = true; + + if (oper == oper_print) + xfd = STDOUT_FILENO; + else + { + xfd = mkstemp (tempfname); + if (unlikely (xfd == -1)) + { + /* We cannot create a temporary file. Try to overwrite + the file or create it if it does not exist. */ + int flags = O_WRONLY | O_CREAT; + if (dont_replace_existing) + flags |= O_EXCL; + else + flags |= O_TRUNC; + xfd = open (arhdr->ar_name, flags, 0600); + if (unlikely (xfd == -1)) + { + int printlen = INT_MAX; + + if (should_truncate_fname (&name_max)) + { + /* Try to truncate the name. First find out by how + much. */ + printlen = name_max; + char truncfname[name_max + 1]; + *((char *) mempcpy (truncfname, arhdr->ar_name, + name_max)) = '\0'; + + xfd = open (truncfname, flags, 0600); + } + + if (xfd == -1) + { + error (0, errno, _("cannot open %.*s"), + (int) printlen, arhdr->ar_name); + status = 1; + goto next; + } + } + + use_mkstemp = false; + } + } + + ssize_t n; + while ((n = TEMP_FAILURE_RETRY (write (xfd, data, nleft))) != -1) + { + nleft -= n; + if (nleft == 0) + break; + data += n; + } + + if (unlikely (n == -1)) + { + error (0, errno, _("failed to write %s"), arhdr->ar_name); + status = 1; + unlink (tempfname); + close (xfd); + goto next; + } + + if (oper != oper_print) + { + /* Fix up the mode. */ + if (unlikely (fchmod (xfd, arhdr->ar_mode) != 0)) + { + error (0, errno, _("cannot change mode of %s"), + arhdr->ar_name); + status = 0; + } + + if (preserve_dates) + { + struct timespec tv[2]; + tv[0].tv_sec = arhdr->ar_date; + tv[0].tv_nsec = 0; + tv[1].tv_sec = arhdr->ar_date; + tv[1].tv_nsec = 0; + + if (unlikely (futimens (xfd, tv) != 0)) + { + error (0, errno, + _("cannot change modification time of %s"), + arhdr->ar_name); + status = 1; + } + } + + /* If we used a temporary file, move it do the right + name now. */ + if (use_mkstemp) + { + int r; + + if (dont_replace_existing) + { + r = link (tempfname, arhdr->ar_name); + if (likely (r == 0)) + unlink (tempfname); + } + else + r = rename (tempfname, arhdr->ar_name); + + if (unlikely (r) != 0) + { + int printlen = INT_MAX; + + if (should_truncate_fname (&name_max)) + { + /* Try to truncate the name. First find out by how + much. */ + printlen = name_max; + char truncfname[name_max + 1]; + *((char *) mempcpy (truncfname, arhdr->ar_name, + name_max)) = '\0'; + + if (dont_replace_existing) + { + r = link (tempfname, truncfname); + if (likely (r == 0)) + unlink (tempfname); + } + else + r = rename (tempfname, truncfname); + } + + if (r != 0) + { + error (0, errno, _("\ +cannot rename temporary file to %.*s"), + printlen, arhdr->ar_name); + unlink (tempfname); + status = 1; + } + } + } + + close (xfd); + } + } + + next: + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + error (1, 0, "%s: %s", arfname, elf_errmsg (-1)); + } + + hdestroy (); + + if (force_symtab) + { + arlib_finalize (); + + if (symtab.symsnamelen != 0 + /* We have to rewrite the file also if it initially had an index + but now does not need one anymore. */ + || (symtab.symsnamelen == 0 && index_size != 0)) + { + char tmpfname[strlen (arfname) + 7]; + strcpy (stpcpy (tmpfname, arfname), "XXXXXX"); + int newfd = mkstemp (tmpfname); + if (unlikely (newfd == -1)) + { + nonew: + error (0, errno, _("cannot create new file")); + status = 1; + } + else + { + /* Create the header. */ + if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG)) + { + // XXX Use /prof/self/fd/%d ??? + nonew_unlink: + unlink (tmpfname); + if (newfd != -1) + close (newfd); + goto nonew; + } + + /* Create the new file. There are three parts as far we are + concerned: 1. original context before the index, 2. the + new index, 3. everything after the new index. */ + off_t rest_off; + if (index_off != -1) + rest_off = (index_off + sizeof (struct ar_hdr) + + ((index_size + 1) & ~1ul)); + else + rest_off = SARMAG; + + if (symtab.symsnamelen != 0 + && ((write_retry (newfd, symtab.symsoff, + symtab.symsofflen) + != (ssize_t) symtab.symsofflen) + || (write_retry (newfd, symtab.symsname, + symtab.symsnamelen) + != (ssize_t) symtab.symsnamelen))) + goto nonew_unlink; + /* Even if the original file had content before the + symbol table, we write it in the correct order. */ + if ((index_off != SARMAG + && copy_content (elf, newfd, SARMAG, index_off - SARMAG)) + || copy_content (elf, newfd, rest_off, st.st_size - rest_off)) + goto nonew_unlink; + + /* Never complain about fchown failing. */ + if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; } + /* Set the mode of the new file to the same values the + original file has. */ + if (fchmod (newfd, st.st_mode & ALLPERMS) != 0 + || close (newfd) != 0) + goto nonew_unlink; + newfd = -1; + if (rename (tmpfname, arfname) != 0) + goto nonew_unlink; + } + } + } + + elf_end (elf); + + close (fd); + + not_found (argc, argv, found); + + return status; +} + + +struct armem +{ + off_t off; + off_t old_off; + size_t size; + long int long_name_off; + struct armem *next; + void *mem; + time_t sec; + uid_t uid; + gid_t gid; + mode_t mode; + const char *name; + Elf *elf; +}; + + +static int +write_member (struct armem *memb, off_t *startp, off_t *lenp, Elf *elf, + off_t end_off, int newfd) +{ + struct ar_hdr arhdr; + /* The ar_name is not actually zero terminated, but we need that for + snprintf. Also if the name is too long, then the string starts + with '/' plus an index off number (decimal). */ + char tmpbuf[sizeof (arhdr.ar_name) + 2]; + + bool changed_header = memb->long_name_off != -1; + if (changed_header) + { + /* In case of a long file name we assume the archive header + changed and we write it here. */ + memcpy (&arhdr, elf_rawfile (elf, NULL) + *startp, sizeof (arhdr)); + + snprintf (tmpbuf, sizeof (tmpbuf), "/%-*ld", + (int) sizeof (arhdr.ar_name), memb->long_name_off); + changed_header = memcmp (arhdr.ar_name, tmpbuf, + sizeof (arhdr.ar_name)) != 0; + } + + /* If the files are adjacent in the old file extend the range. */ + if (*startp != -1 && !changed_header && *startp + *lenp == memb->old_off) + { + /* Extend the current range. */ + *lenp += (memb->next != NULL + ? memb->next->off : end_off) - memb->off; + return 0; + } + + /* Write out the old range. */ + if (*startp != -1 && copy_content (elf, newfd, *startp, *lenp)) + return -1; + + *startp = memb->old_off; + *lenp = (memb->next != NULL ? memb->next->off : end_off) - memb->off; + + if (changed_header) + { + memcpy (arhdr.ar_name, tmpbuf, sizeof (arhdr.ar_name)); + + if (unlikely (write_retry (newfd, &arhdr, sizeof (arhdr)) + != sizeof (arhdr))) + return -1; + + *startp += sizeof (struct ar_hdr); + assert ((size_t) *lenp >= sizeof (struct ar_hdr)); + *lenp -= sizeof (struct ar_hdr); + } + + return 0; +} + +/* Store the name in the long name table if necessary. + Record its offset or -1 if we did not need to use the table. */ +static void +remember_long_name (struct armem *mem, const char *name, size_t namelen) +{ + mem->long_name_off = (namelen > MAX_AR_NAME_LEN + ? arlib_add_long_name (name, namelen) + : -1l); +} + +static int +do_oper_delete (const char *arfname, char **argv, int argc, + long int instance) +{ + bool *found = alloca (sizeof (bool) * argc); + memset (found, '\0', sizeof (bool) * argc); + + /* List of the files we keep. */ + struct armem *to_copy = NULL; + + int status = 0; + Elf *elf; + struct stat st; + int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, false); + + if (hcreate (2 * argc) == 0) + error (EXIT_FAILURE, errno, _("cannot create hash table")); + + for (int cnt = 0; cnt < argc; ++cnt) + { + ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] }; + if (hsearch (entry, ENTER) == NULL) + error (EXIT_FAILURE, errno, + _("cannot insert into hash table")); + } + + arlib_init (); + + off_t cur_off = SARMAG; + Elf_Cmd cmd = ELF_C_READ_MMAP; + Elf *subelf; + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + /* Ignore the symbol table and the long file name table here. */ + if (strcmp (arhdr->ar_name, "/") == 0 + || strcmp (arhdr->ar_name, "//") == 0) + goto next; + + bool do_delete = argc <= 0; + if (!do_delete) + { + ENTRY entry; + entry.key = arhdr->ar_name; + ENTRY *res = hsearch (entry, FIND); + if (res != NULL && (instance < 0 || instance-- == 0) + && !found[(char **) res->data - argv]) + found[(char **) res->data - argv] = do_delete = true; + } + + if (do_delete) + { + if (verbose) + printf ("d - %s\n", arhdr->ar_name); + } + else + { + struct armem *newp = alloca (sizeof (struct armem)); + newp->old_off = elf_getaroff (subelf); + newp->off = cur_off; + + cur_off += (((arhdr->ar_size + 1) & ~((off_t) 1)) + + sizeof (struct ar_hdr)); + + if (to_copy == NULL) + to_copy = newp->next = newp; + else + { + newp->next = to_copy->next; + to_copy = to_copy->next = newp; + } + + /* If we recreate the symbol table read the file's symbol + table now. */ + arlib_add_symbols (subelf, arfname, arhdr->ar_name, newp->off); + + /* Remember long file names. */ + remember_long_name (newp, arhdr->ar_name, strlen (arhdr->ar_name)); + } + + next: + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + error (1, 0, "%s: %s", arfname, elf_errmsg (-1)); + } + + arlib_finalize (); + + hdestroy (); + + /* Create a new, temporary file in the same directory as the + original file. */ + char tmpfname[strlen (arfname) + 7]; + strcpy (stpcpy (tmpfname, arfname), "XXXXXX"); + int newfd = mkstemp (tmpfname); + if (unlikely (newfd == -1)) + goto nonew; + + /* Create the header. */ + if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG)) + { + // XXX Use /prof/self/fd/%d ??? + nonew_unlink: + unlink (tmpfname); + if (newfd != -1) + close (newfd); + nonew: + error (0, errno, _("cannot create new file")); + status = 1; + goto errout; + } + + /* If the archive is empty that is all we have to do. */ + if (likely (to_copy != NULL)) + { + /* Write the symbol table or the long file name table or both. */ + if (symtab.symsnamelen != 0 + && ((write_retry (newfd, symtab.symsoff, symtab.symsofflen) + != (ssize_t) symtab.symsofflen) + || (write_retry (newfd, symtab.symsname, symtab.symsnamelen) + != (ssize_t) symtab.symsnamelen))) + goto nonew_unlink; + + if (symtab.longnameslen > sizeof (struct ar_hdr) + && (write_retry (newfd, symtab.longnames, symtab.longnameslen) + != (ssize_t) symtab.longnameslen)) + goto nonew_unlink; + + /* NULL-terminate the list of files to copy. */ + struct armem *last = to_copy; + to_copy = to_copy->next; + last->next = NULL; + + off_t start = -1; + off_t len = -1; + + do + if (write_member (to_copy, &start, &len, elf, cur_off, newfd) != 0) + goto nonew_unlink; + while ((to_copy = to_copy->next) != NULL); + + /* Write the last part. */ + if (copy_content (elf, newfd, start, len)) + goto nonew_unlink; + } + + /* Set the mode of the new file to the same values the original file + has. Never complain about fchown failing. But do it before + setting the mode (which might be reset/ignored if the owner is + wrong. */ + if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; } + if (fchmod (newfd, st.st_mode & ALLPERMS) != 0 + || close (newfd) != 0) + goto nonew_unlink; + newfd = -1; + if (rename (tmpfname, arfname) != 0) + goto nonew_unlink; + + errout: + elf_end (elf); + + arlib_fini (); + + close (fd); + + not_found (argc, argv, found); + + return status; +} + + +/* Prints the given value in the given buffer without a trailing zero char. + Returns false if the given value doesn't fit in the given buffer. */ +static bool +no0print (bool ofmt, char *buf, int bufsize, long int val) +{ + char tmpbuf[bufsize + 1]; + int ret = snprintf (tmpbuf, sizeof (tmpbuf), ofmt ? "%-*lo" : "%-*ld", + bufsize, val); + if (ret >= (int) sizeof (tmpbuf)) + return false; + memcpy (buf, tmpbuf, bufsize); + return true; +} + + +static int +do_oper_insert (int oper, const char *arfname, char **argv, int argc, + const char *member) +{ + int status = 0; + Elf *elf = NULL; + struct stat st; + int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, oper != oper_move); + + /* List of the files we keep. */ + struct armem *all = NULL; + struct armem *after_memberelem = NULL; + struct armem **found = alloca (sizeof (*found) * argc); + memset (found, '\0', sizeof (*found) * argc); + + arlib_init (); + + /* Initialize early for no_old case. */ + off_t cur_off = SARMAG; + + if (fd == -1) + { + if (!suppress_create_msg) + fprintf (stderr, "%s: creating %s\n", + program_invocation_short_name, arfname); + + goto no_old; + } + + /* Store the names of all files from the command line in a hash + table so that we can match it. Note that when no file name is + given we are basically doing nothing except recreating the + index. */ + if (oper != oper_qappend) + { + if (hcreate (2 * argc) == 0) + error (EXIT_FAILURE, errno, _("cannot create hash table")); + + for (int cnt = 0; cnt < argc; ++cnt) + { + ENTRY entry; + entry.key = full_path ? argv[cnt] : basename (argv[cnt]); + entry.data = &argv[cnt]; + if (hsearch (entry, ENTER) == NULL) + error (EXIT_FAILURE, errno, + _("cannot insert into hash table")); + } + } + + /* While iterating over the current content of the archive we must + determine a number of things: which archive members to keep, + which are replaced, and where to insert the new members. */ + Elf_Cmd cmd = ELF_C_READ_MMAP; + Elf *subelf; + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + /* Ignore the symbol table and the long file name table here. */ + if (strcmp (arhdr->ar_name, "/") == 0 + || strcmp (arhdr->ar_name, "//") == 0) + goto next; + + struct armem *newp = alloca (sizeof (struct armem)); + newp->old_off = elf_getaroff (subelf); + newp->size = arhdr->ar_size; + newp->sec = arhdr->ar_date; + newp->mem = NULL; + + /* Remember long file names. */ + remember_long_name (newp, arhdr->ar_name, strlen (arhdr->ar_name)); + + /* Check whether this is a file we are looking for. */ + if (oper != oper_qappend) + { + /* Check whether this is the member used as the insert point. */ + if (member != NULL && strcmp (arhdr->ar_name, member) == 0) + { + /* Note that all == NULL means insert at the beginning. */ + if (ipos == ipos_before) + after_memberelem = all; + else + after_memberelem = newp; + member = NULL; + } + + ENTRY entry; + entry.key = arhdr->ar_name; + ENTRY *res = hsearch (entry, FIND); + if (res != NULL && found[(char **) res->data - argv] == NULL) + { + found[(char **) res->data - argv] = newp; + + /* If we insert before or after a certain element move + all files to a special list. */ + if (unlikely (ipos != ipos_none || oper == oper_move)) + { + if (after_memberelem == newp) + /* Since we remove this element even though we should + insert everything after it, we in fact insert + everything after the previous element. */ + after_memberelem = all; + + goto next; + } + } + } + + if (all == NULL) + all = newp->next = newp; + else + { + newp->next = all->next; + all = all->next = newp; + } + + next: + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + error (EXIT_FAILURE, 0, "%s: %s", arfname, elf_errmsg (-1)); + } + + if (oper != oper_qappend) + hdestroy (); + + no_old: + if (member != NULL) + error (EXIT_FAILURE, 0, _("position member %s not found"), + member); + + if (oper == oper_move) + { + /* Make sure all requested elements are found in the archive. */ + for (int cnt = 0; cnt < argc; ++cnt) + { + if (found[cnt] == NULL) + { + fprintf (stderr, _("%s: no entry %s in archive!\n"), + program_invocation_short_name, argv[cnt]); + status = 1; + } + + if (verbose) + printf ("m - %s\n", argv[cnt]); + } + } + else + { + /* Open all the new files, get their sizes and add all symbols. */ + for (int cnt = 0; cnt < argc; ++cnt) + { + const char *bname = basename (argv[cnt]); + size_t bnamelen = strlen (bname); + if (found[cnt] == NULL) + { + found[cnt] = alloca (sizeof (struct armem)); + found[cnt]->old_off = -1; + + remember_long_name (found[cnt], bname, bnamelen); + } + + struct stat newst; + Elf *newelf; + int newfd = open (argv[cnt], O_RDONLY); + if (newfd == -1) + { + error (0, errno, _("cannot open %s"), argv[cnt]); + status = 1; + } + else if (fstat (newfd, &newst) == -1) + { + error (0, errno, _("cannot stat %s"), argv[cnt]); + close (newfd); + status = 1; + } + else if (!S_ISREG (newst.st_mode)) + { + error (0, errno, _("%s is no regular file"), argv[cnt]); + close (newfd); + status = 1; + } + else if (update_newer + && found[cnt]->old_off != -1l + && found[cnt]->sec > st.st_mtime) + /* Do nothing, the file in the archive is younger. */ + close (newfd); + else if ((newelf = elf_begin (newfd, ELF_C_READ_MMAP, NULL)) + == NULL) + { + fprintf (stderr, + _("cannot get ELF descriptor for %s: %s\n"), + argv[cnt], elf_errmsg (-1)); + status = 1; + } + else + { + if (verbose) + printf ("%c - %s\n", + found[cnt]->old_off == -1l ? 'a' : 'r', argv[cnt]); + + found[cnt]->elf = newelf; + found[cnt]->sec = arlib_deterministic_output ? 0 : newst.st_mtime; + found[cnt]->uid = arlib_deterministic_output ? 0 : newst.st_uid; + found[cnt]->gid = arlib_deterministic_output ? 0 : newst.st_gid; + found[cnt]->mode = newst.st_mode; + found[cnt]->name = bname; + + found[cnt]->mem = elf_rawfile (newelf, &found[cnt]->size); + if (found[cnt]->mem == NULL + || elf_cntl (newelf, ELF_C_FDDONE) != 0) + error (EXIT_FAILURE, 0, _("cannot read %s: %s"), + argv[cnt], elf_errmsg (-1)); + + close (newfd); + + if (found[cnt]->old_off != -1l) + /* Remember long file names. */ + remember_long_name (found[cnt], bname, bnamelen); + } + } + } + + if (status != 0) + { + elf_end (elf); + + arlib_fini (); + + close (fd); + + return status; + } + + /* If we have no entry point so far add at the end. AFTER_MEMBERELEM + being NULL when adding before an entry means add at the beginning. */ + if (ipos != ipos_before && after_memberelem == NULL) + after_memberelem = all; + + /* Convert the circular list into a normal list first. */ + if (all != NULL) + { + struct armem *tmp = all; + all = all->next; + tmp->next = NULL; + } + + struct armem *last_added = after_memberelem; + for (int cnt = 0; cnt < argc; ++cnt) + if (oper != oper_replace || found[cnt]->old_off == -1) + { + if (last_added == NULL) + { + found[cnt]->next = all; + last_added = all = found[cnt]; + } + else + { + found[cnt]->next = last_added->next; + last_added = last_added->next = found[cnt]; + } + } + + /* Finally compute the offset and add the symbols for the files + after the insert point. */ + if (likely (all != NULL)) + for (struct armem *memp = all; memp != NULL; memp = memp->next) + { + memp->off = cur_off; + + if (memp->mem == NULL) + { + Elf_Arhdr *arhdr; + /* Fake initializing arhdr and subelf to keep gcc calm. */ + asm ("" : "=m" (arhdr), "=m" (subelf)); + if (elf_rand (elf, memp->old_off) == 0 + || (subelf = elf_begin (fd, ELF_C_READ_MMAP, elf)) == NULL + || (arhdr = elf_getarhdr (subelf)) == NULL) + /* This should never happen since we already looked at the + archive content. But who knows... */ + error (EXIT_FAILURE, 0, "%s: %s", arfname, elf_errmsg (-1)); + + arlib_add_symbols (subelf, arfname, arhdr->ar_name, cur_off); + + elf_end (subelf); + } + else + arlib_add_symbols (memp->elf, arfname, memp->name, cur_off); + + cur_off += (((memp->size + 1) & ~((off_t) 1)) + + sizeof (struct ar_hdr)); + } + + /* Now we have all the information for the symbol table and long + file name table. Construct the final layout. */ + arlib_finalize (); + + /* Create a new, temporary file in the same directory as the + original file. */ + char tmpfname[strlen (arfname) + 7]; + strcpy (stpcpy (tmpfname, arfname), "XXXXXX"); + int newfd; + if (fd != -1) + newfd = mkstemp (tmpfname); + else + { + newfd = open (arfname, O_RDWR | O_CREAT | O_EXCL, DEFFILEMODE); + if (newfd == -1 && errno == EEXIST) + /* Bah, first the file did not exist, now it does. Restart. */ + return do_oper_insert (oper, arfname, argv, argc, member); + } + if (unlikely (newfd == -1)) + goto nonew; + + /* Create the header. */ + if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG)) + { + nonew_unlink: + if (fd != -1) + { + // XXX Use /prof/self/fd/%d ??? + unlink (tmpfname); + if (newfd != -1) + close (newfd); + } + nonew: + error (0, errno, _("cannot create new file")); + status = 1; + goto errout; + } + + /* If the new archive is not empty we actually have something to do. */ + if (likely (all != NULL)) + { + /* Write the symbol table or the long file name table or both. */ + if (symtab.symsnamelen != 0 + && ((write_retry (newfd, symtab.symsoff, symtab.symsofflen) + != (ssize_t) symtab.symsofflen) + || (write_retry (newfd, symtab.symsname, symtab.symsnamelen) + != (ssize_t) symtab.symsnamelen))) + goto nonew_unlink; + + if (symtab.longnameslen > sizeof (struct ar_hdr) + && (write_retry (newfd, symtab.longnames, symtab.longnameslen) + != (ssize_t) symtab.longnameslen)) + goto nonew_unlink; + + off_t start = -1; + off_t len = -1; + + while (all != NULL) + { + if (all->mem != NULL) + { + /* This is a new file. If there is anything from the + archive left to be written do it now. */ + if (start != -1 && copy_content (elf, newfd, start, len)) + goto nonew_unlink; + + start = -1; + len = -1; + + /* Create the header. */ + struct ar_hdr arhdr; + /* The ar_name is not actually zero terminated, but we + need that for snprintf. Also if the name is too + long, then the string starts with '/' plus an index + off number (decimal). */ + char tmpbuf[sizeof (arhdr.ar_name) + 2]; + if (all->long_name_off == -1) + { + size_t namelen = strlen (all->name); + char *p = mempcpy (arhdr.ar_name, all->name, namelen); + *p++ = '/'; + memset (p, ' ', sizeof (arhdr.ar_name) - namelen - 1); + } + else + { + snprintf (tmpbuf, sizeof (tmpbuf), "/%-*ld", + (int) sizeof (arhdr.ar_name), all->long_name_off); + memcpy (arhdr.ar_name, tmpbuf, sizeof (arhdr.ar_name)); + } + + if (! no0print (false, arhdr.ar_date, sizeof (arhdr.ar_date), + all->sec)) + { + error (0, errno, _("cannot represent ar_date")); + goto nonew_unlink; + } + if (! no0print (false, arhdr.ar_uid, sizeof (arhdr.ar_uid), + all->uid)) + { + error (0, errno, _("cannot represent ar_uid")); + goto nonew_unlink; + } + if (! no0print (false, arhdr.ar_gid, sizeof (arhdr.ar_gid), + all->gid)) + { + error (0, errno, _("cannot represent ar_gid")); + goto nonew_unlink; + } + if (! no0print (true, arhdr.ar_mode, sizeof (arhdr.ar_mode), + all->mode)) + { + error (0, errno, _("cannot represent ar_mode")); + goto nonew_unlink; + } + if (! no0print (false, arhdr.ar_size, sizeof (arhdr.ar_size), + all->size)) + { + error (0, errno, _("cannot represent ar_size")); + goto nonew_unlink; + } + memcpy (arhdr.ar_fmag, ARFMAG, sizeof (arhdr.ar_fmag)); + + if (unlikely (write_retry (newfd, &arhdr, sizeof (arhdr)) + != sizeof (arhdr))) + goto nonew_unlink; + + /* Now the file itself. */ + if (unlikely (write_retry (newfd, all->mem, all->size) + != (off_t) all->size)) + goto nonew_unlink; + + /* Pad the file if its size is odd. */ + if ((all->size & 1) != 0) + if (unlikely (write_retry (newfd, "\n", 1) != 1)) + goto nonew_unlink; + } + else + { + /* This is a member from the archive. */ + if (write_member (all, &start, &len, elf, cur_off, newfd) + != 0) + goto nonew_unlink; + } + + all = all->next; + } + + /* Write the last part. */ + if (start != -1 && copy_content (elf, newfd, start, len)) + goto nonew_unlink; + } + + /* Set the mode of the new file to the same values the original file + has. */ + if (fd != -1) + { + /* Never complain about fchown failing. But do it before + setting the modes, or they might be reset/ignored if the + owner is wrong. */ + if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; } + if (fchmod (newfd, st.st_mode & ALLPERMS) != 0 + || close (newfd) != 0) + goto nonew_unlink; + newfd = -1; + if (rename (tmpfname, arfname) != 0) + goto nonew_unlink; + } + + errout: + for (int cnt = 0; cnt < argc; ++cnt) + elf_end (found[cnt]->elf); + + elf_end (elf); + + arlib_fini (); + + if (fd != -1) + close (fd); + + if (newfd != -1) + close (newfd); + + return status; +} + + +#include "debugpred.h" diff --git a/src/arlib-argp.c b/src/arlib-argp.c new file mode 100644 index 00000000..a3c12e4d --- /dev/null +++ b/src/arlib-argp.c @@ -0,0 +1,95 @@ +/* Options common to ar and ranlib. + Copyright (C) 2012 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "arlib.h" + +bool arlib_deterministic_output = DEFAULT_AR_DETERMINISTIC; + +static const struct argp_option options[] = + { + { NULL, 'D', NULL, 0, + N_("Use zero for uid, gid, and date in archive members."), 0 }, + { NULL, 'U', NULL, 0, + N_("Use actual uid, gid, and date in archive members."), 0 }, + + { NULL, 0, NULL, 0, NULL, 0 } + }; + +static error_t +parse_opt (int key, char *arg __attribute__ ((unused)), + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'D': + arlib_deterministic_output = true; + break; + + case 'U': + arlib_deterministic_output = false; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static char * +text_for_default (const char *text) +{ + char *new_text; + if (unlikely (asprintf (&new_text, _("%s (default)"), text) < 0)) + return (char *) text; + return new_text; +} + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case 'D': + if (DEFAULT_AR_DETERMINISTIC) + return text_for_default (text); + break; + case 'U': + if (! DEFAULT_AR_DETERMINISTIC) + return text_for_default (text); + break; + } + + return (char *) text; +} + +static const struct argp argp = + { + options, parse_opt, NULL, NULL, NULL, help_filter, NULL + }; + +const struct argp_child arlib_argp_children[] = + { + { &argp, 0, "", 2 }, + { NULL, 0, NULL, 0 } + }; diff --git a/src/arlib.c b/src/arlib.c new file mode 100644 index 00000000..a14c44d3 --- /dev/null +++ b/src/arlib.c @@ -0,0 +1,280 @@ +/* Functions to handle creation of Linux archives. + Copyright (C) 2007-2012, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "system.h" +#include "arlib.h" + + +/* The one symbol table we hanble. */ +struct arlib_symtab symtab; + + +/* Initialize ARLIB_SYMTAB structure. */ +void +arlib_init (void) +{ +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + obstack_init (&symtab.symsoffob); + obstack_init (&symtab.symsnameob); + obstack_init (&symtab.longnamesob); + + /* We add the archive header here as well, that avoids allocating + another memory block. */ + struct ar_hdr ar_hdr; + memcpy (ar_hdr.ar_name, "/ ", sizeof (ar_hdr.ar_name)); + /* Using snprintf here has a problem: the call always wants to add a + NUL byte. We could use a trick whereby we specify the target + buffer size longer than it is and this would not actually fail, + since all the fields are consecutive and we fill them in + sequence (i.e., the NUL byte gets overwritten). But + _FORTIFY_SOURCE=2 would not let us play these games. Therefore + we play it safe. */ + char tmpbuf[sizeof (ar_hdr.ar_date) + 1]; + int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld", + (int) sizeof (ar_hdr.ar_date), + (arlib_deterministic_output ? 0 + : (long long int) time (NULL))); + memcpy (ar_hdr.ar_date, tmpbuf, s); + assert ((sizeof (struct ar_hdr) % sizeof (uint32_t)) == 0); + + /* Note the string for the ar_uid and ar_gid cases is longer than + necessary. This does not matter since we copy only as much as + necessary but it helps the compiler to use the same string for + the ar_mode case. */ + memcpy (ar_hdr.ar_uid, "0 ", sizeof (ar_hdr.ar_uid)); + memcpy (ar_hdr.ar_gid, "0 ", sizeof (ar_hdr.ar_gid)); + memcpy (ar_hdr.ar_mode, "0 ", sizeof (ar_hdr.ar_mode)); + memcpy (ar_hdr.ar_fmag, ARFMAG, sizeof (ar_hdr.ar_fmag)); + + /* Add the archive header to the file content. */ + obstack_grow (&symtab.symsoffob, &ar_hdr, sizeof (ar_hdr)); + + /* The first word in the offset table specifies the size. Create + such an entry now. The real value will be filled-in later. For + all supported platforms the following is true. */ + assert (sizeof (uint32_t) == sizeof (int)); + obstack_int_grow (&symtab.symsoffob, 0); + + /* The long name obstack also gets its archive header. As above, + some of the input strings are longer than required but we only + copy the necessary part. */ + memcpy (ar_hdr.ar_name, "// ", sizeof (ar_hdr.ar_name)); + memcpy (ar_hdr.ar_date, " ", sizeof (ar_hdr.ar_date)); + memcpy (ar_hdr.ar_uid, " ", sizeof (ar_hdr.ar_uid)); + memcpy (ar_hdr.ar_gid, " ", sizeof (ar_hdr.ar_gid)); + memcpy (ar_hdr.ar_mode, " ", sizeof (ar_hdr.ar_mode)); + /* The ar_size field will be filled in later and ar_fmag is already OK. */ + obstack_grow (&symtab.longnamesob, &ar_hdr, sizeof (ar_hdr)); + + /* All other members are zero. */ + symtab.symsofflen = 0; + symtab.symsoff = NULL; + symtab.symsnamelen = 0; + symtab.symsname = NULL; +} + + +/* Finalize ARLIB_SYMTAB content. */ +void +arlib_finalize (void) +{ + /* Note that the size is stored as decimal string in 10 chars, + without zero terminator (we add + 1 here only so snprintf can + put it at the end, we then don't use it when we memcpy it). */ + char tmpbuf[sizeof (((struct ar_hdr *) NULL)->ar_size) + 1]; + + symtab.longnameslen = obstack_object_size (&symtab.longnamesob); + if (symtab.longnameslen != sizeof (struct ar_hdr)) + { + if ((symtab.longnameslen & 1) != 0) + { + /* Add one more byte to make length even. */ + obstack_grow (&symtab.longnamesob, "\n", 1); + ++symtab.longnameslen; + } + + symtab.longnames = obstack_finish (&symtab.longnamesob); + + int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "", + (int) sizeof (((struct ar_hdr *) NULL)->ar_size), + (uint32_t) (symtab.longnameslen - sizeof (struct ar_hdr))); + memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, s); + } + + symtab.symsofflen = obstack_object_size (&symtab.symsoffob); + assert (symtab.symsofflen % sizeof (uint32_t) == 0); + if (symtab.symsofflen != 0) + { + symtab.symsoff = (uint32_t *) obstack_finish (&symtab.symsoffob); + + /* Fill in the number of offsets now. */ + symtab.symsoff[AR_HDR_WORDS] = le_bswap_32 ((symtab.symsofflen + - sizeof (struct ar_hdr)) + / sizeof (uint32_t) - 1); + } + + symtab.symsnamelen = obstack_object_size (&symtab.symsnameob); + if ((symtab.symsnamelen & 1) != 0) + { + /* Add one more NUL byte to make length even. */ + obstack_grow (&symtab.symsnameob, "", 1); + ++symtab.symsnamelen; + } + symtab.symsname = obstack_finish (&symtab.symsnameob); + + /* Determine correction for the offsets in the symbol table. */ + off_t disp = 0; + if (symtab.symsnamelen > 0) + disp = symtab.symsofflen + symtab.symsnamelen; + if (symtab.longnameslen > sizeof (struct ar_hdr)) + disp += symtab.longnameslen; + + if (disp != 0 && symtab.symsoff != NULL) + { + uint32_t nsyms = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS]); + + for (uint32_t cnt = 1; cnt <= nsyms; ++cnt) + { + uint32_t val = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS + cnt]); + val += disp; + symtab.symsoff[AR_HDR_WORDS + cnt] = le_bswap_32 (val); + } + } + + /* See comment for ar_date above. */ + memcpy (&((struct ar_hdr *) symtab.symsoff)->ar_size, tmpbuf, + snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "", + (int) sizeof (((struct ar_hdr *) NULL)->ar_size), + (uint32_t) (symtab.symsofflen + symtab.symsnamelen + - sizeof (struct ar_hdr)))); +} + + +/* Free resources for ARLIB_SYMTAB. */ +void +arlib_fini (void) +{ + obstack_free (&symtab.symsoffob, NULL); + obstack_free (&symtab.symsnameob, NULL); + obstack_free (&symtab.longnamesob, NULL); +} + + +/* Add name a file offset of a symbol. */ +void +arlib_add_symref (const char *symname, off_t symoff) +{ + /* For all supported platforms the following is true. */ + assert (sizeof (uint32_t) == sizeof (int)); + obstack_int_grow (&symtab.symsoffob, (int) le_bswap_32 (symoff)); + + size_t symname_len = strlen (symname) + 1; + obstack_grow (&symtab.symsnameob, symname, symname_len); +} + + +/* Add symbols from ELF with value OFFSET to the symbol table SYMTAB. */ +void +arlib_add_symbols (Elf *elf, const char *arfname, const char *membername, + off_t off) +{ + if (sizeof (off) > sizeof (uint32_t) && off > ~((uint32_t) 0)) + /* The archive is too big. */ + error (EXIT_FAILURE, 0, _("the archive '%s' is too large"), + arfname); + + /* We only add symbol tables for ELF files. It makes not much sense + to add symbols from executables but we do so for compatibility. + For DSOs and executables we use the dynamic symbol table, for + relocatable files all the DT_SYMTAB tables. */ + if (elf_kind (elf) != ELF_K_ELF) + return; + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + error (EXIT_FAILURE, 0, _("cannot read ELF header of %s(%s): %s"), + arfname, membername, elf_errmsg (-1)); + + GElf_Word symtype; + if (ehdr->e_type == ET_REL) + symtype = SHT_SYMTAB; + else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) + symtype = SHT_DYNSYM; + else + /* We do not handle that type. */ + return; + + /* Iterate over all sections. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + /* Get the section header. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + continue; + + if (shdr->sh_type != symtype) + continue; + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + continue; + + if (shdr->sh_entsize == 0) + continue; + + int nsyms = shdr->sh_size / shdr->sh_entsize; + for (int ndx = shdr->sh_info; ndx < nsyms; ++ndx) + { + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (data, ndx, &sym_mem); + if (sym == NULL) + continue; + + /* Ignore undefined symbols. */ + if (sym->st_shndx == SHN_UNDEF) + continue; + + /* Use this symbol. */ + const char *symname = elf_strptr (elf, shdr->sh_link, sym->st_name); + if (symname != NULL) + arlib_add_symref (symname, off); + } + + /* Only relocatable files can have more than one symbol table. */ + if (ehdr->e_type != ET_REL) + break; + } +} diff --git a/src/arlib.h b/src/arlib.h new file mode 100644 index 00000000..e117166e --- /dev/null +++ b/src/arlib.h @@ -0,0 +1,98 @@ +/* Copyright (C) 2007-2012 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifndef _ARLIB_H +#define _ARLIB_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* State of -D/-U flags. */ +extern bool arlib_deterministic_output; + +/* For options common to ar and ranlib. */ +extern const struct argp_child arlib_argp_children[]; + + +/* Maximum length of a file name that fits directly into the ar header. + We cannot use the final byte since a / goes there. */ +#define MAX_AR_NAME_LEN (sizeof (((struct ar_hdr *) NULL)->ar_name) - 1) + + +/* Words matching in size to archive header. */ +#define AR_HDR_WORDS (sizeof (struct ar_hdr) / sizeof (uint32_t)) + + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define le_bswap_32(val) bswap_32 (val) +#else +# define le_bswap_32(val) (val) +#endif + + +/* Symbol table type. */ +struct arlib_symtab +{ + /* Symbol table handling. */ + struct obstack symsoffob; + struct obstack symsnameob; + size_t symsofflen; + uint32_t *symsoff; + size_t symsnamelen; + char *symsname; + + /* Long filename handling. */ + struct obstack longnamesob; + size_t longnameslen; + char *longnames; +}; + + +/* Global variable with symbol table. */ +extern struct arlib_symtab symtab; + + +/* Initialize ARLIB_SYMTAB structure. */ +extern void arlib_init (void); + +/* Finalize ARLIB_SYMTAB content. */ +extern void arlib_finalize (void); + +/* Free resources for ARLIB_SYMTAB. */ +extern void arlib_fini (void); + +/* Add symbols from ELF with value OFFSET to the symbol table SYMTAB. */ +extern void arlib_add_symbols (Elf *elf, const char *arfname, + const char *membername, off_t off); + +/* Add name a file offset of a symbol. */ +extern void arlib_add_symref (const char *symname, off_t symoff); + +/* Add long file name FILENAME of length FILENAMELEN to the symbol table + SYMTAB. Return the offset into the long file name table. */ +extern long int arlib_add_long_name (const char *filename, size_t filenamelen); + +#endif /* arlib.h */ diff --git a/src/arlib2.c b/src/arlib2.c new file mode 100644 index 00000000..11f44e5d --- /dev/null +++ b/src/arlib2.c @@ -0,0 +1,41 @@ +/* Functions to handle creation of Linux archives. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "arlib.h" + + +/* Add long file name FILENAME of length FILENAMELEN to the symbol table + SYMTAB. Return the offset into the long file name table. */ +long int +arlib_add_long_name (const char *filename, size_t filenamelen) +{ + size_t size = obstack_object_size (&symtab.longnamesob); + + obstack_grow (&symtab.longnamesob, filename, filenamelen); + obstack_grow (&symtab.longnamesob, "/\n", 2); + + return size - sizeof (struct ar_hdr); +} diff --git a/src/debugpred.h b/src/debugpred.h new file mode 100644 index 00000000..4845a6e2 --- /dev/null +++ b/src/debugpred.h @@ -0,0 +1,45 @@ +/* Support to debug branch prediction. + Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2007. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include + +#if DEBUGPRED +extern const unsigned long int __start_predict_data; +extern const unsigned long int __stop_predict_data; +extern const unsigned long int __start_predict_line; +extern const char *const __start_predict_file; + +static void +__attribute__ ((destructor)) +predprint (void) +{ + const unsigned long int *s = &__start_predict_data; + const unsigned long int *e = &__stop_predict_data; + const unsigned long int *sl = &__start_predict_line; + const char *const *sf = &__start_predict_file; + while (s < e) + { + if (s[0] != 0 || s[1] != 0) + printf ("%s:%lu: wrong=%lu, correct=%lu%s\n", *sf, *sl, s[0], s[1], + s[0] > s[1] ? " <==== WARNING" : ""); + ++sl; + ++sf; + s += 2; + } +} +#endif diff --git a/src/elfclassify.c b/src/elfclassify.c new file mode 100644 index 00000000..fe7eeeed --- /dev/null +++ b/src/elfclassify.c @@ -0,0 +1,1045 @@ +/* Classification of ELF files. + Copyright (C) 2019 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include ELFUTILS_HEADER(elf) +#include ELFUTILS_HEADER(dwelf) +#include "printversion.h" + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Set by parse_opt. */ +static int verbose; + +/* Set by the main function. */ +static const char *current_path; + +/* Set by open_file. */ +static int file_fd = -1; + +/* Set by issue or elf_issue. */ +static bool issue_found; + +/* Non-fatal issue occurred while processing the current_path. */ +static void +issue (int e, const char *msg) +{ + if (verbose >= 0) + { + if (current_path == NULL) + error (0, e, "%s", msg); + else + error (0, e, "%s '%s'", msg, current_path); + } + issue_found = true; +} + +/* Non-fatal issue occurred while processing the current ELF. */ +static void +elf_issue (const char *msg) +{ + if (verbose >= 0) + error (0, 0, "%s: %s: '%s'", msg, elf_errmsg (-1), current_path); + issue_found = true; +} + +/* Set by parse_opt. */ +static bool flag_only_regular_files; + +static bool +open_file (void) +{ + if (verbose > 1) + fprintf (stderr, "debug: processing file: %s\n", current_path); + + file_fd = open (current_path, O_RDONLY | (flag_only_regular_files + ? O_NOFOLLOW : 0)); + if (file_fd < 0) + { + if (!flag_only_regular_files || errno != ELOOP) + issue (errno, N_("opening")); + return false; + } + + struct stat st; + if (fstat (file_fd, &st) != 0) + { + issue (errno, N_("reading")); + return false; + } + + /* Don't even bother with directories. */ + if (S_ISDIR (st.st_mode) + || (flag_only_regular_files && !S_ISREG (st.st_mode))) + return false; + + return true; +} + +static void +close_file (void) +{ + if (file_fd >= 0) + { + close (file_fd); + file_fd = -1; + } +} + +/* Set by open_elf. */ +static Elf *elf; + +/* Set by parse_opt. */ +static bool flag_compressed; + +static bool +open_elf (void) +{ + if (!open_file ()) + { + /* Make sure the file descriptor is gone. */ + close_file (); + return false; + } + + if (flag_compressed) + elf = dwelf_elf_begin (file_fd); + else + elf = elf_begin (file_fd, ELF_C_READ, NULL); + + if (elf == NULL) + { + elf_issue ("opening ELF file"); + close_file (); + return false; + } + + return true; +} + +static void +close_elf (void) +{ + if (elf != NULL) + { + elf_end (elf); + elf = NULL; + } + + close_file (); +} + +static const char * +elf_kind_string (int kind) +{ + switch (kind) + { + case ELF_K_NONE: + return "ELF_K_NONE"; + case ELF_K_AR: + return "ELF_K_AR"; + case ELF_K_COFF: + return "ELF_K_COFF"; /* libelf doesn't really support this. */ + case ELF_K_ELF: + return "ELF_K_ELF"; + default: + return ""; + } +} + +static const char * +elf_type_string (int type) +{ + switch (type) + { + case ET_NONE: + return "ET_NONE"; + case ET_REL: + return "ET_REL"; + case ET_EXEC: + return "ET_EXEC"; + case ET_DYN: + return "ET_DYN"; + case ET_CORE: + return "ET_CORE"; + default: + return ""; + } +} + +static int elf_type; +static bool has_program_load; +static bool has_sections; +static bool has_bits_alloc; +static bool has_program_interpreter; +static bool has_dynamic; +static bool has_soname; +static bool has_pie_flag; +static bool has_dt_debug; +static bool has_symtab; +static bool has_debug_sections; +static bool has_modinfo; +static bool has_gnu_linkonce_this_module; + +static bool +run_classify (void) +{ + /* Reset to unanalyzed default. */ + elf_type = 0; + has_program_load = false; + has_sections = false; + has_bits_alloc = false; + has_program_interpreter = false; + has_dynamic = false; + has_soname = false; + has_pie_flag = false; + has_dt_debug = false; + has_symtab = false; + has_debug_sections = false; + has_modinfo = false; + has_gnu_linkonce_this_module = false; + + int kind = elf_kind (elf); + if (verbose > 0) + fprintf (stderr, "info: %s: ELF kind: %s (0x%x)\n", current_path, + elf_kind_string (kind), kind); + if (kind != ELF_K_ELF) + return true; + + GElf_Ehdr ehdr_storage; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_storage); + if (ehdr == NULL) + { + elf_issue (N_("ELF header")); + return false; + } + elf_type = ehdr->e_type; + + /* Examine program headers. */ + GElf_Phdr dyn_seg = { .p_type = 0 }; + { + size_t nphdrs; + if (elf_getphdrnum (elf, &nphdrs) != 0) + { + elf_issue (N_("program headers")); + return false; + } + for (size_t phdr_idx = 0; phdr_idx < nphdrs; ++phdr_idx) + { + GElf_Phdr phdr_storage; + GElf_Phdr *phdr = gelf_getphdr (elf, phdr_idx, &phdr_storage); + if (phdr == NULL) + { + elf_issue (N_("program header")); + return false; + } + if (phdr->p_type == PT_DYNAMIC) + { + dyn_seg = *phdr; + has_dynamic = true; + } + if (phdr->p_type == PT_INTERP) + has_program_interpreter = true; + if (phdr->p_type == PT_LOAD) + has_program_load = true; + } + } + + /* Do we have sections? */ + { + size_t nshdrs; + if (elf_getshdrnum (elf, &nshdrs) != 0) + { + elf_issue (N_("section headers")); + return false; + } + if (nshdrs > 0) + has_sections = true; + } + + { + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0)) + { + elf_issue (N_("section header string table index")); + return false; + } + + Elf_Scn *scn = NULL; + while (true) + { + scn = elf_nextscn (elf, scn); + if (scn == NULL) + break; + GElf_Shdr shdr_storage; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_storage); + if (shdr == NULL) + { + elf_issue (N_("could not obtain section header")); + return false; + } + const char *section_name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (section_name == NULL) + { + elf_issue(N_("could not obtain section name")); + return false; + } + if (verbose > 2) + fprintf (stderr, "debug: section header %s (type %d) found\n", + section_name, shdr->sh_type); + if (shdr->sh_type == SHT_SYMTAB) + { + if (verbose > 1) + fputs ("debug: symtab section found\n", stderr); + has_symtab = true; + } + /* NOBITS and NOTE sections can be in any file. We want to be + sure there is at least one other allocated section. */ + if (shdr->sh_type != SHT_NOBITS + && shdr->sh_type != SHT_NOTE + && (shdr->sh_flags & SHF_ALLOC) != 0) + { + if (verbose > 1 && !has_bits_alloc) + fputs ("debug: allocated (non-nobits/note) section found\n", + stderr); + has_bits_alloc = true; + } + if (startswith (section_name, ".debug_") + || startswith (section_name, ".zdebug_")) + { + if (verbose > 1 && !has_debug_sections) + fputs ("debug: .debug_* section found\n", stderr); + has_debug_sections = true; + } + if (strcmp (section_name, ".modinfo") == 0) + { + if (verbose > 1) + fputs ("debug: .modinfo section found\n", stderr); + has_modinfo = true; + } + if (strcmp (section_name, ".gnu.linkonce.this_module") == 0) + { + if (verbose > 1) + fputs ("debug: .gnu.linkonce.this_module section found\n", + stderr); + has_gnu_linkonce_this_module = true; + } + } + } + + /* Examine the dynamic section. */ + if (has_dynamic) + { + Elf_Data *data = elf_getdata_rawchunk (elf, dyn_seg.p_offset, + dyn_seg.p_filesz, + ELF_T_DYN); + if (data != NULL) + for (int dyn_idx = 0; ; ++dyn_idx) + { + GElf_Dyn dyn_storage; + GElf_Dyn *dyn = gelf_getdyn (data, dyn_idx, &dyn_storage); + if (dyn == NULL) + break; + if (verbose > 2) + fprintf (stderr, "debug: dynamic entry %d" + " with tag %llu found\n", + dyn_idx, (unsigned long long int) dyn->d_tag); + if (dyn->d_tag == DT_SONAME) + has_soname = true; + if (dyn->d_tag == DT_FLAGS_1 && (dyn->d_un.d_val & DF_1_PIE)) + has_pie_flag = true; + if (dyn->d_tag == DT_DEBUG) + has_dt_debug = true; + if (dyn->d_tag == DT_NULL) + break; + } + } + + if (verbose > 0) + { + fprintf (stderr, "info: %s: ELF type: %s (0x%x)\n", current_path, + elf_type_string (elf_type), elf_type); + if (has_program_load) + fprintf (stderr, "info: %s: PT_LOAD found\n", current_path); + if (has_sections) + fprintf (stderr, "info: %s: has sections\n", current_path); + if (has_bits_alloc) + fprintf (stderr, "info: %s: allocated (real) section found\n", + current_path); + if (has_program_interpreter) + fprintf (stderr, "info: %s: program interpreter found\n", + current_path); + if (has_dynamic) + fprintf (stderr, "info: %s: dynamic segment found\n", current_path); + if (has_soname) + fprintf (stderr, "info: %s: soname found\n", current_path); + if (has_pie_flag) + fprintf (stderr, "info: %s: DF_1_PIE flag found\n", current_path); + if (has_dt_debug) + fprintf (stderr, "info: %s: DT_DEBUG found\n", current_path); + if (has_symtab) + fprintf (stderr, "info: %s: symbol table found\n", current_path); + if (has_debug_sections) + fprintf (stderr, "info: %s: .debug_* section found\n", current_path); + if (has_modinfo) + fprintf (stderr, "info: %s: .modinfo section found\n", current_path); + if (has_gnu_linkonce_this_module) + fprintf (stderr, + "info: %s: .gnu.linkonce.this_module section found\n", + current_path); + } + + return true; +} + +static bool +is_elf (void) +{ + return elf_kind (elf) != ELF_K_NONE; +} + +static bool +is_elf_file (void) +{ + return elf_kind (elf) == ELF_K_ELF; +} + +static bool +is_elf_archive (void) +{ + return elf_kind (elf) == ELF_K_AR; +} + +static bool +is_core (void) +{ + return elf_kind (elf) == ELF_K_ELF && elf_type == ET_CORE; +} + +/* Return true if the file is a loadable object, which basically means + it is an ELF file, but not a relocatable object or a core dump + file. (The kernel and various userspace components can load ET_REL + files, but we disregard that for our classification purposes.) */ +static bool +is_loadable (void) +{ + return elf_kind (elf) == ELF_K_ELF + && (elf_type == ET_EXEC || elf_type == ET_DYN) + && has_program_load + && (!has_sections || has_bits_alloc); /* It isn't debug-only. */ +} + +/* Return true if the file is an ELF file which has a symbol table or + .debug_* sections (and thus can be stripped further). */ +static bool +is_unstripped (void) +{ + return elf_kind (elf) != ELF_K_NONE + && (elf_type == ET_REL || elf_type == ET_EXEC || elf_type == ET_DYN) + && (has_symtab || has_debug_sections); +} + +/* Return true if the file contains only debuginfo, but no loadable + program bits. Then it is most likely a separate .debug file, a dwz + multi-file or a .dwo file. Note that it can still be loadable, + but in that case the phdrs shouldn't be trusted. */ +static bool +is_debug_only (void) +{ + return elf_kind (elf) != ELF_K_NONE + && (elf_type == ET_REL || elf_type == ET_EXEC || elf_type == ET_DYN) + && (has_debug_sections || has_symtab) + && !has_bits_alloc; +} + +static bool +is_shared (void) +{ + if (!is_loadable ()) + return false; + + /* The ELF type is very clear: this is an executable. */ + if (elf_type == ET_EXEC) + return false; + + /* If there is no dynamic section, the file cannot be loaded as a + shared object. */ + if (!has_dynamic) + return false; + + /* If the object is marked as PIE, it is definitely an executable, + and not a loadlable shared object. */ + if (has_pie_flag) + return false; + + /* Treat a DT_SONAME tag as a strong indicator that this is a shared + object. */ + if (has_soname) + return true; + + /* This is probably a PIE program: there is no soname, but a program + interpreter. In theory, this file could be also a DSO with a + soname implied by its file name that can be run as a program. + This situation is impossible to resolve in the general case. */ + if (has_program_interpreter) + return false; + + /* Roland McGrath mentions in + , + that “we defined a PIE as an ET_DYN with a DT_DEBUG”. This + matches current binutils behavior (version 2.32). DT_DEBUG is + added if bfd_link_executable returns true or if bfd_link_pic + returns false, depending on the architectures. However, DT_DEBUG + is not documented as being specific to executables, therefore use + it only as a low-priority discriminator. */ + if (has_dt_debug) + return false; + + return true; +} + +static bool +is_executable (void) +{ + if (!is_loadable ()) + return false; + + /* A loadable object which is not a shared object is treated as an + executable. */ + return !is_shared (); +} + +/* Like is_executable, but the object can also be a shared library at + the same time. */ +static bool +is_program (void) +{ + if (!is_loadable ()) + return false; + + /* The ELF type is very clear: this is an executable. */ + if (elf_type == ET_EXEC) + return true; + + /* If the object is marked as PIE, it is definitely an executable, + and not a loadlable shared object. */ + if (has_pie_flag) + return true; + + /* This is probably a PIE program. It isn't ET_EXEC, but has a + program interpreter. In theory, this file could be also a DSO + with a soname. This situation is impossible to resolve in the + general case. See is_shared. This is different from + is_executable. */ + if (has_program_interpreter) + return true; + + /* Roland McGrath mentions in + , + that “we defined a PIE as an ET_DYN with a DT_DEBUG”. This + matches current binutils behavior (version 2.32). DT_DEBUG is + added if bfd_link_executable returns true or if bfd_link_pic + returns false, depending on the architectures. However, DT_DEBUG + is not documented as being specific to executables, therefore use + it only as a low-priority discriminator. */ + if (has_dt_debug) + return true; + + return false; +} + +/* Like is_shared but the library could also be an executable. */ +static bool +is_library (void) +{ + /* Only ET_DYN can be shared libraries. */ + if (elf_type != ET_DYN) + return false; + + if (!is_loadable ()) + return false; + + /* Without a PT_DYNAMIC segment the library cannot be loaded. */ + if (!has_dynamic) + return false; + + /* This really is a (PIE) executable. See is_shared. */ + if (has_pie_flag || has_dt_debug) + return false; + + /* It could still (also) be a (PIE) executable, but most likely you + can dlopen it just fine. */ + return true; +} + +/* Returns true if the file is a linux kernel module (is ET_REL and + has the two magic sections .modinfo and .gnu.linkonce.this_module). */ +static bool +is_linux_kernel_module (void) +{ + return (elf_kind (elf) == ELF_K_ELF + && elf_type == ET_REL + && has_modinfo + && has_gnu_linkonce_this_module); +} + +enum classify_requirement { do_not_care, required, forbidden }; + +enum classify_check +{ + classify_elf, + classify_elf_file, + classify_elf_archive, + classify_core, + classify_unstripped, + classify_executable, + classify_program, + classify_shared, + classify_library, + classify_linux_kernel_module, + classify_debug_only, + classify_loadable, + + classify_check_last = classify_loadable +}; + +enum +{ + classify_check_offset = 1000, + classify_check_not_offset = 2000, + + classify_flag_stdin = 3000, + classify_flag_stdin0, + classify_flag_no_stdin, + classify_flag_print, + classify_flag_print0, + classify_flag_no_print, + classify_flag_matching, + classify_flag_not_matching, +}; + +static bool +classify_check_positive (int key) +{ + return key >= classify_check_offset + && key <= classify_check_offset + classify_check_last; +} + +static bool +classify_check_negative (int key) +{ + return key >= classify_check_not_offset + && key <= classify_check_not_offset + classify_check_last; +} + +/* Set by parse_opt. */ +static enum classify_requirement requirements[classify_check_last + 1]; +static enum { no_stdin, do_stdin, do_stdin0 } flag_stdin; +static enum { no_print, do_print, do_print0 } flag_print; +static bool flag_print_matching = true; + +static error_t +parse_opt (int key, char *arg __attribute__ ((unused)), + struct argp_state *state __attribute__ ((unused))) +{ + if (classify_check_positive (key)) + requirements[key - classify_check_offset] = required; + else if (classify_check_negative (key)) + requirements[key - classify_check_not_offset] = forbidden; + else + switch (key) + { + case 'v': + ++verbose; + break; + + case 'q': + --verbose; + break; + + case 'z': + flag_compressed = true; + break; + + case 'f': + flag_only_regular_files = true; + break; + + case classify_flag_stdin: + flag_stdin = do_stdin; + break; + + case classify_flag_stdin0: + flag_stdin = do_stdin0; + break; + + case classify_flag_no_stdin: + flag_stdin = no_stdin; + break; + + case classify_flag_print: + flag_print = do_print; + break; + + case classify_flag_print0: + flag_print = do_print0; + break; + + case classify_flag_no_print: + flag_print = no_print; + break; + + case classify_flag_matching: + flag_print_matching = true; + break; + + case classify_flag_not_matching: + flag_print_matching = false; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +/* Perform requested checks against the file at current_path. If + necessary, sets *STATUS to 1 if checks failed. */ +static void +process_current_path (int *status) +{ + bool checks_passed = true; + + if (open_elf () && run_classify ()) + { + bool checks[] = + { + [classify_elf] = is_elf (), + [classify_elf_file] = is_elf_file (), + [classify_elf_archive] = is_elf_archive (), + [classify_core] = is_core (), + [classify_unstripped] = is_unstripped (), + [classify_executable] = is_executable (), + [classify_program] = is_program (), + [classify_shared] = is_shared (), + [classify_library] = is_library (), + [classify_linux_kernel_module] = is_linux_kernel_module (), + [classify_debug_only] = is_debug_only (), + [classify_loadable] = is_loadable (), + }; + + if (verbose > 1) + { + if (checks[classify_elf]) + fprintf (stderr, "debug: %s: elf\n", current_path); + if (checks[classify_elf_file]) + fprintf (stderr, "debug: %s: elf_file\n", current_path); + if (checks[classify_elf_archive]) + fprintf (stderr, "debug: %s: elf_archive\n", current_path); + if (checks[classify_core]) + fprintf (stderr, "debug: %s: core\n", current_path); + if (checks[classify_unstripped]) + fprintf (stderr, "debug: %s: unstripped\n", current_path); + if (checks[classify_executable]) + fprintf (stderr, "debug: %s: executable\n", current_path); + if (checks[classify_program]) + fprintf (stderr, "debug: %s: program\n", current_path); + if (checks[classify_shared]) + fprintf (stderr, "debug: %s: shared\n", current_path); + if (checks[classify_library]) + fprintf (stderr, "debug: %s: library\n", current_path); + if (checks[classify_linux_kernel_module]) + fprintf (stderr, "debug: %s: linux kernel module\n", current_path); + if (checks[classify_debug_only]) + fprintf (stderr, "debug: %s: debug-only\n", current_path); + if (checks[classify_loadable]) + fprintf (stderr, "debug: %s: loadable\n", current_path); + } + + for (enum classify_check check = 0; + check <= classify_check_last; ++check) + switch (requirements[check]) + { + case required: + if (!checks[check]) + checks_passed = false; + break; + case forbidden: + if (checks[check]) + checks_passed = false; + break; + case do_not_care: + break; + } + } + else if (file_fd == -1) + checks_passed = false; /* There is nothing to check, bad file. */ + else + { + for (enum classify_check check = 0; + check <= classify_check_last; ++check) + if (requirements[check] == required) + checks_passed = false; + } + + close_elf (); + + switch (flag_print) + { + case do_print: + if (checks_passed == flag_print_matching) + puts (current_path); + break; + case do_print0: + if (checks_passed == flag_print_matching) + if (fwrite (current_path, strlen (current_path) + 1, 1, stdout) < 1) + issue (errno, N_("writing to standard output")); + break; + case no_print: + if (!checks_passed) + *status = 1; + break; + } +} + +/* Called to process standard input if flag_stdin is not no_stdin. */ +static void +process_stdin (int *status) +{ + char delim; + if (flag_stdin == do_stdin0) + delim = '\0'; + else + delim = '\n'; + + char *buffer = NULL; + size_t buffer_size = 0; + while (true) + { + ssize_t ret = getdelim (&buffer, &buffer_size, delim, stdin); + if (ferror (stdin)) + { + current_path = NULL; + issue (errno, N_("reading from standard input")); + break; + } + if (feof (stdin)) + break; + if (ret < 0) + abort (); /* Cannot happen due to error checks above. */ + if (delim != '\0' && ret > 0 && buffer[ret - 1] == '\n') + buffer[ret - 1] = '\0'; + current_path = buffer; + process_current_path (status); + } + + free (buffer); +} + +int +main (int argc, char **argv) +{ + const struct argp_option options[] = + { + { NULL, 0, NULL, OPTION_DOC, N_("Classification options"), 1 }, + { "elf", classify_check_offset + classify_elf, NULL, 0, + N_("File looks like an ELF object or archive/static library (default)") + , 1 }, + { "elf-file", classify_check_offset + classify_elf_file, NULL, 0, + N_("File is an regular ELF object (not an archive/static library)") + , 1 }, + { "elf-archive", classify_check_offset + classify_elf_archive, NULL, 0, + N_("File is an ELF archive or static library") + , 1 }, + { "core", classify_check_offset + classify_core, NULL, 0, + N_("File is an ELF core dump file") + , 1 }, + { "unstripped", classify_check_offset + classify_unstripped, NULL, 0, + N_("File is an ELF file with symbol table or .debug_* sections \ +and can be stripped further"), 1 }, + { "executable", classify_check_offset + classify_executable, NULL, 0, + N_("File is (primarily) an ELF program executable \ +(not primarily a DSO)"), 1 }, + { "program", classify_check_offset + classify_program, NULL, 0, + N_("File is an ELF program executable \ +(might also be a DSO)"), 1 }, + { "shared", classify_check_offset + classify_shared, NULL, 0, + N_("File is (primarily) an ELF shared object (DSO) \ +(not primarily an executable)"), 1 }, + { "library", classify_check_offset + classify_library, NULL, 0, + N_("File is an ELF shared object (DSO) \ +(might also be an executable)"), 1 }, + { "linux-kernel-module", (classify_check_offset + + classify_linux_kernel_module), NULL, 0, + N_("File is a linux kernel module"), 1 }, + { "debug-only", (classify_check_offset + classify_debug_only), NULL, 0, + N_("File is a debug only ELF file \ +(separate .debug, .dwo or dwz multi-file)"), 1 }, + { "loadable", classify_check_offset + classify_loadable, NULL, 0, + N_("File is a loadable ELF object (program or shared object)"), 1 }, + + /* Negated versions of the above. */ + { "not-elf", classify_check_not_offset + classify_elf, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-elf-file", classify_check_not_offset + classify_elf_file, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-elf-archive", classify_check_not_offset + classify_elf_archive, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-core", classify_check_not_offset + classify_core, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-unstripped", classify_check_not_offset + classify_unstripped, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-executable", classify_check_not_offset + classify_executable, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-program", classify_check_not_offset + classify_program, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-shared", classify_check_not_offset + classify_shared, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-library", classify_check_not_offset + classify_library, + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-linux-kernel-module", (classify_check_not_offset + + classify_linux_kernel_module), + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-debug-only", (classify_check_not_offset + classify_debug_only), + NULL, OPTION_HIDDEN, NULL, 1 }, + { "not-loadable", classify_check_not_offset + classify_loadable, + NULL, OPTION_HIDDEN, NULL, 1 }, + + { NULL, 0, NULL, OPTION_DOC, N_("Input flags"), 2 }, + { "file", 'f', NULL, 0, + N_("Only classify regular (not symlink nor special device) files"), 2 }, + { "stdin", classify_flag_stdin, NULL, 0, + N_("Also read file names to process from standard input, \ +separated by newlines"), 2 }, + { "stdin0", classify_flag_stdin0, NULL, 0, + N_("Also read file names to process from standard input, \ +separated by ASCII NUL bytes"), 2 }, + { "no-stdin", classify_flag_stdin, NULL, 0, + N_("Do not read files from standard input (default)"), 2 }, + { "compressed", 'z', NULL, 0, + N_("Try to open compressed files or embedded (kernel) ELF images"), + 2 }, + + { NULL, 0, NULL, OPTION_DOC, N_("Output flags"), 3 }, + { "print", classify_flag_print, NULL, 0, + N_("Output names of files, separated by newline"), 3 }, + { "print0", classify_flag_print0, NULL, 0, + N_("Output names of files, separated by ASCII NUL"), 3 }, + { "no-print", classify_flag_no_print, NULL, 0, + N_("Do not output file names"), 3 }, + { "matching", classify_flag_matching, NULL, 0, + N_("If printing file names, print matching files (default)"), 3 }, + { "not-matching", classify_flag_not_matching, NULL, 0, + N_("If printing file names, print files that do not match"), 3 }, + + { NULL, 0, NULL, OPTION_DOC, N_("Additional flags"), 4 }, + { "verbose", 'v', NULL, 0, + N_("Output additional information (can be specified multiple times)"), 4 }, + { "quiet", 'q', NULL, 0, + N_("Suppress some error output (counterpart to --verbose)"), 4 }, + { NULL, 0, NULL, 0, NULL, 0 } + }; + + const struct argp argp = + { + .options = options, + .parser = parse_opt, + .args_doc = N_("FILE..."), + .doc = N_("\ +Determine the type of an ELF file.\ +\n\n\ +All of the classification options must apply at the same time to a \ +particular file. Classification options can be negated using a \ +\"--not-\" prefix.\ +\n\n\ +Since modern ELF does not clearly distinguish between programs and \ +dynamic shared objects, you should normally use either --executable or \ +--shared to identify the primary purpose of a file. \ +Only one of the --shared and --executable checks can pass for a file.\ +\n\n\ +If you want to know whether an ELF object might a program or a \ +shared library (but could be both), then use --program or --library. \ +Some ELF files will classify as both a program and a library.\ +\n\n\ +If you just want to know whether an ELF file is loadable (as program \ +or library) use --loadable. Note that files that only contain \ +(separate) debug information (--debug-only) are never --loadable (even \ +though they might contain program headers). Linux kernel modules are \ +also not --loadable (in the normal sense).\ +\n\n\ +Without any of the --print options, the program exits with status 0 \ +if the requested checks pass for all input files, with 1 if a check \ +fails for any file, and 2 if there is an environmental issue (such \ +as a file read error or a memory allocation error).\ +\n\n\ +When printing file names, the program exits with status 0 even if \ +no file names are printed, and exits with status 2 if there is an \ +environmental issue.\ +\n\n\ +On usage error (e.g. a bad option was given), the program exits with \ +a status code larger than 2.\ +\n\n\ +The --quiet or -q option suppresses some error warning output, but \ +doesn't change the exit status.\ +") + }; + + /* Require that the file is an ELF file by default. User can + disable with --not-elf. */ + requirements[classify_elf] = required; + + int remaining; + if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0) + return 2; + + elf_version (EV_CURRENT); + + int status = 0; + + for (int i = remaining; i < argc; ++i) + { + current_path = argv[i]; + process_current_path (&status); + } + + if (flag_stdin != no_stdin) + process_stdin (&status); + + if (issue_found) + return 2; + + return status; +} diff --git a/src/elfcmp.c b/src/elfcmp.c new file mode 100644 index 00000000..21d8d9dc --- /dev/null +++ b/src/elfcmp.c @@ -0,0 +1,911 @@ +/* Compare relevant content of two ELF files. + Copyright (C) 2005-2012, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../libelf/elf-knowledge.h" +#include "../libebl/libeblP.h" +#include "system.h" + +/* Prototypes of local functions. */ +static Elf *open_file (const char *fname, int *fdp, Ebl **eblp); +static bool search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx); +static int regioncompare (const void *p1, const void *p2); + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Values for the parameters which have no short form. */ +#define OPT_GAPS 0x100 +#define OPT_HASH_INEXACT 0x101 +#define OPT_IGNORE_BUILD_ID 0x102 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Control options:"), 0 }, + { "verbose", 'l', NULL, 0, + N_("Output all differences, not just the first"), 0 }, + { "gaps", OPT_GAPS, "ACTION", 0, N_("Control treatment of gaps in loadable segments [ignore|match] (default: ignore)"), 0 }, + { "hash-inexact", OPT_HASH_INEXACT, NULL, 0, + N_("Ignore permutation of buckets in SHT_HASH section"), 0 }, + { "ignore-build-id", OPT_IGNORE_BUILD_ID, NULL, 0, + N_("Ignore differences in build ID"), 0 }, + { "quiet", 'q', NULL, 0, N_("Output nothing; yield exit status only"), 0 }, + + { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Compare relevant parts of two ELF files for equality."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("FILE1 FILE2"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + + +/* How to treat gaps in loadable segments. */ +static enum + { + gaps_ignore = 0, + gaps_match + } + gaps; + +/* Structure to hold information about used regions. */ +struct region +{ + GElf_Addr from; + GElf_Addr to; + struct region *next; +}; + +/* Nonzero if only exit status is wanted. */ +static bool quiet; + +/* True iff multiple differences should be output. */ +static bool verbose; + +/* True iff SHT_HASH treatment should be generous. */ +static bool hash_inexact; + +/* True iff build ID notes should be ignored. */ +static bool ignore_build_id; + +static bool hash_content_equivalent (size_t entsize, Elf_Data *, Elf_Data *); + + +int +main (int argc, char *argv[]) +{ + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + int remaining; + (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* We expect exactly two non-option parameters. */ + if (unlikely (remaining + 2 != argc)) + { + fputs (_("Invalid number of parameters.\n"), stderr); + argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name); + exit (1); + } + + if (quiet) + verbose = false; + + /* Comparing the files is done in two phases: + 1. compare all sections. Sections which are irrelevant (i.e., if + strip would remove them) are ignored. Some section types are + handled special. + 2. all parts of the loadable segments which are not parts of any + section is compared according to the rules of the --gaps option. + */ + int result = 0; + elf_version (EV_CURRENT); + + const char *const fname1 = argv[remaining]; + int fd1; + Ebl *ebl1; + Elf *elf1 = open_file (fname1, &fd1, &ebl1); + + const char *const fname2 = argv[remaining + 1]; + int fd2; + Ebl *ebl2; + Elf *elf2 = open_file (fname2, &fd2, &ebl2); + + GElf_Ehdr ehdr1_mem; + GElf_Ehdr *ehdr1 = gelf_getehdr (elf1, &ehdr1_mem); + if (ehdr1 == NULL) + error (2, 0, _("cannot get ELF header of '%s': %s"), + fname1, elf_errmsg (-1)); + GElf_Ehdr ehdr2_mem; + GElf_Ehdr *ehdr2 = gelf_getehdr (elf2, &ehdr2_mem); + if (ehdr2 == NULL) + error (2, 0, _("cannot get ELF header of '%s': %s"), + fname2, elf_errmsg (-1)); + +#define DIFFERENCE \ + do \ + { \ + result = 1; \ + if (! verbose) \ + goto out; \ + } \ + while (0) + + /* Compare the ELF headers. */ + if (unlikely (memcmp (ehdr1->e_ident, ehdr2->e_ident, EI_NIDENT) != 0 + || ehdr1->e_type != ehdr2->e_type + || ehdr1->e_machine != ehdr2->e_machine + || ehdr1->e_version != ehdr2->e_version + || ehdr1->e_entry != ehdr2->e_entry + || ehdr1->e_phoff != ehdr2->e_phoff + || ehdr1->e_flags != ehdr2->e_flags + || ehdr1->e_ehsize != ehdr2->e_ehsize + || ehdr1->e_phentsize != ehdr2->e_phentsize + || ehdr1->e_phnum != ehdr2->e_phnum + || ehdr1->e_shentsize != ehdr2->e_shentsize)) + { + if (! quiet) + error (0, 0, _("%s %s diff: ELF header"), fname1, fname2); + DIFFERENCE; + } + + size_t shnum1; + size_t shnum2; + if (unlikely (elf_getshdrnum (elf1, &shnum1) != 0)) + error (2, 0, _("cannot get section count of '%s': %s"), + fname1, elf_errmsg (-1)); + if (unlikely (elf_getshdrnum (elf2, &shnum2) != 0)) + error (2, 0, _("cannot get section count of '%s': %s"), + fname2, elf_errmsg (-1)); + if (unlikely (shnum1 != shnum2)) + { + if (! quiet) + error (0, 0, _("%s %s diff: section count"), fname1, fname2); + DIFFERENCE; + } + + size_t phnum1; + size_t phnum2; + if (unlikely (elf_getphdrnum (elf1, &phnum1) != 0)) + error (2, 0, _("cannot get program header count of '%s': %s"), + fname1, elf_errmsg (-1)); + if (unlikely (elf_getphdrnum (elf2, &phnum2) != 0)) + error (2, 0, _("cannot get program header count of '%s': %s"), + fname2, elf_errmsg (-1)); + if (unlikely (phnum1 != phnum2)) + { + if (! quiet) + error (0, 0, _("%s %s diff: program header count"), + fname1, fname2); + DIFFERENCE; + } + + size_t shstrndx1; + size_t shstrndx2; + if (elf_getshdrstrndx (elf1, &shstrndx1) != 0) + error (2, 0, _("cannot get hdrstrndx of '%s': %s"), + fname1, elf_errmsg (-1)); + if (elf_getshdrstrndx (elf2, &shstrndx2) != 0) + error (2, 0, _("cannot get hdrstrndx of '%s': %s"), + fname2, elf_errmsg (-1)); + if (shstrndx1 != shstrndx2) + { + if (! quiet) + error (0, 0, _("%s %s diff: shdr string index"), + fname1, fname2); + DIFFERENCE; + } + + /* Iterate over all sections. We expect the sections in the two + files to match exactly. */ + Elf_Scn *scn1 = NULL; + Elf_Scn *scn2 = NULL; + struct region *regions = NULL; + size_t nregions = 0; + while (1) + { + GElf_Shdr shdr1_mem; + GElf_Shdr *shdr1; + const char *sname1 = NULL; + do + { + scn1 = elf_nextscn (elf1, scn1); + shdr1 = gelf_getshdr (scn1, &shdr1_mem); + if (shdr1 != NULL) + sname1 = elf_strptr (elf1, shstrndx1, shdr1->sh_name); + } + while (scn1 != NULL && shdr1 != NULL + && ebl_section_strip_p (ebl1, shdr1, sname1, true, false)); + + GElf_Shdr shdr2_mem; + GElf_Shdr *shdr2; + const char *sname2 = NULL; + do + { + scn2 = elf_nextscn (elf2, scn2); + shdr2 = gelf_getshdr (scn2, &shdr2_mem); + if (shdr2 != NULL) + sname2 = elf_strptr (elf2, shstrndx2, shdr2->sh_name); + } + while (scn2 != NULL && shdr2 != NULL + && ebl_section_strip_p (ebl2, shdr2, sname2, true, false)); + + if (scn1 == NULL || scn2 == NULL || shdr1 == NULL || shdr2 == NULL) + break; + + if (gaps != gaps_ignore && (shdr1->sh_flags & SHF_ALLOC) != 0) + { + struct region *newp = (struct region *) alloca (sizeof (*newp)); + newp->from = shdr1->sh_offset; + newp->to = shdr1->sh_offset + shdr1->sh_size; + newp->next = regions; + regions = newp; + + ++nregions; + } + + /* Compare the headers. We allow the name to be at a different + location. */ + if (unlikely (sname1 == NULL || sname2 == NULL + || strcmp (sname1, sname2) != 0)) + { + error (0, 0, _("%s %s differ: section [%zu], [%zu] name"), + fname1, fname2, elf_ndxscn (scn1), elf_ndxscn (scn2)); + DIFFERENCE; + } + + /* We ignore certain sections. */ + if ((sname1 != NULL && strcmp (sname1, ".gnu_debuglink") == 0) + || (sname1 != NULL && strcmp (sname1, ".gnu.prelink_undo") == 0)) + continue; + + if (shdr1->sh_type != shdr2->sh_type + // XXX Any flags which should be ignored? + || shdr1->sh_flags != shdr2->sh_flags + || shdr1->sh_addr != shdr2->sh_addr + || (shdr1->sh_offset != shdr2->sh_offset + && (shdr1->sh_flags & SHF_ALLOC) + && ehdr1->e_type != ET_REL) + || shdr1->sh_size != shdr2->sh_size + || shdr1->sh_link != shdr2->sh_link + || shdr1->sh_info != shdr2->sh_info + || shdr1->sh_addralign != shdr2->sh_addralign + || shdr1->sh_entsize != shdr2->sh_entsize) + { + error (0, 0, _("%s %s differ: section [%zu] '%s' header"), + fname1, fname2, elf_ndxscn (scn1), sname1); + DIFFERENCE; + } + + Elf_Data *data1 = elf_getdata (scn1, NULL); + if (data1 == NULL) + error (2, 0, + _("cannot get content of section %zu in '%s': %s"), + elf_ndxscn (scn1), fname1, elf_errmsg (-1)); + + Elf_Data *data2 = elf_getdata (scn2, NULL); + if (data2 == NULL) + error (2, 0, + _("cannot get content of section %zu in '%s': %s"), + elf_ndxscn (scn2), fname2, elf_errmsg (-1)); + + switch (shdr1->sh_type) + { + case SHT_DYNSYM: + case SHT_SYMTAB: + if (shdr1->sh_entsize == 0) + error (2, 0, + _("symbol table [%zu] in '%s' has zero sh_entsize"), + elf_ndxscn (scn1), fname1); + + /* Iterate over the symbol table. We ignore the st_size + value of undefined symbols. */ + for (int ndx = 0; ndx < (int) (shdr1->sh_size / shdr1->sh_entsize); + ++ndx) + { + GElf_Sym sym1_mem; + GElf_Sym *sym1 = gelf_getsym (data1, ndx, &sym1_mem); + if (sym1 == NULL) + error (2, 0, + _("cannot get symbol in '%s': %s"), + fname1, elf_errmsg (-1)); + GElf_Sym sym2_mem; + GElf_Sym *sym2 = gelf_getsym (data2, ndx, &sym2_mem); + if (sym2 == NULL) + error (2, 0, + _("cannot get symbol in '%s': %s"), + fname2, elf_errmsg (-1)); + + const char *name1 = elf_strptr (elf1, shdr1->sh_link, + sym1->st_name); + const char *name2 = elf_strptr (elf2, shdr2->sh_link, + sym2->st_name); + if (unlikely (name1 == NULL || name2 == NULL + || strcmp (name1, name2) != 0 + || sym1->st_value != sym2->st_value + || (sym1->st_size != sym2->st_size + && sym1->st_shndx != SHN_UNDEF) + || sym1->st_info != sym2->st_info + || sym1->st_other != sym2->st_other + || sym1->st_shndx != sym2->st_shndx)) + { + // XXX Do we want to allow reordered symbol tables? + symtab_mismatch: + if (! quiet) + { + if (elf_ndxscn (scn1) == elf_ndxscn (scn2)) + error (0, 0, + _("%s %s differ: symbol table [%zu]"), + fname1, fname2, elf_ndxscn (scn1)); + else + error (0, 0, _("\ +%s %s differ: symbol table [%zu,%zu]"), + fname1, fname2, elf_ndxscn (scn1), + elf_ndxscn (scn2)); + } + DIFFERENCE; + break; + } + + if (sym1->st_shndx == SHN_UNDEF + && sym1->st_size != sym2->st_size) + { + /* The size of the symbol in the object defining it + might have changed. That is OK unless the symbol + is used in a copy relocation. Look over the + sections in both files and determine which + relocation section uses this symbol table + section. Then look through the relocations to + see whether any copy relocation references this + symbol. */ + if (search_for_copy_reloc (ebl1, elf_ndxscn (scn1), ndx) + || search_for_copy_reloc (ebl2, elf_ndxscn (scn2), ndx)) + goto symtab_mismatch; + } + } + break; + + case SHT_NOTE: + /* Parse the note format and compare the notes themselves. */ + { + GElf_Nhdr note1; + GElf_Nhdr note2; + + size_t off1 = 0; + size_t off2 = 0; + size_t name_offset; + size_t desc_offset; + while (off1 < data1->d_size + && (off1 = gelf_getnote (data1, off1, ¬e1, + &name_offset, &desc_offset)) > 0) + { + const char *name1 = (note1.n_namesz == 0 + ? "" : data1->d_buf + name_offset); + const void *desc1 = data1->d_buf + desc_offset; + if (off2 >= data2->d_size) + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: section [%zu] '%s' number of notes"), + fname1, fname2, elf_ndxscn (scn1), sname1); + DIFFERENCE; + } + off2 = gelf_getnote (data2, off2, ¬e2, + &name_offset, &desc_offset); + if (off2 == 0) + error (2, 0, _("\ +cannot read note section [%zu] '%s' in '%s': %s"), + elf_ndxscn (scn2), sname2, fname2, elf_errmsg (-1)); + const char *name2 = (note2.n_namesz == 0 + ? "" : data2->d_buf + name_offset); + const void *desc2 = data2->d_buf + desc_offset; + + if (note1.n_namesz != note2.n_namesz + || memcmp (name1, name2, note1.n_namesz)) + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: section [%zu] '%s' note name"), + fname1, fname2, elf_ndxscn (scn1), sname1); + DIFFERENCE; + } + if (note1.n_type != note2.n_type) + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: section [%zu] '%s' note '%s' type"), + fname1, fname2, elf_ndxscn (scn1), sname1, name1); + DIFFERENCE; + } + if (note1.n_descsz != note2.n_descsz + || memcmp (desc1, desc2, note1.n_descsz)) + { + if (note1.n_type == NT_GNU_BUILD_ID + && note1.n_namesz == sizeof "GNU" + && !memcmp (name1, "GNU", sizeof "GNU")) + { + if (note1.n_descsz != note2.n_descsz) + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: build ID length"), + fname1, fname2); + DIFFERENCE; + } + else if (! ignore_build_id) + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: build ID content"), + fname1, fname2); + DIFFERENCE; + } + } + else + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: section [%zu] '%s' note '%s' content"), + fname1, fname2, elf_ndxscn (scn1), sname1, + name1); + DIFFERENCE; + } + } + } + if (off2 < data2->d_size) + { + if (! quiet) + error (0, 0, _("\ +%s %s differ: section [%zu] '%s' number of notes"), + fname1, fname2, elf_ndxscn (scn1), sname1); + DIFFERENCE; + } + } + break; + + default: + /* Compare the section content byte for byte. */ + assert (shdr1->sh_type == SHT_NOBITS + || (data1->d_buf != NULL || data1->d_size == 0)); + assert (shdr2->sh_type == SHT_NOBITS + || (data2->d_buf != NULL || data1->d_size == 0)); + + if (unlikely (data1->d_size != data2->d_size + || (shdr1->sh_type != SHT_NOBITS + && data1->d_size != 0 + && memcmp (data1->d_buf, data2->d_buf, + data1->d_size) != 0))) + { + if (hash_inexact + && shdr1->sh_type == SHT_HASH + && data1->d_size == data2->d_size + && hash_content_equivalent (shdr1->sh_entsize, data1, data2)) + break; + + if (! quiet) + { + if (elf_ndxscn (scn1) == elf_ndxscn (scn2)) + error (0, 0, _("\ +%s %s differ: section [%zu] '%s' content"), + fname1, fname2, elf_ndxscn (scn1), sname1); + else + error (0, 0, _("\ +%s %s differ: section [%zu,%zu] '%s' content"), + fname1, fname2, elf_ndxscn (scn1), + elf_ndxscn (scn2), sname1); + } + DIFFERENCE; + } + break; + } + } + + if (unlikely (scn1 != scn2)) + { + if (! quiet) + error (0, 0, + _("%s %s differ: unequal amount of important sections"), + fname1, fname2); + DIFFERENCE; + } + + /* We we look at gaps, create artificial ones for the parts of the + program which we are not in sections. */ + struct region ehdr_region; + struct region phdr_region; + if (gaps != gaps_ignore) + { + ehdr_region.from = 0; + ehdr_region.to = ehdr1->e_ehsize; + ehdr_region.next = &phdr_region; + + phdr_region.from = ehdr1->e_phoff; + phdr_region.to = ehdr1->e_phoff + phnum1 * ehdr1->e_phentsize; + phdr_region.next = regions; + + regions = &ehdr_region; + nregions += 2; + } + + /* If we need to look at the gaps we need access to the file data. */ + char *raw1 = NULL; + size_t size1 = 0; + char *raw2 = NULL; + size_t size2 = 0; + struct region *regionsarr = alloca (nregions * sizeof (struct region)); + if (gaps != gaps_ignore) + { + raw1 = elf_rawfile (elf1, &size1); + if (raw1 == NULL ) + error (2, 0, _("cannot load data of '%s': %s"), + fname1, elf_errmsg (-1)); + + raw2 = elf_rawfile (elf2, &size2); + if (raw2 == NULL ) + error (2, 0, _("cannot load data of '%s': %s"), + fname2, elf_errmsg (-1)); + + for (size_t cnt = 0; cnt < nregions; ++cnt) + { + regionsarr[cnt] = *regions; + regions = regions->next; + } + + qsort (regionsarr, nregions, sizeof (regionsarr[0]), regioncompare); + } + + /* Compare the program header tables. */ + for (unsigned int ndx = 0; ndx < phnum1; ++ndx) + { + GElf_Phdr phdr1_mem; + GElf_Phdr *phdr1 = gelf_getphdr (elf1, ndx, &phdr1_mem); + if (phdr1 == NULL) + error (2, 0, + _("cannot get program header entry %d of '%s': %s"), + ndx, fname1, elf_errmsg (-1)); + GElf_Phdr phdr2_mem; + GElf_Phdr *phdr2 = gelf_getphdr (elf2, ndx, &phdr2_mem); + if (phdr2 == NULL) + error (2, 0, + _("cannot get program header entry %d of '%s': %s"), + ndx, fname2, elf_errmsg (-1)); + + if (unlikely (memcmp (phdr1, phdr2, sizeof (GElf_Phdr)) != 0)) + { + if (! quiet) + error (0, 0, _("%s %s differ: program header %d"), + fname1, fname2, ndx); + DIFFERENCE; + } + + if (gaps != gaps_ignore && phdr1->p_type == PT_LOAD) + { + size_t cnt = 0; + while (cnt < nregions && regionsarr[cnt].to < phdr1->p_offset) + ++cnt; + + GElf_Off last = phdr1->p_offset; + GElf_Off end = phdr1->p_offset + phdr1->p_filesz; + while (cnt < nregions && regionsarr[cnt].from < end) + { + if (last < regionsarr[cnt].from) + { + /* Compare the [LAST,FROM) region. */ + assert (gaps == gaps_match); + if (unlikely (memcmp (raw1 + last, raw2 + last, + regionsarr[cnt].from - last) != 0)) + { + gapmismatch: + if (!quiet) + error (0, 0, _("%s %s differ: gap"), + fname1, fname2); + DIFFERENCE; + break; + } + + } + last = regionsarr[cnt].to; + ++cnt; + } + + if (cnt == nregions && last < end) + goto gapmismatch; + } + } + + out: + elf_end (elf1); + elf_end (elf2); + ebl_closebackend (ebl1); + ebl_closebackend (ebl2); + close (fd1); + close (fd2); + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'q': + quiet = true; + break; + + case 'l': + verbose = true; + break; + + case OPT_GAPS: + if (strcasecmp (arg, "ignore") == 0) + gaps = gaps_ignore; + else if (likely (strcasecmp (arg, "match") == 0)) + gaps = gaps_match; + else + { + fprintf (stderr, + _("Invalid value '%s' for --gaps parameter."), + arg); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); + exit (1); + } + break; + + case OPT_HASH_INEXACT: + hash_inexact = true; + break; + + case OPT_IGNORE_BUILD_ID: + ignore_build_id = true; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +static Elf * +open_file (const char *fname, int *fdp, Ebl **eblp) +{ + int fd = open (fname, O_RDONLY); + if (unlikely (fd == -1)) + error (2, errno, _("cannot open '%s'"), fname); + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + error (2, 0, + _("cannot create ELF descriptor for '%s': %s"), + fname, elf_errmsg (-1)); + Ebl *ebl = ebl_openbackend (elf); + if (ebl == NULL) + error (2, 0, + _("cannot create EBL descriptor for '%s'"), fname); + + *fdp = fd; + *eblp = ebl; + return elf; +} + + +static bool +search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) +{ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + error (2, 0, + _("cannot get section header of section %zu: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + + if ((shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA) + || shdr->sh_link != scnndx) + continue; + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + error (2, 0, + _("cannot get content of section %zu: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + + if (shdr->sh_type == SHT_REL && shdr->sh_entsize != 0) + for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize); + ++ndx) + { + GElf_Rel rel_mem; + GElf_Rel *rel = gelf_getrel (data, ndx, &rel_mem); + if (rel == NULL) + error (2, 0, _("cannot get relocation: %s"), + elf_errmsg (-1)); + + if ((int) GELF_R_SYM (rel->r_info) == symndx + && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) + return true; + } + else if (shdr->sh_entsize != 0) + for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize); + ++ndx) + { + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (data, ndx, &rela_mem); + if (rela == NULL) + error (2, 0, _("cannot get relocation: %s"), + elf_errmsg (-1)); + + if ((int) GELF_R_SYM (rela->r_info) == symndx + && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) + return true; + } + } + + return false; +} + + +static int +regioncompare (const void *p1, const void *p2) +{ + const struct region *r1 = (const struct region *) p1; + const struct region *r2 = (const struct region *) p2; + + if (r1->from < r2->from) + return -1; + return 1; +} + + +static int +compare_Elf32_Word (const void *p1, const void *p2) +{ + const Elf32_Word *w1 = p1; + const Elf32_Word *w2 = p2; + return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0; +} + +static int +compare_Elf64_Xword (const void *p1, const void *p2) +{ + const Elf64_Xword *w1 = p1; + const Elf64_Xword *w2 = p2; + return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0; +} + +static bool +hash_content_equivalent (size_t entsize, Elf_Data *data1, Elf_Data *data2) +{ +#define CHECK_HASH(Hash_Word) \ + { \ + const Hash_Word *const hash1 = data1->d_buf; \ + const Hash_Word *const hash2 = data2->d_buf; \ + const size_t nbucket = hash1[0]; \ + const size_t nchain = hash1[1]; \ + if (data1->d_size != (2 + nbucket + nchain) * sizeof hash1[0] \ + || hash2[0] != nbucket || hash2[1] != nchain) \ + return false; \ + \ + const Hash_Word *const bucket1 = &hash1[2]; \ + const Hash_Word *const chain1 = &bucket1[nbucket]; \ + const Hash_Word *const bucket2 = &hash2[2]; \ + const Hash_Word *const chain2 = &bucket2[nbucket]; \ + \ + bool chain_ok[nchain]; \ + Hash_Word temp1[nchain - 1]; \ + Hash_Word temp2[nchain - 1]; \ + memset (chain_ok, 0, sizeof chain_ok); \ + for (size_t i = 0; i < nbucket; ++i) \ + { \ + if (bucket1[i] >= nchain || bucket2[i] >= nchain) \ + return false; \ + \ + size_t b1 = 0; \ + for (size_t p = bucket1[i]; p != STN_UNDEF; p = chain1[p]) \ + if (p >= nchain || b1 >= nchain - 1) \ + return false; \ + else \ + temp1[b1++] = p; \ + \ + size_t b2 = 0; \ + for (size_t p = bucket2[i]; p != STN_UNDEF; p = chain2[p]) \ + if (p >= nchain || b2 >= nchain - 1) \ + return false; \ + else \ + temp2[b2++] = p; \ + \ + if (b1 != b2) \ + return false; \ + \ + qsort (temp1, b1, sizeof temp1[0], compare_##Hash_Word); \ + qsort (temp2, b2, sizeof temp2[0], compare_##Hash_Word); \ + \ + for (b1 = 0; b1 < b2; ++b1) \ + if (temp1[b1] != temp2[b1]) \ + return false; \ + else \ + chain_ok[temp1[b1]] = true; \ + } \ + \ + for (size_t i = 0; i < nchain; ++i) \ + if (!chain_ok[i] && chain1[i] != chain2[i]) \ + return false; \ + \ + return true; \ + } + + switch (entsize) + { + case 4: + CHECK_HASH (Elf32_Word); + break; + case 8: + CHECK_HASH (Elf64_Xword); + break; + } + + return false; +} + + +#include "debugpred.h" diff --git a/src/elfcompress.c b/src/elfcompress.c new file mode 100644 index 00000000..2c6d91ba --- /dev/null +++ b/src/elfcompress.c @@ -0,0 +1,1362 @@ +/* Compress or decompress an ELF file. + Copyright (C) 2015, 2016, 2018 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include ELFUTILS_HEADER(elf) +#include ELFUTILS_HEADER(ebl) +#include ELFUTILS_HEADER(dwelf) +#include +#include "system.h" +#include "libeu.h" +#include "printversion.h" + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +static int verbose = 0; /* < 0, no warnings, > 0 extra verbosity. */ +static bool force = false; +static bool permissive = false; +static const char *foutput = NULL; + +#define T_UNSET 0 +#define T_DECOMPRESS 1 /* none */ +#define T_COMPRESS_ZLIB 2 /* zlib */ +#define T_COMPRESS_GNU 3 /* zlib-gnu */ +#define WORD_BITS (8U * sizeof (unsigned int)) + +static int type = T_UNSET; + +struct section_pattern +{ + char *pattern; + struct section_pattern *next; +}; + +static struct section_pattern *patterns = NULL; + +static void +add_pattern (const char *pattern) +{ + struct section_pattern *p = xmalloc (sizeof *p); + p->pattern = xstrdup (pattern); + p->next = patterns; + patterns = p; +} + +static void +free_patterns (void) +{ + struct section_pattern *pattern = patterns; + while (pattern != NULL) + { + struct section_pattern *p = pattern; + pattern = p->next; + free (p->pattern); + free (p); + } +} + +static error_t +parse_opt (int key, char *arg __attribute__ ((unused)), + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'v': + verbose++; + break; + + case 'q': + verbose--; + break; + + case 'f': + force = true; + break; + + case 'p': + permissive = true; + break; + + case 'n': + add_pattern (arg); + break; + + case 'o': + if (foutput != NULL) + argp_error (state, N_("-o option specified twice")); + else + foutput = arg; + break; + + case 't': + if (type != T_UNSET) + argp_error (state, N_("-t option specified twice")); + + if (strcmp ("none", arg) == 0) + type = T_DECOMPRESS; + else if (strcmp ("zlib", arg) == 0 || strcmp ("zlib-gabi", arg) == 0) + type = T_COMPRESS_ZLIB; + else if (strcmp ("zlib-gnu", arg) == 0 || strcmp ("gnu", arg) == 0) + type = T_COMPRESS_GNU; + else + argp_error (state, N_("unknown compression type '%s'"), arg); + break; + + case ARGP_KEY_SUCCESS: + if (type == T_UNSET) + type = T_COMPRESS_ZLIB; + if (patterns == NULL) + add_pattern (".?(z)debug*"); + break; + + case ARGP_KEY_NO_ARGS: + /* We need at least one input file. */ + argp_error (state, N_("No input file given")); + break; + + case ARGP_KEY_ARGS: + if (foutput != NULL && state->argc - state->next > 1) + argp_error (state, + N_("Only one input file allowed together with '-o'")); + /* We only use this for checking the number of arguments, we don't + actually want to consume them. */ + FALLTHROUGH; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static bool +section_name_matches (const char *name) +{ + struct section_pattern *pattern = patterns; + while (pattern != NULL) + { + if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0) + return true; + pattern = pattern->next; + } + return false; +} + +static int +setshdrstrndx (Elf *elf, GElf_Ehdr *ehdr, size_t ndx) +{ + if (ndx < SHN_LORESERVE) + ehdr->e_shstrndx = ndx; + else + { + ehdr->e_shstrndx = SHN_XINDEX; + Elf_Scn *zscn = elf_getscn (elf, 0); + GElf_Shdr zshdr_mem; + GElf_Shdr *zshdr = gelf_getshdr (zscn, &zshdr_mem); + if (zshdr == NULL) + return -1; + zshdr->sh_link = ndx; + if (gelf_update_shdr (zscn, zshdr) == 0) + return -1; + } + + if (gelf_update_ehdr (elf, ehdr) == 0) + return -1; + + return 0; +} + +static int +compress_section (Elf_Scn *scn, size_t orig_size, const char *name, + const char *newname, size_t ndx, + bool gnu, bool compress, bool report_verbose) +{ + int res; + unsigned int flags = compress && force ? ELF_CHF_FORCE : 0; + if (gnu) + res = elf_compress_gnu (scn, compress ? 1 : 0, flags); + else + res = elf_compress (scn, compress ? ELFCOMPRESS_ZLIB : 0, flags); + + if (res < 0) + error (0, 0, "Couldn't decompress section [%zd] %s: %s", + ndx, name, elf_errmsg (-1)); + else + { + if (compress && res == 0) + { + if (verbose >= 0) + printf ("[%zd] %s NOT compressed, wouldn't be smaller\n", + ndx, name); + } + + if (report_verbose && res > 0) + { + printf ("[%zd] %s %s", ndx, name, + compress ? "compressed" : "decompressed"); + if (newname != NULL) + printf (" -> %s", newname); + + /* Reload shdr, it has changed. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for section [%zd]", ndx); + return -1; + } + float new = shdr->sh_size; + float orig = orig_size ?: 1; + printf (" (%zu => %" PRIu64 " %.2f%%)\n", + orig_size, shdr->sh_size, (new / orig) * 100); + } + } + + return res; +} + +static void +set_section (unsigned int *sections, size_t ndx) +{ + sections[ndx / WORD_BITS] |= (1U << (ndx % WORD_BITS)); +} + +static bool +get_section (unsigned int *sections, size_t ndx) +{ + return (sections[ndx / WORD_BITS] & (1U << (ndx % WORD_BITS))) != 0; +} + +/* How many sections are we going to change? */ +static size_t +get_sections (unsigned int *sections, size_t shnum) +{ + size_t s = 0; + for (size_t i = 0; i < shnum / WORD_BITS + 1; i++) + s += __builtin_popcount (sections[i]); + return s; +} + +static int +process_file (const char *fname) +{ + if (verbose > 0) + printf ("processing: %s\n", fname); + + /* The input ELF. */ + int fd = -1; + Elf *elf = NULL; + + /* The output ELF. */ + char *fnew = NULL; + int fdnew = -1; + Elf *elfnew = NULL; + + /* Buffer for (one) new section name if necessary. */ + char *snamebuf = NULL; + + /* String table (and symbol table), if section names need adjusting. */ + Dwelf_Strtab *names = NULL; + Dwelf_Strent **scnstrents = NULL; + Dwelf_Strent **symstrents = NULL; + char **scnnames = NULL; + + /* Section data from names. */ + void *namesbuf = NULL; + + /* Which sections match and need to be (un)compressed. */ + unsigned int *sections = NULL; + + /* How many sections are we talking about? */ + size_t shnum = 0; + int res = 1; + + fd = open (fname, O_RDONLY); + if (fd < 0) + { + error (0, errno, "Couldn't open %s\n", fname); + goto cleanup; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + error (0, 0, "Couldn't open ELF file %s for reading: %s", + fname, elf_errmsg (-1)); + goto cleanup; + } + + /* We don't handle ar files (or anything else), we probably should. */ + Elf_Kind kind = elf_kind (elf); + if (kind != ELF_K_ELF) + { + if (kind == ELF_K_AR) + error (0, 0, "Cannot handle ar files: %s", fname); + else + error (0, 0, "Unknown file type: %s", fname); + goto cleanup; + } + + struct stat st; + if (fstat (fd, &st) != 0) + { + error (0, errno, "Couldn't fstat %s", fname); + goto cleanup; + } + + GElf_Ehdr ehdr; + if (gelf_getehdr (elf, &ehdr) == NULL) + { + error (0, 0, "Couldn't get ehdr for %s: %s", fname, elf_errmsg (-1)); + goto cleanup; + } + + /* Get the section header string table. */ + size_t shdrstrndx; + if (elf_getshdrstrndx (elf, &shdrstrndx) != 0) + { + error (0, 0, "Couldn't get section header string table index in %s: %s", + fname, elf_errmsg (-1)); + goto cleanup; + } + + /* How many sections are we talking about? */ + if (elf_getshdrnum (elf, &shnum) != 0) + { + error (0, 0, "Couldn't get number of sections in %s: %s", + fname, elf_errmsg (1)); + goto cleanup; + } + + if (shnum == 0) + { + error (0, 0, "ELF file %s has no sections", fname); + goto cleanup; + } + + sections = xcalloc (shnum / 8 + 1, sizeof (unsigned int)); + + size_t phnum; + if (elf_getphdrnum (elf, &phnum) != 0) + { + error (0, 0, "Couldn't get phdrnum: %s", elf_errmsg (-1)); + goto cleanup; + } + + /* Whether we need to adjust any section names (going to/from GNU + naming). If so we'll need to build a new section header string + table. */ + bool adjust_names = false; + + /* If there are phdrs we want to maintain the layout of the + allocated sections in the file. */ + bool layout = phnum != 0; + + /* While going through all sections keep track of last section data + offset if needed to keep the layout. We are responsible for + adding the section offsets and headers (e_shoff) in that case + (which we will place after the last section). */ + GElf_Off last_offset = 0; + if (layout) + last_offset = (ehdr.e_phoff + + gelf_fsize (elf, ELF_T_PHDR, phnum, EV_CURRENT)); + + /* Which section, if any, is a symbol table that shares a string + table with the section header string table? */ + size_t symtabndx = 0; + + /* We do three passes over all sections. + + First an inspection pass over the old Elf to see which section + data needs to be copied and/or transformed, which sections need a + names change and whether there is a symbol table that might need + to be adjusted be if the section header name table is changed. + + If nothing needs changing, and the input and output file are the + same, we are done. + + Second a collection pass that creates the Elf sections and copies + the data. This pass will compress/decompress section data when + needed. And it will collect all data needed if we'll need to + construct a new string table. Afterwards the new string table is + constructed. + + Third a fixup/adjustment pass over the new Elf that will adjust + any section references (names) and adjust the layout based on the + new sizes of the sections if necessary. This pass is optional if + we aren't responsible for the layout and the section header + string table hasn't been changed. */ + + /* Inspection pass. */ + size_t maxnamelen = 0; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + size_t ndx = elf_ndxscn (scn); + if (ndx > shnum) + { + error (0, 0, "Unexpected section number %zd, expected only %zd", + ndx, shnum); + goto cleanup; + } + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for section %zd", ndx); + goto cleanup; + } + + const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name); + if (sname == NULL) + { + error (0, 0, "Couldn't get name for section %zd", ndx); + goto cleanup; + } + + if (section_name_matches (sname)) + { + if (!force && type == T_DECOMPRESS + && (shdr->sh_flags & SHF_COMPRESSED) == 0 + && !startswith (sname, ".zdebug")) + { + if (verbose > 0) + printf ("[%zd] %s already decompressed\n", ndx, sname); + } + else if (!force && type == T_COMPRESS_ZLIB + && (shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (verbose > 0) + printf ("[%zd] %s already compressed\n", ndx, sname); + } + else if (!force && type == T_COMPRESS_GNU + && startswith (sname, ".zdebug")) + { + if (verbose > 0) + printf ("[%zd] %s already GNU compressed\n", ndx, sname); + } + else if (shdr->sh_type != SHT_NOBITS + && (shdr->sh_flags & SHF_ALLOC) == 0) + { + set_section (sections, ndx); + /* Check if we might want to change this section name. */ + if (! adjust_names + && ((type != T_COMPRESS_GNU + && startswith (sname, ".zdebug")) + || (type == T_COMPRESS_GNU + && startswith (sname, ".debug")))) + adjust_names = true; + + /* We need a buffer this large if we change the names. */ + if (adjust_names) + { + size_t slen = strlen (sname); + if (slen > maxnamelen) + maxnamelen = slen; + } + } + else + if (verbose >= 0) + printf ("[%zd] %s ignoring %s section\n", ndx, sname, + (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); + } + + if (shdr->sh_type == SHT_SYMTAB) + { + /* Check if we might have to adjust the symbol name indexes. */ + if (shdr->sh_link == shdrstrndx) + { + if (symtabndx != 0) + { + error (0, 0, + "Multiple symbol tables (%zd, %zd) using the same string table unsupported", symtabndx, ndx); + goto cleanup; + } + symtabndx = ndx; + } + } + + /* Keep track of last allocated data offset. */ + if (layout) + if ((shdr->sh_flags & SHF_ALLOC) != 0) + { + GElf_Off off = shdr->sh_offset + (shdr->sh_type != SHT_NOBITS + ? shdr->sh_size : 0); + if (last_offset < off) + last_offset = off; + } + } + + if (foutput == NULL && get_sections (sections, shnum) == 0) + { + if (verbose > 0) + printf ("Nothing to do.\n"); + res = 0; + goto cleanup; + } + + if (adjust_names) + { + names = dwelf_strtab_init (true); + if (names == NULL) + { + error (0, 0, "Not enough memory for new strtab"); + goto cleanup; + } + scnstrents = xmalloc (shnum + * sizeof (Dwelf_Strent *)); + scnnames = xcalloc (shnum, sizeof (char *)); + } + + /* Create a new (temporary) ELF file for the result. */ + if (foutput == NULL) + { + size_t fname_len = strlen (fname); + fnew = xmalloc (fname_len + sizeof (".XXXXXX")); + strcpy (mempcpy (fnew, fname, fname_len), ".XXXXXX"); + fdnew = mkstemp (fnew); + } + else + { + fnew = xstrdup (foutput); + fdnew = open (fnew, O_WRONLY | O_CREAT, st.st_mode & ALLPERMS); + } + + if (fdnew < 0) + { + error (0, errno, "Couldn't create output file %s", fnew); + /* Since we didn't create it we don't want to try to unlink it. */ + free (fnew); + fnew = NULL; + goto cleanup; + } + + elfnew = elf_begin (fdnew, ELF_C_WRITE, NULL); + if (elfnew == NULL) + { + error (0, 0, "Couldn't open new ELF %s for writing: %s", + fnew, elf_errmsg (-1)); + goto cleanup; + } + + /* Create the new ELF header and copy over all the data. */ + if (gelf_newehdr (elfnew, gelf_getclass (elf)) == 0) + { + error (0, 0, "Couldn't create new ehdr: %s", elf_errmsg (-1)); + goto cleanup; + } + + GElf_Ehdr newehdr; + if (gelf_getehdr (elfnew, &newehdr) == NULL) + { + error (0, 0, "Couldn't get new ehdr: %s", elf_errmsg (-1)); + goto cleanup; + } + + newehdr.e_ident[EI_DATA] = ehdr.e_ident[EI_DATA]; + newehdr.e_type = ehdr.e_type; + newehdr.e_machine = ehdr.e_machine; + newehdr.e_version = ehdr.e_version; + newehdr.e_entry = ehdr.e_entry; + newehdr.e_flags = ehdr.e_flags; + + if (gelf_update_ehdr (elfnew, &newehdr) == 0) + { + error (0, 0, "Couldn't update ehdr: %s", elf_errmsg (-1)); + goto cleanup; + } + + /* Copy over the phdrs as is. */ + if (phnum != 0) + { + if (gelf_newphdr (elfnew, phnum) == 0) + { + error (0, 0, "Couldn't create phdrs: %s", elf_errmsg (-1)); + goto cleanup; + } + + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); + if (phdr == NULL) + { + error (0, 0, "Couldn't get phdr %zd: %s", cnt, elf_errmsg (-1)); + goto cleanup; + } + if (gelf_update_phdr (elfnew, cnt, phdr) == 0) + { + error (0, 0, "Couldn't create phdr %zd: %s", cnt, + elf_errmsg (-1)); + goto cleanup; + } + } + } + + /* Possibly add a 'z' and zero terminator. */ + if (maxnamelen > 0) + snamebuf = xmalloc (maxnamelen + 2); + + /* We might want to read/adjust the section header strings and + symbol tables. If so, and those sections are to be compressed + then we will have to decompress it during the collection pass and + compress it again in the fixup pass. Don't compress unnecessary + and keep track of whether or not to compress them (later in the + fixup pass). Also record the original size, so we can report the + difference later when we do compress. */ + int shstrtab_compressed = T_UNSET; + size_t shstrtab_size = 0; + char *shstrtab_name = NULL; + char *shstrtab_newname = NULL; + int symtab_compressed = T_UNSET; + size_t symtab_size = 0; + char *symtab_name = NULL; + char *symtab_newname = NULL; + + /* Collection pass. Copy over the sections, (de)compresses matching + sections, collect names of sections and symbol table if + necessary. */ + scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + size_t ndx = elf_ndxscn (scn); + assert (ndx < shnum); + + /* (de)compress if section matched. */ + char *sname = NULL; + char *newname = NULL; + if (get_section (sections, ndx)) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for section %zd", ndx); + goto cleanup; + } + + uint64_t size = shdr->sh_size; + sname = elf_strptr (elf, shdrstrndx, shdr->sh_name); + if (sname == NULL) + { + error (0, 0, "Couldn't get name for section %zd", ndx); + goto cleanup; + } + + /* strdup sname, the shdrstrndx section itself might be + (de)compressed, invalidating the string pointers. */ + sname = xstrdup (sname); + + /* We might want to decompress (and rename), but not + compress during this pass since we might need the section + data in later passes. Skip those sections for now and + compress them in the fixup pass. */ + bool skip_compress_section = (adjust_names + && (ndx == shdrstrndx + || ndx == symtabndx)); + + switch (type) + { + case T_DECOMPRESS: + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (compress_section (scn, size, sname, NULL, ndx, + false, false, verbose > 0) < 0) + goto cleanup; + } + else if (startswith (sname, ".zdebug")) + { + snamebuf[0] = '.'; + strcpy (&snamebuf[1], &sname[2]); + newname = snamebuf; + if (compress_section (scn, size, sname, newname, ndx, + true, false, verbose > 0) < 0) + goto cleanup; + } + else if (verbose > 0) + printf ("[%zd] %s already decompressed\n", ndx, sname); + break; + + case T_COMPRESS_GNU: + if (startswith (sname, ".debug")) + { + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + /* First decompress to recompress GNU style. + Don't report even when verbose. */ + if (compress_section (scn, size, sname, NULL, ndx, + false, false, false) < 0) + goto cleanup; + } + + snamebuf[0] = '.'; + snamebuf[1] = 'z'; + strcpy (&snamebuf[2], &sname[1]); + newname = snamebuf; + + if (skip_compress_section) + { + if (ndx == shdrstrndx) + { + shstrtab_size = size; + shstrtab_compressed = T_COMPRESS_GNU; + shstrtab_name = xstrdup (sname); + shstrtab_newname = xstrdup (newname); + } + else + { + symtab_size = size; + symtab_compressed = T_COMPRESS_GNU; + symtab_name = xstrdup (sname); + symtab_newname = xstrdup (newname); + } + } + else + { + int result = compress_section (scn, size, sname, newname, + ndx, true, true, + verbose > 0); + if (result < 0) + goto cleanup; + + if (result == 0) + newname = NULL; + } + } + else if (verbose >= 0) + { + if (startswith (sname, ".zdebug")) + printf ("[%zd] %s unchanged, already GNU compressed", + ndx, sname); + else + printf ("[%zd] %s cannot GNU compress section not starting with .debug\n", + ndx, sname); + } + break; + + case T_COMPRESS_ZLIB: + if ((shdr->sh_flags & SHF_COMPRESSED) == 0) + { + if (startswith (sname, ".zdebug")) + { + /* First decompress to recompress zlib style. + Don't report even when verbose. */ + if (compress_section (scn, size, sname, NULL, ndx, + true, false, false) < 0) + goto cleanup; + + snamebuf[0] = '.'; + strcpy (&snamebuf[1], &sname[2]); + newname = snamebuf; + } + + if (skip_compress_section) + { + if (ndx == shdrstrndx) + { + shstrtab_size = size; + shstrtab_compressed = T_COMPRESS_ZLIB; + shstrtab_name = xstrdup (sname); + shstrtab_newname = (newname == NULL + ? NULL : xstrdup (newname)); + } + else + { + symtab_size = size; + symtab_compressed = T_COMPRESS_ZLIB; + symtab_name = xstrdup (sname); + symtab_newname = (newname == NULL + ? NULL : xstrdup (newname)); + } + } + else if (compress_section (scn, size, sname, newname, ndx, + false, true, verbose > 0) < 0) + goto cleanup; + } + else if (verbose > 0) + printf ("[%zd] %s already compressed\n", ndx, sname); + break; + } + + free (sname); + } + + Elf_Scn *newscn = elf_newscn (elfnew); + if (newscn == NULL) + { + error (0, 0, "Couldn't create new section %zd", ndx); + goto cleanup; + } + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for section %zd", ndx); + goto cleanup; + } + + if (gelf_update_shdr (newscn, shdr) == 0) + { + error (0, 0, "Couldn't update section header %zd", ndx); + goto cleanup; + } + + /* Except for the section header string table all data can be + copied as is. The section header string table will be + created later and the symbol table might be fixed up if + necessary. */ + if (! adjust_names || ndx != shdrstrndx) + { + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + { + error (0, 0, "Couldn't get data from section %zd", ndx); + goto cleanup; + } + + Elf_Data *newdata = elf_newdata (newscn); + if (newdata == NULL) + { + error (0, 0, "Couldn't create new data for section %zd", ndx); + goto cleanup; + } + + *newdata = *data; + } + + /* Keep track of the (new) section names. */ + if (adjust_names) + { + char *name; + if (newname != NULL) + name = newname; + else + { + name = elf_strptr (elf, shdrstrndx, shdr->sh_name); + if (name == NULL) + { + error (0, 0, "Couldn't get name for section [%zd]", ndx); + goto cleanup; + } + } + + /* We need to keep a copy of the name till the strtab is done. */ + name = scnnames[ndx] = xstrdup (name); + if ((scnstrents[ndx] = dwelf_strtab_add (names, name)) == NULL) + { + error (0, 0, "No memory to add section name string table"); + goto cleanup; + } + + /* If the symtab shares strings then add those too. */ + if (ndx == symtabndx) + { + /* If the section is (still) compressed we'll need to + uncompress it first to adjust the data, then + recompress it in the fixup pass. */ + if (symtab_compressed == T_UNSET) + { + size_t size = shdr->sh_size; + if ((shdr->sh_flags == SHF_COMPRESSED) != 0) + { + /* Don't report the (internal) uncompression. */ + if (compress_section (newscn, size, sname, NULL, ndx, + false, false, false) < 0) + goto cleanup; + + symtab_size = size; + symtab_compressed = T_COMPRESS_ZLIB; + } + else if (startswith (name, ".zdebug")) + { + /* Don't report the (internal) uncompression. */ + if (compress_section (newscn, size, sname, NULL, ndx, + true, false, false) < 0) + goto cleanup; + + symtab_size = size; + symtab_compressed = T_COMPRESS_GNU; + } + } + + Elf_Data *symd = elf_getdata (newscn, NULL); + if (symd == NULL) + { + error (0, 0, "Couldn't get symtab data for section [%zd] %s", + ndx, name); + goto cleanup; + } + size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT); + size_t syms = symd->d_size / elsize; + symstrents = xmalloc (syms * sizeof (Dwelf_Strent *)); + for (size_t i = 0; i < syms; i++) + { + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem); + if (sym == NULL) + { + error (0, 0, "Couldn't get symbol %zd", i); + goto cleanup; + } + if (sym->st_name != 0) + { + /* Note we take the name from the original ELF, + since the new one will not have setup the + strtab yet. */ + const char *symname = elf_strptr (elf, shdrstrndx, + sym->st_name); + if (symname == NULL) + { + error (0, 0, "Couldn't get symbol %zd name", i); + goto cleanup; + } + symstrents[i] = dwelf_strtab_add (names, symname); + if (symstrents[i] == NULL) + { + error (0, 0, "No memory to add to symbol name"); + goto cleanup; + } + } + } + } + } + } + + if (adjust_names) + { + /* We got all needed strings, put the new data in the shstrtab. */ + if (verbose > 0) + printf ("[%zd] Updating section string table\n", shdrstrndx); + + scn = elf_getscn (elfnew, shdrstrndx); + if (scn == NULL) + { + error (0, 0, "Couldn't get new section header string table [%zd]", + shdrstrndx); + goto cleanup; + } + + Elf_Data *data = elf_newdata (scn); + if (data == NULL) + { + error (0, 0, "Couldn't create new section header string table data"); + goto cleanup; + } + if (dwelf_strtab_finalize (names, data) == NULL) + { + error (0, 0, "Not enough memory to create string table"); + goto cleanup; + } + namesbuf = data->d_buf; + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for new section strings %zd", + shdrstrndx); + goto cleanup; + } + + /* Note that we also might have to compress and possibly set + sh_off below */ + shdr->sh_name = dwelf_strent_off (scnstrents[shdrstrndx]); + shdr->sh_type = SHT_STRTAB; + shdr->sh_flags = 0; + shdr->sh_addr = 0; + shdr->sh_offset = 0; + shdr->sh_size = data->d_size; + shdr->sh_link = SHN_UNDEF; + shdr->sh_info = SHN_UNDEF; + shdr->sh_addralign = 1; + shdr->sh_entsize = 0; + + if (gelf_update_shdr (scn, shdr) == 0) + { + error (0, 0, "Couldn't update new section strings [%zd]", + shdrstrndx); + goto cleanup; + } + + /* We might have to compress the data if the user asked us to, + or if the section was already compressed (and the user didn't + ask for decompression). Note somewhat identical code for + symtab below. */ + if (shstrtab_compressed == T_UNSET) + { + /* The user didn't ask for compression, but maybe it was + compressed in the original ELF file. */ + Elf_Scn *oldscn = elf_getscn (elf, shdrstrndx); + if (oldscn == NULL) + { + error (0, 0, "Couldn't get section header string table [%zd]", + shdrstrndx); + goto cleanup; + } + + shdr = gelf_getshdr (oldscn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for old section strings [%zd]", + shdrstrndx); + goto cleanup; + } + + shstrtab_name = elf_strptr (elf, shdrstrndx, shdr->sh_name); + if (shstrtab_name == NULL) + { + error (0, 0, "Couldn't get name for old section strings [%zd]", + shdrstrndx); + goto cleanup; + } + + shstrtab_size = shdr->sh_size; + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + shstrtab_compressed = T_COMPRESS_ZLIB; + else if (startswith (shstrtab_name, ".zdebug")) + shstrtab_compressed = T_COMPRESS_GNU; + } + + /* Should we (re)compress? */ + if (shstrtab_compressed != T_UNSET) + { + if (compress_section (scn, shstrtab_size, shstrtab_name, + shstrtab_newname, shdrstrndx, + shstrtab_compressed == T_COMPRESS_GNU, + true, verbose > 0) < 0) + goto cleanup; + } + } + + /* Make sure to re-get the new ehdr. Adding phdrs and shdrs will + have changed it. */ + if (gelf_getehdr (elfnew, &newehdr) == NULL) + { + error (0, 0, "Couldn't re-get new ehdr: %s", elf_errmsg (-1)); + goto cleanup; + } + + /* Set this after the sections have been created, otherwise section + zero might not exist yet. */ + if (setshdrstrndx (elfnew, &newehdr, shdrstrndx) != 0) + { + error (0, 0, "Couldn't set new shdrstrndx: %s", elf_errmsg (-1)); + goto cleanup; + } + + /* Fixup pass. Adjust string table references, symbol table and + layout if necessary. */ + if (layout || adjust_names) + { + scn = NULL; + while ((scn = elf_nextscn (elfnew, scn)) != NULL) + { + size_t ndx = elf_ndxscn (scn); + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get shdr for section %zd", ndx); + goto cleanup; + } + + /* Keep the offset of allocated sections so they are at the + same place in the file. Add (possibly changed) + unallocated ones after the allocated ones. */ + if ((shdr->sh_flags & SHF_ALLOC) == 0) + { + /* Zero means one. No alignment constraints. */ + size_t addralign = shdr->sh_addralign ?: 1; + last_offset = (last_offset + addralign - 1) & ~(addralign - 1); + shdr->sh_offset = last_offset; + if (shdr->sh_type != SHT_NOBITS) + last_offset += shdr->sh_size; + } + + if (adjust_names) + shdr->sh_name = dwelf_strent_off (scnstrents[ndx]); + + if (gelf_update_shdr (scn, shdr) == 0) + { + error (0, 0, "Couldn't update section header %zd", ndx); + goto cleanup; + } + + if (adjust_names && ndx == symtabndx) + { + if (verbose > 0) + printf ("[%zd] Updating symbol table\n", symtabndx); + + Elf_Data *symd = elf_getdata (scn, NULL); + if (symd == NULL) + { + error (0, 0, "Couldn't get new symtab data section [%zd]", + ndx); + goto cleanup; + } + size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT); + size_t syms = symd->d_size / elsize; + for (size_t i = 0; i < syms; i++) + { + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem); + if (sym == NULL) + { + error (0, 0, "2 Couldn't get symbol %zd", i); + goto cleanup; + } + + if (sym->st_name != 0) + { + sym->st_name = dwelf_strent_off (symstrents[i]); + + if (gelf_update_sym (symd, i, sym) == 0) + { + error (0, 0, "Couldn't update symbol %zd", i); + goto cleanup; + } + } + } + + /* We might have to compress the data if the user asked + us to, or if the section was already compressed (and + the user didn't ask for decompression). Note + somewhat identical code for shstrtab above. */ + if (symtab_compressed == T_UNSET) + { + /* The user didn't ask for compression, but maybe it was + compressed in the original ELF file. */ + Elf_Scn *oldscn = elf_getscn (elf, symtabndx); + if (oldscn == NULL) + { + error (0, 0, "Couldn't get symbol table [%zd]", + symtabndx); + goto cleanup; + } + + shdr = gelf_getshdr (oldscn, &shdr_mem); + if (shdr == NULL) + { + error (0, 0, "Couldn't get old symbol table shdr [%zd]", + symtabndx); + goto cleanup; + } + + symtab_name = elf_strptr (elf, shdrstrndx, shdr->sh_name); + if (symtab_name == NULL) + { + error (0, 0, "Couldn't get old symbol table name [%zd]", + symtabndx); + goto cleanup; + } + + symtab_size = shdr->sh_size; + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + symtab_compressed = T_COMPRESS_ZLIB; + else if (startswith (symtab_name, ".zdebug")) + symtab_compressed = T_COMPRESS_GNU; + } + + /* Should we (re)compress? */ + if (symtab_compressed != T_UNSET) + { + if (compress_section (scn, symtab_size, symtab_name, + symtab_newname, symtabndx, + symtab_compressed == T_COMPRESS_GNU, + true, verbose > 0) < 0) + goto cleanup; + } + } + } + } + + /* If we have phdrs we want elf_update to layout the SHF_ALLOC + sections precisely as in the original file. In that case we are + also responsible for setting phoff and shoff */ + if (layout) + { + if (gelf_getehdr (elfnew, &newehdr) == NULL) + { + error (0, 0, "Couldn't get ehdr: %s", elf_errmsg (-1)); + goto cleanup; + } + + /* Position the shdrs after the last (unallocated) section. */ + const size_t offsize = gelf_fsize (elfnew, ELF_T_OFF, 1, EV_CURRENT); + newehdr.e_shoff = ((last_offset + offsize - 1) + & ~((GElf_Off) (offsize - 1))); + + /* The phdrs go in the same place as in the original file. + Normally right after the ELF header. */ + newehdr.e_phoff = ehdr.e_phoff; + + if (gelf_update_ehdr (elfnew, &newehdr) == 0) + { + error (0, 0, "Couldn't update ehdr: %s", elf_errmsg (-1)); + goto cleanup; + } + } + + elf_flagelf (elfnew, ELF_C_SET, ((layout ? ELF_F_LAYOUT : 0) + | (permissive ? ELF_F_PERMISSIVE : 0))); + + if (elf_update (elfnew, ELF_C_WRITE) < 0) + { + error (0, 0, "Couldn't write %s: %s", fnew, elf_errmsg (-1)); + goto cleanup; + } + + elf_end (elfnew); + elfnew = NULL; + + /* Try to match mode and owner.group of the original file. + Note to set suid bits we have to make sure the owner is setup + correctly first. Otherwise fchmod will drop them silently + or fchown may clear them. */ + if (fchown (fdnew, st.st_uid, st.st_gid) != 0) + if (verbose >= 0) + error (0, errno, "Couldn't fchown %s", fnew); + if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0) + if (verbose >= 0) + error (0, errno, "Couldn't fchmod %s", fnew); + + /* Finally replace the old file with the new file. */ + if (foutput == NULL) + if (rename (fnew, fname) != 0) + { + error (0, errno, "Couldn't rename %s to %s", fnew, fname); + goto cleanup; + } + + /* We are finally done with the new file, don't unlink it now. */ + free (fnew); + fnew = NULL; + res = 0; + +cleanup: + elf_end (elf); + close (fd); + + elf_end (elfnew); + close (fdnew); + + if (fnew != NULL) + { + unlink (fnew); + free (fnew); + fnew = NULL; + } + + free (snamebuf); + if (names != NULL) + { + dwelf_strtab_free (names); + free (scnstrents); + free (symstrents); + free (namesbuf); + if (scnnames != NULL) + { + for (size_t n = 0; n < shnum; n++) + free (scnnames[n]); + free (scnnames); + } + } + + free (sections); + return res; +} + +int +main (int argc, char **argv) +{ + const struct argp_option options[] = + { + { "output", 'o', "FILE", 0, + N_("Place (de)compressed output into FILE"), + 0 }, + { "type", 't', "TYPE", 0, + N_("What type of compression to apply. TYPE can be 'none' (decompress), 'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-gnu' (.zdebug GNU style compression, 'gnu' is an alias)"), + 0 }, + { "name", 'n', "SECTION", 0, + N_("SECTION name to (de)compress, SECTION is an extended wildcard pattern (defaults to '.?(z)debug*')"), + 0 }, + { "verbose", 'v', NULL, 0, + N_("Print a message for each section being (de)compressed"), + 0 }, + { "force", 'f', NULL, 0, + N_("Force compression of section even if it would become larger or update/rewrite the file even if no section would be (de)compressed"), + 0 }, + { "permissive", 'p', NULL, 0, + N_("Relax a few rules to handle slightly broken ELF files"), + 0 }, + { "quiet", 'q', NULL, 0, + N_("Be silent when a section cannot be compressed"), + 0 }, + { NULL, 0, NULL, 0, NULL, 0 } + }; + + const struct argp argp = + { + .options = options, + .parser = parse_opt, + .args_doc = N_("FILE..."), + .doc = N_("Compress or decompress sections in an ELF file.") + }; + + int remaining; + if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0) + return EXIT_FAILURE; + + /* Should already be handled by ARGP_KEY_NO_ARGS case above, + just sanity check. */ + if (remaining >= argc) + error (EXIT_FAILURE, 0, N_("No input file given")); + + /* Likewise for the ARGP_KEY_ARGS case above, an extra sanity check. */ + if (foutput != NULL && remaining + 1 < argc) + error (EXIT_FAILURE, 0, + N_("Only one input file allowed together with '-o'")); + + elf_version (EV_CURRENT); + + /* Process all the remaining files. */ + int result = 0; + do + result |= process_file (argv[remaining]); + while (++remaining < argc); + + free_patterns (); + return result; +} diff --git a/src/elflint.c b/src/elflint.c new file mode 100644 index 00000000..85cc7833 --- /dev/null +++ b/src/elflint.c @@ -0,0 +1,4825 @@ +/* Pedantic checking of ELF files compliance with gABI/psABI spec. + Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "../libelf/libelfP.h" +#include "../libelf/common.h" +#include "../libebl/libeblP.h" +#include "../libdw/libdwP.h" +#include "../libdwfl/libdwflP.h" +#include "../libdw/memory-access.h" + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +#define ARGP_strict 300 +#define ARGP_gnuld 301 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { "strict", ARGP_strict, NULL, 0, + N_("Be extremely strict, flag level 2 features."), 0 }, + { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, + { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 }, + { "gnu-ld", ARGP_gnuld, NULL, 0, + N_("Binary has been created with GNU ld and is therefore known to be \ +broken in certain ways"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Pedantic checking of ELF files compliance with gABI/psABI spec."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("FILE..."); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + + +/* Declarations of local functions. */ +static void process_file (int fd, Elf *elf, const char *prefix, + const char *suffix, const char *fname, size_t size, + bool only_one); +static void process_elf_file (Elf *elf, const char *prefix, const char *suffix, + const char *fname, size_t size, bool only_one); +static void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, + GElf_Shdr *shdr, int idx); + + +/* Report an error. */ +#define ERROR(str, args...) \ + do { \ + printf (str, ##args); \ + ++error_count; \ + } while (0) +static unsigned int error_count; + +/* True if we should perform very strict testing. */ +static bool be_strict; + +/* True if no message is to be printed if the run is successful. */ +static bool be_quiet; + +/* True if binary is from strip -f, not a normal ELF file. */ +static bool is_debuginfo; + +/* True if binary is assumed to be generated with GNU ld. */ +static bool gnuld; + +/* Index of section header string table. */ +static uint32_t shstrndx; + +/* Array to count references in section groups. */ +static int *scnref; + +/* Numbers of sections and program headers. */ +static unsigned int shnum; +static unsigned int phnum; + + +int +main (int argc, char *argv[]) +{ + /* Set locale. */ + setlocale (LC_ALL, ""); + + /* Initialize the message catalog. */ + textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + int remaining; + argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* Before we start tell the ELF library which version we are using. */ + elf_version (EV_CURRENT); + + /* Now process all the files given at the command line. */ + bool only_one = remaining + 1 == argc; + do + { + /* Open the file. */ + int fd = open (argv[remaining], O_RDONLY); + if (fd == -1) + { + error (0, errno, _("cannot open input file '%s'"), argv[remaining]); + continue; + } + + /* Create an `Elf' descriptor. */ + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + ERROR (_("cannot generate Elf descriptor for '%s': %s\n"), + argv[remaining], elf_errmsg (-1)); + else + { + unsigned int prev_error_count = error_count; + struct stat st; + + if (fstat (fd, &st) != 0) + { + printf ("cannot stat '%s': %m\n", argv[remaining]); + close (fd); + continue; + } + + process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size, + only_one); + + /* Now we can close the descriptor. */ + if (elf_end (elf) != 0) + ERROR (_("error while closing Elf descriptor: %s\n"), + elf_errmsg (-1)); + + if (prev_error_count == error_count && !be_quiet) + puts (_("No errors")); + } + + close (fd); + } + while (++remaining < argc); + + return error_count != 0; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg __attribute__ ((unused)), + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case ARGP_strict: + be_strict = true; + break; + + case 'q': + be_quiet = true; + break; + + case 'd': + is_debuginfo = true; + break; + + case ARGP_gnuld: + gnuld = true; + break; + + case ARGP_KEY_NO_ARGS: + fputs (_("Missing file name.\n"), stderr); + argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name); + exit (EXIT_FAILURE); + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +/* Process one file. */ +static void +process_file (int fd, Elf *elf, const char *prefix, const char *suffix, + const char *fname, size_t size, bool only_one) +{ + /* We can handle two types of files: ELF files and archives. */ + Elf_Kind kind = elf_kind (elf); + + switch (kind) + { + case ELF_K_ELF: + /* Yes! It's an ELF file. */ + process_elf_file (elf, prefix, suffix, fname, size, only_one); + break; + + case ELF_K_AR: + { + Elf *subelf; + Elf_Cmd cmd = ELF_C_READ_MMAP; + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t fname_len = strlen (fname) + 1; + char new_prefix[prefix_len + 1 + fname_len]; + char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2]; + char *cp = new_prefix; + + /* Create the full name of the file. */ + if (prefix != NULL) + { + cp = mempcpy (cp, prefix, prefix_len); + *cp++ = '('; + strcpy (stpcpy (new_suffix, suffix), ")"); + } + else + new_suffix[0] = '\0'; + memcpy (cp, fname, fname_len); + + /* It's an archive. We process each file in it. */ + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + kind = elf_kind (subelf); + + /* Call this function recursively. */ + if (kind == ELF_K_ELF || kind == ELF_K_AR) + { + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + assert (arhdr != NULL); + + process_file (fd, subelf, new_prefix, new_suffix, + arhdr->ar_name, arhdr->ar_size, false); + } + + /* Get next archive element. */ + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + ERROR (_(" error while freeing sub-ELF descriptor: %s\n"), + elf_errmsg (-1)); + } + } + break; + + default: + /* We cannot do anything. */ + ERROR (_("\ +Not an ELF file - it has the wrong magic bytes at the start\n")); + break; + } +} + + +static const char * +section_name (Ebl *ebl, int idx) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + const char *ret; + + if ((unsigned int) idx > shnum) + return ""; + + shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); + if (shdr == NULL) + return ""; + + ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); + if (ret == NULL) + return ""; + return ret; +} + + +static const int valid_e_machine[] = + { + EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370, + EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC, + EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM, + EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300, + EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE, + EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16, + EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7, + EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, + EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, + EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, + EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA, + EM_TILEGX, EM_TILEPRO, EM_AARCH64, EM_BPF, EM_RISCV, EM_CSKY + }; +#define nvalid_e_machine \ + (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) + + +static void +check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) +{ + char buf[512]; + size_t cnt; + + /* Check e_ident field. */ + if (ehdr->e_ident[EI_MAG0] != ELFMAG0) + ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0); + if (ehdr->e_ident[EI_MAG1] != ELFMAG1) + ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1); + if (ehdr->e_ident[EI_MAG2] != ELFMAG2) + ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2); + if (ehdr->e_ident[EI_MAG3] != ELFMAG3) + ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3); + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 + && ehdr->e_ident[EI_CLASS] != ELFCLASS64) + ERROR (_("e_ident[%d] == %d is no known class\n"), + EI_CLASS, ehdr->e_ident[EI_CLASS]); + + if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB + && ehdr->e_ident[EI_DATA] != ELFDATA2MSB) + ERROR (_("e_ident[%d] == %d is no known data encoding\n"), + EI_DATA, ehdr->e_ident[EI_DATA]); + + if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) + ERROR (_("unknown ELF header version number e_ident[%d] == %d\n"), + EI_VERSION, ehdr->e_ident[EI_VERSION]); + + /* We currently don't handle any OS ABIs other than Linux and the + kFreeBSD variant of Debian. */ + if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE + && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX + && ehdr->e_ident[EI_OSABI] != ELFOSABI_FREEBSD) + ERROR (_("unsupported OS ABI e_ident[%d] == '%s'\n"), + EI_OSABI, + ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); + + /* No ABI versions other than zero are supported either. */ + if (ehdr->e_ident[EI_ABIVERSION] != 0) + ERROR (_("unsupported ABI version e_ident[%d] == %d\n"), + EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]); + + for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt) + if (ehdr->e_ident[cnt] != 0) + ERROR (_("e_ident[%zu] is not zero\n"), cnt); + + /* Check the e_type field. */ + if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC + && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE) + ERROR (_("unknown object file type %d\n"), ehdr->e_type); + + /* Check the e_machine field. */ + for (cnt = 0; cnt < nvalid_e_machine; ++cnt) + if (valid_e_machine[cnt] == ehdr->e_machine) + break; + if (cnt == nvalid_e_machine) + ERROR (_("unknown machine type %d\n"), ehdr->e_machine); + + /* Check the e_version field. */ + if (ehdr->e_version != EV_CURRENT) + ERROR (_("unknown object file version\n")); + + /* Check the e_phoff and e_phnum fields. */ + if (ehdr->e_phoff == 0) + { + if (ehdr->e_phnum != 0) + ERROR (_("invalid program header offset\n")); + else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) + ERROR (_("\ +executables and DSOs cannot have zero program header offset\n")); + } + else if (ehdr->e_phnum == 0) + ERROR (_("invalid number of program header entries\n")); + + /* Check the e_shoff field. */ + shnum = ehdr->e_shnum; + shstrndx = ehdr->e_shstrndx; + if (ehdr->e_shoff == 0) + { + if (ehdr->e_shnum != 0) + ERROR (_("invalid section header table offset\n")); + else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN + && ehdr->e_type != ET_CORE) + ERROR (_("section header table must be present\n")); + } + else + { + if (ehdr->e_shnum == 0) + { + /* Get the header of the zeroth section. The sh_size field + might contain the section number. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr != NULL) + { + /* The error will be reported later. */ + if (shdr->sh_size == 0) + ERROR (_("\ +invalid number of section header table entries\n")); + else + shnum = shdr->sh_size; + } + } + + if (ehdr->e_shstrndx == SHN_XINDEX) + { + /* Get the header of the zeroth section. The sh_size field + might contain the section number. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr != NULL && shdr->sh_link < shnum) + shstrndx = shdr->sh_link; + } + else if (shstrndx >= shnum) + ERROR (_("invalid section header index\n")); + } + + /* Check the shdrs actually exist. And uncompress them before + further checking. Indexes between sections reference the + uncompressed data. */ + unsigned int scnt; + Elf_Scn *scn = NULL; + for (scnt = 1; scnt < shnum; ++scnt) + { + scn = elf_nextscn (ebl->elf, scn); + if (scn == NULL) + break; + /* If the section wasn't compressed this does nothing, but + returns an error. We don't care. */ + if (elf_compress (scn, 0, 0) < 0) { ; } + } + if (scnt < shnum) + ERROR (_("Can only check %u headers, shnum was %u\n"), scnt, shnum); + shnum = scnt; + + phnum = ehdr->e_phnum; + if (ehdr->e_phnum == PN_XNUM) + { + /* Get the header of the zeroth section. The sh_info field + might contain the phnum count. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr != NULL) + { + /* The error will be reported later. */ + if (shdr->sh_info < PN_XNUM) + ERROR (_("\ +invalid number of program header table entries\n")); + else + phnum = shdr->sh_info; + } + } + + /* Check the phdrs actually exist. */ + unsigned int pcnt; + for (pcnt = 0; pcnt < phnum; ++pcnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); + if (phdr == NULL) + break; + } + if (pcnt < phnum) + ERROR (_("Can only check %u headers, phnum was %u\n"), pcnt, phnum); + phnum = pcnt; + + /* Check the e_flags field. */ + if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) + ERROR (_("invalid machine flags: %s\n"), + ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); + + /* Check e_ehsize, e_phentsize, and e_shentsize fields. */ + if (gelf_getclass (ebl->elf) == ELFCLASS32) + { + if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr)) + ERROR (_("invalid ELF header size: %hd\n"), ehdr->e_ehsize); + + if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr)) + ERROR (_("invalid program header size: %hd\n"), + ehdr->e_phentsize); + else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size) + ERROR (_("invalid program header position or size\n")); + + if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr)) + ERROR (_("invalid section header size: %hd\n"), + ehdr->e_shentsize); + else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size) + ERROR (_("invalid section header position or size\n")); + } + else if (gelf_getclass (ebl->elf) == ELFCLASS64) + { + if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr)) + ERROR (_("invalid ELF header size: %hd\n"), ehdr->e_ehsize); + + if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr)) + ERROR (_("invalid program header size: %hd\n"), + ehdr->e_phentsize); + else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size) + ERROR (_("invalid program header position or size\n")); + + if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr)) + ERROR (_("invalid section header size: %hd\n"), + ehdr->e_shentsize); + else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size) + ERROR (_("invalid section header position or size\n")); + } +} + + +/* Check that there is a section group section with index < IDX which + contains section IDX and that there is exactly one. */ +static void +check_scn_group (Ebl *ebl, int idx) +{ + if (scnref[idx] == 0) + { + /* No reference so far. Search following sections, maybe the + order is wrong. */ + size_t cnt; + + for (cnt = idx + 1; cnt < shnum; ++cnt) + { + Elf_Scn *scn = elf_getscn (ebl->elf, cnt); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + /* We cannot get the section header so we cannot check it. + The error to get the section header will be shown + somewhere else. */ + continue; + + if (shdr->sh_type != SHT_GROUP) + continue; + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL || data->d_buf == NULL + || data->d_size < sizeof (Elf32_Word)) + /* Cannot check the section. */ + continue; + + Elf32_Word *grpdata = (Elf32_Word *) data->d_buf; + for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word); + ++inner) + if (grpdata[inner] == (Elf32_Word) idx) + goto out; + } + + out: + if (cnt == shnum) + ERROR (_("\ +section [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"), + idx, section_name (ebl, idx)); + else + ERROR (_("\ +section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"), + idx, section_name (ebl, idx), + cnt, section_name (ebl, cnt)); + } +} + + +static void +check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + bool no_xndx_warned = false; + int no_pt_tls = 0; + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + GElf_Shdr strshdr_mem; + GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &strshdr_mem); + if (strshdr == NULL) + return; + + if (strshdr->sh_type != SHT_STRTAB) + { + ERROR (_("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), + shdr->sh_link, section_name (ebl, shdr->sh_link), + idx, section_name (ebl, idx)); + strshdr = NULL; + } + + /* Search for an extended section index table section. */ + Elf_Data *xndxdata = NULL; + Elf32_Word xndxscnidx = 0; + bool found_xndx = false; + for (size_t cnt = 1; cnt < shnum; ++cnt) + if (cnt != (size_t) idx) + { + Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt); + GElf_Shdr xndxshdr_mem; + GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); + if (xndxshdr == NULL) + continue; + + if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX + && xndxshdr->sh_link == (GElf_Word) idx) + { + if (found_xndx) + ERROR (_("\ +section [%2d] '%s': symbol table cannot have more than one extended index section\n"), + idx, section_name (ebl, idx)); + + xndxdata = elf_getdata (xndxscn, NULL); + xndxscnidx = elf_ndxscn (xndxscn); + found_xndx = true; + } + } + + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT); + if (shdr->sh_entsize != sh_entsize) + ERROR (_("\ +section [%2u] '%s': entry size is does not match ElfXX_Sym\n"), + idx, section_name (ebl, idx)); + else if (shdr->sh_info > shdr->sh_size / sh_entsize) + ERROR (_("\ +section [%2u] '%s': number of local entries in 'st_info' larger than table size\n"), + idx, section_name (ebl, idx)); + + /* Test the zeroth entry. */ + GElf_Sym sym_mem; + Elf32_Word xndx; + GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx); + if (sym == NULL) + ERROR (_("section [%2d] '%s': cannot get symbol %d: %s\n"), + idx, section_name (ebl, idx), 0, elf_errmsg (-1)); + else + { + if (sym->st_name != 0) + ERROR (_("section [%2d] '%s': '%s' in zeroth entry not zero\n"), + idx, section_name (ebl, idx), "st_name"); + if (sym->st_value != 0) + ERROR (_("section [%2d] '%s': '%s' in zeroth entry not zero\n"), + idx, section_name (ebl, idx), "st_value"); + if (sym->st_size != 0) + ERROR (_("section [%2d] '%s': '%s' in zeroth entry not zero\n"), + idx, section_name (ebl, idx), "st_size"); + if (sym->st_info != 0) + ERROR (_("section [%2d] '%s': '%s' in zeroth entry not zero\n"), + idx, section_name (ebl, idx), "st_info"); + if (sym->st_other != 0) + ERROR (_("section [%2d] '%s': '%s' in zeroth entry not zero\n"), + idx, section_name (ebl, idx), "st_other"); + if (sym->st_shndx != 0) + ERROR (_("section [%2d] '%s': '%s' in zeroth entry not zero\n"), + idx, section_name (ebl, idx), "st_shndx"); + if (xndxdata != NULL && xndx != 0) + ERROR (_("\ +section [%2d] '%s': XINDEX for zeroth entry not zero\n"), + xndxscnidx, section_name (ebl, xndxscnidx)); + } + + for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt) + { + sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); + if (sym == NULL) + { + ERROR (_("section [%2d] '%s': cannot get symbol %zu: %s\n"), + idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); + continue; + } + + const char *name = ""; + if (strshdr == NULL) + name = ""; + else if (sym->st_name >= strshdr->sh_size) + ERROR (_("\ +section [%2d] '%s': symbol %zu: invalid name value\n"), + idx, section_name (ebl, idx), cnt); + else + { + name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); + if (name == NULL) + name = ""; + } + + if (sym->st_shndx == SHN_XINDEX) + { + if (xndxdata == NULL) + { + if (!no_xndx_warned) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): too large section index but no extended section index section\n"), + idx, section_name (ebl, idx), cnt, name); + no_xndx_warned = true; + } + else if (xndx < SHN_LORESERVE) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"), + xndxscnidx, section_name (ebl, xndxscnidx), cnt, name, + xndx); + } + else if ((sym->st_shndx >= SHN_LORESERVE + // && sym->st_shndx <= SHN_HIRESERVE always true + && sym->st_shndx != SHN_ABS + && sym->st_shndx != SHN_COMMON) + || (sym->st_shndx >= shnum + && (sym->st_shndx < SHN_LORESERVE + /* || sym->st_shndx > SHN_HIRESERVE always false */))) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): invalid section index\n"), + idx, section_name (ebl, idx), cnt, name); + else + xndx = sym->st_shndx; + + if (GELF_ST_TYPE (sym->st_info) >= STT_NUM + && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0)) + ERROR (_("section [%2d] '%s': symbol %zu (%s): unknown type\n"), + idx, section_name (ebl, idx), cnt, name); + + if (GELF_ST_BIND (sym->st_info) >= STB_NUM + && !ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), NULL, + 0)) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): unknown symbol binding\n"), + idx, section_name (ebl, idx), cnt, name); + if (GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE + && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): unique symbol not of object type\n"), + idx, section_name (ebl, idx), cnt, name); + + if (xndx == SHN_COMMON) + { + /* Common symbols can only appear in relocatable files. */ + if (ehdr->e_type != ET_REL) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): COMMON only allowed in relocatable files\n"), + idx, section_name (ebl, idx), cnt, name); + if (cnt < shdr->sh_info) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): local COMMON symbols are nonsense\n"), + idx, section_name (ebl, idx), cnt, name); + if (GELF_R_TYPE (sym->st_info) == STT_FUNC) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): function in COMMON section is nonsense\n"), + idx, section_name (ebl, idx), cnt, name); + } + else if (xndx > 0 && xndx < shnum) + { + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr; + + destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem); + if (destshdr != NULL) + { + GElf_Addr sh_addr = (ehdr->e_type == ET_REL ? 0 + : destshdr->sh_addr); + GElf_Addr st_value; + if (GELF_ST_TYPE (sym->st_info) == STT_FUNC + || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)) + st_value = sym->st_value & ebl_func_addr_mask (ebl); + else + st_value = sym->st_value; + if (GELF_ST_TYPE (sym->st_info) != STT_TLS) + { + if (! ebl_check_special_symbol (ebl, sym, name, + destshdr)) + { + if (st_value - sh_addr > destshdr->sh_size) + { + /* GNU ld has severe bugs. When it decides to remove + empty sections it leaves symbols referencing them + behind. These are symbols in .symtab or .dynsym + and for the named symbols have zero size. See + sourceware PR13621. */ + if (!gnuld + || (strcmp (section_name (ebl, idx), ".symtab") + && strcmp (section_name (ebl, idx), + ".dynsym")) + || sym->st_size != 0 + || (strcmp (name, "__preinit_array_start") != 0 + && strcmp (name, "__preinit_array_end") != 0 + && strcmp (name, "__init_array_start") != 0 + && strcmp (name, "__init_array_end") != 0 + && strcmp (name, "__fini_array_start") != 0 + && strcmp (name, "__fini_array_end") != 0 + && strcmp (name, "__bss_start") != 0 + && strcmp (name, "__bss_start__") != 0 + && strcmp (name, "__TMC_END__") != 0 + && strcmp (name, ".TOC.") != 0 + && strcmp (name, "_edata") != 0 + && strcmp (name, "__edata") != 0 + && strcmp (name, "_end") != 0 + && strcmp (name, "__end") != 0)) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): st_value out of bounds\n"), + idx, section_name (ebl, idx), cnt, name); + } + else if ((st_value - sh_addr + + sym->st_size) > destshdr->sh_size) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + } + } + else + { + if ((destshdr->sh_flags & SHF_TLS) == 0) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + + if (ehdr->e_type == ET_REL) + { + /* For object files the symbol value must fall + into the section. */ + if (st_value > destshdr->sh_size) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + else if (st_value + sym->st_size + > destshdr->sh_size) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + } + else + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = NULL; + unsigned int pcnt; + + for (pcnt = 0; pcnt < phnum; ++pcnt) + { + phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); + if (phdr != NULL && phdr->p_type == PT_TLS) + break; + } + + if (pcnt == phnum) + { + if (no_pt_tls++ == 0) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): TLS symbol but no TLS program header entry\n"), + idx, section_name (ebl, idx), cnt, name); + } + else if (phdr == NULL) + { + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): TLS symbol but couldn't get TLS program header entry\n"), + idx, section_name (ebl, idx), cnt, name); + } + else if (!is_debuginfo) + { + if (st_value + < destshdr->sh_offset - phdr->p_offset) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): st_value short of referenced section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + else if (st_value + > (destshdr->sh_offset - phdr->p_offset + + destshdr->sh_size)) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): st_value out of bounds of referenced section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + else if (st_value + sym->st_size + > (destshdr->sh_offset - phdr->p_offset + + destshdr->sh_size)) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s) does not fit completely in referenced section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, name, + (int) xndx, section_name (ebl, xndx)); + } + } + } + } + } + + if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) + { + if (cnt >= shdr->sh_info) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): local symbol outside range described in sh_info\n"), + idx, section_name (ebl, idx), cnt, name); + } + else + { + if (cnt < shdr->sh_info) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): non-local symbol outside range described in sh_info\n"), + idx, section_name (ebl, idx), cnt, name); + } + + if (GELF_ST_TYPE (sym->st_info) == STT_SECTION + && GELF_ST_BIND (sym->st_info) != STB_LOCAL) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): non-local section symbol\n"), + idx, section_name (ebl, idx), cnt, name); + + if (name != NULL) + { + if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + { + /* Check that address and size match the global offset table. */ + + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), + &destshdr_mem); + + if (destshdr == NULL && xndx == SHN_ABS) + { + /* In a DSO, we have to find the GOT section by name. */ + Elf_Scn *gotscn = NULL; + Elf_Scn *gscn = NULL; + while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) + { + destshdr = gelf_getshdr (gscn, &destshdr_mem); + assert (destshdr != NULL); + const char *sname = elf_strptr (ebl->elf, + shstrndx, + destshdr->sh_name); + if (sname != NULL) + { + if (strcmp (sname, ".got.plt") == 0) + break; + if (strcmp (sname, ".got") == 0) + /* Do not stop looking. + There might be a .got.plt section. */ + gotscn = gscn; + } + + destshdr = NULL; + } + + if (destshdr == NULL && gotscn != NULL) + destshdr = gelf_getshdr (gotscn, &destshdr_mem); + } + + const char *sname = ((destshdr == NULL || xndx == SHN_UNDEF) + ? NULL + : elf_strptr (ebl->elf, shstrndx, + destshdr->sh_name)); + if (sname == NULL) + { + if (xndx != SHN_UNDEF || ehdr->e_type != ET_REL) + ERROR (_("\ +section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \ +bad section [%2d]\n"), + idx, section_name (ebl, idx), xndx); + } + else if (strcmp (sname, ".got.plt") != 0 + && strcmp (sname, ".got") != 0) + ERROR (_("\ +section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \ +section [%2d] '%s'\n"), + idx, section_name (ebl, idx), xndx, sname); + + if (destshdr != NULL) + { + /* Found it. */ + if (!ebl_check_special_symbol (ebl, sym, name, + destshdr)) + { + if (ehdr->e_type != ET_REL + && sym->st_value != destshdr->sh_addr) + /* This test is more strict than the psABIs which + usually allow the symbol to be in the middle of + the .got section, allowing negative offsets. */ + ERROR (_("\ +section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), + idx, section_name (ebl, idx), + (uint64_t) sym->st_value, + sname, (uint64_t) destshdr->sh_addr); + + if (!gnuld && sym->st_size != destshdr->sh_size) + ERROR (_("\ +section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), + idx, section_name (ebl, idx), + (uint64_t) sym->st_size, + sname, (uint64_t) destshdr->sh_size); + } + } + else + ERROR (_("\ +section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), + idx, section_name (ebl, idx)); + } + else if (strcmp (name, "_DYNAMIC") == 0) + /* Check that address and size match the dynamic section. + We locate the dynamic section via the program header + entry. */ + for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); + + if (phdr != NULL && phdr->p_type == PT_DYNAMIC) + { + if (sym->st_value != phdr->p_vaddr) + ERROR (_("\ +section [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), + idx, section_name (ebl, idx), + (uint64_t) sym->st_value, + (uint64_t) phdr->p_vaddr); + + if (!gnuld && sym->st_size != phdr->p_memsz) + ERROR (_("\ +section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), + idx, section_name (ebl, idx), + (uint64_t) sym->st_size, + (uint64_t) phdr->p_memsz); + + break; + } + } + } + + if (GELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT + && shdr->sh_type == SHT_DYNSYM) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): symbol in dynamic symbol table with non-default visibility\n"), + idx, section_name (ebl, idx), cnt, name); + if (! ebl_check_st_other_bits (ebl, sym->st_other)) + ERROR (_("\ +section [%2d] '%s': symbol %zu (%s): unknown bit set in st_other\n"), + idx, section_name (ebl, idx), cnt, name); + + } +} + + +static bool +is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, + bool is_rela) +{ + /* If this is no executable or DSO it cannot be a .rel.dyn section. */ + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + return false; + + /* Check the section name. Unfortunately necessary. */ + if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn")) + return false; + + /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section + entry can be present as well. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr rcshdr_mem; + const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); + + if (rcshdr == NULL) + break; + + if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize != 0) + { + /* Found the dynamic section. Look through it. */ + Elf_Data *d = elf_getdata (scn, NULL); + size_t cnt; + + if (d == NULL) + ERROR (_("\ +section [%2d] '%s': cannot get section data.\n"), + idx, section_name (ebl, idx)); + + for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); + + if (dyn == NULL) + break; + + if (dyn->d_tag == DT_RELCOUNT) + { + /* Found it. Does the type match. */ + if (is_rela) + ERROR (_("\ +section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"), + idx, section_name (ebl, idx)); + else + { + /* Does the number specified number of relative + relocations exceed the total number of + relocations? */ + if (shdr->sh_entsize != 0 + && dyn->d_un.d_val > (shdr->sh_size + / shdr->sh_entsize)) + ERROR (_("\ +section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), + idx, section_name (ebl, idx), + (int) dyn->d_un.d_val); + + /* Make sure the specified number of relocations are + relative. */ + Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, + idx), NULL); + if (reldata != NULL && shdr->sh_entsize != 0) + for (size_t inner = 0; + inner < shdr->sh_size / shdr->sh_entsize; + ++inner) + { + GElf_Rel rel_mem; + GElf_Rel *rel = gelf_getrel (reldata, inner, + &rel_mem); + if (rel == NULL) + /* The problem will be reported elsewhere. */ + break; + + if (ebl_relative_reloc_p (ebl, + GELF_R_TYPE (rel->r_info))) + { + if (inner >= dyn->d_un.d_val) + ERROR (_("\ +section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), + idx, section_name (ebl, idx), + (int) dyn->d_un.d_val); + } + else if (inner < dyn->d_un.d_val) + ERROR (_("\ +section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), + idx, section_name (ebl, idx), + inner, (int) dyn->d_un.d_val); + } + } + } + + if (dyn->d_tag == DT_RELACOUNT) + { + /* Found it. Does the type match. */ + if (!is_rela) + ERROR (_("\ +section [%2d] '%s': DT_RELACOUNT used for this REL section\n"), + idx, section_name (ebl, idx)); + else + { + /* Does the number specified number of relative + relocations exceed the total number of + relocations? */ + if (shdr->sh_entsize != 0 + && dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) + ERROR (_("\ +section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), + idx, section_name (ebl, idx), + (int) dyn->d_un.d_val); + + /* Make sure the specified number of relocations are + relative. */ + Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, + idx), NULL); + if (reldata != NULL && shdr->sh_entsize != 0) + for (size_t inner = 0; + inner < shdr->sh_size / shdr->sh_entsize; + ++inner) + { + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (reldata, inner, + &rela_mem); + if (rela == NULL) + /* The problem will be reported elsewhere. */ + break; + + if (ebl_relative_reloc_p (ebl, + GELF_R_TYPE (rela->r_info))) + { + if (inner >= dyn->d_un.d_val) + ERROR (_("\ +section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), + idx, section_name (ebl, idx), + (int) dyn->d_un.d_val); + } + else if (inner < dyn->d_un.d_val) + ERROR (_("\ +section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), + idx, section_name (ebl, idx), + inner, (int) dyn->d_un.d_val); + } + } + } + } + + break; + } + } + + return true; +} + + +struct loaded_segment +{ + GElf_Addr from; + GElf_Addr to; + bool read_only; + struct loaded_segment *next; +}; + + +/* Check whether binary has text relocation flag set. */ +static bool textrel; + +/* Keep track of whether text relocation flag is needed. */ +static bool needed_textrel; + + +static bool +check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, + int idx, int reltype, GElf_Shdr **destshdrp, + GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp) +{ + bool reldyn = false; + + /* Check whether the link to the section we relocate is reasonable. */ + if (shdr->sh_info >= shnum) + ERROR (_("section [%2d] '%s': invalid destination section index\n"), + idx, section_name (ebl, idx)); + else if (shdr->sh_info != 0) + { + *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), + destshdr_memp); + if (*destshdrp != NULL) + { + if(! ebl_check_reloc_target_type (ebl, (*destshdrp)->sh_type)) + { + reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); + if (!reldyn) + ERROR (_("\ +section [%2d] '%s': invalid destination section type\n"), + idx, section_name (ebl, idx)); + else + { + /* There is no standard, but we require that .rel{,a}.dyn + sections have a sh_info value of zero. */ + if (shdr->sh_info != 0) + ERROR (_("\ +section [%2d] '%s': sh_info should be zero\n"), + idx, section_name (ebl, idx)); + } + } + + if ((((*destshdrp)->sh_flags & SHF_MERGE) != 0) + && ((*destshdrp)->sh_flags & SHF_STRINGS) != 0) + ERROR (_("\ +section [%2d] '%s': no relocations for merge-able string sections possible\n"), + idx, section_name (ebl, idx)); + } + } + + size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT); + if (shdr->sh_entsize != sh_entsize) + ERROR (_(reltype == ELF_T_RELA ? "\ +section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ +section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), + idx, section_name (ebl, idx)); + + /* In preparation of checking whether relocations are text + relocations or not we need to determine whether the file is + flagged to have text relocation and we need to determine a) what + the loaded segments are and b) which are read-only. This will + also allow us to determine whether the same reloc section is + modifying loaded and not loaded segments. */ + for (unsigned int i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); + if (phdr == NULL) + continue; + + if (phdr->p_type == PT_LOAD) + { + struct loaded_segment *newp = xmalloc (sizeof (*newp)); + newp->from = phdr->p_vaddr; + newp->to = phdr->p_vaddr + phdr->p_memsz; + newp->read_only = (phdr->p_flags & PF_W) == 0; + newp->next = *loadedp; + *loadedp = newp; + } + else if (phdr->p_type == PT_DYNAMIC) + { + Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset); + GElf_Shdr dynshdr_mem; + GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem); + Elf_Data *dyndata = elf_getdata (dynscn, NULL); + if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC + && dyndata != NULL && dynshdr->sh_entsize != 0) + for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem); + if (dyn != NULL + && (dyn->d_tag == DT_TEXTREL + || (dyn->d_tag == DT_FLAGS + && (dyn->d_un.d_val & DF_TEXTREL) != 0))) + { + textrel = true; + break; + } + } + } + } + + /* A quick test which can be easily done here (although it is a bit + out of place): the text relocation flag makes only sense if there + is a segment which is not writable. */ + if (textrel) + { + struct loaded_segment *seg = *loadedp; + while (seg != NULL && !seg->read_only) + seg = seg->next; + if (seg == NULL) + ERROR (_("\ +text relocation flag set but there is no read-only segment\n")); + } + + return reldyn; +} + + +enum load_state + { + state_undecided, + state_loaded, + state_unloaded, + state_error + }; + + +static void +check_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx, + size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata, + GElf_Addr r_offset, GElf_Xword r_info, + const GElf_Shdr *destshdr, bool reldyn, + struct loaded_segment *loaded, enum load_state *statep) +{ + bool known_broken = gnuld; + + if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) + ERROR (_("section [%2d] '%s': relocation %zu: invalid type\n"), + idx, section_name (ebl, idx), cnt); + else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + /* The executable/DSO can contain relocation sections with + all the relocations the linker has applied. Those sections + are marked non-loaded, though. */ + || (relshdr->sh_flags & SHF_ALLOC) != 0) + && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) + ERROR (_("\ +section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), + idx, section_name (ebl, idx), cnt); + + if (symshdr != NULL + && ((GELF_R_SYM (r_info) + 1) + * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) + > symshdr->sh_size)) + ERROR (_("\ +section [%2d] '%s': relocation %zu: invalid symbol index\n"), + idx, section_name (ebl, idx), cnt); + + /* No more tests if this is a no-op relocation. */ + if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info))) + return; + + if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) + { + const char *name; + char buf[64]; + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); + if (sym != NULL + /* Get the name for the symbol. */ + && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) + && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) + ERROR (_("\ +section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), + idx, section_name (ebl, idx), cnt, + ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), + buf, sizeof (buf))); + } + + if (reldyn) + { + // XXX TODO Check .rel.dyn section addresses. + } + else if (!known_broken) + { + if (destshdr != NULL + && GELF_R_TYPE (r_info) != 0 + && (r_offset - (ehdr->e_type == ET_REL ? 0 + : destshdr->sh_addr)) >= destshdr->sh_size) + ERROR (_("\ +section [%2d] '%s': relocation %zu: offset out of bounds\n"), + idx, section_name (ebl, idx), cnt); + } + + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); + + if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info)) + /* Make sure the referenced symbol is an object or unspecified. */ + && sym != NULL + && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE + && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) + { + char buf[64]; + ERROR (_("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), + idx, section_name (ebl, idx), cnt, + ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), + buf, sizeof (buf))); + } + + if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + || (relshdr->sh_flags & SHF_ALLOC) != 0) + { + bool in_loaded_seg = false; + while (loaded != NULL) + { + if (r_offset < loaded->to + && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from) + { + /* The symbol is in this segment. */ + if (loaded->read_only) + { + if (textrel) + needed_textrel = true; + else + ERROR (_("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"), + idx, section_name (ebl, idx), cnt); + } + + in_loaded_seg = true; + } + + loaded = loaded->next; + } + + if (*statep == state_undecided) + *statep = in_loaded_seg ? state_loaded : state_unloaded; + else if ((*statep == state_unloaded && in_loaded_seg) + || (*statep == state_loaded && !in_loaded_seg)) + { + ERROR (_("\ +section [%2d] '%s': relocations are against loaded and unloaded data\n"), + idx, section_name (ebl, idx)); + *statep = state_error; + } + } +} + + +static void +check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + /* Check the fields of the section header. */ + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = NULL; + struct loaded_segment *loaded = NULL; + bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, + &destshdr_mem, &loaded); + + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + enum load_state state = state_undecided; + + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); + for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) + { + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); + if (rela == NULL) + { + ERROR (_("\ +section [%2d] '%s': cannot get relocation %zu: %s\n"), + idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); + continue; + } + + check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, + rela->r_offset, rela->r_info, destshdr, reldyn, loaded, + &state); + } + + while (loaded != NULL) + { + struct loaded_segment *old = loaded; + loaded = loaded->next; + free (old); + } +} + + +static void +check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + /* Check the fields of the section header. */ + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = NULL; + struct loaded_segment *loaded = NULL; + bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, + &destshdr_mem, &loaded); + + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + enum load_state state = state_undecided; + + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); + for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) + { + GElf_Rel rel_mem; + GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); + if (rel == NULL) + { + ERROR (_("\ +section [%2d] '%s': cannot get relocation %zu: %s\n"), + idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); + continue; + } + + check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, + rel->r_offset, rel->r_info, destshdr, reldyn, loaded, + &state); + } + + while (loaded != NULL) + { + struct loaded_segment *old = loaded; + loaded = loaded->next; + free (old); + } +} + + +/* Number of dynamic sections. */ +static int ndynamic; + + +static void +check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + Elf_Data *data; + GElf_Shdr strshdr_mem; + GElf_Shdr *strshdr; + size_t cnt; + static const bool dependencies[DT_NUM][DT_NUM] = + { + [DT_NEEDED] = { [DT_STRTAB] = true }, + [DT_PLTRELSZ] = { [DT_JMPREL] = true }, + [DT_HASH] = { [DT_SYMTAB] = true }, + [DT_STRTAB] = { [DT_STRSZ] = true }, + [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true }, + [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, + [DT_RELASZ] = { [DT_RELA] = true }, + [DT_RELAENT] = { [DT_RELA] = true }, + [DT_STRSZ] = { [DT_STRTAB] = true }, + [DT_SYMENT] = { [DT_SYMTAB] = true }, + [DT_SONAME] = { [DT_STRTAB] = true }, + [DT_RPATH] = { [DT_STRTAB] = true }, + [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, + [DT_RELSZ] = { [DT_REL] = true }, + [DT_RELENT] = { [DT_REL] = true }, + [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, + [DT_RUNPATH] = { [DT_STRTAB] = true }, + [DT_PLTREL] = { [DT_JMPREL] = true }, + }; + bool has_dt[DT_NUM]; + bool has_val_dt[DT_VALNUM]; + bool has_addr_dt[DT_ADDRNUM]; + static const bool level2[DT_NUM] = + { + [DT_RPATH] = true, + [DT_SYMBOLIC] = true, + [DT_TEXTREL] = true, + [DT_BIND_NOW] = true + }; + static const bool mandatory[DT_NUM] = + { + [DT_NULL] = true, + [DT_STRTAB] = true, + [DT_SYMTAB] = true, + [DT_STRSZ] = true, + [DT_SYMENT] = true + }; + + memset (has_dt, '\0', sizeof (has_dt)); + memset (has_val_dt, '\0', sizeof (has_val_dt)); + memset (has_addr_dt, '\0', sizeof (has_addr_dt)); + + if (++ndynamic == 2) + ERROR (_("more than one dynamic section present\n")); + + data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); + if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) + ERROR (_("\ +section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), + shdr->sh_link, section_name (ebl, shdr->sh_link), + idx, section_name (ebl, idx)); + else if (strshdr == NULL) + { + ERROR (_("\ +section [%2d]: referenced as string table for section [%2d] '%s' but section link value is invalid\n"), + shdr->sh_link, idx, section_name (ebl, idx)); + return; + } + + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT); + if (shdr->sh_entsize != sh_entsize) + ERROR (_("\ +section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), + idx, section_name (ebl, idx)); + + if (shdr->sh_info != 0) + ERROR (_("section [%2d] '%s': sh_info not zero\n"), + idx, section_name (ebl, idx)); + + bool non_null_warned = false; + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem); + if (dyn == NULL) + { + ERROR (_("\ +section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), + idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); + continue; + } + + if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) + { + ERROR (_("\ +section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), + idx, section_name (ebl, idx)); + non_null_warned = true; + } + + if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) + ERROR (_("section [%2d] '%s': entry %zu: unknown tag\n"), + idx, section_name (ebl, idx), cnt); + + if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM) + { + if (has_dt[dyn->d_tag] + && dyn->d_tag != DT_NEEDED + && dyn->d_tag != DT_NULL + && dyn->d_tag != DT_POSFLAG_1) + { + char buf[50]; + ERROR (_("\ +section [%2d] '%s': entry %zu: more than one entry with tag %s\n"), + idx, section_name (ebl, idx), cnt, + ebl_dynamic_tag_name (ebl, dyn->d_tag, + buf, sizeof (buf))); + } + + if (be_strict && level2[dyn->d_tag]) + { + char buf[50]; + ERROR (_("\ +section [%2d] '%s': entry %zu: level 2 tag %s used\n"), + idx, section_name (ebl, idx), cnt, + ebl_dynamic_tag_name (ebl, dyn->d_tag, + buf, sizeof (buf))); + } + + has_dt[dyn->d_tag] = true; + } + else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_VALRNGHI + && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) + has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true; + else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_ADDRRNGHI + && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) + has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true; + + if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL + && dyn->d_un.d_val != DT_RELA) + ERROR (_("\ +section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), + idx, section_name (ebl, idx), cnt); + + /* Check that addresses for entries are in loaded segments. */ + switch (dyn->d_tag) + { + size_t n; + case DT_STRTAB: + /* We require the referenced section is the same as the one + specified in sh_link. */ + if (strshdr->sh_addr != dyn->d_un.d_val) + { + ERROR (_("\ +section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"), + idx, section_name (ebl, idx), cnt, + shdr->sh_link, section_name (ebl, shdr->sh_link)); + break; + } + goto check_addr; + + default: + if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI) + /* Value is no pointer. */ + break; + FALLTHROUGH; + + case DT_AUXILIARY: + case DT_FILTER: + case DT_FINI: + case DT_FINI_ARRAY: + case DT_HASH: + case DT_INIT: + case DT_INIT_ARRAY: + case DT_JMPREL: + case DT_PLTGOT: + case DT_REL: + case DT_RELA: + case DT_SYMBOLIC: + case DT_SYMTAB: + case DT_VERDEF: + case DT_VERNEED: + case DT_VERSYM: + check_addr: + for (n = 0; n < phnum; ++n) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem); + if (phdr != NULL && phdr->p_type == PT_LOAD + && phdr->p_vaddr <= dyn->d_un.d_ptr + && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr) + break; + } + if (unlikely (n >= phnum)) + { + char buf[50]; + ERROR (_("\ +section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"), + idx, section_name (ebl, idx), cnt, + ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, + sizeof (buf))); + } + break; + + case DT_NEEDED: + case DT_RPATH: + case DT_RUNPATH: + case DT_SONAME: + if (dyn->d_un.d_ptr >= strshdr->sh_size) + { + char buf[50]; + ERROR (_("\ +section [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"), + idx, section_name (ebl, idx), cnt, + ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, + sizeof (buf)), + shdr->sh_link, section_name (ebl, shdr->sh_link)); + } + break; + } + } + + for (cnt = 1; cnt < DT_NUM; ++cnt) + if (has_dt[cnt]) + { + for (int inner = 0; inner < DT_NUM; ++inner) + if (dependencies[cnt][inner] && ! has_dt[inner]) + { + char buf1[50]; + char buf2[50]; + + ERROR (_("\ +section [%2d] '%s': contains %s entry but not %s\n"), + idx, section_name (ebl, idx), + ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), + ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); + } + } + else + { + if (mandatory[cnt]) + { + char buf[50]; + ERROR (_("\ +section [%2d] '%s': mandatory tag %s not present\n"), + idx, section_name (ebl, idx), + ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); + } + } + + /* Make sure we have an hash table. */ + if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]) + ERROR (_("\ +section [%2d] '%s': no hash section present\n"), + idx, section_name (ebl, idx)); + + /* The GNU-style hash table also needs a symbol table. */ + if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)] + && !has_dt[DT_SYMTAB]) + ERROR (_("\ +section [%2d] '%s': contains %s entry but not %s\n"), + idx, section_name (ebl, idx), + "DT_GNU_HASH", "DT_SYMTAB"); + + /* Check the rel/rela tags. At least one group must be available. */ + if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) + && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) + ERROR (_("\ +section [%2d] '%s': not all of %s, %s, and %s are present\n"), + idx, section_name (ebl, idx), + "DT_RELA", "DT_RELASZ", "DT_RELAENT"); + + if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) + && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) + ERROR (_("\ +section [%2d] '%s': not all of %s, %s, and %s are present\n"), + idx, section_name (ebl, idx), + "DT_REL", "DT_RELSZ", "DT_RELENT"); + + /* Check that all prelink sections are present if any of them is. */ + if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)] + || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) + { + if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]) + ERROR (_("\ +section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), + idx, section_name (ebl, idx), "DT_GNU_PRELINKED"); + if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) + ERROR (_("\ +section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), + idx, section_name (ebl, idx), "DT_CHECKSUM"); + + /* Only DSOs can be marked like this. */ + if (ehdr->e_type != ET_DYN) + ERROR (_("\ +section [%2d] '%s': non-DSO file marked as dependency during prelink\n"), + idx, section_name (ebl, idx)); + } + + if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)] + || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)] + || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)] + || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) + { + if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]) + ERROR (_("\ +section [%2d] '%s': %s tag missing in prelinked executable\n"), + idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ"); + if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]) + ERROR (_("\ +section [%2d] '%s': %s tag missing in prelinked executable\n"), + idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ"); + if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]) + ERROR (_("\ +section [%2d] '%s': %s tag missing in prelinked executable\n"), + idx, section_name (ebl, idx), "DT_GNU_CONFLICT"); + if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) + ERROR (_("\ +section [%2d] '%s': %s tag missing in prelinked executable\n"), + idx, section_name (ebl, idx), "DT_GNU_LIBLIST"); + } +} + + +static void +check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + if (ehdr->e_type != ET_REL) + { + ERROR (_("\ +section [%2d] '%s': only relocatable files can have extended section index\n"), + idx, section_name (ebl, idx)); + return; + } + + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) + ERROR (_("\ +section [%2d] '%s': extended section index section not for symbol table\n"), + idx, section_name (ebl, idx)); + else if (symshdr == NULL) + ERROR (_("\ +section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"), + idx, section_name (ebl, idx), shdr->sh_link); + Elf_Data *symdata = elf_getdata (symscn, NULL); + if (symdata == NULL) + ERROR (_("cannot get data for symbol section\n")); + + if (shdr->sh_entsize != sizeof (Elf32_Word)) + ERROR (_("\ +section [%2d] '%s': entry size does not match Elf32_Word\n"), + idx, section_name (ebl, idx)); + + if (symshdr != NULL + && shdr->sh_entsize != 0 + && symshdr->sh_entsize != 0 + && (shdr->sh_size / shdr->sh_entsize + < symshdr->sh_size / symshdr->sh_entsize)) + ERROR (_("\ +section [%2d] '%s': extended index table too small for symbol table\n"), + idx, section_name (ebl, idx)); + + if (shdr->sh_info != 0) + ERROR (_("section [%2d] '%s': sh_info not zero\n"), + idx, section_name (ebl, idx)); + + for (size_t cnt = idx + 1; cnt < shnum; ++cnt) + { + GElf_Shdr rshdr_mem; + GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); + if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX + && rshdr->sh_link == shdr->sh_link) + { + ERROR (_("\ +section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), + idx, section_name (ebl, idx), + cnt, section_name (ebl, cnt)); + break; + } + } + + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL || data->d_buf == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + if (data->d_size < sizeof (Elf32_Word) + || *((Elf32_Word *) data->d_buf) != 0) + ERROR (_("symbol 0 should have zero extended section index\n")); + + for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) + { + Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; + + if (xndx != 0) + { + GElf_Sym sym_data; + GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); + if (sym == NULL) + { + ERROR (_("cannot get data for symbol %zu\n"), cnt); + continue; + } + + if (sym->st_shndx != SHN_XINDEX) + ERROR (_("\ +extended section index is %" PRIu32 " but symbol index is not XINDEX\n"), + (uint32_t) xndx); + } + } +} + + +static void +check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, + GElf_Shdr *symshdr) +{ + Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; + Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; + + if (shdr->sh_size < (2ULL + nbucket + nchain) * sizeof (Elf32_Word)) + { + ERROR (_("\ +section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), + idx, section_name (ebl, idx), (long int) shdr->sh_size, + (long int) ((2 + nbucket + nchain) * sizeof (Elf32_Word))); + return; + } + + size_t maxidx = nchain; + + if (symshdr != NULL && symshdr->sh_entsize != 0) + { + size_t symsize = symshdr->sh_size / symshdr->sh_entsize; + + if (nchain > symshdr->sh_size / symshdr->sh_entsize) + ERROR (_("section [%2d] '%s': chain array too large\n"), + idx, section_name (ebl, idx)); + + maxidx = symsize; + } + + Elf32_Word *buf = (Elf32_Word *) data->d_buf; + Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size); + size_t cnt; + for (cnt = 2; cnt < 2 + nbucket; ++cnt) + { + if (buf + cnt >= end) + break; + else if (buf[cnt] >= maxidx) + ERROR (_("\ +section [%2d] '%s': hash bucket reference %zu out of bounds\n"), + idx, section_name (ebl, idx), cnt - 2); + } + + for (; cnt < 2 + nbucket + nchain; ++cnt) + { + if (buf + cnt >= end) + break; + else if (buf[cnt] >= maxidx) + ERROR (_("\ +section [%2d] '%s': hash chain reference %zu out of bounds\n"), + idx, section_name (ebl, idx), cnt - 2 - nbucket); + } +} + + +static void +check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, + GElf_Shdr *symshdr) +{ + Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; + Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; + + uint64_t maxwords = shdr->sh_size / sizeof (Elf64_Xword); + if (maxwords < 2 + || maxwords - 2 < nbucket + || maxwords - 2 - nbucket < nchain) + { + ERROR (_("\ +section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), + idx, section_name (ebl, idx), (long int) shdr->sh_size, + (long int) ((2 + nbucket + nchain) * sizeof (Elf64_Xword))); + return; + } + + size_t maxidx = nchain; + + if (symshdr != NULL && symshdr->sh_entsize != 0) + { + size_t symsize = symshdr->sh_size / symshdr->sh_entsize; + + if (nchain > symshdr->sh_size / symshdr->sh_entsize) + ERROR (_("section [%2d] '%s': chain array too large\n"), + idx, section_name (ebl, idx)); + + maxidx = symsize; + } + + Elf64_Xword *buf = (Elf64_Xword *) data->d_buf; + Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size); + size_t cnt; + for (cnt = 2; cnt < 2 + nbucket; ++cnt) + { + if (buf + cnt >= end) + break; + else if (buf[cnt] >= maxidx) + ERROR (_("\ +section [%2d] '%s': hash bucket reference %zu out of bounds\n"), + idx, section_name (ebl, idx), cnt - 2); + } + + for (; cnt < 2 + nbucket + nchain; ++cnt) + { + if (buf + cnt >= end) + break; + else if (buf[cnt] >= maxidx) + ERROR (_("\ +section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"), + idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket); + } +} + + +static void +check_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, + GElf_Shdr *symshdr) +{ + if (data->d_size < 4 * sizeof (Elf32_Word)) + { + ERROR (_("\ +section [%2d] '%s': not enough data\n"), + idx, section_name (ebl, idx)); + return; + } + + Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0]; + Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; + Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; + + if (bitmask_words == 0 || !powerof2 (bitmask_words)) + { + ERROR (_("\ +section [%2d] '%s': bitmask size zero or not power of 2: %u\n"), + idx, section_name (ebl, idx), bitmask_words); + return; + } + + size_t bitmask_idxmask = bitmask_words - 1; + if (gelf_getclass (ebl->elf) == ELFCLASS64) + bitmask_words *= 2; + Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; + + /* Is there still room for the sym chain? + Use uint64_t calculation to prevent 32bit overflow. */ + uint64_t used_buf = (4ULL + bitmask_words + nbuckets) * sizeof (Elf32_Word); + if (used_buf > data->d_size) + { + ERROR (_("\ +section [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"), + idx, section_name (ebl, idx), (long int) shdr->sh_size, + (long int) used_buf); + return; + } + + if (shift > 31) + { + ERROR (_("\ +section [%2d] '%s': 2nd hash function shift too big: %u\n"), + idx, section_name (ebl, idx), shift); + return; + } + + size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words + + nbuckets); + + if (symshdr != NULL && symshdr->sh_entsize != 0) + maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize); + + /* We need the symbol section data. */ + Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL); + + union + { + Elf32_Word *p32; + Elf64_Xword *p64; + } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] }, + collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) }; + + size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64; + + size_t cnt; + for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt) + { + Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt]; + + if (symidx == 0) + continue; + + if (symidx < symbias) + { + ERROR (_("\ +section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"), + idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); + continue; + } + + while (symidx - symbias < maxidx) + { + Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4 + + bitmask_words + + nbuckets + + symidx + - symbias]; + + if (symdata != NULL) + { + /* Check that the referenced symbol is not undefined. */ + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem); + if (sym != NULL && sym->st_shndx == SHN_UNDEF + && GELF_ST_TYPE (sym->st_info) != STT_FUNC) + ERROR (_("\ +section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"), + idx, section_name (ebl, idx), symidx, + cnt - (4 + bitmask_words)); + + const char *symname = (sym != NULL + ? elf_strptr (ebl->elf, symshdr->sh_link, + sym->st_name) + : NULL); + if (symname != NULL) + { + Elf32_Word hval = elf_gnu_hash (symname); + if ((hval & ~1u) != (chainhash & ~1u)) + ERROR (_("\ +section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"), + idx, section_name (ebl, idx), symidx, + cnt - (4 + bitmask_words)); + + /* Set the bits in the bitmask. */ + size_t maskidx = (hval / classbits) & bitmask_idxmask; + if (maskidx >= bitmask_words) + { + ERROR (_("\ +section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"), + idx, section_name (ebl, idx), symidx, + cnt - (4 + bitmask_words)); + return; + } + if (classbits == 32) + { + collected.p32[maskidx] + |= UINT32_C (1) << (hval & (classbits - 1)); + collected.p32[maskidx] + |= UINT32_C (1) << ((hval >> shift) & (classbits - 1)); + } + else + { + collected.p64[maskidx] + |= UINT64_C (1) << (hval & (classbits - 1)); + collected.p64[maskidx] + |= UINT64_C (1) << ((hval >> shift) & (classbits - 1)); + } + } + } + + if ((chainhash & 1) != 0) + break; + + ++symidx; + } + + if (symidx - symbias >= maxidx) + ERROR (_("\ +section [%2d] '%s': hash chain for bucket %zu out of bounds\n"), + idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); + else if (symshdr != NULL && symshdr->sh_entsize != 0 + && symidx > symshdr->sh_size / symshdr->sh_entsize) + ERROR (_("\ +section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"), + idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); + } + + if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word))) + ERROR (_("\ +section [%2d] '%s': bitmask does not match names in the hash table\n"), + idx, section_name (ebl, idx)); + + free (collected.p32); +} + + +static void +check_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + if (ehdr->e_type == ET_REL) + { + ERROR (_("\ +section [%2d] '%s': relocatable files cannot have hash tables\n"), + idx, section_name (ebl, idx)); + return; + } + + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL || data->d_buf == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &symshdr_mem); + if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) + ERROR (_("\ +section [%2d] '%s': hash table not for dynamic symbol table\n"), + idx, section_name (ebl, idx)); + else if (symshdr == NULL) + ERROR (_("\ +section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"), + idx, section_name (ebl, idx), shdr->sh_link); + + size_t expect_entsize = (tag == SHT_GNU_HASH + ? (gelf_getclass (ebl->elf) == ELFCLASS32 + ? sizeof (Elf32_Word) : 0) + : (size_t) ebl_sysvhash_entrysize (ebl)); + + if (shdr->sh_entsize != expect_entsize) + ERROR (_("\ +section [%2d] '%s': hash table entry size incorrect\n"), + idx, section_name (ebl, idx)); + + if ((shdr->sh_flags & SHF_ALLOC) == 0) + ERROR (_("section [%2d] '%s': not marked to be allocated\n"), + idx, section_name (ebl, idx)); + + if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (expect_entsize ?: 4)) + { + ERROR (_("\ +section [%2d] '%s': hash table has not even room for initial administrative entries\n"), + idx, section_name (ebl, idx)); + return; + } + + switch (tag) + { + case SHT_HASH: + if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) + check_sysv_hash64 (ebl, shdr, data, idx, symshdr); + else + check_sysv_hash (ebl, shdr, data, idx, symshdr); + break; + + case SHT_GNU_HASH: + check_gnu_hash (ebl, shdr, data, idx, symshdr); + break; + + default: + assert (! "should not happen"); + } +} + + +/* Compare content of both hash tables, it must be identical. */ +static void +compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx, + size_t gnu_hash_idx) +{ + Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx); + Elf_Data *hash_data = elf_getdata (hash_scn, NULL); + GElf_Shdr hash_shdr_mem; + GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem); + Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx); + Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL); + GElf_Shdr gnu_hash_shdr_mem; + GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem); + + if (hash_shdr == NULL || gnu_hash_shdr == NULL + || hash_data == NULL || hash_data->d_buf == NULL + || gnu_hash_data == NULL || gnu_hash_data->d_buf == NULL) + /* None of these pointers should be NULL since we used the + sections already. We are careful nonetheless. */ + return; + + /* The link must point to the same symbol table. */ + if (hash_shdr->sh_link != gnu_hash_shdr->sh_link) + { + ERROR (_("\ +sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"), + hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), + gnu_hash_idx, + elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); + return; + } + + Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link); + Elf_Data *sym_data = elf_getdata (sym_scn, NULL); + GElf_Shdr sym_shdr_mem; + GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem); + + if (sym_data == NULL || sym_data->d_buf == NULL + || sym_shdr == NULL || sym_shdr->sh_entsize == 0) + return; + + const char *hash_name; + const char *gnu_hash_name; + hash_name = elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name); + gnu_hash_name = elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name); + + if (gnu_hash_data->d_size < 4 * sizeof (Elf32_Word)) + { + ERROR (_("\ +hash section [%2zu] '%s' does not contain enough data\n"), + gnu_hash_idx, gnu_hash_name); + return; + } + + uint32_t nentries = sym_shdr->sh_size / sym_shdr->sh_entsize; + char *used = alloca (nentries); + memset (used, '\0', nentries); + + /* First go over the GNU_HASH table and mark the entries as used. */ + const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf; + Elf32_Word gnu_nbucket = gnu_hasharr[0]; + Elf32_Word gnu_symbias = gnu_hasharr[1]; + const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2; + const Elf32_Word *gnu_bucket = (gnu_hasharr + + (4 + gnu_hasharr[2] * bitmap_factor)); + const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0]; + + if (gnu_hasharr[2] == 0) + { + ERROR (_("\ +hash section [%2zu] '%s' has zero bit mask words\n"), + gnu_hash_idx, gnu_hash_name); + return; + } + + uint64_t used_buf = ((4ULL + gnu_hasharr[2] * bitmap_factor + gnu_nbucket) + * sizeof (Elf32_Word)); + uint32_t max_nsyms = (gnu_hash_data->d_size - used_buf) / sizeof (Elf32_Word); + if (used_buf > gnu_hash_data->d_size) + { + ERROR (_("\ +hash section [%2zu] '%s' uses too much data\n"), + gnu_hash_idx, gnu_hash_name); + return; + } + + for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt) + { + if (gnu_bucket[cnt] != STN_UNDEF) + { + Elf32_Word symidx = gnu_bucket[cnt] - gnu_symbias; + do + { + if (symidx >= max_nsyms || symidx + gnu_symbias >= nentries) + { + ERROR (_("\ +hash section [%2zu] '%s' invalid symbol index %" PRIu32 " (max_nsyms: %" PRIu32 ", nentries: %" PRIu32 "\n"), + gnu_hash_idx, gnu_hash_name, symidx, max_nsyms, nentries); + return; + } + used[symidx + gnu_symbias] |= 1; + } + while ((gnu_chain[symidx++] & 1u) == 0); + } + } + + /* Now go over the old hash table and check that we cover the same + entries. */ + if (hash_shdr->sh_entsize == sizeof (Elf32_Word)) + { + const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf; + if (hash_data->d_size < 2 * sizeof (Elf32_Word)) + { + ERROR (_("\ +hash section [%2zu] '%s' does not contain enough data\n"), + hash_idx, hash_name); + return; + } + + Elf32_Word nbucket = hasharr[0]; + Elf32_Word nchain = hasharr[1]; + uint64_t hash_used = (2ULL + nchain + nbucket) * sizeof (Elf32_Word); + if (hash_used > hash_data->d_size) + { + ERROR (_("\ +hash section [%2zu] '%s' uses too much data\n"), + hash_idx, hash_name); + return; + } + + const Elf32_Word *bucket = &hasharr[2]; + const Elf32_Word *chain = &hasharr[2 + nbucket]; + + for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) + { + Elf32_Word symidx = bucket[cnt]; + while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain) + { + used[symidx] |= 2; + symidx = chain[symidx]; + } + } + } + else if (hash_shdr->sh_entsize == sizeof (Elf64_Xword)) + { + const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf; + if (hash_data->d_size < 2 * sizeof (Elf32_Word)) + { + ERROR (_("\ +hash section [%2zu] '%s' does not contain enough data\n"), + hash_idx, hash_name); + return; + } + + Elf64_Xword nbucket = hasharr[0]; + Elf64_Xword nchain = hasharr[1]; + uint64_t maxwords = hash_data->d_size / sizeof (Elf64_Xword); + if (maxwords < 2 + || maxwords - 2 < nbucket + || maxwords - 2 - nbucket < nchain) + { + ERROR (_("\ +hash section [%2zu] '%s' uses too much data\n"), + hash_idx, hash_name); + return; + } + + const Elf64_Xword *bucket = &hasharr[2]; + const Elf64_Xword *chain = &hasharr[2 + nbucket]; + + for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) + { + Elf64_Xword symidx = bucket[cnt]; + while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain) + { + used[symidx] |= 2; + symidx = chain[symidx]; + } + } + } + else + { + ERROR (_("\ +hash section [%2zu] '%s' invalid sh_entsize\n"), + hash_idx, hash_name); + return; + } + + /* Now see which entries are not set in one or both hash tables + (unless the symbol is undefined in which case it can be omitted + in the new table format). */ + if ((used[0] & 1) != 0) + ERROR (_("section [%2zu] '%s': reference to symbol index 0\n"), + gnu_hash_idx, + elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); + if ((used[0] & 2) != 0) + ERROR (_("section [%2zu] '%s': reference to symbol index 0\n"), + hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); + + for (uint32_t cnt = 1; cnt < nentries; ++cnt) + if (used[cnt] != 0 && used[cnt] != 3) + { + if (used[cnt] == 1) + ERROR (_("\ +symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"), + cnt, gnu_hash_idx, + elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name), + hash_idx, + elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); + else + { + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem); + + if (sym != NULL && sym->st_shndx != STN_UNDEF) + ERROR (_("\ +symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"), + cnt, hash_idx, + elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), + gnu_hash_idx, + elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); + } + } +} + + +static void +check_null (Ebl *ebl, GElf_Shdr *shdr, int idx) +{ +#define TEST(name, extra) \ + if (extra && shdr->sh_##name != 0) \ + ERROR (_("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ + idx, section_name (ebl, idx), #name) + + TEST (name, 1); + TEST (flags, 1); + TEST (addr, 1); + TEST (offset, 1); + TEST (size, idx != 0); + TEST (link, idx != 0); + TEST (info, 1); + TEST (addralign, 1); + TEST (entsize, 1); +} + + +static void +check_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + if (ehdr->e_type != ET_REL) + { + ERROR (_("\ +section [%2d] '%s': section groups only allowed in relocatable object files\n"), + idx, section_name (ebl, idx)); + return; + } + + /* Check that sh_link is an index of a symbol table. */ + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + if (symshdr == NULL) + ERROR (_("section [%2d] '%s': cannot get symbol table: %s\n"), + idx, section_name (ebl, idx), elf_errmsg (-1)); + else + { + if (symshdr->sh_type != SHT_SYMTAB) + ERROR (_("\ +section [%2d] '%s': section reference in sh_link is no symbol table\n"), + idx, section_name (ebl, idx)); + + if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, + 1, EV_CURRENT)) + ERROR (_("\ +section [%2d] '%s': invalid symbol index in sh_info\n"), + idx, section_name (ebl, idx)); + + if (shdr->sh_flags != 0) + ERROR (_("section [%2d] '%s': sh_flags not zero\n"), + idx, section_name (ebl, idx)); + + GElf_Sym sym_data; + GElf_Sym *sym = gelf_getsym (elf_getdata (symscn, NULL), shdr->sh_info, + &sym_data); + if (sym == NULL) + ERROR (_("\ +section [%2d] '%s': cannot get symbol for signature\n"), + idx, section_name (ebl, idx)); + else if (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name) == NULL) + ERROR (_("\ +section [%2d] '%s': cannot get symbol name for signature\n"), + idx, section_name (ebl, idx)); + else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name), + "") == 0) + ERROR (_("\ +section [%2d] '%s': signature symbol cannot be empty string\n"), + idx, section_name (ebl, idx)); + + if (be_strict + && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) + ERROR (_("section [%2d] '%s': sh_flags not set correctly\n"), + idx, section_name (ebl, idx)); + } + + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL || data->d_buf == NULL) + ERROR (_("section [%2d] '%s': cannot get data: %s\n"), + idx, section_name (ebl, idx), elf_errmsg (-1)); + else + { + size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); + size_t cnt; + Elf32_Word val; + + if (data->d_size % elsize != 0) + ERROR (_("\ +section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), + idx, section_name (ebl, idx)); + + if (data->d_size < elsize) + { + ERROR (_("\ +section [%2d] '%s': section group without flags word\n"), + idx, section_name (ebl, idx)); + return; + } + else if (be_strict) + { + if (data->d_size < 2 * elsize) + ERROR (_("\ +section [%2d] '%s': section group without member\n"), + idx, section_name (ebl, idx)); + else if (data->d_size < 3 * elsize) + ERROR (_("\ +section [%2d] '%s': section group with only one member\n"), + idx, section_name (ebl, idx)); + } + +#if ALLOW_UNALIGNED + val = *((Elf32_Word *) data->d_buf); +#else + memcpy (&val, data->d_buf, elsize); +#endif + if ((val & ~GRP_COMDAT) != 0) + ERROR (_("section [%2d] '%s': unknown section group flags\n"), + idx, section_name (ebl, idx)); + + for (cnt = elsize; cnt + elsize <= data->d_size; cnt += elsize) + { +#if ALLOW_UNALIGNED + val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); +#else + memcpy (&val, (char *) data->d_buf + cnt, elsize); +#endif + + if (val > shnum) + ERROR (_("\ +section [%2d] '%s': section index %zu out of range\n"), + idx, section_name (ebl, idx), cnt / elsize); + else + { + GElf_Shdr refshdr_mem; + GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), + &refshdr_mem); + if (refshdr == NULL) + ERROR (_("\ +section [%2d] '%s': cannot get section header for element %zu: %s\n"), + idx, section_name (ebl, idx), cnt / elsize, + elf_errmsg (-1)); + else + { + if (refshdr->sh_type == SHT_GROUP) + ERROR (_("\ +section [%2d] '%s': section group contains another group [%2d] '%s'\n"), + idx, section_name (ebl, idx), + val, section_name (ebl, val)); + + if ((refshdr->sh_flags & SHF_GROUP) == 0) + ERROR (_("\ +section [%2d] '%s': element %zu references section [%2d] '%s' without SHF_GROUP flag set\n"), + idx, section_name (ebl, idx), cnt / elsize, + val, section_name (ebl, val)); + } + + if (val < shnum && ++scnref[val] == 2) + ERROR (_("\ +section [%2d] '%s' is contained in more than one section group\n"), + val, section_name (ebl, val)); + } + } + } +} + + +static const char * +section_flags_string (GElf_Word flags, char *buf, size_t len) +{ + if (flags == 0) + return "none"; + + static const struct + { + GElf_Word flag; + const char *name; + } known_flags[] = + { +#define NEWFLAG(name) { SHF_##name, #name } + NEWFLAG (WRITE), + NEWFLAG (ALLOC), + NEWFLAG (EXECINSTR), + NEWFLAG (MERGE), + NEWFLAG (STRINGS), + NEWFLAG (INFO_LINK), + NEWFLAG (LINK_ORDER), + NEWFLAG (OS_NONCONFORMING), + NEWFLAG (GROUP), + NEWFLAG (TLS), + NEWFLAG (COMPRESSED), + NEWFLAG (GNU_RETAIN), + NEWFLAG (ORDERED), + NEWFLAG (EXCLUDE) + }; +#undef NEWFLAG + const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); + + char *cp = buf; + + for (size_t cnt = 0; cnt < nknown_flags; ++cnt) + if (flags & known_flags[cnt].flag) + { + if (cp != buf && len > 1) + { + *cp++ = '|'; + --len; + } + + size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); + cp = mempcpy (cp, known_flags[cnt].name, ncopy); + len -= ncopy; + + flags ^= known_flags[cnt].flag; + } + + if (flags != 0 || cp == buf) + { + int r = snprintf (cp, len - 1, "%s%" PRIx64, + (cp == buf) ? "" : "|", (uint64_t) flags); + if (r > 0) + cp += r; + } + *cp = '\0'; + + return buf; +} + + +static int +has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx) +{ + /* First find the relocation section for the symbol table. */ + Elf_Scn *scn = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL + && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) + && shdr->sh_link == symscnndx) + /* Found the section. */ + break; + } + + if (scn == NULL) + return 0; + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL || shdr->sh_entsize == 0) + return 0; + + if (shdr->sh_type == SHT_REL) + for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) + { + GElf_Rel rel_mem; + GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); + if (rel == NULL) + continue; + + if (GELF_R_SYM (rel->r_info) == symndx + && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) + return 1; + } + else + for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) + { + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); + if (rela == NULL) + continue; + + if (GELF_R_SYM (rela->r_info) == symndx + && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) + return 1; + } + + return 0; +} + + +static int +in_nobits_scn (Ebl *ebl, unsigned int shndx) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem); + return shdr != NULL && shdr->sh_type == SHT_NOBITS; +} + + +static struct version_namelist +{ + const char *objname; + const char *name; + GElf_Versym ndx; + enum { ver_def, ver_need } type; + struct version_namelist *next; +} *version_namelist; + + +static int +add_version (const char *objname, const char *name, GElf_Versym ndx, int type) +{ + /* Check that there are no duplications. */ + struct version_namelist *nlp = version_namelist; + while (nlp != NULL) + { + if (((nlp->objname == NULL && objname == NULL) + || (nlp->objname != NULL && objname != NULL + && strcmp (nlp->objname, objname) == 0)) + && strcmp (nlp->name, name) == 0) + return nlp->type == ver_def ? 1 : -1; + nlp = nlp->next; + } + + nlp = xmalloc (sizeof (*nlp)); + nlp->objname = objname; + nlp->name = name; + nlp->ndx = ndx; + nlp->type = type; + nlp->next = version_namelist; + version_namelist = nlp; + + return 0; +} + + +static void +check_versym (Ebl *ebl, int idx) +{ + Elf_Scn *scn = elf_getscn (ebl->elf, idx); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + /* The error has already been reported. */ + return; + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + if (symshdr == NULL) + /* The error has already been reported. */ + return; + + if (symshdr->sh_type != SHT_DYNSYM) + { + ERROR (_("\ +section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), + idx, section_name (ebl, idx), + shdr->sh_link, section_name (ebl, shdr->sh_link)); + return; + } + + /* The number of elements in the version symbol table must be the + same as the number of symbols. */ + if (shdr->sh_entsize != 0 && symshdr->sh_entsize != 0 + && (shdr->sh_size / shdr->sh_entsize + != symshdr->sh_size / symshdr->sh_entsize)) + ERROR (_("\ +section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), + idx, section_name (ebl, idx), + shdr->sh_link, section_name (ebl, shdr->sh_link)); + + Elf_Data *symdata = elf_getdata (symscn, NULL); + if (symdata == NULL || shdr->sh_entsize == 0) + /* The error has already been reported. */ + return; + + for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) + { + GElf_Versym versym_mem; + GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem); + if (versym == NULL) + { + ERROR (_("\ +section [%2d] '%s': symbol %d: cannot read version data\n"), + idx, section_name (ebl, idx), cnt); + break; + } + + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem); + if (sym == NULL) + /* Already reported elsewhere. */ + continue; + + if (*versym == VER_NDX_GLOBAL) + { + /* Global symbol. Make sure it is not defined as local. */ + if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) + ERROR (_("\ +section [%2d] '%s': symbol %d: local symbol with global scope\n"), + idx, section_name (ebl, idx), cnt); + } + else if (*versym != VER_NDX_LOCAL) + { + /* Versioned symbol. Make sure it is not defined as local. */ + if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL) + ERROR (_("\ +section [%2d] '%s': symbol %d: local symbol with version\n"), + idx, section_name (ebl, idx), cnt); + + /* Look through the list of defined versions and locate the + index we need for this symbol. */ + struct version_namelist *runp = version_namelist; + while (runp != NULL) + if (runp->ndx == (*versym & (GElf_Versym) 0x7fff)) + break; + else + runp = runp->next; + + if (runp == NULL) + ERROR (_("\ +section [%2d] '%s': symbol %d: invalid version index %d\n"), + idx, section_name (ebl, idx), cnt, (int) *versym); + else if (sym->st_shndx == SHN_UNDEF + && runp->type == ver_def) + ERROR (_("\ +section [%2d] '%s': symbol %d: version index %d is for defined version\n"), + idx, section_name (ebl, idx), cnt, (int) *versym); + else if (sym->st_shndx != SHN_UNDEF + && runp->type == ver_need) + { + /* Unless this symbol has a copy relocation associated + this must not happen. */ + if (!has_copy_reloc (ebl, shdr->sh_link, cnt) + && !in_nobits_scn (ebl, sym->st_shndx)) + ERROR (_("\ +section [%2d] '%s': symbol %d: version index %d is for requested version\n"), + idx, section_name (ebl, idx), cnt, (int) *versym); + } + } + } +} + + +static int +unknown_dependency_p (Elf *elf, const char *fname) +{ + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = NULL; + + unsigned int i; + for (i = 0; i < phnum; ++i) + if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL + && phdr->p_type == PT_DYNAMIC) + break; + + if (i == phnum) + return 1; + assert (phdr != NULL); + Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + Elf_Data *data = elf_getdata (scn, NULL); + if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC + && data != NULL && shdr->sh_entsize != 0) + for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); + if (dyn != NULL && dyn->d_tag == DT_NEEDED) + { + const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val); + if (str != NULL && strcmp (str, fname) == 0) + /* Found it. */ + return 0; + } + } + + return 1; +} + + +static unsigned int nverneed; + +static void +check_verneed (Ebl *ebl, GElf_Shdr *shdr, int idx) +{ + if (++nverneed == 2) + ERROR (_("more than one version reference section present\n")); + + GElf_Shdr strshdr_mem; + GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &strshdr_mem); + if (strshdr == NULL) + return; + if (strshdr->sh_type != SHT_STRTAB) + ERROR (_("\ +section [%2d] '%s': sh_link does not link to string table\n"), + idx, section_name (ebl, idx)); + + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + unsigned int offset = 0; + for (Elf64_Word cnt = shdr->sh_info; cnt > 0; ) + { + cnt--; + + /* Get the data at the next offset. */ + GElf_Verneed needmem; + GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); + if (need == NULL) + break; + + unsigned int auxoffset = offset + need->vn_aux; + + if (need->vn_version != EV_CURRENT) + ERROR (_("\ +section [%2d] '%s': entry %d has wrong version %d\n"), + idx, section_name (ebl, idx), cnt, (int) need->vn_version); + + if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED, + 1, EV_CURRENT)) + { + ERROR (_("\ +section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), + idx, section_name (ebl, idx), cnt); + break; + } + + const char *libname = elf_strptr (ebl->elf, shdr->sh_link, + need->vn_file); + if (libname == NULL) + { + ERROR (_("\ +section [%2d] '%s': entry %d has invalid file reference\n"), + idx, section_name (ebl, idx), cnt); + goto next_need; + } + + /* Check that there is a DT_NEEDED entry for the referenced library. */ + if (unknown_dependency_p (ebl->elf, libname)) + ERROR (_("\ +section [%2d] '%s': entry %d references unknown dependency\n"), + idx, section_name (ebl, idx), cnt); + + for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) + { + GElf_Vernaux auxmem; + GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); + if (aux == NULL) + break; + + if ((aux->vna_flags & ~VER_FLG_WEAK) != 0) + ERROR (_("\ +section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"), + idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); + + const char *verstr = elf_strptr (ebl->elf, shdr->sh_link, + aux->vna_name); + if (verstr == NULL) + { + ERROR (_("\ +section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"), + idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); + break; + } + else + { + GElf_Word hashval = elf_hash (verstr); + if (hashval != aux->vna_hash) + ERROR (_("\ +section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"), + idx, section_name (ebl, idx), need->vn_cnt - cnt2, + cnt, (int) hashval, (int) aux->vna_hash); + + int res = add_version (libname, verstr, aux->vna_other, + ver_need); + if (unlikely (res !=0)) + { + ERROR (_("\ +section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"), + idx, section_name (ebl, idx), need->vn_cnt - cnt2, + cnt, verstr); + } + } + + if ((aux->vna_next != 0 || cnt2 > 0) + && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, + EV_CURRENT)) + { + ERROR (_("\ +section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"), + idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); + break; + } + + auxoffset += MAX (aux->vna_next, + gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT)); + } + + /* Find the next offset. */ + next_need: + offset += need->vn_next; + + if ((need->vn_next != 0 || cnt > 0) + && offset < auxoffset) + { + ERROR (_("\ +section [%2d] '%s': entry %d has invalid offset to next entry\n"), + idx, section_name (ebl, idx), cnt); + break; + } + + if (need->vn_next == 0 && cnt > 0) + { + ERROR (_("\ +section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says there are more entries\n"), + idx, section_name (ebl, idx), cnt); + break; + } + } +} + + +static unsigned int nverdef; + +static void +check_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx) +{ + if (++nverdef == 2) + ERROR (_("more than one version definition section present\n")); + + GElf_Shdr strshdr_mem; + GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &strshdr_mem); + if (strshdr == NULL) + return; + if (strshdr->sh_type != SHT_STRTAB) + ERROR (_("\ +section [%2d] '%s': sh_link does not link to string table\n"), + idx, section_name (ebl, idx)); + + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL) + { + no_data: + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + /* Iterate over all version definition entries. We check that there + is a BASE entry and that each index is unique. To do the later + we collection the information in a list which is later + examined. */ + struct namelist + { + const char *name; + struct namelist *next; + } *namelist = NULL; + struct namelist *refnamelist = NULL; + + bool has_base = false; + unsigned int offset = 0; + for (Elf64_Word cnt = shdr->sh_info; cnt > 0; ) + { + cnt--; + + /* Get the data at the next offset. */ + GElf_Verdef defmem; + GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); + if (def == NULL) + goto no_data; + + if ((def->vd_flags & VER_FLG_BASE) != 0) + { + if (has_base) + ERROR (_("\ +section [%2d] '%s': more than one BASE definition\n"), + idx, section_name (ebl, idx)); + if (def->vd_ndx != VER_NDX_GLOBAL) + ERROR (_("\ +section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"), + idx, section_name (ebl, idx)); + has_base = true; + } + if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0) + ERROR (_("\ +section [%2d] '%s': entry %d has unknown flag\n"), + idx, section_name (ebl, idx), cnt); + + if (def->vd_version != EV_CURRENT) + ERROR (_("\ +section [%2d] '%s': entry %d has wrong version %d\n"), + idx, section_name (ebl, idx), cnt, (int) def->vd_version); + + if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF, + 1, EV_CURRENT)) + { + ERROR (_("\ +section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), + idx, section_name (ebl, idx), cnt); + break; + } + + unsigned int auxoffset = offset + def->vd_aux; + GElf_Verdaux auxmem; + GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); + if (aux == NULL) + goto no_data; + + const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); + if (name == NULL) + { + ERROR (_("\ +section [%2d] '%s': entry %d has invalid name reference\n"), + idx, section_name (ebl, idx), cnt); + goto next_def; + } + GElf_Word hashval = elf_hash (name); + if (def->vd_hash != hashval) + ERROR (_("\ +section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"), + idx, section_name (ebl, idx), cnt, (int) hashval, + (int) def->vd_hash); + + int res = add_version (NULL, name, def->vd_ndx, ver_def); + if (unlikely (res !=0)) + { + ERROR (_("\ +section [%2d] '%s': entry %d has duplicate version name '%s'\n"), + idx, section_name (ebl, idx), cnt, name); + } + + struct namelist *newname = alloca (sizeof (*newname)); + newname->name = name; + newname->next = namelist; + namelist = newname; + + auxoffset += aux->vda_next; + for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) + { + aux = gelf_getverdaux (data, auxoffset, &auxmem); + if (aux == NULL) + goto no_data; + + name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); + if (name == NULL) + { + ERROR (_("\ +section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"), + idx, section_name (ebl, idx), cnt); + break; + } + else + { + newname = alloca (sizeof (*newname)); + newname->name = name; + newname->next = refnamelist; + refnamelist = newname; + } + + if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt) + && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, + EV_CURRENT)) + { + ERROR (_("\ +section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"), + idx, section_name (ebl, idx), cnt); + break; + } + + auxoffset += MAX (aux->vda_next, + gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT)); + } + + /* Find the next offset. */ + next_def: + offset += def->vd_next; + + if ((def->vd_next != 0 || cnt > 0) + && offset < auxoffset) + { + ERROR (_("\ +section [%2d] '%s': entry %d has invalid offset to next entry\n"), + idx, section_name (ebl, idx), cnt); + break; + } + + if (def->vd_next == 0 && cnt > 0) + { + ERROR (_("\ +section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says there are more entries\n"), + idx, section_name (ebl, idx), cnt); + break; + } + } + + if (!has_base) + ERROR (_("section [%2d] '%s': no BASE definition\n"), + idx, section_name (ebl, idx)); + + /* Check whether the referenced names are available. */ + while (namelist != NULL) + { + struct version_namelist *runp = version_namelist; + while (runp != NULL) + { + if (runp->type == ver_def + && strcmp (runp->name, namelist->name) == 0) + break; + runp = runp->next; + } + + if (runp == NULL) + ERROR (_("\ +section [%2d] '%s': unknown parent version '%s'\n"), + idx, section_name (ebl, idx), namelist->name); + + namelist = namelist->next; + } +} + +static inline size_t +buffer_pos (Elf_Data *data, const unsigned char *p) +{ + return p - (const unsigned char *) data->d_buf; +} + +inline size_t +buffer_left (Elf_Data *data, const unsigned char *p) +{ + return (const unsigned char *) data->d_buf + data->d_size - p; +} + +static void +check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + if (shdr->sh_size == 0) + { + ERROR (_("section [%2d] '%s': empty object attributes section\n"), + idx, section_name (ebl, idx)); + return; + } + + Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL || data->d_size == 0 || data->d_buf == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + const unsigned char *p = data->d_buf; + if (*p++ != 'A') + { + ERROR (_("section [%2d] '%s': unrecognized attribute format\n"), + idx, section_name (ebl, idx)); + return; + } + + while (buffer_left (data, p) >= 4) + { + uint32_t len; + memcpy (&len, p, sizeof len); + + if (len == 0) + ERROR (_("\ +section [%2d] '%s': offset %zu: zero length field in attribute section\n"), + idx, section_name (ebl, idx), buffer_pos (data, p)); + + if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) + CONVERT (len); + + if (len > buffer_left (data, p)) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: invalid length in attribute section\n"), + idx, section_name (ebl, idx), buffer_pos (data, p)); + break; + } + + const unsigned char *name = p + sizeof len; + p += len; + + unsigned const char *q = memchr (name, '\0', len); + if (q == NULL) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: unterminated vendor name string\n"), + idx, section_name (ebl, idx), buffer_pos (data, p)); + break; + } + ++q; + + if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu")) + while (q < p) + { + unsigned const char *chunk = q; + + unsigned int subsection_tag; + get_uleb128 (subsection_tag, q, p); + + if (q >= p) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"), + idx, section_name (ebl, idx), buffer_pos (data, chunk)); + break; + } + + uint32_t subsection_len; + if (p - q < (ptrdiff_t) sizeof subsection_len) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: truncated attribute section\n"), + idx, section_name (ebl, idx), buffer_pos (data, q)); + break; + } + + memcpy (&subsection_len, q, sizeof subsection_len); + if (subsection_len == 0) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"), + idx, section_name (ebl, idx), buffer_pos (data, q)); + + q += sizeof subsection_len; + continue; + } + + if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) + CONVERT (subsection_len); + + /* Don't overflow, ptrdiff_t might be 32bits, but signed. */ + if (p - chunk < (ptrdiff_t) subsection_len + || subsection_len >= (uint32_t) PTRDIFF_MAX) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"), + idx, section_name (ebl, idx), buffer_pos (data, q)); + break; + } + + const unsigned char *subsection_end = chunk + subsection_len; + chunk = q; + q = subsection_end; + + if (subsection_tag != 1) /* Tag_File */ + ERROR (_("\ +section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"), + idx, section_name (ebl, idx), buffer_pos (data, chunk), subsection_tag); + else + { + chunk += sizeof subsection_len; + while (chunk < q) + { + unsigned int tag; + get_uleb128 (tag, chunk, q); + + uint64_t value = 0; + const unsigned char *r = chunk; + if (tag == 32 || (tag & 1) == 0) + { + get_uleb128 (value, r, q); + if (r > q) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"), + idx, section_name (ebl, idx), buffer_pos (data, chunk)); + break; + } + } + if (tag == 32 || (tag & 1) != 0) + { + r = memchr (r, '\0', q - r); + if (r == NULL) + { + ERROR (_("\ +section [%2d] '%s': offset %zu: unterminated string in attribute\n"), + idx, section_name (ebl, idx), buffer_pos (data, chunk)); + break; + } + ++r; + } + + const char *tag_name = NULL; + const char *value_name = NULL; + if (!ebl_check_object_attribute (ebl, (const char *) name, + tag, value, + &tag_name, &value_name)) + ERROR (_("\ +section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"), + idx, section_name (ebl, idx), buffer_pos (data, chunk), tag); + else if ((tag & 1) == 0 && value_name == NULL) + ERROR (_("\ +section [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"), + idx, section_name (ebl, idx), buffer_pos (data, chunk), + tag_name, value); + + chunk = r; + } + } + } + else + ERROR (_("\ +section [%2d] '%s': offset %zu: vendor '%s' unknown\n"), + idx, section_name (ebl, idx), buffer_pos (data, p), name); + } + + if (buffer_left (data, p) != 0) + ERROR (_("\ +section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"), + idx, section_name (ebl, idx), buffer_pos (data, p)); +} + +static bool has_loadable_segment; +static bool has_interp_segment; + +static const struct +{ + const char *name; + size_t namelen; + GElf_Word type; + enum { unused, exact, atleast, exact_or_gnuld } attrflag; + GElf_Word attr; + GElf_Word attr2; +} special_sections[] = + { + /* See figure 4-14 in the gABI. */ + { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".comment", 8, SHT_PROGBITS, atleast, 0, SHF_MERGE | SHF_STRINGS }, + { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 }, + { ".debug_line_str", 16, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 }, + { ".debug", 6, SHT_PROGBITS, exact, 0, 0 }, + { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, + { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, + { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, + { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, + { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? + { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, + { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, + { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? + { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, + { ".note", 6, SHT_NOTE, atleast, 0, SHF_ALLOC }, + { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests + { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests + { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests + { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, + { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, + { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, + { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests + { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests + { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests + { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, + { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, + { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, + { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, + + /* The following are GNU extensions. */ + { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 }, + { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 }, + { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 }, + { ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 }, + }; +#define nspecial_sections \ + (sizeof (special_sections) / sizeof (special_sections[0])) + +#define IS_KNOWN_SPECIAL(idx, string, prefix) \ + (special_sections[idx].namelen == sizeof string - (prefix ? 1 : 0) \ + && !memcmp (special_sections[idx].name, string, \ + sizeof string - (prefix ? 1 : 0))) + +/* Extra section flags that might or might not be added to the section + and have to be ignored. */ +#define EXTRA_SHFLAGS (SHF_LINK_ORDER \ + | SHF_GNU_RETAIN \ + | SHF_GROUP \ + | SHF_COMPRESSED) + + +/* Indices of some sections we need later. */ +static size_t eh_frame_hdr_scnndx; +static size_t eh_frame_scnndx; +static size_t gcc_except_table_scnndx; + + +static void +check_sections (Ebl *ebl, GElf_Ehdr *ehdr) +{ + if (ehdr->e_shoff == 0) + /* No section header. */ + return; + + /* Allocate array to count references in section groups. */ + scnref = (int *) xcalloc (shnum, sizeof (int)); + + /* Check the zeroth section first. It must not have any contents + and the section header must contain nonzero value at most in the + sh_size and sh_link fields. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr == NULL) + ERROR (_("cannot get section header of zeroth section\n")); + else + { + if (shdr->sh_name != 0) + ERROR (_("zeroth section has nonzero name\n")); + if (shdr->sh_type != 0) + ERROR (_("zeroth section has nonzero type\n")); + if (shdr->sh_flags != 0) + ERROR (_("zeroth section has nonzero flags\n")); + if (shdr->sh_addr != 0) + ERROR (_("zeroth section has nonzero address\n")); + if (shdr->sh_offset != 0) + ERROR (_("zeroth section has nonzero offset\n")); + if (shdr->sh_addralign != 0) + ERROR (_("zeroth section has nonzero align value\n")); + if (shdr->sh_entsize != 0) + ERROR (_("zeroth section has nonzero entry size value\n")); + + if (shdr->sh_size != 0 && ehdr->e_shnum != 0) + ERROR (_("\ +zeroth section has nonzero size value while ELF header has nonzero shnum value\n")); + + if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) + ERROR (_("\ +zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); + + if (shdr->sh_info != 0 && ehdr->e_phnum != PN_XNUM) + ERROR (_("\ +zeroth section has nonzero link value while ELF header does not signal overflow in phnum\n")); + } + + int *segment_flags = xcalloc (phnum, sizeof segment_flags[0]); + + bool dot_interp_section = false; + + size_t hash_idx = 0; + size_t gnu_hash_idx = 0; + + size_t versym_scnndx = 0; + for (size_t cnt = 1; cnt < shnum; ++cnt) + { + Elf_Scn *scn = elf_getscn (ebl->elf, cnt); + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + ERROR (_("\ +cannot get section header for section [%2zu] '%s': %s\n"), + cnt, section_name (ebl, cnt), elf_errmsg (-1)); + continue; + } + + const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); + + if (scnname == NULL) + ERROR (_("section [%2zu]: invalid name\n"), cnt); + else + { + /* Check whether it is one of the special sections defined in + the gABI. */ + size_t s; + for (s = 0; s < nspecial_sections; ++s) + if (strncmp (scnname, special_sections[s].name, + special_sections[s].namelen) == 0) + { + char stbuf1[100]; + char stbuf2[100]; + char stbuf3[100]; + + GElf_Word good_type = special_sections[s].type; + if (IS_KNOWN_SPECIAL (s, ".plt", false) + && ebl_bss_plt_p (ebl)) + good_type = SHT_NOBITS; + + /* In a debuginfo file, any normal section can be SHT_NOBITS. + This is only invalid for DWARF sections and .shstrtab. */ + if (shdr->sh_type != good_type + && (shdr->sh_type != SHT_NOBITS + || !is_debuginfo + || IS_KNOWN_SPECIAL (s, ".debug_str", false) + || IS_KNOWN_SPECIAL (s, ".debug", true) + || IS_KNOWN_SPECIAL (s, ".shstrtab", false))) + ERROR (_("\ +section [%2d] '%s' has wrong type: expected %s, is %s\n"), + (int) cnt, scnname, + ebl_section_type_name (ebl, special_sections[s].type, + stbuf1, sizeof (stbuf1)), + ebl_section_type_name (ebl, shdr->sh_type, + stbuf2, sizeof (stbuf2))); + + if (special_sections[s].attrflag == exact + || special_sections[s].attrflag == exact_or_gnuld) + { + /* Except for the link order, retain, group bit and + compression flag all the other bits should + match exactly. */ + if ((shdr->sh_flags & ~EXTRA_SHFLAGS) + != special_sections[s].attr + && (special_sections[s].attrflag == exact || !gnuld)) + ERROR (_("\ +section [%2zu] '%s' has wrong flags: expected %s, is %s\n"), + cnt, scnname, + section_flags_string (special_sections[s].attr, + stbuf1, sizeof (stbuf1)), + section_flags_string (shdr->sh_flags + & ~EXTRA_SHFLAGS, + stbuf2, sizeof (stbuf2))); + } + else if (special_sections[s].attrflag == atleast) + { + if ((shdr->sh_flags & special_sections[s].attr) + != special_sections[s].attr + || ((shdr->sh_flags + & ~(EXTRA_SHFLAGS + | special_sections[s].attr + | special_sections[s].attr2)) + != 0)) + ERROR (_("\ +section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), + cnt, scnname, + section_flags_string (special_sections[s].attr, + stbuf1, sizeof (stbuf1)), + section_flags_string (special_sections[s].attr2, + stbuf2, sizeof (stbuf2)), + section_flags_string (shdr->sh_flags + & ~EXTRA_SHFLAGS, + stbuf3, sizeof (stbuf3))); + } + + if (strcmp (scnname, ".interp") == 0) + { + dot_interp_section = true; + + if (ehdr->e_type == ET_REL) + ERROR (_("\ +section [%2zu] '%s' present in object file\n"), + cnt, scnname); + + if ((shdr->sh_flags & SHF_ALLOC) != 0 + && !has_loadable_segment) + ERROR (_("\ +section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), + cnt, scnname); + else if ((shdr->sh_flags & SHF_ALLOC) == 0 + && has_loadable_segment) + ERROR (_("\ +section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), + cnt, scnname); + } + else + { + if (strcmp (scnname, ".symtab_shndx") == 0 + && ehdr->e_type != ET_REL) + ERROR (_("\ +section [%2zu] '%s' is extension section index table in non-object file\n"), + cnt, scnname); + + /* These sections must have the SHF_ALLOC flag set iff + a loadable segment is available. + + .relxxx + .strtab + .symtab + .symtab_shndx + + Check that if there is a reference from the + loaded section these sections also have the + ALLOC flag set. */ +#if 0 + // XXX TODO + if ((shdr->sh_flags & SHF_ALLOC) != 0 + && !has_loadable_segment) + ERROR (_("\ +section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), + cnt, scnname); + else if ((shdr->sh_flags & SHF_ALLOC) == 0 + && has_loadable_segment) + ERROR (_("\ +section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), + cnt, scnname); +#endif + } + + break; + } + + /* Remember a few special sections for later. */ + if (strcmp (scnname, ".eh_frame_hdr") == 0) + eh_frame_hdr_scnndx = cnt; + else if (strcmp (scnname, ".eh_frame") == 0) + eh_frame_scnndx = cnt; + else if (strcmp (scnname, ".gcc_except_table") == 0) + gcc_except_table_scnndx = cnt; + } + + if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) + ERROR (_("\ +section [%2zu] '%s': size not multiple of entry size\n"), + cnt, section_name (ebl, cnt)); + + if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) + ERROR (_("cannot get section header\n")); + + if (shdr->sh_type >= SHT_NUM + && shdr->sh_type != SHT_GNU_ATTRIBUTES + && shdr->sh_type != SHT_GNU_LIBLIST + && shdr->sh_type != SHT_CHECKSUM + && shdr->sh_type != SHT_GNU_verdef + && shdr->sh_type != SHT_GNU_verneed + && shdr->sh_type != SHT_GNU_versym + && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL) + ERROR (_("section [%2zu] '%s' has unsupported type %d\n"), + cnt, section_name (ebl, cnt), + (int) shdr->sh_type); + +#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ + | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ + | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS \ + | SHF_COMPRESSED | SHF_GNU_RETAIN) + if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) + { + GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; + if (sh_flags & SHF_MASKPROC) + { + /* Strictly speaking SHF_EXCLUDE is a processor specific + section flag, but it is used generically in the GNU + toolchain. */ + if (gnuld) + sh_flags &= ~(GElf_Xword) SHF_EXCLUDE; + if (!ebl_machine_section_flag_check (ebl, + sh_flags & SHF_MASKPROC)) + ERROR (_("section [%2zu] '%s'" + " contains invalid processor-specific flag(s)" + " %#" PRIx64 "\n"), + cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC); + sh_flags &= ~(GElf_Xword) SHF_MASKPROC; + } + if (sh_flags & SHF_MASKOS) + if (gnuld) + sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN; + if (sh_flags != 0) + ERROR (_("section [%2zu] '%s' contains unknown flag(s)" + " %#" PRIx64 "\n"), + cnt, section_name (ebl, cnt), sh_flags); + } + if (shdr->sh_flags & SHF_TLS) + { + // XXX Correct? + if (shdr->sh_addr != 0 && !gnuld) + ERROR (_("\ +section [%2zu] '%s': thread-local data sections address not zero\n"), + cnt, section_name (ebl, cnt)); + + // XXX TODO more tests!? + } + + if (shdr->sh_flags & SHF_COMPRESSED) + { + if (shdr->sh_flags & SHF_ALLOC) + ERROR (_("\ +section [%2zu] '%s': allocated section cannot be compressed\n"), + cnt, section_name (ebl, cnt)); + + if (shdr->sh_type == SHT_NOBITS) + ERROR (_("\ +section [%2zu] '%s': nobits section cannot be compressed\n"), + cnt, section_name (ebl, cnt)); + + GElf_Chdr chdr; + if (gelf_getchdr (scn, &chdr) == NULL) + ERROR (_("\ +section [%2zu] '%s': compressed section with no compression header: %s\n"), + cnt, section_name (ebl, cnt), elf_errmsg (-1)); + } + + if (shdr->sh_link >= shnum) + ERROR (_("\ +section [%2zu] '%s': invalid section reference in link value\n"), + cnt, section_name (ebl, cnt)); + + if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) + ERROR (_("\ +section [%2zu] '%s': invalid section reference in info value\n"), + cnt, section_name (ebl, cnt)); + + if ((shdr->sh_flags & SHF_MERGE) == 0 + && (shdr->sh_flags & SHF_STRINGS) != 0 + && be_strict) + ERROR (_("\ +section [%2zu] '%s': strings flag set without merge flag\n"), + cnt, section_name (ebl, cnt)); + + if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) + ERROR (_("\ +section [%2zu] '%s': merge flag set but entry size is zero\n"), + cnt, section_name (ebl, cnt)); + + if (shdr->sh_flags & SHF_GROUP) + check_scn_group (ebl, cnt); + + if (shdr->sh_flags & SHF_EXECINSTR) + { + switch (shdr->sh_type) + { + case SHT_PROGBITS: + break; + + case SHT_NOBITS: + if (is_debuginfo) + break; + FALLTHROUGH; + default: + ERROR (_("\ +section [%2zu] '%s' has unexpected type %d for an executable section\n"), + cnt, section_name (ebl, cnt), shdr->sh_type); + break; + } + + if (shdr->sh_flags & SHF_WRITE) + { + if (is_debuginfo && shdr->sh_type != SHT_NOBITS) + ERROR (_("\ +section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"), + cnt, section_name (ebl, cnt)); + + if (!is_debuginfo + && !ebl_check_special_section (ebl, cnt, shdr, + section_name (ebl, cnt))) + ERROR (_("\ +section [%2zu] '%s' is both executable and writable\n"), + cnt, section_name (ebl, cnt)); + } + } + + if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0 + && !is_debuginfo) + { + /* Make sure the section is contained in a loaded segment + and that the initialization part matches NOBITS sections. */ + unsigned int pcnt; + GElf_Phdr phdr_mem; + GElf_Phdr *phdr; + + for (pcnt = 0; pcnt < phnum; ++pcnt) + if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL + && ((phdr->p_type == PT_LOAD + && (shdr->sh_flags & SHF_TLS) == 0) + || (phdr->p_type == PT_TLS + && (shdr->sh_flags & SHF_TLS) != 0)) + && phdr->p_offset <= shdr->sh_offset + && ((shdr->sh_offset - phdr->p_offset <= phdr->p_filesz + && (shdr->sh_offset - phdr->p_offset < phdr->p_filesz + || shdr->sh_size == 0)) + || (shdr->sh_offset - phdr->p_offset < phdr->p_memsz + && shdr->sh_type == SHT_NOBITS))) + { + /* Found the segment. */ + if (phdr->p_offset + phdr->p_memsz + < shdr->sh_offset + shdr->sh_size) + ERROR (_("\ +section [%2zu] '%s' not fully contained in segment of program header entry %d\n"), + cnt, section_name (ebl, cnt), pcnt); + + if (shdr->sh_type == SHT_NOBITS) + { + if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz + && !is_debuginfo) + { + if (!gnuld) + ERROR (_("\ +section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), + cnt, section_name (ebl, cnt), pcnt); + else + { + /* This is truly horrible. GNU ld might put a + NOBITS section in the middle of a PT_LOAD + segment, assuming the next gap in the file + actually consists of zero bits... + So it really is like a PROGBITS section + where the data is all zeros. Check those + zero bytes are really there. */ + bool bad; + Elf_Data *databits; + databits = elf_getdata_rawchunk (ebl->elf, + shdr->sh_offset, + shdr->sh_size, + ELF_T_BYTE); + bad = (databits == NULL + || databits->d_size != shdr->sh_size); + for (size_t idx = 0; + idx < databits->d_size && ! bad; + idx++) + bad = ((char *) databits->d_buf)[idx] != 0; + + if (bad) + ERROR (_("\ +section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d and file contents is non-zero\n"), + cnt, section_name (ebl, cnt), pcnt); + } + } + } + else + { + const GElf_Off end = phdr->p_offset + phdr->p_filesz; + if (shdr->sh_offset > end || + (shdr->sh_offset == end && shdr->sh_size != 0)) + ERROR (_("\ +section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), + cnt, section_name (ebl, cnt), pcnt); + } + + if (shdr->sh_type != SHT_NOBITS) + { + if ((shdr->sh_flags & SHF_EXECINSTR) != 0) + { + segment_flags[pcnt] |= PF_X; + if ((phdr->p_flags & PF_X) == 0) + ERROR (_("\ +section [%2zu] '%s' is executable in nonexecutable segment %d\n"), + cnt, section_name (ebl, cnt), pcnt); + } + + if ((shdr->sh_flags & SHF_WRITE) != 0) + { + segment_flags[pcnt] |= PF_W; + if (0 /* XXX vdso images have this */ + && (phdr->p_flags & PF_W) == 0) + ERROR (_("\ +section [%2zu] '%s' is writable in unwritable segment %d\n"), + cnt, section_name (ebl, cnt), pcnt); + } + } + + break; + } + + if (pcnt == phnum) + ERROR (_("\ +section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), + cnt, section_name (ebl, cnt)); + } + + if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) + ERROR (_("\ +section [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), + cnt, section_name (ebl, cnt)); + + switch (shdr->sh_type) + { + case SHT_DYNSYM: + if (ehdr->e_type == ET_REL) + ERROR (_("\ +section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), + cnt, section_name (ebl, cnt)); + FALLTHROUGH; + case SHT_SYMTAB: + check_symtab (ebl, ehdr, shdr, cnt); + break; + + case SHT_RELA: + check_rela (ebl, ehdr, shdr, cnt); + break; + + case SHT_REL: + check_rel (ebl, ehdr, shdr, cnt); + break; + + case SHT_DYNAMIC: + check_dynamic (ebl, ehdr, shdr, cnt); + break; + + case SHT_SYMTAB_SHNDX: + check_symtab_shndx (ebl, ehdr, shdr, cnt); + break; + + case SHT_HASH: + check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); + hash_idx = cnt; + break; + + case SHT_GNU_HASH: + check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); + gnu_hash_idx = cnt; + break; + + case SHT_NULL: + check_null (ebl, shdr, cnt); + break; + + case SHT_GROUP: + check_group (ebl, ehdr, shdr, cnt); + break; + + case SHT_NOTE: + check_note_section (ebl, ehdr, shdr, cnt); + break; + + case SHT_GNU_versym: + /* We cannot process this section now since we have no guarantee + that the verneed and verdef sections have already been read. + Just remember the section index. */ + if (versym_scnndx != 0) + ERROR (_("more than one version symbol table present\n")); + versym_scnndx = cnt; + break; + + case SHT_GNU_verneed: + check_verneed (ebl, shdr, cnt); + break; + + case SHT_GNU_verdef: + check_verdef (ebl, shdr, cnt); + break; + + case SHT_GNU_ATTRIBUTES: + check_attributes (ebl, ehdr, shdr, cnt); + break; + + default: + /* Nothing. */ + break; + } + } + + if (has_interp_segment && !dot_interp_section) + ERROR (_("INTERP program header entry but no .interp section\n")); + + if (!is_debuginfo) + for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); + if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS)) + { + if ((phdr->p_flags & PF_X) != 0 + && (segment_flags[pcnt] & PF_X) == 0) + ERROR (_("\ +loadable segment [%u] is executable but contains no executable sections\n"), + pcnt); + + if ((phdr->p_flags & PF_W) != 0 + && (segment_flags[pcnt] & PF_W) == 0) + ERROR (_("\ +loadable segment [%u] is writable but contains no writable sections\n"), + pcnt); + } + } + + free (segment_flags); + + if (version_namelist != NULL) + { + if (versym_scnndx == 0) + ERROR (_("\ +no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n")); + else + check_versym (ebl, versym_scnndx); + + /* Check for duplicate index numbers. */ + do + { + struct version_namelist *runp = version_namelist->next; + while (runp != NULL) + { + if (version_namelist->ndx == runp->ndx) + { + ERROR (_("duplicate version index %d\n"), + (int) version_namelist->ndx); + break; + } + runp = runp->next; + } + + struct version_namelist *old = version_namelist; + version_namelist = version_namelist->next; + free (old); + } + while (version_namelist != NULL); + } + else if (versym_scnndx != 0) + ERROR (_("\ +.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n")); + + if (hash_idx != 0 && gnu_hash_idx != 0) + compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx); + + free (scnref); +} + + +static GElf_Off +check_note_data (Ebl *ebl, const GElf_Ehdr *ehdr, + Elf_Data *data, int shndx, int phndx, GElf_Off start) +{ + size_t offset = 0; + size_t last_offset = 0; + GElf_Nhdr nhdr; + size_t name_offset; + size_t desc_offset; + while (offset < data->d_size + && (offset = gelf_getnote (data, offset, + &nhdr, &name_offset, &desc_offset)) > 0) + { + last_offset = offset; + + /* Make sure it is one of the note types we know about. */ + if (ehdr->e_type == ET_CORE) + switch (nhdr.n_type) + { + case NT_PRSTATUS: + case NT_FPREGSET: + case NT_PRPSINFO: + case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ + case NT_PLATFORM: + case NT_AUXV: + case NT_GWINDOWS: + case NT_ASRS: + case NT_PSTATUS: + case NT_PSINFO: + case NT_PRCRED: + case NT_UTSNAME: + case NT_LWPSTATUS: + case NT_LWPSINFO: + case NT_PRFPXREG: + /* Known type. */ + break; + + default: + if (shndx == 0) + ERROR (_("\ +phdr[%d]: unknown core file note type %" PRIu32 " at offset %" PRIu64 "\n"), + phndx, (uint32_t) nhdr.n_type, start + offset); + else + ERROR (_("\ +section [%2d] '%s': unknown core file note type %" PRIu32 + " at offset %zu\n"), + shndx, section_name (ebl, shndx), + (uint32_t) nhdr.n_type, offset); + } + else + switch (nhdr.n_type) + { + case NT_GNU_ABI_TAG: + case NT_GNU_HWCAP: + case NT_GNU_BUILD_ID: + case NT_GNU_GOLD_VERSION: + case NT_GNU_PROPERTY_TYPE_0: + if (nhdr.n_namesz == sizeof ELF_NOTE_GNU + && strcmp (data->d_buf + name_offset, ELF_NOTE_GNU) == 0) + break; + else + { + /* NT_VERSION is 1, same as NT_GNU_ABI_TAG. It has no + descriptor and (ab)uses the name as version string. */ + if (nhdr.n_descsz == 0 && nhdr.n_type == NT_VERSION) + break; + } + goto unknown_note; + + case NT_GNU_BUILD_ATTRIBUTE_OPEN: + case NT_GNU_BUILD_ATTRIBUTE_FUNC: + /* GNU Build Attributes store most data in the owner + name, which must start with the + ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX "GA". */ + if (nhdr.n_namesz >= sizeof ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX + && strncmp (data->d_buf + name_offset, + ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX, + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0) + break; + else + goto unknown_note; + + case 0: + /* Linux vDSOs use a type 0 note for the kernel version word. */ + if (nhdr.n_namesz == sizeof "Linux" + && !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux")) + break; + FALLTHROUGH; + default: + { + unknown_note: + if (shndx == 0) + ERROR (_("\ +phdr[%d]: unknown object file note type %" PRIu32 " with owner name '%s' at offset %zu\n"), + phndx, (uint32_t) nhdr.n_type, + (char *) data->d_buf + name_offset, offset); + else + ERROR (_("\ +section [%2d] '%s': unknown object file note type %" PRIu32 + " with owner name '%s' at offset %zu\n"), + shndx, section_name (ebl, shndx), + (uint32_t) nhdr.n_type, + (char *) data->d_buf + name_offset, offset); + } + } + } + + return last_offset; +} + + +static void +check_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) +{ + if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL + && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + ERROR (_("\ +phdr[%d]: no note entries defined for the type of file\n"), + cnt); + + if (is_debuginfo) + /* The p_offset values in a separate debug file are bogus. */ + return; + + if (phdr->p_filesz == 0) + return; + + GElf_Off notes_size = 0; + Elf_Data *data = elf_getdata_rawchunk (ebl->elf, + phdr->p_offset, phdr->p_filesz, + (phdr->p_align == 8 + ? ELF_T_NHDR8 : ELF_T_NHDR)); + if (data != NULL && data->d_buf != NULL) + notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset); + + if (notes_size == 0) + ERROR (_("phdr[%d]: cannot get content of note section: %s\n"), + cnt, elf_errmsg (-1)); + else if (notes_size != phdr->p_filesz) + ERROR (_("phdr[%d]: extra %" PRIu64 " bytes after last note\n"), + cnt, phdr->p_filesz - notes_size); +} + + +static void +check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) +{ + if (shdr->sh_size == 0) + return; + + Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); + if (data == NULL || data->d_buf == NULL) + { + ERROR (_("section [%2d] '%s': cannot get section data\n"), + idx, section_name (ebl, idx)); + return; + } + + if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL + && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + ERROR (_("\ +section [%2d] '%s': no note entries defined for the type of file\n"), + idx, section_name (ebl, idx)); + + GElf_Off notes_size = check_note_data (ebl, ehdr, data, idx, 0, 0); + + if (notes_size == 0) + ERROR (_("section [%2d] '%s': cannot get content of note section\n"), + idx, section_name (ebl, idx)); + else if (notes_size != shdr->sh_size) + ERROR (_("section [%2d] '%s': extra %" PRIu64 + " bytes after last note\n"), + idx, section_name (ebl, idx), shdr->sh_size - notes_size); +} + + +/* Index of the PT_GNU_EH_FRAME program eader entry. */ +static int pt_gnu_eh_frame_pndx; + + +static void +check_program_header (Ebl *ebl, GElf_Ehdr *ehdr) +{ + if (ehdr->e_phoff == 0) + return; + + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN + && ehdr->e_type != ET_CORE) + ERROR (_("\ +only executables, shared objects, and core files can have program headers\n")); + + int num_pt_interp = 0; + int num_pt_tls = 0; + int num_pt_relro = 0; + + for (unsigned int cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr; + + phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); + if (phdr == NULL) + { + ERROR (_("cannot get program header entry %d: %s\n"), + cnt, elf_errmsg (-1)); + continue; + } + + if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME + && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO + && phdr->p_type != PT_GNU_PROPERTY + /* Check for a known machine-specific type. */ + && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL) + ERROR (_("\ +program header entry %d: unknown program header entry type %#" PRIx64 "\n"), + cnt, (uint64_t) phdr->p_type); + + if (phdr->p_type == PT_LOAD) + has_loadable_segment = true; + else if (phdr->p_type == PT_INTERP) + { + if (++num_pt_interp != 1) + { + if (num_pt_interp == 2) + ERROR (_("\ +more than one INTERP entry in program header\n")); + } + has_interp_segment = true; + } + else if (phdr->p_type == PT_TLS) + { + if (++num_pt_tls == 2) + ERROR (_("more than one TLS entry in program header\n")); + } + else if (phdr->p_type == PT_NOTE) + check_note (ebl, ehdr, phdr, cnt); + else if (phdr->p_type == PT_DYNAMIC) + { + if (ehdr->e_type == ET_EXEC && ! has_interp_segment) + ERROR (_("\ +static executable cannot have dynamic sections\n")); + else + { + /* Check that the .dynamic section, if it exists, has + the same address. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) + { + if (phdr->p_offset != shdr->sh_offset) + ERROR (_("\ +dynamic section reference in program header has wrong offset\n")); + if (phdr->p_memsz != shdr->sh_size) + ERROR (_("\ +dynamic section size mismatch in program and section header\n")); + break; + } + } + } + } + else if (phdr->p_type == PT_GNU_RELRO) + { + if (++num_pt_relro == 2) + ERROR (_("\ +more than one GNU_RELRO entry in program header\n")); + else + { + /* Check that the region is in a writable segment. */ + unsigned int inner; + for (inner = 0; inner < phnum; ++inner) + { + GElf_Phdr phdr2_mem; + GElf_Phdr *phdr2; + + phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); + if (phdr2 == NULL) + continue; + + if (phdr2->p_type == PT_LOAD + && phdr->p_vaddr >= phdr2->p_vaddr + && (phdr->p_vaddr + phdr->p_memsz + <= phdr2->p_vaddr + phdr2->p_memsz)) + { + if ((phdr2->p_flags & PF_W) == 0) + ERROR (_("\ +loadable segment GNU_RELRO applies to is not writable\n")); + /* Unless fully covered, relro flags could be a + subset of the phdrs2 flags. For example the load + segment could also have PF_X set. */ + if (phdr->p_vaddr == phdr2->p_vaddr + && (phdr->p_vaddr + phdr->p_memsz + == phdr2->p_vaddr + phdr2->p_memsz)) + { + if ((phdr2->p_flags & ~PF_W) + != (phdr->p_flags & ~PF_W)) + ERROR (_("\ +loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), + cnt, inner); + } + else + { + if ((phdr->p_flags & ~phdr2->p_flags) != 0) + ERROR (_("\ +GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"), + inner, cnt); + } + break; + } + } + + if (inner >= phnum) + ERROR (_("\ +%s segment not contained in a loaded segment\n"), "GNU_RELRO"); + } + } + else if (phdr->p_type == PT_PHDR) + { + /* Check that the region is in a writable segment. */ + unsigned int inner; + for (inner = 0; inner < phnum; ++inner) + { + GElf_Phdr phdr2_mem; + GElf_Phdr *phdr2; + + phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); + if (phdr2 != NULL + && phdr2->p_type == PT_LOAD + && phdr->p_vaddr >= phdr2->p_vaddr + && (phdr->p_vaddr + phdr->p_memsz + <= phdr2->p_vaddr + phdr2->p_memsz)) + break; + } + + if (inner >= phnum) + ERROR (_("\ +%s segment not contained in a loaded segment\n"), "PHDR"); + + /* Check that offset in segment corresponds to offset in ELF + header. */ + if (phdr->p_offset != ehdr->e_phoff) + ERROR (_("\ +program header offset in ELF header and PHDR entry do not match")); + } + else if (phdr->p_type == PT_GNU_EH_FRAME) + { + /* If there is an .eh_frame_hdr section it must be + referenced by this program header entry. */ + Elf_Scn *scn = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = NULL; + bool any = false; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + any = true; + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL + && ((is_debuginfo && shdr->sh_type == SHT_NOBITS) + || (! is_debuginfo + && (shdr->sh_type == SHT_PROGBITS + || shdr->sh_type == SHT_X86_64_UNWIND))) + && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL + && ! strcmp (".eh_frame_hdr", + elf_strptr (ebl->elf, shstrndx, shdr->sh_name))) + { + if (! is_debuginfo) + { + if (phdr->p_offset != shdr->sh_offset) + ERROR (_("\ +call frame search table reference in program header has wrong offset\n")); + if (phdr->p_memsz != shdr->sh_size) + ERROR (_("\ +call frame search table size mismatch in program and section header\n")); + } + break; + } + } + + if (scn == NULL) + { + /* If there is no section header table we don't + complain. But if there is one there should be an + entry for .eh_frame_hdr. */ + if (any) + ERROR (_("\ +PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n")); + } + else + { + /* The section must be allocated and not be writable and + executable. */ + if ((phdr->p_flags & PF_R) == 0) + ERROR (_("\ +call frame search table must be allocated\n")); + else if (shdr != NULL && (shdr->sh_flags & SHF_ALLOC) == 0) + ERROR (_("\ +section [%2zu] '%s' must be allocated\n"), elf_ndxscn (scn), ".eh_frame_hdr"); + + if ((phdr->p_flags & PF_W) != 0) + ERROR (_("\ +call frame search table must not be writable\n")); + else if (shdr != NULL && (shdr->sh_flags & SHF_WRITE) != 0) + ERROR (_("\ +section [%2zu] '%s' must not be writable\n"), + elf_ndxscn (scn), ".eh_frame_hdr"); + + if ((phdr->p_flags & PF_X) != 0) + ERROR (_("\ +call frame search table must not be executable\n")); + else if (shdr != NULL && (shdr->sh_flags & SHF_EXECINSTR) != 0) + ERROR (_("\ +section [%2zu] '%s' must not be executable\n"), + elf_ndxscn (scn), ".eh_frame_hdr"); + } + + /* Remember which entry this is. */ + pt_gnu_eh_frame_pndx = cnt; + } + + if (phdr->p_filesz > phdr->p_memsz + && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE)) + ERROR (_("\ +program header entry %d: file size greater than memory size\n"), + cnt); + + if (phdr->p_align > 1) + { + if (!powerof2 (phdr->p_align)) + ERROR (_("\ +program header entry %d: alignment not a power of 2\n"), cnt); + else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) + ERROR (_("\ +program header entry %d: file offset and virtual address not module of alignment\n"), cnt); + } + } +} + + +static void +check_exception_data (Ebl *ebl __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused))) +{ + if ((ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) + && pt_gnu_eh_frame_pndx == 0 && eh_frame_hdr_scnndx != 0) + ERROR (_("executable/DSO with .eh_frame_hdr section does not have " + "a PT_GNU_EH_FRAME program header entry")); +} + + +/* Process one file. */ +static void +process_elf_file (Elf *elf, const char *prefix, const char *suffix, + const char *fname, size_t size, bool only_one) +{ + /* Reset variables. */ + ndynamic = 0; + nverneed = 0; + nverdef = 0; + textrel = false; + needed_textrel = false; + has_loadable_segment = false; + has_interp_segment = false; + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + Ebl *ebl; + + /* Print the file name. */ + if (!only_one) + { + if (prefix != NULL) + printf ("\n%s(%s)%s:\n", prefix, fname, suffix); + else + printf ("\n%s:\n", fname); + } + + if (ehdr == NULL) + { + ERROR (_("cannot read ELF header: %s\n"), elf_errmsg (-1)); + return; + } + + ebl = ebl_openbackend (elf); + /* If there is no appropriate backend library we cannot test + architecture and OS specific features. Any encountered extension + is an error. Often we'll get a "dummy" ebl, except if something + really bad happen, like a totally corrupted ELF file or out of + memory situation. */ + if (ebl == NULL) + { + ERROR (_("cannot create backend for ELF file\n")); + return; + } + + /* Go straight by the gABI, check all the parts in turn. */ + check_elf_header (ebl, ehdr, size); + + /* Check the program header. */ + check_program_header (ebl, ehdr); + + /* Next the section headers. It is OK if there are no section + headers at all. */ + check_sections (ebl, ehdr); + + /* Check the exception handling data, if it exists. */ + if (pt_gnu_eh_frame_pndx != 0 || eh_frame_hdr_scnndx != 0 + || eh_frame_scnndx != 0 || gcc_except_table_scnndx != 0) + check_exception_data (ebl, ehdr); + + /* Report if no relocation section needed the text relocation flag. */ + if (textrel && !needed_textrel) + ERROR (_("text relocation flag set but not needed\n")); + + /* Free the resources. */ + ebl_closebackend (ebl); +} + + +#include "debugpred.h" diff --git a/src/findtextrel.c b/src/findtextrel.c new file mode 100644 index 00000000..220ee909 --- /dev/null +++ b/src/findtextrel.c @@ -0,0 +1,613 @@ +/* Locate source files or functions which caused text relocations. + Copyright (C) 2005-2010, 2012, 2014, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "system.h" + +struct segments +{ + GElf_Addr from; + GElf_Addr to; +}; + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Values for the parameters which have no short form. */ +#define OPT_DEBUGINFO 0x100 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Input Selection:"), 0 }, + { "root", 'r', "PATH", 0, N_("Prepend PATH to all file names"), 0 }, + { "debuginfo", OPT_DEBUGINFO, "PATH", 0, + N_("Use PATH as root of debuginfo hierarchy"), 0 }, + + { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Locate source of text relocations in FILEs (a.out by default)."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + + +/* Print symbols in file named FNAME. */ +static int process_file (const char *fname, bool more_than_one); + +/* Check for text relocations in the given file. The segment + information is known. */ +static void check_rel (size_t nsegments, struct segments segments[nsegments], + GElf_Addr addr, Elf *elf, Elf_Scn *symscn, Dwarf *dw, + const char *fname, bool more_than_one, + void **knownsrcs); + + + +/* User-provided root directory. */ +static const char *rootdir = "/"; + +/* Root of debuginfo directory hierarchy. */ +static const char *debuginfo_root; + + +int +main (int argc, char *argv[]) +{ + int remaining; + int result = 0; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* Tell the library which version we are expecting. */ + elf_version (EV_CURRENT); + + /* If the user has not specified the root directory for the + debuginfo hierarchy, we have to determine it ourselves. */ + if (debuginfo_root == NULL) + { + // XXX The runtime should provide this information. +#if defined __ia64__ || defined __alpha__ + debuginfo_root = "/usr/lib/debug"; +#else + debuginfo_root = (sizeof (long int) == 4 + ? "/usr/lib/debug" : "/usr/lib64/debug"); +#endif + } + + if (remaining == argc) + result = process_file ("a.out", false); + else + { + /* Process all the remaining files. */ + const bool more_than_one = remaining + 1 < argc; + + do + result |= process_file (argv[remaining], more_than_one); + while (++remaining < argc); + } + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'r': + rootdir = arg; + break; + + case OPT_DEBUGINFO: + debuginfo_root = arg; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +static void +noop (void *arg __attribute__ ((unused))) +{ +} + + +static int +process_file (const char *fname, bool more_than_one) +{ + int result = 0; + void *knownsrcs = NULL; + + size_t fname_len = strlen (fname); + size_t rootdir_len = strlen (rootdir); + const char *real_fname = fname; + if (fname[0] == '/' && (rootdir[0] != '/' || rootdir[1] != '\0')) + { + /* Prepend the user-provided root directory. */ + char *new_fname = alloca (rootdir_len + fname_len + 2); + *((char *) mempcpy (stpcpy (mempcpy (new_fname, rootdir, rootdir_len), + "/"), + fname, fname_len)) = '\0'; + real_fname = new_fname; + } + + int fd = open (real_fname, O_RDONLY); + if (fd == -1) + { + error (0, errno, _("cannot open '%s'"), fname); + return 1; + } + + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + { + error (0, 0, _("cannot create ELF descriptor for '%s': %s"), + fname, elf_errmsg (-1)); + goto err_close; + } + + /* Make sure the file is a DSO. */ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + error (0, 0, _("cannot get ELF header '%s': %s"), + fname, elf_errmsg (-1)); + err_elf_close: + elf_end (elf); + err_close: + close (fd); + return 1; + } + + if (ehdr->e_type != ET_DYN) + { + error (0, 0, _("'%s' is not a DSO or PIE"), fname); + goto err_elf_close; + } + + /* Determine whether the DSO has text relocations at all and locate + the symbol table. */ + Elf_Scn *symscn = NULL; + Elf_Scn *scn = NULL; + bool seen_dynamic = false; + bool have_textrel = false; + while ((scn = elf_nextscn (elf, scn)) != NULL + && (!seen_dynamic || symscn == NULL)) + { + /* Handle the section if it is a symbol table. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + { + error (0, 0, + _("getting get section header of section %zu: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + goto err_elf_close; + } + + switch (shdr->sh_type) + { + case SHT_DYNAMIC: + if (!seen_dynamic) + { + seen_dynamic = true; + + Elf_Data *data = elf_getdata (scn, NULL); + size_t entries = (shdr->sh_entsize == 0 + ? 0 : shdr->sh_size / shdr->sh_entsize); + + for (size_t cnt = 0; cnt < entries; ++cnt) + { + GElf_Dyn dynmem; + GElf_Dyn *dyn; + + dyn = gelf_getdyn (data, cnt, &dynmem); + if (dyn == NULL) + { + error (0, 0, _("cannot read dynamic section: %s"), + elf_errmsg (-1)); + goto err_elf_close; + } + + if (dyn->d_tag == DT_TEXTREL + || (dyn->d_tag == DT_FLAGS + && (dyn->d_un.d_val & DF_TEXTREL) != 0)) + have_textrel = true; + } + } + break; + + case SHT_SYMTAB: + symscn = scn; + break; + } + } + + if (!have_textrel) + { + error (0, 0, _("no text relocations reported in '%s'"), fname); + goto err_elf_close; + } + + int fd2 = -1; + Elf *elf2 = NULL; + /* Get the address ranges for the loaded segments. */ + size_t nsegments_max = 10; + size_t nsegments = 0; + struct segments *segments + = (struct segments *) malloc (nsegments_max * sizeof (segments[0])); + if (segments == NULL) + error (1, errno, _("while reading ELF file")); + + size_t phnum; + if (elf_getphdrnum (elf, &phnum) != 0) + error (1, 0, _("cannot get program header count: %s"), + elf_errmsg (-1)); + + + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (phdr == NULL) + { + error (0, 0, + _("cannot get program header index at offset %zd: %s"), + i, elf_errmsg (-1)); + result = 1; + goto next; + } + + if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0) + { + if (nsegments == nsegments_max) + { + nsegments_max *= 2; + segments + = (struct segments *) realloc (segments, + nsegments_max + * sizeof (segments[0])); + if (segments == NULL) + { + error (0, 0, _("\ +cannot get program header index at offset %zd: %s"), + i, elf_errmsg (-1)); + result = 1; + goto next; + } + } + + segments[nsegments].from = phdr->p_vaddr; + segments[nsegments].to = phdr->p_vaddr + phdr->p_memsz; + ++nsegments; + } + } + + if (nsegments > 0) + { + + Dwarf *dw = dwarf_begin_elf (elf, DWARF_C_READ, NULL); + /* Look for debuginfo files if the information is not the in + opened file itself. This makes only sense if the input file + is specified with an absolute path. */ + if (dw == NULL && fname[0] == '/') + { + size_t debuginfo_rootlen = strlen (debuginfo_root); + char *difname = (char *) alloca (rootdir_len + debuginfo_rootlen + + fname_len + 8); + strcpy (mempcpy (stpcpy (mempcpy (mempcpy (difname, rootdir, + rootdir_len), + debuginfo_root, + debuginfo_rootlen), + "/"), + fname, fname_len), + ".debug"); + + fd2 = open (difname, O_RDONLY); + if (fd2 != -1 + && (elf2 = elf_begin (fd2, ELF_C_READ_MMAP, NULL)) != NULL) + dw = dwarf_begin_elf (elf2, DWARF_C_READ, NULL); + } + + /* Look at all relocations and determine which modify + write-protected segments. */ + scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + /* Handle the section if it is a symbol table. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + { + error (0, 0, + _("cannot get section header of section %zu: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + result = 1; + goto next; + } + + if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) + && symscn == NULL) + { + symscn = elf_getscn (elf, shdr->sh_link); + if (symscn == NULL) + { + error (0, 0, _("\ +cannot get symbol table section %zu in '%s': %s"), + (size_t) shdr->sh_link, fname, elf_errmsg (-1)); + result = 1; + goto next; + } + } + + if (shdr->sh_type == SHT_REL) + { + Elf_Data *data = elf_getdata (scn, NULL); + size_t entries = (shdr->sh_entsize == 0 + ? 0 : shdr->sh_size / shdr->sh_entsize); + + for (int cnt = 0; + (size_t) cnt < entries; ++cnt) + { + GElf_Rel rel_mem; + GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); + if (rel == NULL) + { + error (0, 0, _("\ +cannot get relocation at index %d in section %zu in '%s': %s"), + cnt, elf_ndxscn (scn), fname, elf_errmsg (-1)); + result = 1; + goto next; + } + + check_rel (nsegments, segments, rel->r_offset, elf, + symscn, dw, fname, more_than_one, &knownsrcs); + } + } + else if (shdr->sh_type == SHT_RELA) + { + Elf_Data *data = elf_getdata (scn, NULL); + size_t entries = (shdr->sh_entsize == 0 + ? 0 : shdr->sh_size / shdr->sh_entsize); + + for (int cnt = 0; (size_t) cnt < entries; ++cnt) + { + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); + if (rela == NULL) + { + error (0, 0, _("\ +cannot get relocation at index %d in section %zu in '%s': %s"), + cnt, elf_ndxscn (scn), fname, elf_errmsg (-1)); + result = 1; + goto next; + } + + check_rel (nsegments, segments, rela->r_offset, elf, + symscn, dw, fname, more_than_one, &knownsrcs); + } + } + } + + dwarf_end (dw); + } + + next: + elf_end (elf); + elf_end (elf2); + close (fd); + if (fd2 != -1) + close (fd2); + + free (segments); + tdestroy (knownsrcs, noop); + + return result; +} + + +static int +ptrcompare (const void *p1, const void *p2) +{ + if ((uintptr_t) p1 < (uintptr_t) p2) + return -1; + if ((uintptr_t) p1 > (uintptr_t) p2) + return 1; + return 0; +} + + +static void +check_rel (size_t nsegments, struct segments segments[nsegments], + GElf_Addr addr, Elf *elf, Elf_Scn *symscn, Dwarf *dw, + const char *fname, bool more_than_one, void **knownsrcs) +{ + for (size_t cnt = 0; cnt < nsegments; ++cnt) + if (segments[cnt].from <= addr && segments[cnt].to > addr) + { + Dwarf_Die die_mem; + Dwarf_Die *die; + Dwarf_Line *line; + const char *src; + + if (more_than_one) + printf ("%s: ", fname); + + if ((die = dwarf_addrdie (dw, addr, &die_mem)) != NULL + && (line = dwarf_getsrc_die (die, addr)) != NULL + && (src = dwarf_linesrc (line, NULL, NULL)) != NULL) + { + /* There can be more than one relocation against one file. + Try to avoid multiple messages. And yes, the code uses + pointer comparison. */ + if (tfind (src, knownsrcs, ptrcompare) == NULL) + { + printf (_("%s not compiled with -fpic/-fPIC\n"), src); + tsearch (src, knownsrcs, ptrcompare); + } + return; + } + else + { + /* At least look at the symbol table to see which function + the modified address is in. */ + Elf_Data *symdata = elf_getdata (symscn, NULL); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem); + if (shdr != NULL) + { + GElf_Addr lowaddr = 0; + int lowidx = -1; + GElf_Addr highaddr = ~0ul; + int highidx = -1; + GElf_Sym sym_mem; + GElf_Sym *sym; + size_t entries = (shdr->sh_entsize == 0 + ? 0 : shdr->sh_size / shdr->sh_entsize); + + for (int i = 0; (size_t) i < entries; ++i) + { + sym = gelf_getsym (symdata, i, &sym_mem); + if (sym == NULL) + continue; + + if (sym->st_value < addr && sym->st_value > lowaddr) + { + lowaddr = sym->st_value; + lowidx = i; + } + if (sym->st_value > addr && sym->st_value < highaddr) + { + highaddr = sym->st_value; + highidx = i; + } + } + + if (lowidx != -1) + { + sym = gelf_getsym (symdata, lowidx, &sym_mem); + assert (sym != NULL); + + const char *lowstr = elf_strptr (elf, shdr->sh_link, + sym->st_name); + + if (sym->st_value + sym->st_size > addr) + { + /* It is this function. */ + if (tfind (lowstr, knownsrcs, ptrcompare) == NULL) + { + printf (_("\ +the file containing the function '%s' is not compiled with -fpic/-fPIC\n"), + lowstr); + tsearch (lowstr, knownsrcs, ptrcompare); + } + } + else if (highidx == -1) + printf (_("\ +the file containing the function '%s' might not be compiled with -fpic/-fPIC\n"), + lowstr); + else + { + sym = gelf_getsym (symdata, highidx, &sym_mem); + assert (sym != NULL); + + printf (_("\ +either the file containing the function '%s' or the file containing the function '%s' is not compiled with -fpic/-fPIC\n"), + lowstr, elf_strptr (elf, shdr->sh_link, + sym->st_name)); + } + return; + } + else if (highidx != -1) + { + sym = gelf_getsym (symdata, highidx, &sym_mem); + assert (sym != NULL); + + printf (_("\ +the file containing the function '%s' might not be compiled with -fpic/-fPIC\n"), + elf_strptr (elf, shdr->sh_link, sym->st_name)); + return; + } + } + } + + printf (_("\ +a relocation modifies memory at offset %llu in a write-protected segment\n"), + (unsigned long long int) addr); + break; + } +} + + +#include "debugpred.h" diff --git a/src/make-debug-archive.in b/src/make-debug-archive.in new file mode 100644 index 00000000..c3fcbce4 --- /dev/null +++ b/src/make-debug-archive.in @@ -0,0 +1,132 @@ +#!/bin/sh +# +# Script to make an offline archive for debugging with libdwfl-based tools. +# +# make-debug-archive ARCHIVE {options} +# make-debug-archive --kernel [--force] [RELEASE] +# +# Valid options are those listed under 'Input selection options' +# by running @UNSTRIP@ --help. +# +# The archive installed by --kernel be used automatically by -K. +# An offline archive can be used via -e in any tool that accepts those options. +# + +UNSTRIP=${UNSTRIP:-@UNSTRIP@} +AR=${AR:-@AR@} +SUDO=${SUDO:-/usr/bin/sudo} + +LS=/bin/ls +RM=/bin/rm +MV=/bin/mv +MKDIR=/bin/mkdir +XARGS=/usr/bin/xargs + +outdir=${TMPDIR:-/tmp}/debugar$$ + +usage() +{ + echo "Usage: $0 ARCHIVE {options}" + echo " or: $0 --kernel [--sudo] [--force] [RELEASE]" + echo + echo "Valid options are listed under 'Input selection options'" + echo "when running: $UNSTRIP --help" + echo + echo "The --kernel form updates the file used by -K if the" + echo "kernel installation has changed, or always with --force." + echo "With --sudo, touches the installed file via $SUDO." +} + +fatal_usage() +{ + usage >&2 + exit 2 +} + +script_version() +{ + echo "`basename $0` (@PACKAGE_NAME@) @PACKAGE_VERSION@" + echo "Copyright (C) 2007 Red Hat, Inc." + echo "This is free software; see the source for copying conditions." + echo "There is NO warranty; not even for MERCHANTABILITY or" + echo "FITNESS FOR A PARTICULAR PURPOSE." + echo "Written by Roland McGrath." +} + +sudo= +kernel=no +force_kernel=no +while [ $# -gt 0 ]; do + case "x$1" in + x--help) usage; exit 0 ;; + x--version) script_version; exit 0 ;; + x--kernel) kernel=yes ;; + x--force) force_kernel=yes ;; + x--sudo) sudo=$SUDO ;; + *) break ;; + esac + shift +done + +if [ $kernel = no ] && [ $force_kernel = yes -o -n "$sudo" ]; then + usage +fi + +if [ $kernel = yes ]; then + if [ $# -eq 0 ]; then + release=`uname -r` + elif [ $# -eq 1 ]; then + release=$1 + else + fatal_usage + fi + + dir=/usr/lib/debug/lib/modules/$release + archive=$dir/debug.a + dep=/lib/modules/$release/modules.dep + + if [ ! -d $dir ]; then + echo >&2 "$0: $dir not installed" + exit 1 + fi + + # Without --force, bail if the kernel installation is not newer. + # This file is normally touched by installing new kernels or modules. + if [ $force_kernel = no -a "$archive" -nt "$dep" ]; then + exit 0 + fi + + # We have to kill the old one first, because our own -K would use it. + [ ! -e "$archive" ] || $sudo $RM -f "$archive" || exit + + set "$archive" "-K$release" +fi + +if [ $# -lt 2 ]; then + fatal_usage +fi + +archive="$1" +shift + +case "$archive" in +/*) ;; +*) archive="`/bin/pwd`/$archive" ;; +esac + +if [ -z "$sudo" ]; then + new_archive="$archive.new" +else + new_archive="$outdir.a" +fi + +$RM -f "$new_archive" || exit + +trap '$RM -rf "$outdir" "$new_archive"' 0 1 2 15 + +$MKDIR "$outdir" && +$UNSTRIP -d "$outdir" -m -a -R "$@" && +(cd "$outdir" && $LS | $XARGS $AR cq "$new_archive") && +$sudo $MV -f "$new_archive" "$archive" + +exit diff --git a/src/nm.c b/src/nm.c new file mode 100644 index 00000000..b99805e8 --- /dev/null +++ b/src/nm.c @@ -0,0 +1,1635 @@ +/* Print symbol information from ELF file in human-readable form. + Copyright (C) 2000-2008, 2009, 2011, 2012, 2014, 2015, 2020 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#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 "../libebl/libeblP.h" +#include "../libdwfl/libdwflP.h" + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Values for the parameters which have no short form. */ +#define OPT_DEFINED 0x100 +#define OPT_MARK_SPECIAL 0x101 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Output selection:"), 0 }, + { "debug-syms", 'a', NULL, 0, N_("Display debugger-only symbols"), 0 }, + { "defined-only", OPT_DEFINED, NULL, 0, N_("Display only defined symbols"), + 0 }, + { "dynamic", 'D', NULL, 0, + N_("Display dynamic symbols instead of normal symbols"), 0 }, + { "extern-only", 'g', NULL, 0, N_("Display only external symbols"), 0 }, + { "undefined-only", 'u', NULL, 0, N_("Display only undefined symbols"), 0 }, + { "print-armap", 's', NULL, 0, + N_("Include index for symbols from archive members"), 0 }, + + { NULL, 0, NULL, 0, N_("Output format:"), 0 }, + { "print-file-name", 'A', NULL, 0, + N_("Print name of the input file before every symbol"), 0 }, + { NULL, 'o', NULL, OPTION_HIDDEN, "Same as -A", 0 }, + { "format", 'f', "FORMAT", 0, + N_("Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The default is `sysv'"), + 0 }, + { NULL, 'B', NULL, 0, N_("Same as --format=bsd"), 0 }, + { "portability", 'P', NULL, 0, N_("Same as --format=posix"), 0 }, + { "radix", 't', "RADIX", 0, N_("Use RADIX for printing symbol values"), 0 }, + { "mark-special", OPT_MARK_SPECIAL, NULL, 0, N_("Mark special symbols"), 0 }, + { "mark-weak", OPT_MARK_SPECIAL, NULL, OPTION_HIDDEN, "", 0 }, + { "print-size", 'S', NULL, 0, N_("Print size of defined symbols"), 0 }, + + { NULL, 0, NULL, 0, N_("Output options:"), 0 }, + { "numeric-sort", 'n', NULL, 0, N_("Sort symbols numerically by address"), + 0 }, + { "no-sort", 'p', NULL, 0, N_("Do not sort the symbols"), 0 }, + { "reverse-sort", 'r', NULL, 0, N_("Reverse the sense of the sort"), 0 }, +#ifdef USE_DEMANGLE + { "demangle", 'C', NULL, 0, + N_("Decode low-level symbol names into source code names"), 0 }, +#endif + { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("List symbols from FILEs (a.out by default)."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Parser children. */ +static struct argp_child argp_children[] = + { + { &color_argp, 0, N_("Output formatting"), 2 }, + { NULL, 0, NULL, 0} + }; + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, argp_children, NULL, NULL +}; + + +/* Print symbols in file named FNAME. */ +static int process_file (const char *fname, bool more_than_one); + +/* Handle content of archive. */ +static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, + const char *suffix); + +/* Handle ELF file. */ +static int handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, + const char *suffix); + + +#define INTERNAL_ERROR(fname) \ + error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"), \ + fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)) + + +/* Internal representation of symbols. */ +typedef struct GElf_SymX +{ + GElf_Sym sym; + Elf32_Word xndx; + char *where; +} GElf_SymX; + + +/* User-selectable options. */ + +/* The selected output format. */ +static enum +{ + format_sysv = 0, + format_bsd, + format_posix +} format; + +/* Print defined, undefined, or both? */ +static bool hide_undefined; +static bool hide_defined; + +/* Print local symbols also? */ +static bool hide_local; + +/* Nonzero if full filename should precede every symbol. */ +static bool print_file_name; + +/* If true print size of defined symbols in BSD format. */ +static bool print_size; + +/* If true print archive index. */ +static bool print_armap; + +/* If true reverse sorting. */ +static bool reverse_sort; + +#ifdef USE_DEMANGLE +/* If true demangle symbols. */ +static bool demangle; +#endif + +/* Type of the section we are printing. */ +static GElf_Word symsec_type = SHT_SYMTAB; + +/* Sorting selection. */ +static enum +{ + sort_name = 0, + sort_numeric, + sort_nosort +} sort; + +/* Radix for printed numbers. */ +static enum +{ + radix_hex = 0, + radix_decimal, + radix_octal +} radix; + +/* If nonzero mark special symbols: + - weak symbols are distinguished from global symbols by adding + a `*' after the identifying letter for the symbol class and type. + - TLS symbols are distinguished from normal symbols by adding + a '@' after the identifying letter for the symbol class and type. */ +static bool mark_special; + + +int +main (int argc, char *argv[]) +{ + int remaining; + int result = 0; + + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* Tell the library which version we are expecting. */ + (void) elf_version (EV_CURRENT); + + if (remaining == argc) + /* The user didn't specify a name so we use a.out. */ + result = process_file ("a.out", false); + else + { + /* Process all the remaining files. */ + const bool more_than_one = remaining + 1 < argc; + + do + result |= process_file (argv[remaining], more_than_one); + while (++remaining < argc); + } + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'a': + /* XXX */ + break; + +#ifdef USE_DEMANGLE + case 'C': + demangle = true; + break; +#endif + + case 'f': + if (strcmp (arg, "bsd") == 0) + format = format_bsd; + else if (strcmp (arg, "posix") == 0) + format = format_posix; + else + /* Be bug compatible. The BFD implementation also defaulted to + using the SysV format if nothing else matches. */ + format = format_sysv; + break; + + case 'g': + hide_local = true; + break; + + case 'n': + sort = sort_numeric; + break; + + case 'p': + sort = sort_nosort; + break; + + case 't': + if (strcmp (arg, "10") == 0 || strcmp (arg, "d") == 0) + radix = radix_decimal; + else if (strcmp (arg, "8") == 0 || strcmp (arg, "o") == 0) + radix = radix_octal; + else + radix = radix_hex; + break; + + case 'u': + hide_undefined = false; + hide_defined = true; + break; + + case 'A': + case 'o': + print_file_name = true; + break; + + case 'B': + format = format_bsd; + break; + + case 'D': + symsec_type = SHT_DYNSYM; + break; + + case 'P': + format = format_posix; + break; + + case OPT_DEFINED: + hide_undefined = true; + hide_defined = false; + break; + + case OPT_MARK_SPECIAL: + mark_special = true; + break; + + case 'S': + print_size = true; + break; + + case 's': + print_armap = true; + break; + + case 'r': + reverse_sort = true; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +/* Open the file and determine the type. */ +static int +process_file (const char *fname, bool more_than_one) +{ + /* Open the file. */ + int fd = open (fname, O_RDONLY); + if (fd == -1) + { + error (0, errno, _("cannot open '%s'"), fname); + return 1; + } + + /* Now get the ELF descriptor. */ + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf != NULL) + { + if (elf_kind (elf) == ELF_K_ELF) + { + int result = handle_elf (fd, elf, more_than_one ? "" : NULL, + fname, NULL); + + if (elf_end (elf) != 0) + INTERNAL_ERROR (fname); + + if (close (fd) != 0) + error (EXIT_FAILURE, errno, _("while closing '%s'"), fname); + + return result; + } + else if (elf_kind (elf) == ELF_K_AR) + { + int result = handle_ar (fd, elf, NULL, fname, NULL); + + if (elf_end (elf) != 0) + INTERNAL_ERROR (fname); + + if (close (fd) != 0) + error (EXIT_FAILURE, errno, _("while closing '%s'"), fname); + + return result; + } + + /* We cannot handle this type. Close the descriptor anyway. */ + if (elf_end (elf) != 0) + INTERNAL_ERROR (fname); + } + + error (0, 0, _("%s: File format not recognized"), fname); + + return 1; +} + + +static int +handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, + const char *suffix) +{ + size_t fname_len = strlen (fname) + 1; + size_t prefix_len = prefix != NULL ? strlen (prefix) : 0; + char new_prefix[prefix_len + fname_len + 2]; + size_t suffix_len = suffix != NULL ? strlen (suffix) : 0; + char new_suffix[suffix_len + 2]; + Elf *subelf; + Elf_Cmd cmd = ELF_C_READ_MMAP; + int result = 0; + + char *cp = new_prefix; + if (prefix != NULL) + cp = stpcpy (cp, prefix); + cp = stpcpy (cp, fname); + stpcpy (cp, "["); + + cp = new_suffix; + if (suffix != NULL) + cp = stpcpy (cp, suffix); + stpcpy (cp, "]"); + + /* First print the archive index if this is wanted. */ + if (print_armap) + { + Elf_Arsym *arsym = elf_getarsym (elf, NULL); + + if (arsym != NULL) + { + Elf_Arhdr *arhdr = NULL; + size_t arhdr_off = 0; /* Note: 0 is no valid offset. */ + + fputs_unlocked (_("\nArchive index:\n"), stdout); + + while (arsym->as_off != 0) + { + if (arhdr_off != arsym->as_off + && (elf_rand (elf, arsym->as_off) != arsym->as_off + || (subelf = elf_begin (fd, cmd, elf)) == NULL + || (arhdr = elf_getarhdr (subelf)) == NULL)) + { + error (0, 0, _("invalid offset %zu for symbol %s"), + arsym->as_off, arsym->as_name); + break; + } + + printf (_("%s in %s\n"), arsym->as_name, arhdr->ar_name); + + ++arsym; + } + + if (elf_rand (elf, SARMAG) != SARMAG) + { + error (0, 0, + _("cannot reset archive offset to beginning")); + return 1; + } + } + } + + /* Process all the files contained in the archive. */ + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + /* Skip over the index entries. */ + if (strcmp (arhdr->ar_name, "/") != 0 + && strcmp (arhdr->ar_name, "//") != 0 + && strcmp (arhdr->ar_name, "/SYM64/") != 0) + { + if (elf_kind (subelf) == ELF_K_ELF) + result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, + new_suffix); + else if (elf_kind (subelf) == ELF_K_AR) + result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, + new_suffix); + else + { + error (0, 0, _("%s%s%s: file format not recognized"), + new_prefix, arhdr->ar_name, new_suffix); + result = 1; + } + } + + /* Get next archive element. */ + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + INTERNAL_ERROR (fname); + } + + return result; +} + + +/* Mapping of radix and binary class to length. */ +static const int length_map[2][3] = +{ + [ELFCLASS32 - 1] = + { + [radix_hex] = 8, + [radix_decimal] = 10, + [radix_octal] = 11 + }, + [ELFCLASS64 - 1] = + { + [radix_hex] = 16, + [radix_decimal] = 20, + [radix_octal] = 22 + } +}; + + +static int +global_compare (const void *p1, const void *p2) +{ + const Dwarf_Global *g1 = (const Dwarf_Global *) p1; + const Dwarf_Global *g2 = (const Dwarf_Global *) p2; + + return strcmp (g1->name, g2->name); +} + + +static void *global_root; + + +static int +get_global (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, + void *arg __attribute__ ((unused))) +{ + tsearch (memcpy (xmalloc (sizeof (Dwarf_Global)), global, + sizeof (Dwarf_Global)), + &global_root, global_compare); + + return DWARF_CB_OK; +} + + +struct local_name +{ + const char *name; + const char *file; + Dwarf_Word lineno; + Dwarf_Addr lowpc; + Dwarf_Addr highpc; +}; + + +static int +local_compare (const void *p1, const void *p2) +{ + struct local_name *g1 = (struct local_name *) p1; + struct local_name *g2 = (struct local_name *) p2; + int result; + + result = strcmp (g1->name, g2->name); + if (result == 0) + { + if (g1->lowpc <= g2->lowpc && g1->highpc >= g2->highpc) + { + /* g2 is contained in g1. Update the data. */ + g2->lowpc = g1->lowpc; + g2->highpc = g1->highpc; + result = 0; + } + else if (g2->lowpc <= g1->lowpc && g2->highpc >= g1->highpc) + { + /* g1 is contained in g2. Update the data. */ + g1->lowpc = g2->lowpc; + g1->highpc = g2->highpc; + result = 0; + } + else + result = g1->lowpc < g2->lowpc ? -1 : 1; + } + + return result; +} + + +static int +get_var_range (Dwarf_Die *die, Dwarf_Word *lowpc, Dwarf_Word *highpc) +{ + Dwarf_Attribute locattr_mem; + Dwarf_Attribute *locattr = dwarf_attr (die, DW_AT_location, &locattr_mem); + if (locattr == NULL) + return 1; + + Dwarf_Op *loc; + size_t nloc; + if (dwarf_getlocation (locattr, &loc, &nloc) != 0) + return 1; + + /* Interpret the location expressions. */ + // XXX For now just the simple one: + if (nloc == 1 && loc[0].atom == DW_OP_addr) + { + *lowpc = *highpc = loc[0].number; + return 0; + } + + return 1; +} + + + +static void *local_root; + + +static void +get_local_names (Dwarf *dbg) +{ + Dwarf_Off offset = 0; + Dwarf_Off old_offset; + size_t hsize; + + while (dwarf_nextcu (dbg, old_offset = offset, &offset, &hsize, NULL, NULL, + NULL) == 0) + { + Dwarf_Die cudie_mem; + Dwarf_Die *cudie = dwarf_offdie (dbg, old_offset + hsize, &cudie_mem); + + /* If we cannot get the CU DIE there is no need to go on with + this CU. */ + if (cudie == NULL) + continue; + /* This better be a CU DIE. */ + if (dwarf_tag (cudie) != DW_TAG_compile_unit) + continue; + + /* Get the line information. */ + Dwarf_Files *files; + size_t nfiles; + if (dwarf_getsrcfiles (cudie, &files, &nfiles) != 0) + continue; + + Dwarf_Die die_mem; + Dwarf_Die *die = &die_mem; + if (dwarf_child (cudie, die) == 0) + /* Iterate over all immediate children of the CU DIE. */ + do + { + int tag = dwarf_tag (die); + if (tag != DW_TAG_subprogram && tag != DW_TAG_variable) + continue; + + /* We are interested in five attributes: name, decl_file, + decl_line, low_pc, and high_pc. */ + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = dwarf_attr (die, DW_AT_name, &attr_mem); + const char *name = dwarf_formstring (attr); + if (name == NULL) + continue; + + Dwarf_Word fileidx; + attr = dwarf_attr (die, DW_AT_decl_file, &attr_mem); + if (dwarf_formudata (attr, &fileidx) != 0 || fileidx >= nfiles) + continue; + + Dwarf_Word lineno; + attr = dwarf_attr (die, DW_AT_decl_line, &attr_mem); + if (dwarf_formudata (attr, &lineno) != 0 || lineno == 0) + continue; + + Dwarf_Addr lowpc; + Dwarf_Addr highpc; + if (tag == DW_TAG_subprogram) + { + if (dwarf_lowpc (die, &lowpc) != 0 + || dwarf_highpc (die, &highpc) != 0) + continue; + } + else + { + if (get_var_range (die, &lowpc, &highpc) != 0) + continue; + } + + /* We have all the information. Create a record. */ + struct local_name *newp + = (struct local_name *) xmalloc (sizeof (*newp)); + newp->name = name; + newp->file = dwarf_filesrc (files, fileidx, NULL, NULL); + newp->lineno = lineno; + newp->lowpc = lowpc; + newp->highpc = highpc; + + /* Check whether a similar local_name is already in the + cache. That should not happen. But if it does, we + don't want to leak memory. */ + struct local_name **tres = tsearch (newp, &local_root, + local_compare); + if (tres == NULL) + error (EXIT_FAILURE, errno, + _("cannot create search tree")); + else if (*tres != newp) + free (newp); + } + while (dwarf_siblingof (die, die) == 0); + } +} + +/* Do elf_strptr, but return a backup string and never NULL. */ +static const char * +sym_name (Elf *elf, GElf_Word strndx, GElf_Word st_name, char buf[], size_t n) +{ + const char *symstr = elf_strptr (elf, strndx, st_name); + if (symstr == NULL) + { + snprintf (buf, n, "[invalid st_name %#" PRIx32 "]", st_name); + symstr = buf; + } + return symstr; +} + +/* Show symbols in SysV format. */ +static void +show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname, + GElf_SymX *syms, size_t nsyms, int longest_name, + int longest_where) +{ + size_t shnum; + if (elf_getshdrnum (ebl->elf, &shnum) < 0) + INTERNAL_ERROR (fullname); + + bool scnnames_malloced = shnum * sizeof (const char *) > 128 * 1024; + const char **scnnames; + if (scnnames_malloced) + scnnames = (const char **) xmalloc (sizeof (const char *) * shnum); + else + scnnames = (const char **) alloca (sizeof (const char *) * shnum); + /* Get the section header string table index. */ + size_t shstrndx; + if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + /* Cache the section names. */ + Elf_Scn *scn = NULL; + size_t cnt = 1; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + assert (elf_ndxscn (scn) == cnt); + cnt++; + + char *name = NULL; + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL) + name = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); + if (unlikely (name == NULL)) + name = "[invalid section name]"; + scnnames[elf_ndxscn (scn)] = name; + } + + int digits = length_map[gelf_getclass (ebl->elf) - 1][radix]; + + /* We always print this prolog. */ + printf (_("\n\nSymbols from %s:\n\n"), fullname); + + /* The header line. */ + printf (_("%*s%-*s %-*s Class Type %-*s %*s Section\n\n"), + print_file_name ? (int) strlen (fullname) + 1: 0, "", + longest_name, sgettext ("sysv|Name"), + /* TRANS: the "sysv|" parts makes the string unique. */ + digits, sgettext ("sysv|Value"), + /* TRANS: the "sysv|" parts makes the string unique. */ + digits, sgettext ("sysv|Size"), + /* TRANS: the "sysv|" parts makes the string unique. */ + longest_where, sgettext ("sysv|Line")); + +#ifdef USE_DEMANGLE + size_t demangle_buffer_len = 0; + char *demangle_buffer = NULL; +#endif + + /* Iterate over all symbols. */ + for (cnt = 0; cnt < nsyms; ++cnt) + { + /* In this format SECTION entries are not printed. */ + if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_SECTION) + continue; + + char symstrbuf[50]; + const char *symstr = sym_name (ebl->elf, strndx, syms[cnt].sym.st_name, + symstrbuf, sizeof symstrbuf); + + /* Printing entries with a zero-length name makes the output + not very well parseable. Since these entries don't carry + much information we leave them out. */ + if (symstr[0] == '\0') + continue; + + /* We do not print the entries for files. */ + if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_FILE) + continue; + +#ifdef USE_DEMANGLE + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') + { + int status = -1; + char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, + &demangle_buffer_len, &status); + + if (status == 0) + symstr = dmsymstr; + } +#endif + + char symbindbuf[50]; + char symtypebuf[50]; + char secnamebuf[1024]; + char addressbuf[(64 + 2) / 3 + 1]; + char sizebuf[(64 + 2) / 3 + 1]; + + /* If we have to precede the line with the file name. */ + if (print_file_name) + { + fputs_unlocked (fullname, stdout); + putchar_unlocked (':'); + } + + /* Covert the address. */ + if (syms[cnt].sym.st_shndx == SHN_UNDEF) + { + sprintf (addressbuf, "%*c", digits, ' '); + sprintf (sizebuf, "%*c", digits, ' '); + } + else + { + snprintf (addressbuf, sizeof (addressbuf), + (radix == radix_hex ? "%0*" PRIx64 + : (radix == radix_decimal ? "%0*" PRId64 + : "%0*" PRIo64)), + digits, syms[cnt].sym.st_value); + snprintf (sizebuf, sizeof (sizebuf), + (radix == radix_hex ? "%0*" PRIx64 + : (radix == radix_decimal ? "%0*" PRId64 + : "%0*" PRIo64)), + digits, syms[cnt].sym.st_size); + } + + /* Print the actual string. */ + const char *bind; + bind = ebl_symbol_binding_name (ebl, + GELF_ST_BIND (syms[cnt].sym.st_info), + symbindbuf, sizeof (symbindbuf)); + if (bind != NULL && startswith (bind, "GNU_")) + bind += strlen ("GNU_"); + printf ("%-*s|%s|%-6s|%-8s|%s|%*s|%s\n", + longest_name, symstr, addressbuf, bind, + ebl_symbol_type_name (ebl, GELF_ST_TYPE (syms[cnt].sym.st_info), + symtypebuf, sizeof (symtypebuf)), + sizebuf, longest_where, syms[cnt].where, + ebl_section_name (ebl, syms[cnt].sym.st_shndx, syms[cnt].xndx, + secnamebuf, sizeof (secnamebuf), scnnames, + shnum)); + } + +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif + + if (scnnames_malloced) + free (scnnames); +} + + +static char +class_type_char (Elf *elf, const GElf_Ehdr *ehdr, GElf_Sym *sym) +{ + int local_p = GELF_ST_BIND (sym->st_info) == STB_LOCAL; + + /* XXX Add support for architecture specific types and classes. */ + if (sym->st_shndx == SHN_ABS) + return local_p ? 'a' : 'A'; + + if (sym->st_shndx == SHN_UNDEF) + /* Undefined symbols must be global. */ + return 'U'; + + char result = "NDTSFBD "[GELF_ST_TYPE (sym->st_info)]; + + if (result == 'D') + { + /* Special handling: unique data symbols. */ + if (ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX + && GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE) + result = 'u'; + else if (GELF_ST_BIND (sym->st_info) == STB_WEAK) + result = 'V'; + else if (sym->st_shndx == SHN_COMMON) + result = 'C'; + else + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, sym->st_shndx), + &shdr_mem); + if (shdr != NULL) + { + if ((shdr->sh_flags & SHF_WRITE) == 0) + result = 'R'; + else if (shdr->sh_type == SHT_NOBITS) + result = 'B'; + } + } + } + else if (result == 'T') + { + if (GELF_ST_BIND (sym->st_info) == STB_WEAK) + result = 'W'; + } + + return local_p ? tolower (result) : result; +} + + +static void +show_symbols_bsd (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx, + const char *prefix, const char *fname, const char *fullname, + GElf_SymX *syms, size_t nsyms) +{ + int digits = length_map[gelf_getclass (elf) - 1][radix]; + + if (prefix != NULL && ! print_file_name) + printf ("\n%s:\n", fname); + +#ifdef USE_DEMANGLE + size_t demangle_buffer_len = 0; + char *demangle_buffer = NULL; +#endif + + /* Iterate over all symbols. */ + for (size_t cnt = 0; cnt < nsyms; ++cnt) + { + char symstrbuf[50]; + const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name, + symstrbuf, sizeof symstrbuf); + + /* Printing entries with a zero-length name makes the output + not very well parseable. Since these entries don't carry + much information we leave them out. */ + if (symstr[0] == '\0') + continue; + + /* We do not print the entries for files. */ + if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_FILE) + continue; + +#ifdef USE_DEMANGLE + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') + { + int status = -1; + char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, + &demangle_buffer_len, &status); + + if (status == 0) + symstr = dmsymstr; + } +#endif + + /* If we have to precede the line with the file name. */ + if (print_file_name) + { + fputs_unlocked (fullname, stdout); + putchar_unlocked (':'); + } + + bool is_tls = GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_TLS; + bool is_weak = GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK; + const char *marker = (mark_special + ? (is_tls ? "@" : (is_weak ? "*" : " ")) : ""); + + if (syms[cnt].sym.st_shndx == SHN_UNDEF) + { + const char *color = ""; + if (color_mode) + { + if (is_tls) + color = color_undef_tls; + else if (is_weak) + color = color_undef_weak; + else + color = color_undef; + } + + printf ("%*s %sU%s %s", digits, "", color, marker, symstr); + } + else + { + const char *color = ""; + if (color_mode) + { + if (is_tls) + color = color_tls; + else if (is_weak) + color = color_weak; + else + color = color_symbol; + } + if (print_size && syms[cnt].sym.st_size != 0) + { +#define HEXFMT "%6$s%2$0*1$" PRIx64 "%8$s %10$0*9$" PRIx64 " %7$s%3$c%4$s %5$s" +#define DECFMT "%6$s%2$*1$" PRId64 "%8$s %10$*9$" PRId64 " %7$s%3$c%4$s %5$s" +#define OCTFMT "%6$s%2$0*1$" PRIo64 "%8$s %10$0*9$" PRIo64 " %7$s%3$c%4$s %5$s" + printf ((radix == radix_hex ? HEXFMT + : (radix == radix_decimal ? DECFMT : OCTFMT)), + digits, syms[cnt].sym.st_value, + class_type_char (elf, ehdr, &syms[cnt].sym), marker, + symstr, + color_mode ? color_address : "", + color, + color_mode ? color_off : "", + digits, (uint64_t) syms[cnt].sym.st_size); +#undef HEXFMT +#undef DECFMT +#undef OCTFMT + } + else + { +#define HEXFMT "%6$s%2$0*1$" PRIx64 "%8$s %7$s%3$c%4$s %5$s" +#define DECFMT "%6$s%2$*1$" PRId64 "%8$s %7$s%3$c%4$s %5$s" +#define OCTFMT "%6$s%2$0*1$" PRIo64 "%8$s %7$s%3$c%4$s %5$s" + printf ((radix == radix_hex ? HEXFMT + : (radix == radix_decimal ? DECFMT : OCTFMT)), + digits, syms[cnt].sym.st_value, + class_type_char (elf, ehdr, &syms[cnt].sym), marker, + symstr, + color_mode ? color_address : "", + color, + color_mode ? color_off : ""); +#undef HEXFMT +#undef DECFMT +#undef OCTFMT + } + } + + if (color_mode) + fputs_unlocked (color_off, stdout); + putchar_unlocked ('\n'); + } + +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif +} + + +static void +show_symbols_posix (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx, + const char *prefix, const char *fullname, GElf_SymX *syms, + size_t nsyms) +{ + if (prefix != NULL && ! print_file_name) + printf ("%s:\n", fullname); + + int digits = length_map[gelf_getclass (elf) - 1][radix]; + +#ifdef USE_DEMANGLE + size_t demangle_buffer_len = 0; + char *demangle_buffer = NULL; +#endif + + /* Iterate over all symbols. */ + for (size_t cnt = 0; cnt < nsyms; ++cnt) + { + char symstrbuf[50]; + const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name, + symstrbuf, sizeof symstrbuf); + + /* Printing entries with a zero-length name makes the output + not very well parseable. Since these entries don't carry + much information we leave them out. */ + if (symstr[0] == '\0') + continue; + + /* We do not print the entries for files. */ + if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_FILE) + continue; + +#ifdef USE_DEMANGLE + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') + { + int status = -1; + char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, + &demangle_buffer_len, &status); + + if (status == 0) + symstr = dmsymstr; + } +#endif + + /* If we have to precede the line with the file name. */ + if (print_file_name) + { + fputs_unlocked (fullname, stdout); + putchar_unlocked (':'); + putchar_unlocked (' '); + } + + printf ("%s %c%s", symstr, + class_type_char (elf, ehdr, &syms[cnt].sym), + mark_special + ? (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_TLS + ? "@" + : (GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK + ? "*" : " ")) + : ""); + if (syms[cnt].sym.st_shndx != SHN_UNDEF) + printf ((radix == radix_hex + ? " %0*" PRIx64 " %0*" PRIx64 + : (radix == radix_decimal + ? " %*" PRId64 " %*" PRId64 + : " %0*" PRIo64 " %0*" PRIo64)), + digits, syms[cnt].sym.st_value, + digits, syms[cnt].sym.st_size); + putchar ('\n'); + } + +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif +} + + +/* Maximum size of memory we allocate on the stack. */ +#define MAX_STACK_ALLOC 65536 + +static int +sort_by_address (const void *p1, const void *p2) +{ + GElf_SymX *s1 = (GElf_SymX *) p1; + GElf_SymX *s2 = (GElf_SymX *) p2; + + int result = (s1->sym.st_value < s2->sym.st_value + ? -1 : (s1->sym.st_value == s2->sym.st_value ? 0 : 1)); + + return reverse_sort ? -result : result; +} + +static Elf *sort_by_name_elf; +static size_t sort_by_name_ndx; + +static int +sort_by_name (const void *p1, const void *p2) +{ + GElf_SymX *s1 = (GElf_SymX *) p1; + GElf_SymX *s2 = (GElf_SymX *) p2; + + const char *n1 = elf_strptr (sort_by_name_elf, sort_by_name_ndx, + s1->sym.st_name) ?: ""; + const char *n2 = elf_strptr (sort_by_name_elf, sort_by_name_ndx, + s2->sym.st_name) ?: ""; + + int result = strcmp (n1, n2); + + return reverse_sort ? -result : result; +} + +/* Stub libdwfl callback, only the ELF handle already open is ever + used. Only used for finding the alternate debug file if the Dwarf + comes from the main file. We are not interested in separate + debuginfo. */ +static int +find_no_debuginfo (Dwfl_Module *mod, + void **userdata, + const char *modname, + Dwarf_Addr base, + const char *file_name, + const char *debuglink_file, + GElf_Word debuglink_crc, + char **debuginfo_file_name) +{ + Dwarf_Addr dwbias; + dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL); + + /* We are only interested if the Dwarf has been setup on the main + elf file but is only missing the alternate debug link. If dwbias + hasn't even been setup, this is searching for separate debuginfo + for the main elf. We don't care in that case. */ + if (dwbias == (Dwarf_Addr) -1) + return -1; + + return dwfl_standard_find_debuginfo (mod, userdata, modname, base, + file_name, debuglink_file, + debuglink_crc, debuginfo_file_name); +} + +/* Get the Dwarf for the module/file we want. */ +struct getdbg +{ + const char *name; + Dwarf **dbg; +}; + +static int +getdbg_dwflmod (Dwfl_Module *dwflmod, + void **userdata __attribute__ ((unused)), + const char *name, + Dwarf_Addr base __attribute__ ((unused)), + void *arg) +{ + struct getdbg *get = (struct getdbg *) arg; + if (get != NULL && get->name != NULL && strcmp (get->name, name) == 0) + { + Dwarf_Addr bias; + *get->dbg = dwfl_module_getdwarf (dwflmod, &bias); + return DWARF_CB_ABORT; + } + + return DWARF_CB_OK; +} + +static void +show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, Elf_Scn *xndxscn, + GElf_Shdr *shdr, const char *prefix, const char *fname, + const char *fullname) +{ + /* Get the section header string table index. */ + size_t shstrndx; + if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + /* The section is that large. */ + size_t size = shdr->sh_size; + /* One entry is this large. */ + size_t entsize = shdr->sh_entsize; + + /* Consistency checks. */ + if (entsize == 0 + || entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) + error (0, 0, + _("%s: entry size in section %zd `%s' is not what we expect"), + fullname, elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); + else if (size % entsize != 0) + error (0, 0, + _("%s: size of section %zd `%s' is not multiple of entry size"), + fullname, elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); + + /* Compute number of entries. Handle buggy entsize values. */ + size_t nentries = size / (entsize ?: 1); + + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + struct obstack whereob; + obstack_init (&whereob); + + /* Get a DWARF debugging descriptor. It's no problem if this isn't + possible. We just won't print any line number information. */ + Dwarf *dbg = NULL; + Dwfl *dwfl = NULL; + if (format == format_sysv) + { + if (ehdr->e_type != ET_REL) + dbg = dwarf_begin_elf (ebl->elf, DWARF_C_READ, NULL); + else + { + /* Abuse libdwfl to do the relocations for us. This is just + for the ET_REL file containing Dwarf, so no need for + fancy lookups. */ + + /* Duplicate an fd for dwfl_report_offline to swallow. */ + int dwfl_fd = dup (fd); + if (likely (dwfl_fd >= 0)) + { + static const Dwfl_Callbacks callbacks = + { + .section_address = dwfl_offline_section_address, + .find_debuginfo = find_no_debuginfo + }; + dwfl = dwfl_begin (&callbacks); + if (likely (dwfl != NULL)) + { + /* Let 0 be the logical address of the file (or + first in archive). */ + dwfl->offline_next_address = 0; + if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) + == NULL) + { + /* Consumed on success, not on failure. */ + close (dwfl_fd); + } + else + { + dwfl_report_end (dwfl, NULL, NULL); + + struct getdbg get = { .name = fname, .dbg = &dbg }; + dwfl_getmodules (dwfl, &getdbg_dwflmod, &get, 0); + } + } + else + close (dwfl_fd); + } + } + if (dbg != NULL) + { + (void) dwarf_getpubnames (dbg, get_global, NULL, 0); + + get_local_names (dbg); + } + } + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + Elf_Data *xndxdata = elf_getdata (xndxscn, NULL); + if (data == NULL || (xndxscn != NULL && xndxdata == NULL)) + INTERNAL_ERROR (fullname); + + /* Allocate the memory. + + XXX We can use a dirty trick here. Since GElf_Sym == Elf64_Sym we + can use the data memory instead of copying again if what we read + is a 64 bit file. */ + if (nentries > SIZE_MAX / sizeof (GElf_SymX)) + error (EXIT_FAILURE, 0, + _("%s: entries (%zd) in section %zd `%s' is too large"), + fullname, nentries, elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); + GElf_SymX *sym_mem; + if (nentries * sizeof (GElf_SymX) < MAX_STACK_ALLOC) + sym_mem = (GElf_SymX *) alloca (nentries * sizeof (GElf_SymX)); + else + sym_mem = (GElf_SymX *) xmalloc (nentries * sizeof (GElf_SymX)); + + /* Iterate over all symbols. */ +#ifdef USE_DEMANGLE + size_t demangle_buffer_len = 0; + char *demangle_buffer = NULL; +#endif + int longest_name = 4; + int longest_where = 4; + size_t nentries_used = 0; + for (size_t cnt = 0; cnt < nentries; ++cnt) + { + GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt, + &sym_mem[nentries_used].sym, + &sym_mem[nentries_used].xndx); + if (sym == NULL) + INTERNAL_ERROR (fullname); + + /* Filter out administrative symbols without a name and those + deselected by the user with command line options. */ + if ((hide_undefined && sym->st_shndx == SHN_UNDEF) + || (hide_defined && sym->st_shndx != SHN_UNDEF) + || (hide_local && GELF_ST_BIND (sym->st_info) == STB_LOCAL)) + continue; + + sym_mem[nentries_used].where = ""; + if (format == format_sysv) + { + const char *symstr = elf_strptr (ebl->elf, shdr->sh_link, + sym->st_name); + if (symstr == NULL) + continue; + +#ifdef USE_DEMANGLE + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') + { + int status = -1; + char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, + &demangle_buffer_len, &status); + + if (status == 0) + symstr = dmsymstr; + } +#endif + + longest_name = MAX ((size_t) longest_name, strlen (symstr)); + + if (sym->st_shndx != SHN_UNDEF + && GELF_ST_BIND (sym->st_info) != STB_LOCAL + && global_root != NULL) + { + Dwarf_Global fake = { .name = symstr }; + Dwarf_Global **found = tfind (&fake, &global_root, + global_compare); + if (found != NULL) + { + Dwarf_Die die_mem; + Dwarf_Die *die = dwarf_offdie (dbg, (*found)->die_offset, + &die_mem); + + Dwarf_Die cudie_mem; + Dwarf_Die *cudie = NULL; + + Dwarf_Addr lowpc; + Dwarf_Addr highpc; + if (die != NULL + && dwarf_lowpc (die, &lowpc) == 0 + && lowpc <= sym->st_value + && dwarf_highpc (die, &highpc) == 0 + && highpc > sym->st_value) + cudie = dwarf_offdie (dbg, (*found)->cu_offset, + &cudie_mem); + if (cudie != NULL) + { + Dwarf_Line *line = dwarf_getsrc_die (cudie, + sym->st_value); + if (line != NULL) + { + /* We found the line. */ + int lineno; + (void) dwarf_lineno (line, &lineno); + const char *file = dwarf_linesrc (line, NULL, NULL); + file = (file != NULL) ? basename (file) : "???"; + int n; + n = obstack_printf (&whereob, "%s:%d%c", file, + lineno, '\0'); + sym_mem[nentries_used].where + = obstack_finish (&whereob); + + /* The return value of obstack_print included the + NUL byte, so subtract one. */ + if (--n > (int) longest_where) + longest_where = (size_t) n; + } + } + } + } + + /* Try to find the symbol among the local symbols. */ + if (sym_mem[nentries_used].where[0] == '\0') + { + struct local_name fake = + { + .name = symstr, + .lowpc = sym->st_value, + .highpc = sym->st_value, + }; + struct local_name **found = tfind (&fake, &local_root, + local_compare); + if (found != NULL) + { + /* We found the line. */ + int n = obstack_printf (&whereob, "%s:%" PRIu64 "%c", + basename ((*found)->file), + (*found)->lineno, + '\0'); + sym_mem[nentries_used].where = obstack_finish (&whereob); + + /* The return value of obstack_print included the + NUL byte, so subtract one. */ + if (--n > (int) longest_where) + longest_where = (size_t) n; + } + } + } + + /* We use this entry. */ + ++nentries_used; + } +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif + /* Now we know the exact number. */ + size_t nentries_orig = nentries; + nentries = nentries_used; + + /* Sort the entries according to the users wishes. */ + if (sort == sort_name) + { + sort_by_name_elf = ebl->elf; + sort_by_name_ndx = shdr->sh_link; + qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_name); + } + else if (sort == sort_numeric) + qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_address); + + /* Finally print according to the users selection. */ + switch (format) + { + case format_sysv: + show_symbols_sysv (ebl, shdr->sh_link, fullname, sym_mem, nentries, + longest_name, longest_where); + break; + + case format_bsd: + show_symbols_bsd (ebl->elf, ehdr, shdr->sh_link, prefix, fname, fullname, + sym_mem, nentries); + break; + + case format_posix: + default: + assert (format == format_posix); + show_symbols_posix (ebl->elf, ehdr, shdr->sh_link, prefix, fullname, + sym_mem, nentries); + break; + } + + /* Free all memory. */ + if (nentries_orig * sizeof (sym_mem[0]) >= MAX_STACK_ALLOC) + free (sym_mem); + + obstack_free (&whereob, NULL); + + if (dbg != NULL) + { + tdestroy (global_root, free); + global_root = NULL; + + tdestroy (local_root, free); + local_root = NULL; + + if (dwfl == NULL) + (void) dwarf_end (dbg); + } + if (dwfl != NULL) + dwfl_end (dwfl); +} + + +static int +handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, + const char *suffix) +{ + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t suffix_len = suffix == NULL ? 0 : strlen (suffix); + size_t fname_len = strlen (fname) + 1; + char fullname[prefix_len + 1 + fname_len + suffix_len]; + char *cp = fullname; + Elf_Scn *scn = NULL; + int any = 0; + int result = 0; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + Ebl *ebl; + + /* Create the full name of the file. */ + if (prefix != NULL) + cp = mempcpy (cp, prefix, prefix_len); + cp = mempcpy (cp, fname, fname_len); + if (suffix != NULL) + memcpy (cp - 1, suffix, suffix_len + 1); + + /* Get the backend for this object file type. */ + ebl = ebl_openbackend (elf); + if (ebl == NULL) + INTERNAL_ERROR (fullname); + + /* We need the ELF header in a few places. */ + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + INTERNAL_ERROR (fullname); + + /* If we are asked to print the dynamic symbol table and this is + executable or dynamic executable, fail. */ + if (symsec_type == SHT_DYNSYM + && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) + { + /* XXX Add machine specific object file types. */ + error (0, 0, _("%s%s%s%s: Invalid operation"), + prefix ?: "", prefix ? "(" : "", fname, prefix ? ")" : ""); + result = 1; + goto out; + } + + /* Find the symbol table. + + XXX Can there be more than one? Do we print all? Currently we do. */ + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fullname); + + if (shdr->sh_type == symsec_type) + { + Elf_Scn *xndxscn = NULL; + + /* We have a symbol table. First make sure we remember this. */ + any = 1; + + /* Look for an extended section index table for this section. */ + if (symsec_type == SHT_SYMTAB) + { + size_t scnndx = elf_ndxscn (scn); + + while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL) + { + GElf_Shdr xndxshdr_mem; + GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); + + if (xndxshdr == NULL) + INTERNAL_ERROR (fullname); + + if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX + && xndxshdr->sh_link == scnndx) + break; + } + } + + show_symbols (fd, ebl, ehdr, scn, xndxscn, shdr, prefix, fname, + fullname); + } + } + + if (! any) + { + error (0, 0, _("%s%s%s: no symbols"), + prefix ?: "", prefix ? ":" : "", fname); + result = 1; + } + + out: + /* Close the ELF backend library descriptor. */ + ebl_closebackend (ebl); + + return result; +} + + +#include "debugpred.h" diff --git a/src/objdump.c b/src/objdump.c new file mode 100644 index 00000000..3a93248c --- /dev/null +++ b/src/objdump.c @@ -0,0 +1,799 @@ +/* Print information from ELF file in human-readable form. + Copyright (C) 2005, 2006, 2007, 2009, 2011, 2012, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "../libebl/libeblP.h" + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Mode selection:"), 0 }, + { "reloc", 'r', NULL, 0, N_("Display relocation information."), 0 }, + { "full-contents", 's', NULL, 0, + N_("Display the full contents of all sections requested"), 0 }, + { "disassemble", 'd', NULL, 0, + N_("Display assembler code of executable sections"), 0 }, + + { NULL, 0, NULL, 0, N_("Output content selection:"), 0 }, + { "section", 'j', "NAME", 0, + N_("Only display information for section NAME."), 0 }, + + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Show information from FILEs (a.out by default)."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Parser children. */ +static struct argp_child argp_children[] = + { + { &color_argp, 0, N_("Output formatting"), 2 }, + { NULL, 0, NULL, 0} + }; + +/* Data structure to communicate with argp functions. */ +static const struct argp argp = +{ + options, parse_opt, args_doc, doc, argp_children, NULL, NULL +}; + + +/* Print symbols in file named FNAME. */ +static int process_file (const char *fname, bool more_than_one); + +/* Handle content of archive. */ +static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, + const char *suffix); + +/* Handle ELF file. */ +static int handle_elf (Elf *elf, const char *prefix, const char *fname, + const char *suffix); + + +#define INTERNAL_ERROR(fname) \ + error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"), \ + fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)) + + +/* List of sections which should be used. */ +static struct section_list +{ + bool is_name; + union + { + const char *name; + uint32_t scnndx; + }; + struct section_list *next; +} *section_list; + + +/* If true print archive index. */ +static bool print_relocs; + +/* If true print full contents of requested sections. */ +static bool print_full_content; + +/* If true print disassembled output.. */ +static bool print_disasm; + + +int +main (int argc, char *argv[]) +{ + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + int remaining; + (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* Tell the library which version we are expecting. */ + (void) elf_version (EV_CURRENT); + + int result = 0; + if (remaining == argc) + /* The user didn't specify a name so we use a.out. */ + result = process_file ("a.out", false); + else + { + /* Process all the remaining files. */ + const bool more_than_one = remaining + 1 < argc; + + do + result |= process_file (argv[remaining], more_than_one); + while (++remaining < argc); + } + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + /* True if any of the control options is set. */ + static bool any_control_option; + + switch (key) + { + case 'j': + { + struct section_list *newp = xmalloc (sizeof (*newp)); + char *endp; + newp->scnndx = strtoul (arg, &endp, 0); + if (*endp == 0) + newp->is_name = false; + else + { + newp->name = arg; + newp->is_name = true; + } + newp->next = section_list; + section_list = newp; + } + any_control_option = true; + break; + + case 'd': + print_disasm = true; + any_control_option = true; + break; + + case 'r': + print_relocs = true; + any_control_option = true; + break; + + case 's': + print_full_content = true; + any_control_option = true; + break; + + case ARGP_KEY_FINI: + if (! any_control_option) + { + fputs (_("No operation specified.\n"), stderr); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); + exit (EXIT_FAILURE); + } + /* We only use this for checking the number of arguments, we don't + actually want to consume them. */ + FALLTHROUGH; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +/* Open the file and determine the type. */ +static int +process_file (const char *fname, bool more_than_one) +{ + /* Open the file. */ + int fd = open (fname, O_RDONLY); + if (fd == -1) + { + error (0, errno, _("cannot open %s"), fname); + return 1; + } + + /* Now get the ELF descriptor. */ + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf != NULL) + { + if (elf_kind (elf) == ELF_K_ELF) + { + int result = handle_elf (elf, more_than_one ? "" : NULL, + fname, NULL); + + if (elf_end (elf) != 0) + INTERNAL_ERROR (fname); + + if (close (fd) != 0) + error (EXIT_FAILURE, errno, _("while close `%s'"), fname); + + return result; + } + else if (elf_kind (elf) == ELF_K_AR) + { + int result = handle_ar (fd, elf, NULL, fname, NULL); + + if (elf_end (elf) != 0) + INTERNAL_ERROR (fname); + + if (close (fd) != 0) + error (EXIT_FAILURE, errno, _("while close `%s'"), fname); + + return result; + } + + /* We cannot handle this type. Close the descriptor anyway. */ + if (elf_end (elf) != 0) + INTERNAL_ERROR (fname); + } + + error (0, 0, _("%s: File format not recognized"), fname); + + return 1; +} + + +static int +handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, + const char *suffix) +{ + size_t fname_len = strlen (fname) + 1; + size_t prefix_len = prefix != NULL ? strlen (prefix) : 0; + char new_prefix[prefix_len + fname_len + 2]; + size_t suffix_len = suffix != NULL ? strlen (suffix) : 0; + char new_suffix[suffix_len + 2]; + Elf *subelf; + Elf_Cmd cmd = ELF_C_READ_MMAP; + int result = 0; + + char *cp = new_prefix; + if (prefix != NULL) + cp = stpcpy (cp, prefix); + cp = stpcpy (cp, fname); + stpcpy (cp, "["); + + cp = new_suffix; + if (suffix != NULL) + cp = stpcpy (cp, suffix); + stpcpy (cp, "]"); + + /* Process all the files contained in the archive. */ + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + /* Skip over the index entries. */ + if (strcmp (arhdr->ar_name, "/") != 0 + && strcmp (arhdr->ar_name, "//") != 0) + { + if (elf_kind (subelf) == ELF_K_ELF) + result |= handle_elf (subelf, new_prefix, arhdr->ar_name, + new_suffix); + else if (elf_kind (subelf) == ELF_K_AR) + result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, + new_suffix); + else + { + error (0, 0, _("%s%s%s: file format not recognized"), + new_prefix, arhdr->ar_name, new_suffix); + result = 1; + } + } + + /* Get next archive element. */ + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + INTERNAL_ERROR (fname); + } + + return result; +} + + +static void +show_relocs_x (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *symdata, + Elf_Data *xndxdata, size_t symstrndx, size_t shstrndx, + GElf_Addr r_offset, GElf_Xword r_info, GElf_Sxword r_addend) +{ + int elfclass = gelf_getclass (ebl->elf); + char buf[128]; + + printf ("%0*" PRIx64 " %-20s ", + elfclass == ELFCLASS32 ? 8 : 16, r_offset, + ebl_reloc_type_name (ebl, GELF_R_TYPE (r_info), buf, sizeof (buf))); + + Elf32_Word xndx; + GElf_Sym symmem; + GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (r_info), + &symmem, &xndx); + + if (sym == NULL) + printf ("<%s %ld>", + _("INVALID SYMBOL"), (long int) GELF_R_SYM (r_info)); + else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) + printf ("%s", + elf_strptr (ebl->elf, symstrndx, sym->st_name)); + else + { + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr; + destshdr = gelf_getshdr (elf_getscn (ebl->elf, + sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx), + &destshdr_mem); + + if (shdr == NULL || destshdr == NULL) + printf ("<%s %ld>", + _("INVALID SECTION"), + (long int) (sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx)); + else + printf ("%s", + elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); + } + + if (r_addend != 0) + { + char sign = '+'; + if (r_addend < 0) + { + sign = '-'; + r_addend = -r_addend; + } + printf ("%c%#" PRIx64, sign, r_addend); + } + putchar ('\n'); +} + + +static void +show_relocs_rel (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, + Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx, + size_t shstrndx) +{ + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); + int nentries = shdr->sh_size / sh_entsize; + + for (int cnt = 0; cnt < nentries; ++cnt) + { + GElf_Rel relmem; + GElf_Rel *rel; + + rel = gelf_getrel (data, cnt, &relmem); + if (rel != NULL) + show_relocs_x (ebl, shdr, symdata, xndxdata, symstrndx, shstrndx, + rel->r_offset, rel->r_info, 0); + } +} + + +static void +show_relocs_rela (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, + Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx, + size_t shstrndx) +{ + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); + int nentries = shdr->sh_size / sh_entsize; + + for (int cnt = 0; cnt < nentries; ++cnt) + { + GElf_Rela relmem; + GElf_Rela *rel; + + rel = gelf_getrela (data, cnt, &relmem); + if (rel != NULL) + show_relocs_x (ebl, shdr, symdata, xndxdata, symstrndx, shstrndx, + rel->r_offset, rel->r_info, rel->r_addend); + } +} + + +static bool +section_match (Elf *elf, uint32_t scnndx, GElf_Shdr *shdr, size_t shstrndx) +{ + if (section_list == NULL) + return true; + + struct section_list *runp = section_list; + const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); + + do + { + if (runp->is_name) + { + if (name && strcmp (runp->name, name) == 0) + return true; + } + else + { + if (runp->scnndx == scnndx) + return true; + } + + runp = runp->next; + } + while (runp != NULL); + + return false; +} + + +static int +show_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx) +{ + int elfclass = gelf_getclass (ebl->elf); + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fname); + + if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) + { + if (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx)) + continue; + + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, + shdr->sh_info), + &destshdr_mem); + if (unlikely (destshdr == NULL)) + continue; + + printf (_("\nRELOCATION RECORDS FOR [%s]:\n" + "%-*s TYPE VALUE\n"), + elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), + elfclass == ELFCLASS32 ? 8 : 16, _("OFFSET")); + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + continue; + + /* Get the symbol table information. */ + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + if (unlikely (symshdr == NULL || symdata == NULL)) + continue; + + /* Search for the optional extended section index table. */ + Elf_Data *xndxdata = NULL; + Elf_Scn *xndxscn = NULL; + while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL) + { + GElf_Shdr xndxshdr_mem; + GElf_Shdr *xndxshdr; + + xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); + if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX + && xndxshdr->sh_link == elf_ndxscn (symscn)) + { + /* Found it. */ + xndxdata = elf_getdata (xndxscn, NULL); + break; + } + } + + if (shdr->sh_type == SHT_REL) + show_relocs_rel (ebl, shdr, data, symdata, xndxdata, + symshdr->sh_link, shstrndx); + else + show_relocs_rela (ebl, shdr, data, symdata, xndxdata, + symshdr->sh_link, shstrndx); + + putchar ('\n'); + } + } + + return 0; +} + + +static int +show_full_content (Ebl *ebl, const char *fname, uint32_t shstrndx) +{ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fname); + + if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0) + { + if (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx)) + continue; + + printf (_("Contents of section %s:\n"), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + continue; + + unsigned char *cp = data->d_buf; + size_t cnt; + for (cnt = 0; cnt + 16 < data->d_size; cp += 16, cnt += 16) + { + printf (" %04zx ", cnt); + + for (size_t inner = 0; inner < 16; inner += 4) + printf ("%02hhx%02hhx%02hhx%02hhx ", + cp[inner], cp[inner + 1], cp[inner + 2], + cp[inner + 3]); + fputc_unlocked (' ', stdout); + + for (size_t inner = 0; inner < 16; ++inner) + fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner]) + ? cp[inner] : '.', stdout); + fputc_unlocked ('\n', stdout); + } + + printf (" %04zx ", cnt); + + size_t remaining = data->d_size - cnt; + size_t inner; + for (inner = 0; inner + 4 <= remaining; inner += 4) + printf ("%02hhx%02hhx%02hhx%02hhx ", + cp[inner], cp[inner + 1], cp[inner + 2], cp[inner + 3]); + + for (; inner < remaining; ++inner) + printf ("%02hhx", cp[inner]); + + for (inner = 2 * (16 - inner) + (16 - inner + 3) / 4 + 1; inner > 0; + --inner) + fputc_unlocked (' ', stdout); + + for (inner = 0; inner < remaining; ++inner) + fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner]) + ? cp[inner] : '.', stdout); + fputc_unlocked ('\n', stdout); + + fputc_unlocked ('\n', stdout); + } + } + + return 0; +} + + +struct disasm_info +{ + GElf_Addr addr; + const uint8_t *cur; + const uint8_t *last_end; + const char *address_color; + const char *bytes_color; +}; + + +// XXX This is not the preferred output for all architectures. Needs +// XXX customization, too. +static int +disasm_output (char *buf, size_t buflen, void *arg) +{ + struct disasm_info *info = (struct disasm_info *) arg; + + if (info->address_color != NULL) + printf ("%s%8" PRIx64 "%s: ", + info->address_color, (uint64_t) info->addr, color_off); + else + printf ("%8" PRIx64 ": ", (uint64_t) info->addr); + + if (info->bytes_color != NULL) + fputs_unlocked (info->bytes_color, stdout); + size_t cnt; + for (cnt = 0; cnt < (size_t) MIN (info->cur - info->last_end, 8); ++cnt) + printf (" %02" PRIx8, info->last_end[cnt]); + if (info->bytes_color != NULL) + fputs_unlocked (color_off, stdout); + + printf ("%*s %.*s\n", + (int) (8 - cnt) * 3 + 1, "", (int) buflen, buf); + + info->addr += cnt; + + /* We limit the number of bytes printed before the mnemonic to 8. + Print the rest on a separate, following line. */ + if (info->cur - info->last_end > 8) + { + if (info->address_color != NULL) + printf ("%s%8" PRIx64 "%s: ", + info->address_color, (uint64_t) info->addr, color_off); + else + printf ("%8" PRIx64 ": ", (uint64_t) info->addr); + + if (info->bytes_color != NULL) + fputs_unlocked (info->bytes_color, stdout); + for (; cnt < (size_t) (info->cur - info->last_end); ++cnt) + printf (" %02" PRIx8, info->last_end[cnt]); + if (info->bytes_color != NULL) + fputs_unlocked (color_off, stdout); + putchar_unlocked ('\n'); + info->addr += info->cur - info->last_end - 8; + } + + info->last_end = info->cur; + + return 0; +} + + +static int +show_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx) +{ + DisasmCtx_t *ctx = disasm_begin (ebl, ebl->elf, NULL /* XXX TODO */); + if (ctx == NULL) + error (EXIT_FAILURE, 0, _("cannot disassemble")); + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fname); + + if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0 + && (shdr->sh_flags & SHF_EXECINSTR) != 0) + { + if (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx)) + continue; + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + continue; + + printf ("Disassembly of section %s:\n\n", + elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); + + struct disasm_info info; + info.addr = shdr->sh_addr; + info.last_end = info.cur = data->d_buf; + char *fmt; + if (color_mode) + { + info.address_color = color_address; + info.bytes_color = color_bytes; + + if (asprintf (&fmt, "%s%%7m %s%%.1o,%s%%.2o,%s%%.3o,,%s%%.4o%s%%.5o%%34a %s%%l", + color_mnemonic ?: "", + color_operand1 ?: "", + color_operand2 ?: "", + color_operand3 ?: "", + color_operand4 ?: "", + color_operand5 ?: "", + color_label ?: "") < 0) + error (EXIT_FAILURE, errno, _("cannot allocate memory")); + } + else + { + info.address_color = info.bytes_color = NULL; + + fmt = "%7m %.1o,%.2o,%.3o,%.4o,%.5o%34a %l"; + } + + disasm_cb (ctx, &info.cur, info.cur + data->d_size, info.addr, + fmt, disasm_output, &info, NULL /* XXX */); + + if (color_mode) + free (fmt); + } + } + + (void) disasm_end (ctx); + + return 0; +} + + +static int +handle_elf (Elf *elf, const char *prefix, const char *fname, + const char *suffix) +{ + + /* Get the backend for this object file type. */ + Ebl *ebl = ebl_openbackend (elf); + if (ebl == NULL) + error (EXIT_FAILURE, 0, + _("cannot create backend for elf file")); + + printf ("%s: elf%d-%s\n\n", + fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64, + ebl_backend_name (ebl)); + + /* Create the full name of the file. */ + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t suffix_len = suffix == NULL ? 0 : strlen (suffix); + size_t fname_len = strlen (fname) + 1; + char fullname[prefix_len + 1 + fname_len + suffix_len]; + char *cp = fullname; + if (prefix != NULL) + cp = mempcpy (cp, prefix, prefix_len); + cp = mempcpy (cp, fname, fname_len); + if (suffix != NULL) + memcpy (cp - 1, suffix, suffix_len + 1); + + /* Get the section header string table index. */ + size_t shstrndx; + if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + int result = 0; + if (print_disasm) + result = show_disasm (ebl, fullname, shstrndx); + if (print_relocs && !print_disasm) + result = show_relocs (ebl, fullname, shstrndx); + if (print_full_content) + result = show_full_content (ebl, fullname, shstrndx); + + /* Close the ELF backend library descriptor. */ + ebl_closebackend (ebl); + + return result; +} + + +#include "debugpred.h" diff --git a/src/ranlib.c b/src/ranlib.c new file mode 100644 index 00000000..bd7e1d8a --- /dev/null +++ b/src/ranlib.c @@ -0,0 +1,287 @@ +/* Generate an index to speed access to archives. + Copyright (C) 2005-2012 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "arlib.h" + + +/* Prototypes for local functions. */ +static int handle_file (const char *fname); + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("Generate an index to speed access to archives."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("ARCHIVE"); + +/* Data structure to communicate with argp functions. */ +static const struct argp argp = +{ + options, NULL, args_doc, doc, arlib_argp_children, NULL, NULL +}; + + +int +main (int argc, char *argv[]) +{ + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + int remaining; + (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL); + + /* Tell the library which version we are expecting. */ + (void) elf_version (EV_CURRENT); + + /* There must at least be one more parameter specifying the archive. */ + if (remaining == argc) + { + error (0, 0, _("Archive name required")); + argp_help (&argp, stderr, ARGP_HELP_SEE, "ranlib"); + exit (EXIT_FAILURE); + } + + /* We accept the names of multiple archives. */ + int status = 0; + do + status |= handle_file (argv[remaining]); + while (++remaining < argc); + + return status; +} + + +static int +copy_content (Elf *elf, int newfd, off_t off, size_t n) +{ + size_t len; + char *rawfile = elf_rawfile (elf, &len); + + assert (off + n <= len); + + /* Tell the kernel we will read all the pages sequentially. */ + size_t ps = sysconf (_SC_PAGESIZE); + if (n > 2 * ps) + posix_madvise (rawfile + (off & ~(ps - 1)), n, POSIX_MADV_SEQUENTIAL); + + return write_retry (newfd, rawfile + off, n) != (ssize_t) n; +} + + +/* Handle a file given on the command line. */ +static int +handle_file (const char *fname) +{ + int fd = open (fname, O_RDONLY); + if (fd == -1) + { + error (0, errno, _("cannot open '%s'"), fname); + return 1; + } + + struct stat st; + if (fstat (fd, &st) != 0) + { + error (0, errno, _("cannot stat '%s'"), fname); + close (fd); + return 1; + } + + /* First we walk through the file, looking for all ELF files to + collect symbols from. */ + Elf *arelf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (arelf == NULL) + { + error (0, 0, _("cannot create ELF descriptor for '%s': %s"), + fname, elf_errmsg (-1)); + close (fd); + return 1; + } + + if (elf_kind (arelf) != ELF_K_AR) + { + error (0, 0, _("'%s' is no archive"), fname); + elf_end (arelf); + close (fd); + return 1; + } + + arlib_init (); + + /* Iterate over the content of the archive. */ + off_t index_off = -1; + size_t index_size = 0; + off_t cur_off = SARMAG; + Elf *elf; + Elf_Cmd cmd = ELF_C_READ_MMAP; + while ((elf = elf_begin (fd, cmd, arelf)) != NULL) + { + Elf_Arhdr *arhdr = elf_getarhdr (elf); + assert (arhdr != NULL); + + /* If this is the index, remember the location. */ + if (strcmp (arhdr->ar_name, "/") == 0) + { + index_off = elf_getaroff (elf); + index_size = arhdr->ar_size; + } + else + { + arlib_add_symbols (elf, fname, arhdr->ar_name, cur_off); + cur_off += (((arhdr->ar_size + 1) & ~((off_t) 1)) + + sizeof (struct ar_hdr)); + } + + /* Get next archive element. */ + cmd = elf_next (elf); + if (elf_end (elf) != 0) + error (0, 0, _("error while freeing sub-ELF descriptor: %s"), + elf_errmsg (-1)); + } + + arlib_finalize (); + + /* If the file contains no symbols we need not do anything. */ + int status = 0; + if (symtab.symsnamelen != 0 + /* We have to rewrite the file also if it initially had an index + but now does not need one anymore. */ + || (symtab.symsnamelen == 0 && index_size != 0)) + { + /* Create a new, temporary file in the same directory as the + original file. */ + char tmpfname[strlen (fname) + 7]; + strcpy (stpcpy (tmpfname, fname), "XXXXXX"); + int newfd = mkstemp (tmpfname); + if (unlikely (newfd == -1)) + { + nonew: + error (0, errno, _("cannot create new file")); + status = 1; + } + else + { + /* Create the header. */ + if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG)) + { + // XXX Use /prof/self/fd/%d ??? + nonew_unlink: + unlink (tmpfname); + if (newfd != -1) + close (newfd); + goto nonew; + } + + /* Create the new file. There are three parts as far we are + concerned: 1. original context before the index, 2. the + new index, 3. everything after the new index. */ + off_t rest_off; + if (index_off != -1) + rest_off = (index_off + sizeof (struct ar_hdr) + + ((index_size + 1) & ~1ul)); + else + rest_off = SARMAG; + + if (symtab.symsnamelen != 0 + && ((write_retry (newfd, symtab.symsoff, + symtab.symsofflen) + != (ssize_t) symtab.symsofflen) + || (write_retry (newfd, symtab.symsname, + symtab.symsnamelen) + != (ssize_t) symtab.symsnamelen))) + goto nonew_unlink; + + /* Even if the original file had content before the + symbol table, we write it in the correct order. */ + if ((index_off > SARMAG + && copy_content (arelf, newfd, SARMAG, index_off - SARMAG)) + || copy_content (arelf, newfd, rest_off, st.st_size - rest_off)) + goto nonew_unlink; + + /* Never complain about fchown failing. */ + if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; } + /* Set the mode of the new file to the same values the + original file has. */ + if (fchmod (newfd, st.st_mode & ALLPERMS) != 0 + || close (newfd) != 0) + goto nonew_unlink; + newfd = -1; + if (rename (tmpfname, fname) != 0) + goto nonew_unlink; + } + } + + elf_end (arelf); + + arlib_fini (); + + close (fd); + + return status; +} + + +#include "debugpred.h" diff --git a/src/readelf.c b/src/readelf.c new file mode 100644 index 00000000..9b472622 --- /dev/null +++ b/src/readelf.c @@ -0,0 +1,12885 @@ +/* Print information from ELF file in human-readable form. + Copyright (C) 1999-2018 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#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 "../libelf/libelfP.h" +#include "../libelf/common.h" +#include "../libebl/libeblP.h" +#include "../libdwelf/libdwelf.h" +#include "../libdw/libdwP.h" +#include "../libdwfl/libdwflP.h" +#include "../libdw/memory-access.h" + +#include "../libdw/known-dwarf.h" + +#ifdef __linux__ +#define CORE_SIGILL SIGILL +#define CORE_SIGBUS SIGBUS +#define CORE_SIGFPE SIGFPE +#define CORE_SIGSEGV SIGSEGV +#define CORE_SI_USER SI_USER +#else +/* We want the linux version of those as that is what shows up in the core files. */ +#define CORE_SIGILL 4 /* Illegal instruction (ANSI). */ +#define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */ +#define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */ +#define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define CORE_SI_USER 0 /* Sent by kill, sigsend. */ +#endif + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* argp key value for --elf-section, non-ascii. */ +#define ELF_INPUT_SECTION 256 + +/* argp key value for --dwarf-skeleton, non-ascii. */ +#define DWARF_SKELETON 257 + +/* argp key value for --dyn-syms, non-ascii. */ +#define PRINT_DYNSYM_TABLE 258 + +/* Terrible hack for hooking unrelated skeleton/split compile units, + see __libdw_link_skel_split in print_debug. */ +static bool do_not_close_dwfl = false; + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 }, + { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL, + N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF " + "input data"), 0 }, + { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0, + N_("Used with -w to find the skeleton Compile Units in FILE associated " + "with the Split Compile units in a .dwo input file"), 0 }, + { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 }, + { "all", 'a', NULL, 0, + N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 }, + { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 }, + { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 }, + { "histogram", 'I', NULL, 0, + N_("Display histogram of bucket list lengths"), 0 }, + { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 }, + { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, + { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 }, + { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 }, + { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 }, + { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, + { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL, + N_("Display the symbol table sections"), 0 }, + { "dyn-syms", PRINT_DYNSYM_TABLE, NULL, 0, + N_("Display (only) the dynamic symbol table"), 0 }, + { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 }, + { "notes", 'n', "SECTION", OPTION_ARG_OPTIONAL, N_("Display the ELF notes"), 0 }, + { "arch-specific", 'A', NULL, 0, + N_("Display architecture specific information, if any"), 0 }, + { "exception", 'e', NULL, 0, + N_("Display sections for exception handling"), 0 }, + + { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 }, + { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL, + N_("Display DWARF section content. SECTION can be one of abbrev, addr, " + "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, " + "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 }, + { "hex-dump", 'x', "SECTION", 0, + N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 }, + { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL, + N_("Print string contents of sections"), 0 }, + { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, + { "archive-index", 'c', NULL, 0, + N_("Display the symbol index of an archive"), 0 }, + + { NULL, 0, NULL, 0, N_("Output control:"), 0 }, + { "numeric-addresses", 'N', NULL, 0, + N_("Do not find symbol names for addresses in DWARF data"), 0 }, + { "unresolved-address-offsets", 'U', NULL, 0, + N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 }, + { "wide", 'W', NULL, 0, + N_("Ignored for compatibility (lines always wide)"), 0 }, + { "decompress", 'z', NULL, 0, + N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Print information from ELF file in human-readable form."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("FILE..."); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + +/* If non-null, the section from which we should read to (compressed) ELF. */ +static const char *elf_input_section = NULL; + +/* If non-null, the file that contains the skeleton CUs. */ +static const char *dwarf_skeleton = NULL; + +/* Flags set by the option controlling the output. */ + +/* True if dynamic segment should be printed. */ +static bool print_dynamic_table; + +/* True if the file header should be printed. */ +static bool print_file_header; + +/* True if the program headers should be printed. */ +static bool print_program_header; + +/* True if relocations should be printed. */ +static bool print_relocations; + +/* True if the section headers should be printed. */ +static bool print_section_header; + +/* True if the symbol table should be printed. */ +static bool print_symbol_table; + +/* True if (only) the dynsym table should be printed. */ +static bool print_dynsym_table; + +/* A specific section name, or NULL to print all symbol tables. */ +static char *symbol_table_section; + +/* A specific section name, or NULL to print all ELF notes. */ +static char *notes_section; + +/* True if the version information should be printed. */ +static bool print_version_info; + +/* True if section groups should be printed. */ +static bool print_section_groups; + +/* True if bucket list length histogram should be printed. */ +static bool print_histogram; + +/* True if the architecture specific data should be printed. */ +static bool print_arch; + +/* True if note section content should be printed. */ +static bool print_notes; + +/* True if SHF_STRINGS section content should be printed. */ +static bool print_string_sections; + +/* True if archive index should be printed. */ +static bool print_archive_index; + +/* True if any of the control options except print_archive_index is set. */ +static bool any_control_option; + +/* True if we should print addresses from DWARF in symbolic form. */ +static bool print_address_names = true; + +/* True if we should print raw values instead of relativized addresses. */ +static bool print_unresolved_addresses = false; + +/* True if we should print the .debug_aranges section using libdw. */ +static bool decodedaranges = false; + +/* True if we should print the .debug_aranges section using libdw. */ +static bool decodedline = false; + +/* True if we want to show more information about compressed sections. */ +static bool print_decompress = false; + +/* True if we want to show split compile units for debug_info skeletons. */ +static bool show_split_units = false; + +/* Select printing of debugging sections. */ +static enum section_e +{ + section_abbrev = 1, /* .debug_abbrev */ + section_aranges = 2, /* .debug_aranges */ + section_frame = 4, /* .debug_frame or .eh_frame & al. */ + section_info = 8, /* .debug_info, (implies .debug_types) */ + section_line = 16, /* .debug_line */ + section_loc = 32, /* .debug_loc */ + section_pubnames = 64, /* .debug_pubnames */ + section_str = 128, /* .debug_str */ + section_macinfo = 256, /* .debug_macinfo */ + section_ranges = 512, /* .debug_ranges */ + section_exception = 1024, /* .eh_frame & al. */ + section_gdb_index = 2048, /* .gdb_index */ + section_macro = 4096, /* .debug_macro */ + section_addr = 8192, /* .debug_addr */ + section_types = 16384, /* .debug_types (implied by .debug_info) */ + section_all = (section_abbrev | section_aranges | section_frame + | section_info | section_line | section_loc + | section_pubnames | section_str | section_macinfo + | section_ranges | section_exception | section_gdb_index + | section_macro | section_addr | section_types) +} print_debug_sections, implicit_debug_sections; + +/* Select hex dumping of sections. */ +static struct section_argument *dump_data_sections; +static struct section_argument **dump_data_sections_tail = &dump_data_sections; + +/* Select string dumping of sections. */ +static struct section_argument *string_sections; +static struct section_argument **string_sections_tail = &string_sections; + +struct section_argument +{ + struct section_argument *next; + const char *arg; + bool implicit; +}; + +/* Numbers of sections and program headers in the file. */ +static size_t shnum; +static size_t phnum; + + +/* Declarations of local functions. */ +static void process_file (int fd, const char *fname, bool only_one); +static void process_elf_file (Dwfl_Module *dwflmod, int fd); +static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr); +static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); +static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); +static void print_scngrp (Ebl *ebl); +static void print_dynamic (Ebl *ebl); +static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); +static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr); +static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr); +static void print_symtab (Ebl *ebl, int type); +static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); +static void print_verinfo (Ebl *ebl); +static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); +static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); +static void handle_versym (Ebl *ebl, Elf_Scn *scn, + GElf_Shdr *shdr); +static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr); +static void handle_hash (Ebl *ebl); +static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr); +static void print_liblist (Ebl *ebl); +static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr); +static void dump_data (Ebl *ebl); +static void dump_strings (Ebl *ebl); +static void print_strings (Ebl *ebl); +static void dump_archive_index (Elf *, const char *); + + +/* Looked up once with gettext in main. */ +static char *yes_str; +static char *no_str; + +static void +cleanup_list (struct section_argument *list) +{ + while (list != NULL) + { + struct section_argument *a = list; + list = a->next; + free (a); + } +} + +int +main (int argc, char *argv[]) +{ + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + + /* Set locale. */ + setlocale (LC_ALL, ""); + + /* Initialize the message catalog. */ + textdomain (PACKAGE_TARNAME); + + /* Look up once. */ + yes_str = _("yes"); + no_str = _("no"); + + /* Parse and process arguments. */ + int remaining; + argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* Before we start tell the ELF library which version we are using. */ + elf_version (EV_CURRENT); + + /* Now process all the files given at the command line. */ + bool only_one = remaining + 1 == argc; + do + { + /* Open the file. */ + int fd = open (argv[remaining], O_RDONLY); + if (fd == -1) + { + error (0, errno, _("cannot open input file '%s'"), argv[remaining]); + continue; + } + + process_file (fd, argv[remaining], only_one); + + close (fd); + } + while (++remaining < argc); + + cleanup_list (dump_data_sections); + cleanup_list (string_sections); + + return error_message_count != 0; +} + +static void +add_dump_section (const char *name, + int key, + bool implicit) +{ + struct section_argument *a = xmalloc (sizeof *a); + a->arg = name; + a->next = NULL; + a->implicit = implicit; + struct section_argument ***tailp + = key == 'x' ? &dump_data_sections_tail : &string_sections_tail; + **tailp = a; + *tailp = &a->next; +} + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'a': + print_file_header = true; + print_program_header = true; + print_relocations = true; + print_section_header = true; + print_symbol_table = true; + print_version_info = true; + print_dynamic_table = true; + print_section_groups = true; + print_histogram = true; + print_arch = true; + print_notes = true; + implicit_debug_sections |= section_exception; + add_dump_section (".strtab", key, true); + add_dump_section (".dynstr", key, true); + add_dump_section (".comment", key, true); + any_control_option = true; + break; + case 'A': + print_arch = true; + any_control_option = true; + break; + case 'd': + print_dynamic_table = true; + any_control_option = true; + break; + case 'e': + print_debug_sections |= section_exception; + any_control_option = true; + break; + case 'g': + print_section_groups = true; + any_control_option = true; + break; + case 'h': + print_file_header = true; + any_control_option = true; + break; + case 'I': + print_histogram = true; + any_control_option = true; + break; + case 'l': + print_program_header = true; + any_control_option = true; + break; + case 'n': + print_notes = true; + any_control_option = true; + notes_section = arg; + break; + case 'r': + print_relocations = true; + any_control_option = true; + break; + case 'S': + print_section_header = true; + any_control_option = true; + break; + case 's': + print_symbol_table = true; + any_control_option = true; + symbol_table_section = arg; + break; + case PRINT_DYNSYM_TABLE: + print_dynsym_table = true; + any_control_option = true; + break; + case 'V': + print_version_info = true; + any_control_option = true; + break; + case 'c': + print_archive_index = true; + break; + case 'w': + if (arg == NULL) + { + print_debug_sections = section_all; + implicit_debug_sections = section_info; + show_split_units = true; + } + else if (strcmp (arg, "abbrev") == 0) + print_debug_sections |= section_abbrev; + else if (strcmp (arg, "addr") == 0) + { + print_debug_sections |= section_addr; + implicit_debug_sections |= section_info; + } + else if (strcmp (arg, "aranges") == 0) + print_debug_sections |= section_aranges; + else if (strcmp (arg, "decodedaranges") == 0) + { + print_debug_sections |= section_aranges; + decodedaranges = true; + } + else if (strcmp (arg, "ranges") == 0) + { + print_debug_sections |= section_ranges; + implicit_debug_sections |= section_info; + } + else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0) + print_debug_sections |= section_frame; + else if (strcmp (arg, "info") == 0) + { + print_debug_sections |= section_info; + print_debug_sections |= section_types; + } + else if (strcmp (arg, "info+") == 0) + { + print_debug_sections |= section_info; + print_debug_sections |= section_types; + show_split_units = true; + } + else if (strcmp (arg, "loc") == 0) + { + print_debug_sections |= section_loc; + implicit_debug_sections |= section_info; + } + else if (strcmp (arg, "line") == 0) + print_debug_sections |= section_line; + else if (strcmp (arg, "decodedline") == 0) + { + print_debug_sections |= section_line; + decodedline = true; + } + else if (strcmp (arg, "pubnames") == 0) + print_debug_sections |= section_pubnames; + else if (strcmp (arg, "str") == 0) + { + print_debug_sections |= section_str; + /* For mapping string offset tables to CUs. */ + implicit_debug_sections |= section_info; + } + else if (strcmp (arg, "macinfo") == 0) + print_debug_sections |= section_macinfo; + else if (strcmp (arg, "macro") == 0) + print_debug_sections |= section_macro; + else if (strcmp (arg, "exception") == 0) + print_debug_sections |= section_exception; + else if (strcmp (arg, "gdb_index") == 0) + print_debug_sections |= section_gdb_index; + else + { + fprintf (stderr, _("Unknown DWARF debug section `%s'.\n"), + arg); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); + exit (1); + } + any_control_option = true; + break; + case 'p': + any_control_option = true; + if (arg == NULL) + { + print_string_sections = true; + break; + } + FALLTHROUGH; + case 'x': + add_dump_section (arg, key, false); + any_control_option = true; + break; + case 'N': + print_address_names = false; + break; + case 'U': + print_unresolved_addresses = true; + break; + case ARGP_KEY_NO_ARGS: + fputs (_("Missing file name.\n"), stderr); + goto do_argp_help; + case ARGP_KEY_FINI: + if (! any_control_option && ! print_archive_index) + { + fputs (_("No operation specified.\n"), stderr); + do_argp_help: + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); + exit (EXIT_FAILURE); + } + break; + case 'W': /* Ignored. */ + break; + case 'z': + print_decompress = true; + break; + case ELF_INPUT_SECTION: + if (arg == NULL) + elf_input_section = ".gnu_debugdata"; + else + elf_input_section = arg; + break; + case DWARF_SKELETON: + dwarf_skeleton = arg; + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +/* Create a file descriptor to read the data from the + elf_input_section given a file descriptor to an ELF file. */ +static int +open_input_section (int fd) +{ + size_t shnums; + size_t cnt; + size_t shstrndx; + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + { + error (0, 0, _("cannot generate Elf descriptor: %s"), + elf_errmsg (-1)); + return -1; + } + + if (elf_getshdrnum (elf, &shnums) < 0) + { + error (0, 0, _("cannot determine number of sections: %s"), + elf_errmsg (-1)); + open_error: + elf_end (elf); + return -1; + } + + if (elf_getshdrstrndx (elf, &shstrndx) < 0) + { + error (0, 0, _("cannot get section header string table index")); + goto open_error; + } + + for (cnt = 0; cnt < shnums; ++cnt) + { + Elf_Scn *scn = elf_getscn (elf, cnt); + if (scn == NULL) + { + error (0, 0, _("cannot get section: %s"), + elf_errmsg (-1)); + goto open_error; + } + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + { + error (0, 0, _("cannot get section header: %s"), + elf_errmsg (-1)); + goto open_error; + } + + const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name); + if (sname == NULL) + { + error (0, 0, _("cannot get section name")); + goto open_error; + } + + if (strcmp (sname, elf_input_section) == 0) + { + Elf_Data *data = elf_rawdata (scn, NULL); + if (data == NULL) + { + error (0, 0, _("cannot get %s content: %s"), + sname, elf_errmsg (-1)); + goto open_error; + } + + /* Create (and immediately unlink) a temporary file to store + section data in to create a file descriptor for it. */ + const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir; + static const char suffix[] = "/readelfXXXXXX"; + int tmplen = strlen (tmpdir) + sizeof (suffix); + char *tempname = alloca (tmplen); + sprintf (tempname, "%s%s", tmpdir, suffix); + + int sfd = mkstemp (tempname); + if (sfd == -1) + { + error (0, 0, _("cannot create temp file '%s'"), + tempname); + goto open_error; + } + unlink (tempname); + + ssize_t size = data->d_size; + if (write_retry (sfd, data->d_buf, size) != size) + { + error (0, 0, _("cannot write section data")); + goto open_error; + } + + if (elf_end (elf) != 0) + { + error (0, 0, _("error while closing Elf descriptor: %s"), + elf_errmsg (-1)); + return -1; + } + + if (lseek (sfd, 0, SEEK_SET) == -1) + { + error (0, 0, _("error while rewinding file descriptor")); + return -1; + } + + return sfd; + } + } + + /* Named section not found. */ + if (elf_end (elf) != 0) + error (0, 0, _("error while closing Elf descriptor: %s"), + elf_errmsg (-1)); + return -1; +} + +/* Check if the file is an archive, and if so dump its index. */ +static void +check_archive_index (int fd, const char *fname, bool only_one) +{ + /* Create an `Elf' descriptor. */ + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + error (0, 0, _("cannot generate Elf descriptor: %s"), + elf_errmsg (-1)); + else + { + if (elf_kind (elf) == ELF_K_AR) + { + if (!only_one) + printf ("\n%s:\n\n", fname); + dump_archive_index (elf, fname); + } + else + error (0, 0, + _("'%s' is not an archive, cannot print archive index"), + fname); + + /* Now we can close the descriptor. */ + if (elf_end (elf) != 0) + error (0, 0, _("error while closing Elf descriptor: %s"), + elf_errmsg (-1)); + } +} + +/* Trivial callback used for checking if we opened an archive. */ +static int +count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)), + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + void *arg) +{ + if (*(bool *) arg) + return DWARF_CB_ABORT; + *(bool *) arg = true; + return DWARF_CB_OK; +} + +struct process_dwflmod_args +{ + int fd; + bool only_one; +}; + +static int +process_dwflmod (Dwfl_Module *dwflmod, + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + void *arg) +{ + const struct process_dwflmod_args *a = arg; + + /* Print the file name. */ + if (!a->only_one) + { + const char *fname; + dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL); + + printf ("\n%s:\n\n", fname); + } + + process_elf_file (dwflmod, a->fd); + + return DWARF_CB_OK; +} + +/* Stub libdwfl callback, only the ELF handle already open is ever used. + Only used for finding the alternate debug file if the Dwarf comes from + the main file. We are not interested in separate debuginfo. */ +static int +find_no_debuginfo (Dwfl_Module *mod, + void **userdata, + const char *modname, + Dwarf_Addr base, + const char *file_name, + const char *debuglink_file, + GElf_Word debuglink_crc, + char **debuginfo_file_name) +{ + Dwarf_Addr dwbias; + dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL); + + /* We are only interested if the Dwarf has been setup on the main + elf file but is only missing the alternate debug link. If dwbias + hasn't even been setup, this is searching for separate debuginfo + for the main elf. We don't care in that case. */ + if (dwbias == (Dwarf_Addr) -1) + return -1; + + return dwfl_standard_find_debuginfo (mod, userdata, modname, base, + file_name, debuglink_file, + debuglink_crc, debuginfo_file_name); +} + +static Dwfl * +create_dwfl (int fd, const char *fname) +{ + /* Duplicate an fd for dwfl_report_offline to swallow. */ + int dwfl_fd = dup (fd); + if (unlikely (dwfl_fd < 0)) + error (EXIT_FAILURE, errno, "dup"); + + /* Use libdwfl in a trivial way to open the libdw handle for us. + This takes care of applying relocations to DWARF data in ET_REL files. */ + static const Dwfl_Callbacks callbacks = + { + .section_address = dwfl_offline_section_address, + .find_debuginfo = find_no_debuginfo + }; + Dwfl *dwfl = dwfl_begin (&callbacks); + if (likely (dwfl != NULL)) + /* Let 0 be the logical address of the file (or first in archive). */ + dwfl->offline_next_address = 0; + if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL) + { + struct stat st; + if (fstat (dwfl_fd, &st) != 0) + error (0, errno, _("cannot stat input file")); + else if (unlikely (st.st_size == 0)) + error (0, 0, _("input file is empty")); + else + error (0, 0, _("failed reading '%s': %s"), + fname, dwfl_errmsg (-1)); + close (dwfl_fd); /* Consumed on success, not on failure. */ + dwfl = NULL; + } + else + dwfl_report_end (dwfl, NULL, NULL); + + return dwfl; +} + +/* Process one input file. */ +static void +process_file (int fd, const char *fname, bool only_one) +{ + if (print_archive_index) + check_archive_index (fd, fname, only_one); + + if (!any_control_option) + return; + + if (elf_input_section != NULL) + { + /* Replace fname and fd with section content. */ + char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2); + sprintf (fnname, "%s:%s", fname, elf_input_section); + fd = open_input_section (fd); + if (fd == -1) + { + error (0, 0, _("No such section '%s' in '%s'"), + elf_input_section, fname); + return; + } + fname = fnname; + } + + Dwfl *dwfl = create_dwfl (fd, fname); + if (dwfl != NULL) + { + if (only_one) + { + /* Clear ONLY_ONE if we have multiple modules, from an archive. */ + bool seen = false; + only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0; + } + + /* Process the one or more modules gleaned from this file. */ + struct process_dwflmod_args a = { .fd = fd, .only_one = only_one }; + dwfl_getmodules (dwfl, &process_dwflmod, &a, 0); + } + /* Terrible hack for hooking unrelated skeleton/split compile units, + see __libdw_link_skel_split in print_debug. */ + if (! do_not_close_dwfl) + dwfl_end (dwfl); + + /* Need to close the replaced fd if we created it. Caller takes + care of original. */ + if (elf_input_section != NULL) + close (fd); +} + +/* Check whether there are any compressed sections in the ELF file. */ +static bool +elf_contains_chdrs (Elf *elf) +{ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0) + return true; + } + return false; +} + +/* Process one ELF file. */ +static void +process_elf_file (Dwfl_Module *dwflmod, int fd) +{ + GElf_Addr dwflbias; + Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias); + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + + if (ehdr == NULL) + { + error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1)); + return; + } + + Ebl *ebl = ebl_openbackend (elf); + if (unlikely (ebl == NULL)) + { + ebl_error: + error (0, errno, _("cannot create EBL handle")); + return; + } + + /* Determine the number of sections. */ + if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0)) + error (EXIT_FAILURE, 0, + _("cannot determine number of sections: %s"), + elf_errmsg (-1)); + + /* Determine the number of phdrs. */ + if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0)) + error (EXIT_FAILURE, 0, + _("cannot determine number of program headers: %s"), + elf_errmsg (-1)); + + /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and + may have applied relocation to some sections. If there are any + compressed sections, any pass (or libdw/libdwfl) might have + uncompressed them. So we need to get a fresh Elf handle on the + file to display those. */ + bool print_unchanged = ((print_section_header + || print_relocations + || dump_data_sections != NULL + || print_notes) + && (ehdr->e_type == ET_REL + || elf_contains_chdrs (ebl->elf))); + + Elf *pure_elf = NULL; + Ebl *pure_ebl = ebl; + if (print_unchanged) + { + /* Read the file afresh. */ + off_t aroff = elf_getaroff (elf); + pure_elf = dwelf_elf_begin (fd); + if (aroff > 0) + { + /* Archive member. */ + (void) elf_rand (pure_elf, aroff); + Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf); + elf_end (pure_elf); + pure_elf = armem; + } + if (pure_elf == NULL) + { + error (0, 0, _("cannot read ELF: %s"), elf_errmsg (-1)); + return; + } + pure_ebl = ebl_openbackend (pure_elf); + if (pure_ebl == NULL) + goto ebl_error; + } + + if (print_file_header) + print_ehdr (ebl, ehdr); + if (print_section_header) + print_shdr (pure_ebl, ehdr); + if (print_program_header) + print_phdr (ebl, ehdr); + if (print_section_groups) + print_scngrp (ebl); + if (print_dynamic_table) + print_dynamic (ebl); + if (print_relocations) + print_relocs (pure_ebl, ehdr); + if (print_histogram) + handle_hash (ebl); + if (print_symbol_table || print_dynsym_table) + print_symtab (ebl, SHT_DYNSYM); + if (print_version_info) + print_verinfo (ebl); + if (print_symbol_table) + print_symtab (ebl, SHT_SYMTAB); + if (print_arch) + print_liblist (ebl); + if (print_arch) + print_attributes (ebl, ehdr); + if (dump_data_sections != NULL) + dump_data (pure_ebl); + if (string_sections != NULL) + dump_strings (ebl); + if ((print_debug_sections | implicit_debug_sections) != 0) + print_debug (dwflmod, ebl, ehdr); + if (print_notes) + handle_notes (pure_ebl, ehdr); + if (print_string_sections) + print_strings (ebl); + + ebl_closebackend (ebl); + + if (pure_ebl != ebl) + { + ebl_closebackend (pure_ebl); + elf_end (pure_elf); + } +} + + +/* Print file type. */ +static void +print_file_type (unsigned short int e_type) +{ + if (likely (e_type <= ET_CORE)) + { + static const char *const knowntypes[] = + { + N_("NONE (None)"), + N_("REL (Relocatable file)"), + N_("EXEC (Executable file)"), + N_("DYN (Shared object file)"), + N_("CORE (Core file)") + }; + puts (_(knowntypes[e_type])); + } + else if (e_type >= ET_LOOS && e_type <= ET_HIOS) + printf (_("OS Specific: (%x)\n"), e_type); + else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */) + printf (_("Processor Specific: (%x)\n"), e_type); + else + puts ("???"); +} + + +/* Print ELF header. */ +static void +print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr) +{ + fputs_unlocked (_("ELF Header:\n Magic: "), stdout); + for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt) + printf (" %02hhx", ehdr->e_ident[cnt]); + + printf (_("\n Class: %s\n"), + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32" + : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64" + : "\?\?\?"); + + printf (_(" Data: %s\n"), + ehdr->e_ident[EI_DATA] == ELFDATA2LSB + ? "2's complement, little endian" + : ehdr->e_ident[EI_DATA] == ELFDATA2MSB + ? "2's complement, big endian" : "\?\?\?"); + + printf (_(" Ident Version: %hhd %s\n"), + ehdr->e_ident[EI_VERSION], + ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)") + : "(\?\?\?)"); + + char buf[512]; + printf (_(" OS/ABI: %s\n"), + ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); + + printf (_(" ABI Version: %hhd\n"), + ehdr->e_ident[EI_ABIVERSION]); + + fputs_unlocked (_(" Type: "), stdout); + print_file_type (ehdr->e_type); + + const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine); + if (machine != NULL) + printf (_(" Machine: %s\n"), machine); + else + printf (_(" Machine: : 0x%x\n"), + ehdr->e_machine); + + printf (_(" Version: %d %s\n"), + ehdr->e_version, + ehdr->e_version == EV_CURRENT ? _("(current)") : "(\?\?\?)"); + + printf (_(" Entry point address: %#" PRIx64 "\n"), + ehdr->e_entry); + + printf (_(" Start of program headers: %" PRId64 " %s\n"), + ehdr->e_phoff, _("(bytes into file)")); + + printf (_(" Start of section headers: %" PRId64 " %s\n"), + ehdr->e_shoff, _("(bytes into file)")); + + printf (_(" Flags: %s\n"), + ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); + + printf (_(" Size of this header: %" PRId16 " %s\n"), + ehdr->e_ehsize, _("(bytes)")); + + printf (_(" Size of program header entries: %" PRId16 " %s\n"), + ehdr->e_phentsize, _("(bytes)")); + + printf (_(" Number of program headers entries: %" PRId16), + ehdr->e_phnum); + if (ehdr->e_phnum == PN_XNUM) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr != NULL) + printf (_(" (%" PRIu32 " in [0].sh_info)"), + (uint32_t) shdr->sh_info); + else + fputs_unlocked (_(" ([0] not available)"), stdout); + } + fputc_unlocked ('\n', stdout); + + printf (_(" Size of section header entries: %" PRId16 " %s\n"), + ehdr->e_shentsize, _("(bytes)")); + + printf (_(" Number of section headers entries: %" PRId16), + ehdr->e_shnum); + if (ehdr->e_shnum == 0) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr != NULL) + printf (_(" (%" PRIu32 " in [0].sh_size)"), + (uint32_t) shdr->sh_size); + else + fputs_unlocked (_(" ([0] not available)"), stdout); + } + fputc_unlocked ('\n', stdout); + + if (unlikely (ehdr->e_shstrndx == SHN_XINDEX)) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); + if (shdr != NULL) + /* We managed to get the zeroth section. */ + snprintf (buf, sizeof (buf), _(" (%" PRIu32 " in [0].sh_link)"), + (uint32_t) shdr->sh_link); + else + { + strncpy (buf, _(" ([0] not available)"), sizeof (buf)); + buf[sizeof (buf) - 1] = '\0'; + } + + printf (_(" Section header string table index: XINDEX%s\n\n"), + buf); + } + else + printf (_(" Section header string table index: %" PRId16 "\n\n"), + ehdr->e_shstrndx); +} + + +static const char * +get_visibility_type (int value) +{ + switch (value) + { + case STV_DEFAULT: + return "DEFAULT"; + case STV_INTERNAL: + return "INTERNAL"; + case STV_HIDDEN: + return "HIDDEN"; + case STV_PROTECTED: + return "PROTECTED"; + default: + return "???"; + } +} + +static const char * +elf_ch_type_name (unsigned int code) +{ + if (code == 0) + return "NONE"; + + if (code == ELFCOMPRESS_ZLIB) + return "ZLIB"; + + return "UNKNOWN"; +} + +/* Print the section headers. */ +static void +print_shdr (Ebl *ebl, GElf_Ehdr *ehdr) +{ + size_t cnt; + size_t shstrndx; + + if (! print_file_header) + { + size_t sections; + if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get number of sections: %s"), + elf_errmsg (-1)); + + printf (_("\ +There are %zd section headers, starting at offset %#" PRIx64 ":\n\ +\n"), + sections, ehdr->e_shoff); + } + + /* Get the section header string table index. */ + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index: %s"), + elf_errmsg (-1)); + + puts (_("Section Headers:")); + + if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) + puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); + else + puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); + + if (print_decompress) + { + if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) + puts (_(" [Compression Size Al]")); + else + puts (_(" [Compression Size Al]")); + } + + for (cnt = 0; cnt < shnum; ++cnt) + { + Elf_Scn *scn = elf_getscn (ebl->elf, cnt); + + if (unlikely (scn == NULL)) + error (EXIT_FAILURE, 0, _("cannot get section: %s"), + elf_errmsg (-1)); + + /* Get the section header. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + error (EXIT_FAILURE, 0, _("cannot get section header: %s"), + elf_errmsg (-1)); + + char flagbuf[20]; + char *cp = flagbuf; + if (shdr->sh_flags & SHF_WRITE) + *cp++ = 'W'; + if (shdr->sh_flags & SHF_ALLOC) + *cp++ = 'A'; + if (shdr->sh_flags & SHF_EXECINSTR) + *cp++ = 'X'; + if (shdr->sh_flags & SHF_MERGE) + *cp++ = 'M'; + if (shdr->sh_flags & SHF_STRINGS) + *cp++ = 'S'; + if (shdr->sh_flags & SHF_INFO_LINK) + *cp++ = 'I'; + if (shdr->sh_flags & SHF_LINK_ORDER) + *cp++ = 'L'; + if (shdr->sh_flags & SHF_OS_NONCONFORMING) + *cp++ = 'N'; + if (shdr->sh_flags & SHF_GROUP) + *cp++ = 'G'; + if (shdr->sh_flags & SHF_TLS) + *cp++ = 'T'; + if (shdr->sh_flags & SHF_COMPRESSED) + *cp++ = 'C'; + if (shdr->sh_flags & SHF_ORDERED) + *cp++ = 'O'; + if (shdr->sh_flags & SHF_EXCLUDE) + *cp++ = 'E'; + if (shdr->sh_flags & SHF_GNU_RETAIN) + *cp++ = 'R'; + *cp = '\0'; + + const char *sname; + char buf[128]; + sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: ""; + printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64 + " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32 + " %2" PRId64 "\n", + cnt, sname, + ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)), + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr, + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset, + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size, + shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info, + shdr->sh_addralign); + + if (print_decompress) + { + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + GElf_Chdr chdr; + if (gelf_getchdr (scn, &chdr) != NULL) + printf (" [ELF %s (%" PRId32 ") %0*" PRIx64 + " %2" PRId64 "]\n", + elf_ch_type_name (chdr.ch_type), + chdr.ch_type, + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, + chdr.ch_size, chdr.ch_addralign); + else + error (0, 0, + _("bad compression header for section %zd: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + } + else if (startswith (sname, ".zdebug")) + { + ssize_t size; + if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0) + printf (" [GNU ZLIB %0*zx ]\n", + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size); + else + error (0, 0, + _("bad gnu compressed size for section %zd: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + } + } + } + + fputc_unlocked ('\n', stdout); +} + + +/* Print the program header. */ +static void +print_phdr (Ebl *ebl, GElf_Ehdr *ehdr) +{ + if (phnum == 0) + /* No program header, this is OK in relocatable objects. */ + return; + + puts (_("Program Headers:")); + if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) + puts (_("\ + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); + else + puts (_("\ + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); + + /* Process all program headers. */ + bool has_relro = false; + GElf_Addr relro_from = 0; + GElf_Addr relro_to = 0; + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + char buf[128]; + GElf_Phdr mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); + + /* If for some reason the header cannot be returned show this. */ + if (unlikely (phdr == NULL)) + { + puts (" ???"); + continue; + } + + printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64 + " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n", + ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)), + phdr->p_offset, + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr, + ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr, + phdr->p_filesz, + phdr->p_memsz, + phdr->p_flags & PF_R ? 'R' : ' ', + phdr->p_flags & PF_W ? 'W' : ' ', + phdr->p_flags & PF_X ? 'E' : ' ', + phdr->p_align); + + if (phdr->p_type == PT_INTERP) + { + /* If we are sure the file offset is valid then we can show + the user the name of the interpreter. We check whether + there is a section at the file offset. Normally there + would be a section called ".interp". But in separate + .debug files it is a NOBITS section (and so doesn't match + with gelf_offscn). Which probably means the offset is + not valid another reason could be because the ELF file + just doesn't contain any section headers, in that case + just play it safe and don't display anything. */ + + Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + size_t maxsize; + char *filedata = elf_rawfile (ebl->elf, &maxsize); + + if (shdr != NULL && shdr->sh_type == SHT_PROGBITS + && filedata != NULL && phdr->p_offset < maxsize + && phdr->p_filesz <= maxsize - phdr->p_offset + && memchr (filedata + phdr->p_offset, '\0', + phdr->p_filesz) != NULL) + printf (_("\t[Requesting program interpreter: %s]\n"), + filedata + phdr->p_offset); + } + else if (phdr->p_type == PT_GNU_RELRO) + { + has_relro = true; + relro_from = phdr->p_vaddr; + relro_to = relro_from + phdr->p_memsz; + } + } + + size_t sections; + if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get number of sections: %s"), + elf_errmsg (-1)); + + if (sections == 0) + /* No sections in the file. Punt. */ + return; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + puts (_("\n Section to Segment mapping:\n Segment Sections...")); + + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + /* Print the segment number. */ + printf (" %2.2zu ", cnt); + + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); + /* This must not happen. */ + if (unlikely (phdr == NULL)) + error (EXIT_FAILURE, 0, _("cannot get program header: %s"), + elf_errmsg (-1)); + + /* Iterate over the sections. */ + bool in_relro = false; + bool in_ro = false; + for (size_t inner = 1; inner < shnum; ++inner) + { + Elf_Scn *scn = elf_getscn (ebl->elf, inner); + /* This should not happen. */ + if (unlikely (scn == NULL)) + error (EXIT_FAILURE, 0, _("cannot get section: %s"), + elf_errmsg (-1)); + + /* Get the section header. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + error (EXIT_FAILURE, 0, + _("cannot get section header: %s"), + elf_errmsg (-1)); + + if (shdr->sh_size > 0 + /* Compare allocated sections by VMA, unallocated + sections by file offset. */ + && (shdr->sh_flags & SHF_ALLOC + ? (shdr->sh_addr >= phdr->p_vaddr + && (shdr->sh_addr + shdr->sh_size + <= phdr->p_vaddr + phdr->p_memsz)) + : (shdr->sh_offset >= phdr->p_offset + && (shdr->sh_offset + shdr->sh_size + <= phdr->p_offset + phdr->p_filesz)))) + { + if (has_relro && !in_relro + && shdr->sh_addr >= relro_from + && shdr->sh_addr + shdr->sh_size <= relro_to) + { + fputs_unlocked (" [RELRO:", stdout); + in_relro = true; + } + else if (has_relro && in_relro && shdr->sh_addr >= relro_to) + { + fputs_unlocked ("]", stdout); + in_relro = false; + } + else if (has_relro && in_relro + && shdr->sh_addr + shdr->sh_size > relro_to) + fputs_unlocked ("] p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0) + { + if (!in_ro) + { + fputs_unlocked (" [RO:", stdout); + in_ro = true; + } + } + else + { + /* Determine the segment this section is part of. */ + size_t cnt2; + GElf_Phdr phdr2_mem; + GElf_Phdr *phdr2 = NULL; + for (cnt2 = 0; cnt2 < phnum; ++cnt2) + { + phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem); + + if (phdr2 != NULL && phdr2->p_type == PT_LOAD + && shdr->sh_addr >= phdr2->p_vaddr + && (shdr->sh_addr + shdr->sh_size + <= phdr2->p_vaddr + phdr2->p_memsz)) + break; + } + + if (cnt2 < phnum) + { + if ((phdr2->p_flags & PF_W) == 0 && !in_ro) + { + fputs_unlocked (" [RO:", stdout); + in_ro = true; + } + else if ((phdr2->p_flags & PF_W) != 0 && in_ro) + { + fputs_unlocked ("]", stdout); + in_ro = false; + } + } + } + + printf (" %s", + elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); + + /* Signal that this section is only partially covered. */ + if (has_relro && in_relro + && shdr->sh_addr + shdr->sh_size > relro_to) + { + fputs_unlocked (">", stdout); + in_relro = false; + } + } + } + if (in_relro || in_ro) + fputs_unlocked ("]", stdout); + + /* Finish the line. */ + fputc_unlocked ('\n', stdout); + } +} + + +static const char * +section_name (Ebl *ebl, GElf_Shdr *shdr) +{ + size_t shstrndx; + if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) + return "???"; + return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???"; +} + + +static void +handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) +{ + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + + if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL + || symdata == NULL) + return; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + Elf32_Word *grpref = (Elf32_Word *) data->d_buf; + + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem); + + printf ((grpref[0] & GRP_COMDAT) + ? ngettext ("\ +\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n", + "\ +\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n", + data->d_size / sizeof (Elf32_Word) - 1) + : ngettext ("\ +\nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\ +\nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n", + data->d_size / sizeof (Elf32_Word) - 1), + elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + (sym == NULL ? NULL + : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) + ?: _(""), + data->d_size / sizeof (Elf32_Word) - 1); + + for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) + { + GElf_Shdr grpshdr_mem; + GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]), + &grpshdr_mem); + + const char *str; + printf (" [%2u] %s\n", + grpref[cnt], + grpshdr != NULL + && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name)) + ? str : _("")); + } +} + + +static void +print_scngrp (Ebl *ebl) +{ + /* Find all relocation sections and handle them. */ + Elf_Scn *scn = NULL; + + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + /* Handle the section if it is a symbol table. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr != NULL && shdr->sh_type == SHT_GROUP) + { + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (elf_compress (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + error (EXIT_FAILURE, 0, + _("cannot get section [%zd] header: %s"), + elf_ndxscn (scn), + elf_errmsg (-1)); + } + handle_scngrp (ebl, scn, shdr); + } + } +} + + +static const struct flags +{ + int mask; + const char *str; +} dt_flags[] = + { + { DF_ORIGIN, "ORIGIN" }, + { DF_SYMBOLIC, "SYMBOLIC" }, + { DF_TEXTREL, "TEXTREL" }, + { DF_BIND_NOW, "BIND_NOW" }, + { DF_STATIC_TLS, "STATIC_TLS" } + }; +static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]); + +static const struct flags dt_flags_1[] = + { + { DF_1_NOW, "NOW" }, + { DF_1_GLOBAL, "GLOBAL" }, + { DF_1_GROUP, "GROUP" }, + { DF_1_NODELETE, "NODELETE" }, + { DF_1_LOADFLTR, "LOADFLTR" }, + { DF_1_INITFIRST, "INITFIRST" }, + { DF_1_NOOPEN, "NOOPEN" }, + { DF_1_ORIGIN, "ORIGIN" }, + { DF_1_DIRECT, "DIRECT" }, + { DF_1_TRANS, "TRANS" }, + { DF_1_INTERPOSE, "INTERPOSE" }, + { DF_1_NODEFLIB, "NODEFLIB" }, + { DF_1_NODUMP, "NODUMP" }, + { DF_1_CONFALT, "CONFALT" }, + { DF_1_ENDFILTEE, "ENDFILTEE" }, + { DF_1_DISPRELDNE, "DISPRELDNE" }, + { DF_1_DISPRELPND, "DISPRELPND" }, + }; +static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]); + +static const struct flags dt_feature_1[] = + { + { DTF_1_PARINIT, "PARINIT" }, + { DTF_1_CONFEXP, "CONFEXP" } + }; +static const int ndt_feature_1 = (sizeof (dt_feature_1) + / sizeof (dt_feature_1[0])); + +static const struct flags dt_posflag_1[] = + { + { DF_P1_LAZYLOAD, "LAZYLOAD" }, + { DF_P1_GROUPPERM, "GROUPPERM" } + }; +static const int ndt_posflag_1 = (sizeof (dt_posflag_1) + / sizeof (dt_posflag_1[0])); + + +static void +print_flags (int class, GElf_Xword d_val, const struct flags *flags, + int nflags) +{ + bool first = true; + int cnt; + + for (cnt = 0; cnt < nflags; ++cnt) + if (d_val & flags[cnt].mask) + { + if (!first) + putchar_unlocked (' '); + fputs_unlocked (flags[cnt].str, stdout); + d_val &= ~flags[cnt].mask; + first = false; + } + + if (d_val != 0) + { + if (!first) + putchar_unlocked (' '); + printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val); + } + + putchar_unlocked ('\n'); +} + + +static void +print_dt_flags (int class, GElf_Xword d_val) +{ + print_flags (class, d_val, dt_flags, ndt_flags); +} + + +static void +print_dt_flags_1 (int class, GElf_Xword d_val) +{ + print_flags (class, d_val, dt_flags_1, ndt_flags_1); +} + + +static void +print_dt_feature_1 (int class, GElf_Xword d_val) +{ + print_flags (class, d_val, dt_feature_1, ndt_feature_1); +} + + +static void +print_dt_posflag_1 (int class, GElf_Xword d_val) +{ + print_flags (class, d_val, dt_posflag_1, ndt_posflag_1); +} + + +static void +handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) +{ + int class = gelf_getclass (ebl->elf); + GElf_Shdr glink_mem; + GElf_Shdr *glink; + Elf_Data *data; + size_t cnt; + size_t shstrndx; + size_t sh_entsize; + + /* Get the data of the section. */ + data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Get the section header string table index. */ + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT); + + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + + printf (ngettext ("\ +\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + "\ +\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + shdr->sh_size / sh_entsize), + (unsigned long int) (shdr->sh_size / sh_entsize), + class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, + shdr->sh_offset, + (int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + fputs_unlocked (_(" Type Value\n"), stdout); + + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) + { + GElf_Dyn dynmem; + GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem); + if (dyn == NULL) + break; + + char buf[64]; + printf (" %-17s ", + ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf))); + + switch (dyn->d_tag) + { + case DT_NULL: + case DT_DEBUG: + case DT_BIND_NOW: + case DT_TEXTREL: + /* No further output. */ + fputc_unlocked ('\n', stdout); + break; + + case DT_NEEDED: + printf (_("Shared library: [%s]\n"), + elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); + break; + + case DT_SONAME: + printf (_("Library soname: [%s]\n"), + elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); + break; + + case DT_RPATH: + printf (_("Library rpath: [%s]\n"), + elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); + break; + + case DT_RUNPATH: + printf (_("Library runpath: [%s]\n"), + elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); + break; + + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_STRSZ: + case DT_RELSZ: + case DT_RELAENT: + case DT_SYMENT: + case DT_RELENT: + case DT_PLTPADSZ: + case DT_MOVEENT: + case DT_MOVESZ: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_SYMINSZ: + case DT_SYMINENT: + case DT_GNU_CONFLICTSZ: + case DT_GNU_LIBLISTSZ: + printf (_("%" PRId64 " (bytes)\n"), dyn->d_un.d_val); + break; + + case DT_VERDEFNUM: + case DT_VERNEEDNUM: + case DT_RELACOUNT: + case DT_RELCOUNT: + printf ("%" PRId64 "\n", dyn->d_un.d_val); + break; + + case DT_PLTREL:; + const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val, + NULL, 0); + puts (tagname ?: "???"); + break; + + case DT_FLAGS: + print_dt_flags (class, dyn->d_un.d_val); + break; + + case DT_FLAGS_1: + print_dt_flags_1 (class, dyn->d_un.d_val); + break; + + case DT_FEATURE_1: + print_dt_feature_1 (class, dyn->d_un.d_val); + break; + + case DT_POSFLAG_1: + print_dt_posflag_1 (class, dyn->d_un.d_val); + break; + + default: + printf ("%#0*" PRIx64 "\n", + class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val); + break; + } + } +} + + +/* Print the dynamic segment. */ +static void +print_dynamic (Ebl *ebl) +{ + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); + + if (phdr != NULL && phdr->p_type == PT_DYNAMIC) + { + Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) + handle_dynamic (ebl, scn, shdr); + break; + } + } +} + + +/* Print relocations. */ +static void +print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) +{ + /* Find all relocation sections and handle them. */ + Elf_Scn *scn = NULL; + + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + /* Handle the section if it is a symbol table. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (likely (shdr != NULL)) + { + if (shdr->sh_type == SHT_REL) + handle_relocs_rel (ebl, ehdr, scn, shdr); + else if (shdr->sh_type == SHT_RELA) + handle_relocs_rela (ebl, ehdr, scn, shdr); + } + } +} + + +/* Handle a relocation section. */ +static void +handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) +{ + int class = gelf_getclass (ebl->elf); + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); + int nentries = shdr->sh_size / sh_entsize; + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Get the symbol table information. */ + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + + /* Get the section header of the section the relocations are for. */ + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), + &destshdr_mem); + + if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) + { + printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"), + shdr->sh_offset); + return; + } + + /* Search for the optional extended section index table. */ + Elf_Data *xndxdata = NULL; + int xndxscnidx = elf_scnshndx (scn); + if (unlikely (xndxscnidx > 0)) + xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + if (shdr->sh_info != 0) + printf (ngettext ("\ +\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", + "\ +\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", + nentries), + elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + (unsigned int) shdr->sh_info, + elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), + shdr->sh_offset, + nentries); + else + /* The .rel.dyn section does not refer to a specific section but + instead of section index zero. Do not try to print a section + name. */ + printf (ngettext ("\ +\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", + "\ +\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", + nentries), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + shdr->sh_offset, + nentries); + fputs_unlocked (class == ELFCLASS32 + ? _("\ + Offset Type Value Name\n") + : _("\ + Offset Type Value Name\n"), + stdout); + + int is_statically_linked = 0; + for (int cnt = 0; cnt < nentries; ++cnt) + { + GElf_Rel relmem; + GElf_Rel *rel = gelf_getrel (data, cnt, &relmem); + if (likely (rel != NULL)) + { + char buf[128]; + GElf_Sym symmem; + Elf32_Word xndx; + GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, + GELF_R_SYM (rel->r_info), + &symmem, &xndx); + if (unlikely (sym == NULL)) + { + /* As a special case we have to handle relocations in static + executables. This only happens for IRELATIVE relocations + (so far). There is no symbol table. */ + if (is_statically_linked == 0) + { + /* Find the program header and look for a PT_INTERP entry. */ + is_statically_linked = -1; + if (ehdr->e_type == ET_EXEC) + { + is_statically_linked = 1; + + for (size_t inner = 0; inner < phnum; ++inner) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, + &phdr_mem); + if (phdr != NULL && phdr->p_type == PT_INTERP) + { + is_statically_linked = -1; + break; + } + } + } + } + + if (is_statically_linked > 0 && shdr->sh_link == 0) + printf ("\ + %#0*" PRIx64 " %-20s %*s %s\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + class == ELFCLASS32 ? 10 : 18, "", + elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); + else + printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + _("INVALID SYMBOL"), + (long int) GELF_R_SYM (rel->r_info)); + } + else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) + printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + likely (ebl_reloc_type_check (ebl, + GELF_R_TYPE (rel->r_info))) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + class == ELFCLASS32 ? 10 : 18, sym->st_value, + elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); + else + { + /* This is a relocation against a STT_SECTION symbol. */ + GElf_Shdr secshdr_mem; + GElf_Shdr *secshdr; + secshdr = gelf_getshdr (elf_getscn (ebl->elf, + sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx), + &secshdr_mem); + + if (unlikely (secshdr == NULL)) + printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + _("INVALID SECTION"), + (long int) (sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx)); + else + printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + class == ELFCLASS32 ? 10 : 18, sym->st_value, + elf_strptr (ebl->elf, shstrndx, secshdr->sh_name)); + } + } + } +} + + +/* Handle a relocation section. */ +static void +handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) +{ + int class = gelf_getclass (ebl->elf); + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); + int nentries = shdr->sh_size / sh_entsize; + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Get the symbol table information. */ + Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + Elf_Data *symdata = elf_getdata (symscn, NULL); + + /* Get the section header of the section the relocations are for. */ + GElf_Shdr destshdr_mem; + GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), + &destshdr_mem); + + if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) + { + printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"), + shdr->sh_offset); + return; + } + + /* Search for the optional extended section index table. */ + Elf_Data *xndxdata = NULL; + int xndxscnidx = elf_scnshndx (scn); + if (unlikely (xndxscnidx > 0)) + xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + if (shdr->sh_info != 0) + printf (ngettext ("\ +\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", + "\ +\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", + nentries), + elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + (unsigned int) shdr->sh_info, + elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), + shdr->sh_offset, + nentries); + else + /* The .rela.dyn section does not refer to a specific section but + instead of section index zero. Do not try to print a section + name. */ + printf (ngettext ("\ +\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", + "\ +\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", + nentries), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + shdr->sh_offset, + nentries); + fputs_unlocked (class == ELFCLASS32 + ? _("\ + Offset Type Value Addend Name\n") + : _("\ + Offset Type Value Addend Name\n"), + stdout); + + int is_statically_linked = 0; + for (int cnt = 0; cnt < nentries; ++cnt) + { + GElf_Rela relmem; + GElf_Rela *rel = gelf_getrela (data, cnt, &relmem); + if (likely (rel != NULL)) + { + char buf[64]; + GElf_Sym symmem; + Elf32_Word xndx; + GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, + GELF_R_SYM (rel->r_info), + &symmem, &xndx); + + if (unlikely (sym == NULL)) + { + /* As a special case we have to handle relocations in static + executables. This only happens for IRELATIVE relocations + (so far). There is no symbol table. */ + if (is_statically_linked == 0) + { + /* Find the program header and look for a PT_INTERP entry. */ + is_statically_linked = -1; + if (ehdr->e_type == ET_EXEC) + { + is_statically_linked = 1; + + for (size_t inner = 0; inner < phnum; ++inner) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, + &phdr_mem); + if (phdr != NULL && phdr->p_type == PT_INTERP) + { + is_statically_linked = -1; + break; + } + } + } + } + + if (is_statically_linked > 0 && shdr->sh_link == 0) + printf ("\ + %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + class == ELFCLASS32 ? 10 : 18, "", + rel->r_addend, + elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); + else + printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + _("INVALID SYMBOL"), + (long int) GELF_R_SYM (rel->r_info)); + } + else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) + printf ("\ + %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + likely (ebl_reloc_type_check (ebl, + GELF_R_TYPE (rel->r_info))) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + class == ELFCLASS32 ? 10 : 18, sym->st_value, + rel->r_addend, + elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); + else + { + /* This is a relocation against a STT_SECTION symbol. */ + GElf_Shdr secshdr_mem; + GElf_Shdr *secshdr; + secshdr = gelf_getshdr (elf_getscn (ebl->elf, + sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx), + &secshdr_mem); + + if (unlikely (secshdr == NULL)) + printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + _("INVALID SECTION"), + (long int) (sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx)); + else + printf ("\ + %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", + class == ELFCLASS32 ? 10 : 18, rel->r_offset, + ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) + /* Avoid the leading R_ which isn't carrying any + information. */ + ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), + buf, sizeof (buf)) + 2 + : _(""), + class == ELFCLASS32 ? 10 : 18, sym->st_value, + rel->r_addend, + elf_strptr (ebl->elf, shstrndx, secshdr->sh_name)); + } + } + } +} + + +/* Print the program header. */ +static void +print_symtab (Ebl *ebl, int type) +{ + /* Find the symbol table(s). For this we have to search through the + section table. */ + Elf_Scn *scn = NULL; + + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + /* Handle the section if it is a symbol table. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr != NULL && shdr->sh_type == (GElf_Word) type) + { + if (symbol_table_section != NULL) + { + /* Get the section header string table index. */ + size_t shstrndx; + const char *sname; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); + if (sname == NULL || strcmp (sname, symbol_table_section) != 0) + continue; + } + + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (elf_compress (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + error (EXIT_FAILURE, 0, + _("cannot get section [%zd] header: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + } + handle_symtab (ebl, scn, shdr); + } + } +} + + +static void +handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) +{ + Elf_Data *versym_data = NULL; + Elf_Data *verneed_data = NULL; + Elf_Data *verdef_data = NULL; + Elf_Data *xndx_data = NULL; + int class = gelf_getclass (ebl->elf); + Elf32_Word verneed_stridx = 0; + Elf32_Word verdef_stridx = 0; + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Find out whether we have other sections we might need. */ + Elf_Scn *runscn = NULL; + while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL) + { + GElf_Shdr runshdr_mem; + GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem); + + if (likely (runshdr != NULL)) + { + if (runshdr->sh_type == SHT_GNU_versym + && runshdr->sh_link == elf_ndxscn (scn)) + /* Bingo, found the version information. Now get the data. */ + versym_data = elf_getdata (runscn, NULL); + else if (runshdr->sh_type == SHT_GNU_verneed) + { + /* This is the information about the needed versions. */ + verneed_data = elf_getdata (runscn, NULL); + verneed_stridx = runshdr->sh_link; + } + else if (runshdr->sh_type == SHT_GNU_verdef) + { + /* This is the information about the defined versions. */ + verdef_data = elf_getdata (runscn, NULL); + verdef_stridx = runshdr->sh_link; + } + else if (runshdr->sh_type == SHT_SYMTAB_SHNDX + && runshdr->sh_link == elf_ndxscn (scn)) + /* Extended section index. */ + xndx_data = elf_getdata (runscn, NULL); + } + } + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + + /* Now we can compute the number of entries in the section. */ + unsigned int nsyms = data->d_size / (class == ELFCLASS32 + ? sizeof (Elf32_Sym) + : sizeof (Elf64_Sym)); + + printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n", + "\nSymbol table [%2u] '%s' contains %u entries:\n", + nsyms), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms); + printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n", + " %lu local symbols String table: [%2u] '%s'\n", + shdr->sh_info), + (unsigned long int) shdr->sh_info, + (unsigned int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + + fputs_unlocked (class == ELFCLASS32 + ? _("\ + Num: Value Size Type Bind Vis Ndx Name\n") + : _("\ + Num: Value Size Type Bind Vis Ndx Name\n"), + stdout); + + for (unsigned int cnt = 0; cnt < nsyms; ++cnt) + { + char typebuf[64]; + char bindbuf[64]; + char scnbuf[64]; + Elf32_Word xndx; + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx); + + if (unlikely (sym == NULL)) + continue; + + /* Determine the real section index. */ + if (likely (sym->st_shndx != SHN_XINDEX)) + xndx = sym->st_shndx; + + printf (_("\ +%5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), + cnt, + class == ELFCLASS32 ? 8 : 16, + sym->st_value, + sym->st_size, + ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), + typebuf, sizeof (typebuf)), + ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), + bindbuf, sizeof (bindbuf)), + get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), + ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, + sizeof (scnbuf), NULL, shnum), + elf_strptr (ebl->elf, shdr->sh_link, sym->st_name)); + + if (versym_data != NULL) + { + /* Get the version information. */ + GElf_Versym versym_mem; + GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem); + + if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1)) + { + bool is_nobits = false; + bool check_def = xndx != SHN_UNDEF; + + if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX) + { + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = + gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem); + + is_nobits = (symshdr != NULL + && symshdr->sh_type == SHT_NOBITS); + } + + if (is_nobits || ! check_def) + { + /* We must test both. */ + GElf_Vernaux vernaux_mem; + GElf_Vernaux *vernaux = NULL; + size_t vn_offset = 0; + + GElf_Verneed verneed_mem; + GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0, + &verneed_mem); + while (verneed != NULL) + { + size_t vna_offset = vn_offset; + + vernaux = gelf_getvernaux (verneed_data, + vna_offset += verneed->vn_aux, + &vernaux_mem); + while (vernaux != NULL + && vernaux->vna_other != *versym + && vernaux->vna_next != 0 + && (verneed_data->d_size - vna_offset + >= vernaux->vna_next)) + { + /* Update the offset. */ + vna_offset += vernaux->vna_next; + + vernaux = (vernaux->vna_next == 0 + ? NULL + : gelf_getvernaux (verneed_data, + vna_offset, + &vernaux_mem)); + } + + /* Check whether we found the version. */ + if (vernaux != NULL && vernaux->vna_other == *versym) + /* Found it. */ + break; + + if (verneed_data->d_size - vn_offset < verneed->vn_next) + break; + + vn_offset += verneed->vn_next; + verneed = (verneed->vn_next == 0 + ? NULL + : gelf_getverneed (verneed_data, vn_offset, + &verneed_mem)); + } + + if (vernaux != NULL && vernaux->vna_other == *versym) + { + printf ("@%s (%u)", + elf_strptr (ebl->elf, verneed_stridx, + vernaux->vna_name), + (unsigned int) vernaux->vna_other); + check_def = 0; + } + else if (unlikely (! is_nobits)) + error (0, 0, _("bad dynamic symbol")); + else + check_def = 1; + } + + if (check_def && *versym != 0x8001) + { + /* We must test both. */ + size_t vd_offset = 0; + + GElf_Verdef verdef_mem; + GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0, + &verdef_mem); + while (verdef != NULL) + { + if (verdef->vd_ndx == (*versym & 0x7fff)) + /* Found the definition. */ + break; + + if (verdef_data->d_size - vd_offset < verdef->vd_next) + break; + + vd_offset += verdef->vd_next; + verdef = (verdef->vd_next == 0 + ? NULL + : gelf_getverdef (verdef_data, vd_offset, + &verdef_mem)); + } + + if (verdef != NULL) + { + GElf_Verdaux verdaux_mem; + GElf_Verdaux *verdaux + = gelf_getverdaux (verdef_data, + vd_offset + verdef->vd_aux, + &verdaux_mem); + + if (verdaux != NULL) + printf ((*versym & 0x8000) ? "@%s" : "@@%s", + elf_strptr (ebl->elf, verdef_stridx, + verdaux->vda_name)); + } + } + } + } + + putchar_unlocked ('\n'); + } +} + + +/* Print version information. */ +static void +print_verinfo (Ebl *ebl) +{ + /* Find the version information sections. For this we have to + search through the section table. */ + Elf_Scn *scn = NULL; + + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + /* Handle the section if it is part of the versioning handling. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (likely (shdr != NULL)) + { + if (shdr->sh_type == SHT_GNU_verneed) + handle_verneed (ebl, scn, shdr); + else if (shdr->sh_type == SHT_GNU_verdef) + handle_verdef (ebl, scn, shdr); + else if (shdr->sh_type == SHT_GNU_versym) + handle_versym (ebl, scn, shdr); + } + } +} + + +static const char * +get_ver_flags (unsigned int flags) +{ + static char buf[32]; + char *endp; + + if (flags == 0) + return _("none"); + + if (flags & VER_FLG_BASE) + endp = stpcpy (buf, "BASE "); + else + endp = buf; + + if (flags & VER_FLG_WEAK) + { + if (endp != buf) + endp = stpcpy (endp, "| "); + + endp = stpcpy (endp, "WEAK "); + } + + if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))) + { + strncpy (endp, _("| "), buf + sizeof (buf) - endp); + buf[sizeof (buf) - 1] = '\0'; + } + + return buf; +} + + +static void +handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) +{ + int class = gelf_getclass (ebl->elf); + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + + printf (ngettext ("\ +\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + "\ +\nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + shdr->sh_info), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info, + class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, + shdr->sh_offset, + (unsigned int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + + unsigned int offset = 0; + for (int cnt = shdr->sh_info; --cnt >= 0; ) + { + /* Get the data at the next offset. */ + GElf_Verneed needmem; + GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); + if (unlikely (need == NULL)) + break; + + printf (_(" %#06x: Version: %hu File: %s Cnt: %hu\n"), + offset, (unsigned short int) need->vn_version, + elf_strptr (ebl->elf, shdr->sh_link, need->vn_file), + (unsigned short int) need->vn_cnt); + + unsigned int auxoffset = offset + need->vn_aux; + for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) + { + GElf_Vernaux auxmem; + GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); + if (unlikely (aux == NULL)) + break; + + printf (_(" %#06x: Name: %s Flags: %s Version: %hu\n"), + auxoffset, + elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name), + get_ver_flags (aux->vna_flags), + (unsigned short int) aux->vna_other); + + if (aux->vna_next == 0) + break; + + auxoffset += aux->vna_next; + } + + /* Find the next offset. */ + if (need->vn_next == 0) + break; + + offset += need->vn_next; + } +} + + +static void +handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) +{ + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + + int class = gelf_getclass (ebl->elf); + printf (ngettext ("\ +\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + "\ +\nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + shdr->sh_info), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + shdr->sh_info, + class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, + shdr->sh_offset, + (unsigned int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + + unsigned int offset = 0; + for (int cnt = shdr->sh_info; --cnt >= 0; ) + { + /* Get the data at the next offset. */ + GElf_Verdef defmem; + GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); + if (unlikely (def == NULL)) + break; + + unsigned int auxoffset = offset + def->vd_aux; + GElf_Verdaux auxmem; + GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); + if (unlikely (aux == NULL)) + break; + + printf (_("\ + %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"), + offset, def->vd_version, + get_ver_flags (def->vd_flags), + def->vd_ndx, + def->vd_cnt, + elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); + + auxoffset += aux->vda_next; + for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) + { + aux = gelf_getverdaux (data, auxoffset, &auxmem); + if (unlikely (aux == NULL)) + break; + + printf (_(" %#06x: Parent %d: %s\n"), + auxoffset, cnt2, + elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); + + if (aux->vda_next == 0) + break; + + auxoffset += aux->vda_next; + } + + /* Find the next offset. */ + if (def->vd_next == 0) + break; + offset += def->vd_next; + } +} + + +static void +handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) +{ + int class = gelf_getclass (ebl->elf); + const char **vername; + const char **filename; + + /* Get the data of the section. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + /* We have to find the version definition section and extract the + version names. */ + Elf_Scn *defscn = NULL; + Elf_Scn *needscn = NULL; + + Elf_Scn *verscn = NULL; + while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL) + { + GElf_Shdr vershdr_mem; + GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem); + + if (likely (vershdr != NULL)) + { + if (vershdr->sh_type == SHT_GNU_verdef) + defscn = verscn; + else if (vershdr->sh_type == SHT_GNU_verneed) + needscn = verscn; + } + } + + size_t nvername; + if (defscn != NULL || needscn != NULL) + { + /* We have a version information (better should have). Now get + the version names. First find the maximum version number. */ + nvername = 0; + if (defscn != NULL) + { + /* Run through the version definitions and find the highest + index. */ + unsigned int offset = 0; + Elf_Data *defdata; + GElf_Shdr defshdrmem; + GElf_Shdr *defshdr; + + defdata = elf_getdata (defscn, NULL); + if (unlikely (defdata == NULL)) + return; + + defshdr = gelf_getshdr (defscn, &defshdrmem); + if (unlikely (defshdr == NULL)) + return; + + for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) + { + GElf_Verdef defmem; + GElf_Verdef *def; + + /* Get the data at the next offset. */ + def = gelf_getverdef (defdata, offset, &defmem); + if (unlikely (def == NULL)) + break; + + nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff)); + + if (def->vd_next == 0) + break; + offset += def->vd_next; + } + } + if (needscn != NULL) + { + unsigned int offset = 0; + Elf_Data *needdata; + GElf_Shdr needshdrmem; + GElf_Shdr *needshdr; + + needdata = elf_getdata (needscn, NULL); + if (unlikely (needdata == NULL)) + return; + + needshdr = gelf_getshdr (needscn, &needshdrmem); + if (unlikely (needshdr == NULL)) + return; + + for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) + { + GElf_Verneed needmem; + GElf_Verneed *need; + unsigned int auxoffset; + int cnt2; + + /* Get the data at the next offset. */ + need = gelf_getverneed (needdata, offset, &needmem); + if (unlikely (need == NULL)) + break; + + /* Run through the auxiliary entries. */ + auxoffset = offset + need->vn_aux; + for (cnt2 = need->vn_cnt; --cnt2 >= 0; ) + { + GElf_Vernaux auxmem; + GElf_Vernaux *aux; + + aux = gelf_getvernaux (needdata, auxoffset, &auxmem); + if (unlikely (aux == NULL)) + break; + + nvername = MAX (nvername, + (size_t) (aux->vna_other & 0x7fff)); + + if (aux->vna_next == 0) + break; + auxoffset += aux->vna_next; + } + + if (need->vn_next == 0) + break; + offset += need->vn_next; + } + } + + /* This is the number of versions we know about. */ + ++nvername; + + /* Allocate the array. */ + vername = (const char **) alloca (nvername * sizeof (const char *)); + memset(vername, 0, nvername * sizeof (const char *)); + filename = (const char **) alloca (nvername * sizeof (const char *)); + memset(filename, 0, nvername * sizeof (const char *)); + + /* Run through the data structures again and collect the strings. */ + if (defscn != NULL) + { + /* Run through the version definitions and find the highest + index. */ + unsigned int offset = 0; + Elf_Data *defdata; + GElf_Shdr defshdrmem; + GElf_Shdr *defshdr; + + defdata = elf_getdata (defscn, NULL); + if (unlikely (defdata == NULL)) + return; + + defshdr = gelf_getshdr (defscn, &defshdrmem); + if (unlikely (defshdr == NULL)) + return; + + for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) + { + + /* Get the data at the next offset. */ + GElf_Verdef defmem; + GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem); + if (unlikely (def == NULL)) + break; + + GElf_Verdaux auxmem; + GElf_Verdaux *aux = gelf_getverdaux (defdata, + offset + def->vd_aux, + &auxmem); + if (unlikely (aux == NULL)) + break; + + vername[def->vd_ndx & 0x7fff] + = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name); + filename[def->vd_ndx & 0x7fff] = NULL; + + if (def->vd_next == 0) + break; + offset += def->vd_next; + } + } + if (needscn != NULL) + { + unsigned int offset = 0; + + Elf_Data *needdata = elf_getdata (needscn, NULL); + GElf_Shdr needshdrmem; + GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem); + if (unlikely (needdata == NULL || needshdr == NULL)) + return; + + for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) + { + /* Get the data at the next offset. */ + GElf_Verneed needmem; + GElf_Verneed *need = gelf_getverneed (needdata, offset, + &needmem); + if (unlikely (need == NULL)) + break; + + /* Run through the auxiliary entries. */ + unsigned int auxoffset = offset + need->vn_aux; + for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) + { + GElf_Vernaux auxmem; + GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset, + &auxmem); + if (unlikely (aux == NULL)) + break; + + vername[aux->vna_other & 0x7fff] + = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name); + filename[aux->vna_other & 0x7fff] + = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file); + + if (aux->vna_next == 0) + break; + auxoffset += aux->vna_next; + } + + if (need->vn_next == 0) + break; + offset += need->vn_next; + } + } + } + else + { + vername = NULL; + nvername = 1; + filename = NULL; + } + + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT); + if (glink == NULL) + error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + + /* Print the header. */ + printf (ngettext ("\ +\nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", + "\ +\nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", + shdr->sh_size / sh_entsize), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + (int) (shdr->sh_size / sh_entsize), + class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, + shdr->sh_offset, + (unsigned int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + + /* Now we can finally look at the actual contents of this section. */ + for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) + { + if (cnt % 2 == 0) + printf ("\n %4d:", cnt); + + GElf_Versym symmem; + GElf_Versym *sym = gelf_getversym (data, cnt, &symmem); + if (sym == NULL) + break; + + switch (*sym) + { + ssize_t n; + case 0: + fputs_unlocked (_(" 0 *local* "), + stdout); + break; + + case 1: + fputs_unlocked (_(" 1 *global* "), + stdout); + break; + + default: + n = printf ("%4d%c%s", + *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ', + (vername != NULL + && (unsigned int) (*sym & 0x7fff) < nvername) + ? vername[*sym & 0x7fff] : "???"); + if ((unsigned int) (*sym & 0x7fff) < nvername + && filename != NULL && filename[*sym & 0x7fff] != NULL) + n += printf ("(%s)", filename[*sym & 0x7fff]); + printf ("%*s", MAX (0, 33 - (int) n), " "); + break; + } + } + putchar_unlocked ('\n'); +} + + +static void +print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, + uint_fast32_t maxlength, Elf32_Word nbucket, + uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr) +{ + uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t)); + + for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) + ++counts[lengths[cnt]]; + + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, + shdr->sh_link), + &glink_mem); + if (glink == NULL) + { + error (0, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + return; + } + + printf (ngettext ("\ +\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + "\ +\nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", + nbucket), + (unsigned int) elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + (int) nbucket, + gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18, + shdr->sh_addr, + shdr->sh_offset, + (unsigned int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + + if (extrastr != NULL) + fputs (extrastr, stdout); + + if (likely (nbucket > 0)) + { + uint64_t success = 0; + + /* xgettext:no-c-format */ + fputs_unlocked (_("\ + Length Number % of total Coverage\n"), stdout); + printf (_(" 0 %6" PRIu32 " %5.1f%%\n"), + counts[0], (counts[0] * 100.0) / nbucket); + + uint64_t nzero_counts = 0; + for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) + { + nzero_counts += counts[cnt] * cnt; + printf (_("\ +%7d %6" PRIu32 " %5.1f%% %5.1f%%\n"), + (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket, + (nzero_counts * 100.0) / nsyms); + } + + Elf32_Word acc = 0; + for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) + { + acc += cnt; + success += counts[cnt] * acc; + } + + printf (_("\ + Average number of tests: successful lookup: %f\n\ + unsuccessful lookup: %f\n"), + (double) success / (double) nzero_counts, + (double) nzero_counts / (double) nbucket); + } + + free (counts); +} + + +/* This function handles the traditional System V-style hash table format. */ +static void +handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) +{ + Elf_Data *data = elf_getdata (scn, NULL); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get data for section %d: %s"), + (int) elf_ndxscn (scn), elf_errmsg (-1)); + return; + } + + if (unlikely (data->d_size < 2 * sizeof (Elf32_Word))) + { + invalid_data: + error (0, 0, _("invalid data in sysv.hash section %d"), + (int) elf_ndxscn (scn)); + return; + } + + Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; + Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; + + uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word); + if (used_buf > data->d_size) + goto invalid_data; + + Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2]; + Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket]; + + uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); + + uint_fast32_t maxlength = 0; + uint_fast32_t nsyms = 0; + for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) + { + Elf32_Word inner = bucket[cnt]; + Elf32_Word chain_len = 0; + while (inner > 0 && inner < nchain) + { + ++nsyms; + ++chain_len; + if (chain_len > nchain) + { + error (0, 0, _("invalid chain in sysv.hash section %d"), + (int) elf_ndxscn (scn)); + free (lengths); + return; + } + if (maxlength < ++lengths[cnt]) + ++maxlength; + + inner = chain[inner]; + } + } + + print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, + lengths, NULL); + + free (lengths); +} + + +/* This function handles the incorrect, System V-style hash table + format some 64-bit architectures use. */ +static void +handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) +{ + Elf_Data *data = elf_getdata (scn, NULL); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get data for section %d: %s"), + (int) elf_ndxscn (scn), elf_errmsg (-1)); + return; + } + + if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword))) + { + invalid_data: + error (0, 0, _("invalid data in sysv.hash64 section %d"), + (int) elf_ndxscn (scn)); + return; + } + + Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; + Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; + + uint64_t maxwords = data->d_size / sizeof (Elf64_Xword); + if (maxwords < 2 + || maxwords - 2 < nbucket + || maxwords - 2 - nbucket < nchain) + goto invalid_data; + + Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2]; + Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket]; + + uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); + + uint_fast32_t maxlength = 0; + uint_fast32_t nsyms = 0; + for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) + { + Elf64_Xword inner = bucket[cnt]; + Elf64_Xword chain_len = 0; + while (inner > 0 && inner < nchain) + { + ++nsyms; + ++chain_len; + if (chain_len > nchain) + { + error (0, 0, _("invalid chain in sysv.hash64 section %d"), + (int) elf_ndxscn (scn)); + free (lengths); + return; + } + if (maxlength < ++lengths[cnt]) + ++maxlength; + + inner = chain[inner]; + } + } + + print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, + lengths, NULL); + + free (lengths); +} + + +/* This function handles the GNU-style hash table format. */ +static void +handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) +{ + uint32_t *lengths = NULL; + Elf_Data *data = elf_getdata (scn, NULL); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get data for section %d: %s"), + (int) elf_ndxscn (scn), elf_errmsg (-1)); + return; + } + + if (unlikely (data->d_size < 4 * sizeof (Elf32_Word))) + { + invalid_data: + free (lengths); + error (0, 0, _("invalid data in gnu.hash section %d"), + (int) elf_ndxscn (scn)); + return; + } + + Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; + Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; + + /* Next comes the size of the bitmap. It's measured in words for + the architecture. It's 32 bits for 32 bit archs, and 64 bits for + 64 bit archs. There is always a bloom filter present, so zero is + an invalid value. */ + Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; + if (gelf_getclass (ebl->elf) == ELFCLASS64) + bitmask_words *= 2; + + if (bitmask_words == 0) + goto invalid_data; + + Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; + + /* Is there still room for the sym chain? + Use uint64_t calculation to prevent 32bit overflow. */ + uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word); + uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word); + if (used_buf > data->d_size) + goto invalid_data; + + lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); + + Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4]; + Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words]; + Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words + + nbucket]; + + /* Compute distribution of chain lengths. */ + uint_fast32_t maxlength = 0; + uint_fast32_t nsyms = 0; + for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) + if (bucket[cnt] != 0) + { + Elf32_Word inner = bucket[cnt] - symbias; + do + { + ++nsyms; + if (maxlength < ++lengths[cnt]) + ++maxlength; + if (inner >= max_nsyms) + goto invalid_data; + } + while ((chain[inner++] & 1) == 0); + } + + /* Count bits in bitmask. */ + uint_fast32_t nbits = 0; + for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt) + { + uint_fast32_t word = bitmask[cnt]; + + word = (word & 0x55555555) + ((word >> 1) & 0x55555555); + word = (word & 0x33333333) + ((word >> 2) & 0x33333333); + word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f); + word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff); + nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff); + } + + char *str; + if (unlikely (asprintf (&str, _("\ + Symbol Bias: %u\n\ + Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"), + (unsigned int) symbias, + bitmask_words * sizeof (Elf32_Word), + ((nbits * 100 + 50) + / (uint_fast32_t) (bitmask_words + * sizeof (Elf32_Word) * 8)), + (unsigned int) shift) == -1)) + error (EXIT_FAILURE, 0, _("memory exhausted")); + + print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, + lengths, str); + + free (str); + free (lengths); +} + + +/* Find the symbol table(s). For this we have to search through the + section table. */ +static void +handle_hash (Ebl *ebl) +{ + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + /* Handle the section if it is a symbol table. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (likely (shdr != NULL)) + { + if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH) + && (shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (elf_compress (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + shdr = gelf_getshdr (scn, &shdr_mem); + if (unlikely (shdr == NULL)) + error (EXIT_FAILURE, 0, + _("cannot get section [%zd] header: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + } + + if (shdr->sh_type == SHT_HASH) + { + if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) + handle_sysv_hash64 (ebl, scn, shdr, shstrndx); + else + handle_sysv_hash (ebl, scn, shdr, shstrndx); + } + else if (shdr->sh_type == SHT_GNU_HASH) + handle_gnu_hash (ebl, scn, shdr, shstrndx); + } + } +} + + +static void +print_liblist (Ebl *ebl) +{ + /* Find the library list sections. For this we have to search + through the section table. */ + Elf_Scn *scn = NULL; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST) + { + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT); + int nentries = shdr->sh_size / sh_entsize; + printf (ngettext ("\ +\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n", + "\ +\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n", + nentries), + elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + shdr->sh_offset, + nentries); + + Elf_Data *data = elf_getdata (scn, NULL); + if (data == NULL) + return; + + puts (_("\ + Library Time Stamp Checksum Version Flags")); + + for (int cnt = 0; cnt < nentries; ++cnt) + { + GElf_Lib lib_mem; + GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem); + if (unlikely (lib == NULL)) + continue; + + time_t t = (time_t) lib->l_time_stamp; + struct tm *tm = gmtime (&t); + if (unlikely (tm == NULL)) + continue; + + printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n", + cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name), + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + (unsigned int) lib->l_checksum, + (unsigned int) lib->l_version, + (unsigned int) lib->l_flags); + } + } + } +} + +static inline size_t +left (Elf_Data *data, + const unsigned char *p) +{ + return (const unsigned char *) data->d_buf + data->d_size - p; +} + +static void +print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) +{ + /* Find the object attributes sections. For this we have to search + through the section table. */ + Elf_Scn *scn = NULL; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES + && (shdr->sh_type != SHT_ARM_ATTRIBUTES + || ehdr->e_machine != EM_ARM) + && (shdr->sh_type != SHT_CSKY_ATTRIBUTES + || ehdr->e_machine != EM_CSKY))) + continue; + + printf (_("\ +\nObject attributes section [%2zu] '%s' of %" PRIu64 + " bytes at offset %#0" PRIx64 ":\n"), + elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + shdr->sh_size, shdr->sh_offset); + + Elf_Data *data = elf_rawdata (scn, NULL); + if (unlikely (data == NULL || data->d_size == 0)) + return; + + const unsigned char *p = data->d_buf; + + /* There is only one 'version', A. */ + if (unlikely (*p++ != 'A')) + return; + + fputs_unlocked (_(" Owner Size\n"), stdout); + + /* Loop over the sections. */ + while (left (data, p) >= 4) + { + /* Section length. */ + uint32_t len; + memcpy (&len, p, sizeof len); + + if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) + CONVERT (len); + + if (unlikely (len > left (data, p))) + break; + + /* Section vendor name. */ + const unsigned char *name = p + sizeof len; + p += len; + + unsigned const char *q = memchr (name, '\0', len); + if (unlikely (q == NULL)) + break; + ++q; + + printf (_(" %-13s %4" PRIu32 "\n"), name, len); + + bool gnu_vendor = (q - name == sizeof "gnu" + && !memcmp (name, "gnu", sizeof "gnu")); + + /* Loop over subsections. */ + if (shdr->sh_type != SHT_GNU_ATTRIBUTES + || gnu_vendor) + while (q < p) + { + const unsigned char *const sub = q; + + unsigned int subsection_tag; + get_uleb128 (subsection_tag, q, p); + if (unlikely (q >= p)) + break; + + uint32_t subsection_len; + if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len)) + break; + + memcpy (&subsection_len, q, sizeof subsection_len); + + if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) + CONVERT (subsection_len); + + /* Don't overflow, ptrdiff_t might be 32bits, but signed. */ + if (unlikely (subsection_len == 0 + || subsection_len >= (uint32_t) PTRDIFF_MAX + || p - sub < (ptrdiff_t) subsection_len)) + break; + + const unsigned char *r = q + sizeof subsection_len; + q = sub + subsection_len; + + switch (subsection_tag) + { + default: + /* Unknown subsection, print and skip. */ + printf (_(" %-4u %12" PRIu32 "\n"), + subsection_tag, subsection_len); + break; + + case 1: /* Tag_File */ + printf (_(" File: %11" PRIu32 "\n"), + subsection_len); + + while (r < q) + { + unsigned int tag; + get_uleb128 (tag, r, q); + if (unlikely (r >= q)) + break; + + /* GNU style tags have either a uleb128 value, + when lowest bit is not set, or a string + when the lowest bit is set. + "compatibility" (32) is special. It has + both a string and a uleb128 value. For + non-gnu we assume 6 till 31 only take ints. + XXX see arm backend, do we need a separate + hook? */ + uint64_t value = 0; + const char *string = NULL; + if (tag == 32 || (tag & 1) == 0 + || (! gnu_vendor && (tag > 5 && tag < 32))) + { + get_uleb128 (value, r, q); + if (r > q) + break; + } + if (tag == 32 + || ((tag & 1) != 0 + && (gnu_vendor + || (! gnu_vendor && tag > 32))) + || (! gnu_vendor && tag > 3 && tag < 6)) + { + string = (const char *) r; + r = memchr (r, '\0', q - r); + if (r == NULL) + break; + ++r; + } + + const char *tag_name = NULL; + const char *value_name = NULL; + ebl_check_object_attribute (ebl, (const char *) name, + tag, value, + &tag_name, &value_name); + + if (tag_name != NULL) + { + if (tag == 32) + printf (_(" %s: %" PRId64 ", %s\n"), + tag_name, value, string); + else if (string == NULL && value_name == NULL) + printf (_(" %s: %" PRId64 "\n"), + tag_name, value); + else + printf (_(" %s: %s\n"), + tag_name, string ?: value_name); + } + else + { + /* For "gnu" vendor 32 "compatibility" has + already been handled above. */ + assert (tag != 32 + || strcmp ((const char *) name, "gnu")); + if (string == NULL) + printf (_(" %u: %" PRId64 "\n"), + tag, value); + else + printf (_(" %u: %s\n"), + tag, string); + } + } + } + } + } + } +} + + +void +print_dwarf_addr (Dwfl_Module *dwflmod, + int address_size, Dwarf_Addr address, Dwarf_Addr raw) +{ + /* See if there is a name we can give for this address. */ + GElf_Sym sym; + GElf_Off off = 0; + const char *name = (print_address_names && ! print_unresolved_addresses) + ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL) + : NULL; + + const char *scn; + if (print_unresolved_addresses) + { + address = raw; + scn = NULL; + } + else + { + /* Relativize the address. */ + int n = dwfl_module_relocations (dwflmod); + int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address); + + /* In an ET_REL file there is a section name to refer to. */ + scn = (i < 0 ? NULL + : dwfl_module_relocation_info (dwflmod, i, NULL)); + } + + if ((name != NULL + ? (off != 0 + ? (scn != NULL + ? (address_size == 0 + ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">", + scn, address, name, off) + : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">", + scn, 2 + address_size * 2, address, + name, off)) + : (address_size == 0 + ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">", + address, name, off) + : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">", + 2 + address_size * 2, address, + name, off))) + : (scn != NULL + ? (address_size == 0 + ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name) + : printf ("%s+%#0*" PRIx64 " <%s>", + scn, 2 + address_size * 2, address, name)) + : (address_size == 0 + ? printf ("%#" PRIx64 " <%s>", address, name) + : printf ("%#0*" PRIx64 " <%s>", + 2 + address_size * 2, address, name)))) + : (scn != NULL + ? (address_size == 0 + ? printf ("%s+%#" PRIx64, scn, address) + : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address)) + : (address_size == 0 + ? printf ("%#" PRIx64, address) + : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0) + error (EXIT_FAILURE, 0, _("sprintf failure")); +} + + +static const char * +dwarf_tag_string (unsigned int tag) +{ + switch (tag) + { +#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_TAG +#undef DWARF_ONE_KNOWN_DW_TAG + default: + return NULL; + } +} + + +static const char * +dwarf_attr_string (unsigned int attrnum) +{ + switch (attrnum) + { +#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_AT +#undef DWARF_ONE_KNOWN_DW_AT + default: + return NULL; + } +} + + +static const char * +dwarf_form_string (unsigned int form) +{ + switch (form) + { +#define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_FORM +#undef DWARF_ONE_KNOWN_DW_FORM + default: + return NULL; + } +} + + +static const char * +dwarf_lang_string (unsigned int lang) +{ + switch (lang) + { +#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_LANG +#undef DWARF_ONE_KNOWN_DW_LANG + default: + return NULL; + } +} + + +static const char * +dwarf_inline_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_INL +#undef DWARF_ONE_KNOWN_DW_INL + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_encoding_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_ATE +#undef DWARF_ONE_KNOWN_DW_ATE + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_access_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_ACCESS +#undef DWARF_ONE_KNOWN_DW_ACCESS + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_defaulted_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_DEFAULTED +#undef DWARF_ONE_KNOWN_DW_DEFAULTED + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_visibility_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_VIS +#undef DWARF_ONE_KNOWN_DW_VIS + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_virtuality_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_VIRTUALITY +#undef DWARF_ONE_KNOWN_DW_VIRTUALITY + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_identifier_case_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_ID +#undef DWARF_ONE_KNOWN_DW_ID + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_calling_convention_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_CC +#undef DWARF_ONE_KNOWN_DW_CC + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_ordering_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_ORD +#undef DWARF_ONE_KNOWN_DW_ORD + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_discr_list_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_DSC +#undef DWARF_ONE_KNOWN_DW_DSC + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_locexpr_opcode_string (unsigned int code) +{ + static const char *const known[] = + { + /* Normally we can't afford building huge table of 64K entries, + most of them zero, just because there are a couple defined + values at the far end. In case of opcodes, it's OK. */ +#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_OP +#undef DWARF_ONE_KNOWN_DW_OP + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static const char * +dwarf_unit_string (unsigned int type) +{ + switch (type) + { +#define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_UT +#undef DWARF_ONE_KNOWN_DW_UT + default: + return NULL; + } +} + + +static const char * +dwarf_range_list_encoding_string (unsigned int kind) +{ + switch (kind) + { +#define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_RLE +#undef DWARF_ONE_KNOWN_DW_RLE + default: + return NULL; + } +} + + +static const char * +dwarf_loc_list_encoding_string (unsigned int kind) +{ + switch (kind) + { +#define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_LLE +#undef DWARF_ONE_KNOWN_DW_LLE + default: + return NULL; + } +} + + +static const char * +dwarf_line_content_description_string (unsigned int kind) +{ + switch (kind) + { +#define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME; + DWARF_ALL_KNOWN_DW_LNCT +#undef DWARF_ONE_KNOWN_DW_LNCT + default: + return NULL; + } +} + + +/* Used by all dwarf_foo_name functions. */ +static const char * +string_or_unknown (const char *known, unsigned int code, + unsigned int lo_user, unsigned int hi_user, + bool print_unknown_num) +{ + static char unknown_buf[20]; + + if (likely (known != NULL)) + return known; + + if (lo_user != 0 && code >= lo_user && code <= hi_user) + { + snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x", + code - lo_user); + return unknown_buf; + } + + if (print_unknown_num) + { + snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code); + return unknown_buf; + } + + return "???"; +} + + +static const char * +dwarf_tag_name (unsigned int tag) +{ + const char *ret = dwarf_tag_string (tag); + return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true); +} + +static const char * +dwarf_attr_name (unsigned int attr) +{ + const char *ret = dwarf_attr_string (attr); + return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true); +} + + +static const char * +dwarf_form_name (unsigned int form) +{ + const char *ret = dwarf_form_string (form); + return string_or_unknown (ret, form, 0, 0, true); +} + + +static const char * +dwarf_lang_name (unsigned int lang) +{ + const char *ret = dwarf_lang_string (lang); + return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false); +} + + +static const char * +dwarf_inline_name (unsigned int code) +{ + const char *ret = dwarf_inline_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_encoding_name (unsigned int code) +{ + const char *ret = dwarf_encoding_string (code); + return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false); +} + + +static const char * +dwarf_access_name (unsigned int code) +{ + const char *ret = dwarf_access_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_defaulted_name (unsigned int code) +{ + const char *ret = dwarf_defaulted_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_visibility_name (unsigned int code) +{ + const char *ret = dwarf_visibility_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_virtuality_name (unsigned int code) +{ + const char *ret = dwarf_virtuality_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_identifier_case_name (unsigned int code) +{ + const char *ret = dwarf_identifier_case_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_calling_convention_name (unsigned int code) +{ + const char *ret = dwarf_calling_convention_string (code); + return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false); +} + + +static const char * +dwarf_ordering_name (unsigned int code) +{ + const char *ret = dwarf_ordering_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_discr_list_name (unsigned int code) +{ + const char *ret = dwarf_discr_list_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_unit_name (unsigned int type) +{ + const char *ret = dwarf_unit_string (type); + return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true); +} + + +static const char * +dwarf_range_list_encoding_name (unsigned int kind) +{ + const char *ret = dwarf_range_list_encoding_string (kind); + return string_or_unknown (ret, kind, 0, 0, false); +} + + +static const char * +dwarf_loc_list_encoding_name (unsigned int kind) +{ + const char *ret = dwarf_loc_list_encoding_string (kind); + return string_or_unknown (ret, kind, 0, 0, false); +} + + +static const char * +dwarf_line_content_description_name (unsigned int kind) +{ + const char *ret = dwarf_line_content_description_string (kind); + return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user, + false); +} + + +static void +print_block (size_t n, const void *block) +{ + if (n == 0) + puts (_("empty block")); + else + { + printf (_("%zu byte block:"), n); + const unsigned char *data = block; + do + printf (" %02x", *data++); + while (--n > 0); + putchar ('\n'); + } +} + +static void +print_bytes (size_t n, const unsigned char *bytes) +{ + while (n-- > 0) + { + printf ("%02x", *bytes++); + if (n > 0) + printf (" "); + } +} + +static int +get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr) +{ + if (cu == NULL) + return -1; + + Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr]; + if (debug_addr == NULL) + return -1; + + Dwarf_Off base = __libdw_cu_addr_base (cu); + Dwarf_Word off = idx * cu->address_size; + if (base > debug_addr->d_size + || off > debug_addr->d_size - base + || cu->address_size > debug_addr->d_size - base - off) + return -1; + + const unsigned char *addrp = debug_addr->d_buf + base + off; + if (cu->address_size == 4) + *addr = read_4ubyte_unaligned (cu->dbg, addrp); + else + *addr = read_8ubyte_unaligned (cu->dbg, addrp); + + return 0; +} + +static void +print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, + unsigned int vers, unsigned int addrsize, unsigned int offset_size, + struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data) +{ + const unsigned int ref_size = vers < 3 ? addrsize : offset_size; + + if (len == 0) + { + printf ("%*s(empty)\n", indent, ""); + return; + } + +#define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid +#define CONSUME(n) NEED (n); else len -= (n) + + Dwarf_Word offset = 0; + while (len-- > 0) + { + uint_fast8_t op = *data++; + + const char *op_name = dwarf_locexpr_opcode_string (op); + if (unlikely (op_name == NULL)) + { + static char buf[20]; + if (op >= DW_OP_lo_user) + snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user); + else + snprintf (buf, sizeof buf, "??? (%#x)", op); + op_name = buf; + } + + switch (op) + { + case DW_OP_addr:; + /* Address operand. */ + Dwarf_Word addr; + NEED (addrsize); + if (addrsize == 4) + addr = read_4ubyte_unaligned (dbg, data); + else if (addrsize == 8) + addr = read_8ubyte_unaligned (dbg, data); + else + goto invalid; + data += addrsize; + CONSUME (addrsize); + + printf ("%*s[%2" PRIuMAX "] %s ", + indent, "", (uintmax_t) offset, op_name); + print_dwarf_addr (dwflmod, 0, addr, addr); + printf ("\n"); + + offset += 1 + addrsize; + break; + + case DW_OP_call_ref: + case DW_OP_GNU_variable_value: + /* Offset operand. */ + if (ref_size != 4 && ref_size != 8) + goto invalid; /* Cannot be used in CFA. */ + NEED (ref_size); + if (ref_size == 4) + addr = read_4ubyte_unaligned (dbg, data); + else + addr = read_8ubyte_unaligned (dbg, data); + data += ref_size; + CONSUME (ref_size); + /* addr is a DIE offset, so format it as one. */ + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n", + indent, "", (uintmax_t) offset, + op_name, (uintmax_t) addr); + offset += 1 + ref_size; + break; + + case DW_OP_deref_size: + case DW_OP_xderef_size: + case DW_OP_pick: + case DW_OP_const1u: + // XXX value might be modified by relocation + NEED (1); + printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n", + indent, "", (uintmax_t) offset, + op_name, *((uint8_t *) data)); + ++data; + --len; + offset += 2; + break; + + case DW_OP_const2u: + NEED (2); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n", + indent, "", (uintmax_t) offset, + op_name, read_2ubyte_unaligned (dbg, data)); + CONSUME (2); + data += 2; + offset += 3; + break; + + case DW_OP_const4u: + NEED (4); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n", + indent, "", (uintmax_t) offset, + op_name, read_4ubyte_unaligned (dbg, data)); + CONSUME (4); + data += 4; + offset += 5; + break; + + case DW_OP_const8u: + NEED (8); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n", + indent, "", (uintmax_t) offset, + op_name, (uint64_t) read_8ubyte_unaligned (dbg, data)); + CONSUME (8); + data += 8; + offset += 9; + break; + + case DW_OP_const1s: + NEED (1); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n", + indent, "", (uintmax_t) offset, + op_name, *((int8_t *) data)); + ++data; + --len; + offset += 2; + break; + + case DW_OP_const2s: + NEED (2); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n", + indent, "", (uintmax_t) offset, + op_name, read_2sbyte_unaligned (dbg, data)); + CONSUME (2); + data += 2; + offset += 3; + break; + + case DW_OP_const4s: + NEED (4); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n", + indent, "", (uintmax_t) offset, + op_name, read_4sbyte_unaligned (dbg, data)); + CONSUME (4); + data += 4; + offset += 5; + break; + + case DW_OP_const8s: + NEED (8); + // XXX value might be modified by relocation + printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n", + indent, "", (uintmax_t) offset, + op_name, read_8sbyte_unaligned (dbg, data)); + CONSUME (8); + data += 8; + offset += 9; + break; + + case DW_OP_piece: + case DW_OP_regx: + case DW_OP_plus_uconst: + case DW_OP_constu:; + const unsigned char *start = data; + uint64_t uleb; + NEED (1); + get_uleb128 (uleb, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n", + indent, "", (uintmax_t) offset, op_name, uleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_addrx: + case DW_OP_GNU_addr_index: + case DW_OP_constx: + case DW_OP_GNU_const_index:; + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ", + indent, "", (uintmax_t) offset, op_name, uleb); + CONSUME (data - start); + offset += 1 + (data - start); + if (get_indexed_addr (cu, uleb, &addr) != 0) + printf ("???\n"); + else + { + print_dwarf_addr (dwflmod, 0, addr, addr); + printf ("\n"); + } + break; + + case DW_OP_bit_piece: + start = data; + uint64_t uleb2; + NEED (1); + get_uleb128 (uleb, data, data + len); + NEED (1); + get_uleb128 (uleb2, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n", + indent, "", (uintmax_t) offset, op_name, uleb, uleb2); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_fbreg: + case DW_OP_breg0 ... DW_OP_breg31: + case DW_OP_consts: + start = data; + int64_t sleb; + NEED (1); + get_sleb128 (sleb, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n", + indent, "", (uintmax_t) offset, op_name, sleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_bregx: + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + NEED (1); + get_sleb128 (sleb, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n", + indent, "", (uintmax_t) offset, op_name, uleb, sleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_call2: + NEED (2); + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n", + indent, "", (uintmax_t) offset, op_name, + read_2ubyte_unaligned (dbg, data)); + CONSUME (2); + data += 2; + offset += 3; + break; + + case DW_OP_call4: + NEED (4); + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n", + indent, "", (uintmax_t) offset, op_name, + read_4ubyte_unaligned (dbg, data)); + CONSUME (4); + data += 4; + offset += 5; + break; + + case DW_OP_skip: + case DW_OP_bra: + NEED (2); + printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n", + indent, "", (uintmax_t) offset, op_name, + (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3)); + CONSUME (2); + data += 2; + offset += 3; + break; + + case DW_OP_implicit_value: + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s: ", + indent, "", (uintmax_t) offset, op_name); + NEED (uleb); + print_block (uleb, data); + data += uleb; + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_implicit_pointer: + case DW_OP_GNU_implicit_pointer: + /* DIE offset operand. */ + start = data; + NEED (ref_size); + if (ref_size != 4 && ref_size != 8) + goto invalid; /* Cannot be used in CFA. */ + if (ref_size == 4) + addr = read_4ubyte_unaligned (dbg, data); + else + addr = read_8ubyte_unaligned (dbg, data); + data += ref_size; + /* Byte offset operand. */ + NEED (1); + get_sleb128 (sleb, data, data + len); + + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n", + indent, "", (intmax_t) offset, + op_name, (uintmax_t) addr, sleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_entry_value: + case DW_OP_GNU_entry_value: + /* Size plus expression block. */ + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + printf ("%*s[%2" PRIuMAX "] %s:\n", + indent, "", (uintmax_t) offset, op_name); + NEED (uleb); + print_ops (dwflmod, dbg, indent + 5, indent + 5, vers, + addrsize, offset_size, cu, uleb, data); + data += uleb; + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_const_type: + case DW_OP_GNU_const_type: + /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte + unsigned size plus block. */ + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + if (! print_unresolved_addresses && cu != NULL) + uleb += cu->start; + NEED (1); + uint8_t usize = *(uint8_t *) data++; + NEED (usize); + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ", + indent, "", (uintmax_t) offset, op_name, uleb); + print_block (usize, data); + data += usize; + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_regval_type: + case DW_OP_GNU_regval_type: + /* uleb128 register number, uleb128 CU relative + DW_TAG_base_type DIE offset. */ + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + NEED (1); + get_uleb128 (uleb2, data, data + len); + if (! print_unresolved_addresses && cu != NULL) + uleb2 += cu->start; + printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n", + indent, "", (uintmax_t) offset, op_name, uleb, uleb2); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_deref_type: + case DW_OP_GNU_deref_type: + /* 1-byte unsigned size of value, uleb128 CU relative + DW_TAG_base_type DIE offset. */ + start = data; + NEED (1); + usize = *(uint8_t *) data++; + NEED (1); + get_uleb128 (uleb, data, data + len); + if (! print_unresolved_addresses && cu != NULL) + uleb += cu->start; + printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n", + indent, "", (uintmax_t) offset, + op_name, usize, uleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_xderef_type: + /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */ + start = data; + NEED (1); + usize = *(uint8_t *) data++; + NEED (1); + get_uleb128 (uleb, data, data + len); + printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n", + indent, "", (uintmax_t) offset, + op_name, usize, uleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_convert: + case DW_OP_GNU_convert: + case DW_OP_reinterpret: + case DW_OP_GNU_reinterpret: + /* uleb128 CU relative offset to DW_TAG_base_type, or zero + for conversion to untyped. */ + start = data; + NEED (1); + get_uleb128 (uleb, data, data + len); + if (uleb != 0 && ! print_unresolved_addresses && cu != NULL) + uleb += cu->start; + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n", + indent, "", (uintmax_t) offset, op_name, uleb); + CONSUME (data - start); + offset += 1 + (data - start); + break; + + case DW_OP_GNU_parameter_ref: + /* 4 byte CU relative reference to the abstract optimized away + DW_TAG_formal_parameter. */ + NEED (4); + uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data); + if (! print_unresolved_addresses && cu != NULL) + param_off += cu->start; + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n", + indent, "", (uintmax_t) offset, op_name, param_off); + CONSUME (4); + data += 4; + offset += 5; + break; + + default: + /* No Operand. */ + printf ("%*s[%2" PRIuMAX "] %s\n", + indent, "", (uintmax_t) offset, op_name); + ++offset; + break; + } + + indent = indentrest; + continue; + + invalid: + printf (_("%*s[%2" PRIuMAX "] %s \n"), + indent, "", (uintmax_t) offset, op_name); + break; + } +} + + +struct listptr +{ + Dwarf_Off offset:(64 - 3); + bool addr64:1; + bool dwarf64:1; + bool warned:1; + struct Dwarf_CU *cu; + unsigned int attr; +}; + +#define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4) +#define listptr_address_size(p) ((p)->addr64 ? 8 : 4) + +static Dwarf_Addr +cudie_base (Dwarf_Die *cudie) +{ + Dwarf_Addr base; + /* Find the base address of the compilation unit. It will normally + be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base + address could be overridden by DW_AT_entry_pc. It's been + removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for + compilation units with discontinuous ranges. */ + if (unlikely (dwarf_lowpc (cudie, &base) != 0)) + { + Dwarf_Attribute attr_mem; + if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem), + &base) != 0) + base = 0; + } + return base; +} + +static Dwarf_Addr +listptr_base (struct listptr *p) +{ + Dwarf_Die cu = CUDIE (p->cu); + return cudie_base (&cu); +} + +/* To store the name used in compare_listptr */ +static const char *sort_listptr_name; + +static int +compare_listptr (const void *a, const void *b) +{ + const char *name = sort_listptr_name; + struct listptr *p1 = (void *) a; + struct listptr *p2 = (void *) b; + + if (p1->offset < p2->offset) + return -1; + if (p1->offset > p2->offset) + return 1; + + if (!p1->warned && !p2->warned) + { + if (p1->addr64 != p2->addr64) + { + p1->warned = p2->warned = true; + error (0, 0, + _("%s %#" PRIx64 " used with different address sizes"), + name, (uint64_t) p1->offset); + } + if (p1->dwarf64 != p2->dwarf64) + { + p1->warned = p2->warned = true; + error (0, 0, + _("%s %#" PRIx64 " used with different offset sizes"), + name, (uint64_t) p1->offset); + } + if (listptr_base (p1) != listptr_base (p2)) + { + p1->warned = p2->warned = true; + error (0, 0, + _("%s %#" PRIx64 " used with different base addresses"), + name, (uint64_t) p1->offset); + } + if (p1->attr != p2 ->attr) + { + p1->warned = p2->warned = true; + error (0, 0, + _("%s %#" PRIx64 + " used with different attribute %s and %s"), + name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr), + dwarf_attr_name (p2->attr)); + } + } + + return 0; +} + +struct listptr_table +{ + size_t n; + size_t alloc; + struct listptr *table; +}; + +static struct listptr_table known_locsptr; +static struct listptr_table known_loclistsptr; +static struct listptr_table known_rangelistptr; +static struct listptr_table known_rnglistptr; +static struct listptr_table known_addrbases; +static struct listptr_table known_stroffbases; + +static void +reset_listptr (struct listptr_table *table) +{ + free (table->table); + table->table = NULL; + table->n = table->alloc = 0; +} + +/* Returns false if offset doesn't fit. See struct listptr. */ +static bool +notice_listptr (enum section_e section, struct listptr_table *table, + uint_fast8_t address_size, uint_fast8_t offset_size, + struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr) +{ + if (print_debug_sections & section) + { + if (table->n == table->alloc) + { + if (table->alloc == 0) + table->alloc = 128; + else + table->alloc *= 2; + table->table = xrealloc (table->table, + table->alloc * sizeof table->table[0]); + } + + struct listptr *p = &table->table[table->n++]; + + *p = (struct listptr) + { + .addr64 = address_size == 8, + .dwarf64 = offset_size == 8, + .offset = offset, + .cu = cu, + .attr = attr + }; + + if (p->offset != offset) + { + table->n--; + return false; + } + } + return true; +} + +static void +sort_listptr (struct listptr_table *table, const char *name) +{ + if (table->n > 0) + { + sort_listptr_name = name; + qsort (table->table, table->n, sizeof table->table[0], + &compare_listptr); + } +} + +static bool +skip_listptr_hole (struct listptr_table *table, size_t *idxp, + uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep, + Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset, + unsigned char **readp, unsigned char *endp, + unsigned int *attr) +{ + if (table->n == 0) + return false; + + while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset) + ++*idxp; + + struct listptr *p = &table->table[*idxp]; + + if (*idxp == table->n + || p->offset >= (Dwarf_Off) (endp - *readp + offset)) + { + *readp = endp; + printf (_(" [%6tx] \n"), + offset); + return true; + } + + if (p->offset != (Dwarf_Off) offset) + { + *readp += p->offset - offset; + printf (_(" [%6tx] ... %" PRIu64 " bytes ...\n"), + offset, (Dwarf_Off) p->offset - offset); + return true; + } + + if (address_sizep != NULL) + *address_sizep = listptr_address_size (p); + if (offset_sizep != NULL) + *offset_sizep = listptr_offset_size (p); + if (base != NULL) + *base = listptr_base (p); + if (cu != NULL) + *cu = p->cu; + if (attr != NULL) + *attr = p->attr; + + return false; +} + +static Dwarf_Off +next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off) +{ + /* Note that multiple attributes could in theory point to the same loclist + offset, so make sure we pick one that is bigger than the current one. + The table is sorted on offset. */ + if (*idxp < table->n) + { + while (++*idxp < table->n) + { + Dwarf_Off next = table->table[*idxp].offset; + if (next > off) + return next; + } + } + return 0; +} + +/* Returns the listptr associated with the given index, or NULL. */ +static struct listptr * +get_listptr (struct listptr_table *table, size_t idx) +{ + if (idx >= table->n) + return NULL; + return &table->table[idx]; +} + +/* Returns the next index, base address and CU associated with the + list unit offsets. If there is none false is returned, otherwise + true. Assumes the table has been sorted. */ +static bool +listptr_cu (struct listptr_table *table, size_t *idxp, + Dwarf_Off start, Dwarf_Off end, + Dwarf_Addr *base, struct Dwarf_CU **cu) +{ + while (*idxp < table->n + && table->table[*idxp].offset < start) + ++*idxp; + + if (*idxp < table->n + && table->table[*idxp].offset >= start + && table->table[*idxp].offset < end) + { + struct listptr *p = &table->table[*idxp]; + *base = listptr_base (p); + *cu = p->cu; + return true; + } + + return false; +} + +/* Returns the next index with the current CU for the given attribute. + If there is none false is returned, otherwise true. Assumes the + table has been sorted. */ +static bool +listptr_attr (struct listptr_table *table, size_t idxp, + Dwarf_Off offset, unsigned int attr) +{ + struct listptr *listptr; + do + { + listptr = get_listptr (table, idxp); + if (listptr == NULL) + return false; + + if (listptr->offset == offset && listptr->attr == attr) + return true; + + idxp++; + } + while (listptr->offset <= offset); + + return false; +} + +static void +print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ? + dbg->sectiondata[IDX_debug_abbrev]->d_size : 0); + + printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" + " [ Code]\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + Dwarf_Off offset = 0; + while (offset < sh_size) + { + printf (_("\nAbbreviation section at offset %" PRIu64 ":\n"), + offset); + + while (1) + { + size_t length; + Dwarf_Abbrev abbrev; + + int res = dwarf_offabbrev (dbg, offset, &length, &abbrev); + if (res != 0) + { + if (unlikely (res < 0)) + { + printf (_("\ + *** error while reading abbreviation: %s\n"), + dwarf_errmsg (-1)); + return; + } + + /* This is the NUL byte at the end of the section. */ + ++offset; + break; + } + + /* We know these calls can never fail. */ + unsigned int code = dwarf_getabbrevcode (&abbrev); + unsigned int tag = dwarf_getabbrevtag (&abbrev); + int has_children = dwarf_abbrevhaschildren (&abbrev); + + printf (_(" [%5u] offset: %" PRId64 + ", children: %s, tag: %s\n"), + code, (int64_t) offset, + has_children ? yes_str : no_str, + dwarf_tag_name (tag)); + + size_t cnt = 0; + unsigned int name; + unsigned int form; + Dwarf_Sword data; + Dwarf_Off enoffset; + while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form, + &data, &enoffset) == 0) + { + printf (" attr: %s, form: %s", + dwarf_attr_name (name), dwarf_form_name (form)); + if (form == DW_FORM_implicit_const) + printf (" (%" PRId64 ")", data); + printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset); + ++cnt; + } + + offset += length; + } + } +} + + +static void +print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + if (shdr->sh_size == 0) + return; + + /* We like to get the section from libdw to make sure they are relocated. */ + Elf_Data *data = (dbg->sectiondata[IDX_debug_addr] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_addr section data: %s"), + elf_errmsg (-1)); + return; + } + + size_t idx = 0; + sort_listptr (&known_addrbases, "addr_base"); + + const unsigned char *start = (const unsigned char *) data->d_buf; + const unsigned char *readp = start; + const unsigned char *readendp = ((const unsigned char *) data->d_buf + + data->d_size); + + while (readp < readendp) + { + /* We cannot really know whether or not there is an header. The + DebugFission extension to DWARF4 doesn't add one. The DWARF5 + .debug_addr variant does. Whether or not we have an header, + DW_AT_[GNU_]addr_base points at "index 0". So if the current + offset equals the CU addr_base then we can just start + printing addresses. If there is no CU with an exact match + then we'll try to parse the header first. */ + Dwarf_Off off = (Dwarf_Off) (readp + - (const unsigned char *) data->d_buf); + + printf ("Table at offset %" PRIx64 " ", off); + + struct listptr *listptr = get_listptr (&known_addrbases, idx++); + const unsigned char *next_unitp; + + uint64_t unit_length; + uint16_t version; + uint8_t address_size; + uint8_t segment_size; + if (listptr == NULL) + { + error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64, + off); + + /* We will have to assume it is just addresses to the end... */ + address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + next_unitp = readendp; + printf ("Unknown CU:\n"); + } + else + { + Dwarf_Die cudie; + if (dwarf_cu_die (listptr->cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf ("Unknown CU (%s):\n", dwarf_errmsg (-1)); + else + printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie)); + + if (listptr->offset == off) + { + address_size = listptr_address_size (listptr); + segment_size = 0; + version = 4; + + /* The addresses start here, but where do they end? */ + listptr = get_listptr (&known_addrbases, idx); + if (listptr == NULL) + next_unitp = readendp; + else if (listptr->cu->version < 5) + { + next_unitp = start + listptr->offset; + if (listptr->offset < off || listptr->offset > data->d_size) + { + error (0, 0, + "Warning: Bad address base for next unit at %" + PRIx64, off); + next_unitp = readendp; + } + } + else + { + /* Tricky, we don't have a header for this unit, but + there is one for the next. We will have to + "guess" how big it is and subtract it from the + offset (because that points after the header). */ + unsigned int offset_size = listptr_offset_size (listptr); + Dwarf_Off next_off = (listptr->offset + - (offset_size == 4 ? 4 : 12) /* len */ + - 2 /* version */ + - 1 /* address size */ + - 1); /* segment selector size */ + next_unitp = start + next_off; + if (next_off < off || next_off > data->d_size) + { + error (0, 0, + "Warning: Couldn't calculate .debug_addr " + " unit length at %" PRIx64, off); + next_unitp = readendp; + } + } + unit_length = (uint64_t) (next_unitp - readp); + + /* Pretend we have a header. */ + printf ("\n"); + printf (_(" Length: %8" PRIu64 "\n"), + unit_length); + printf (_(" DWARF version: %8" PRIu16 "\n"), version); + printf (_(" Address size: %8" PRIu64 "\n"), + (uint64_t) address_size); + printf (_(" Segment size: %8" PRIu64 "\n"), + (uint64_t) segment_size); + printf ("\n"); + } + else + { + /* OK, we have to parse an header first. */ + unit_length = read_4ubyte_unaligned_inc (dbg, readp); + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp > readendp - 8)) + { + invalid_data: + error (0, 0, "Invalid data"); + return; + } + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + } + printf ("\n"); + printf (_(" Length: %8" PRIu64 "\n"), + unit_length); + + /* We need at least 2-bytes (version) + 1-byte + (addr_size) + 1-byte (segment_size) = 4 bytes to + complete the header. And this unit cannot go beyond + the section data. */ + if (readp > readendp - 4 + || unit_length < 4 + || unit_length > (uint64_t) (readendp - readp)) + goto invalid_data; + + next_unitp = readp + unit_length; + + version = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" DWARF version: %8" PRIu16 "\n"), version); + + if (version != 5) + { + error (0, 0, _("Unknown version")); + goto next_unit; + } + + address_size = *readp++; + printf (_(" Address size: %8" PRIu64 "\n"), + (uint64_t) address_size); + + if (address_size != 4 && address_size != 8) + { + error (0, 0, _("unsupported address size")); + goto next_unit; + } + + segment_size = *readp++; + printf (_(" Segment size: %8" PRIu64 "\n"), + (uint64_t) segment_size); + printf ("\n"); + + if (segment_size != 0) + { + error (0, 0, _("unsupported segment size")); + goto next_unit; + } + + if (listptr->offset != (Dwarf_Off) (readp - start)) + { + error (0, 0, "Address index doesn't start after header"); + goto next_unit; + } + } + } + + int digits = 1; + size_t addresses = (next_unitp - readp) / address_size; + while (addresses >= 10) + { + ++digits; + addresses /= 10; + } + + unsigned int uidx = 0; + size_t index_offset = readp - (const unsigned char *) data->d_buf; + printf (" Addresses start at offset 0x%zx:\n", index_offset); + while (readp <= next_unitp - address_size) + { + Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg, + readp); + printf (" [%*u] ", digits, uidx++); + print_dwarf_addr (dwflmod, address_size, addr, addr); + printf ("\n"); + } + printf ("\n"); + + if (readp != next_unitp) + error (0, 0, "extra %zd bytes at end of unit", + (size_t) (next_unitp - readp)); + + next_unit: + readp = next_unitp; + } +} + +/* Print content of DWARF .debug_aranges section. We fortunately do + not have to know a bit about the structure of the section, libdwarf + takes care of it. */ +static void +print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr, Dwarf *dbg) +{ + Dwarf_Aranges *aranges; + size_t cnt; + if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0)) + { + error (0, 0, _("cannot get .debug_aranges content: %s"), + dwarf_errmsg (-1)); + return; + } + + GElf_Shdr glink_mem; + GElf_Shdr *glink; + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); + if (glink == NULL) + { + error (0, 0, _("invalid sh_link value in section %zu"), + elf_ndxscn (scn)); + return; + } + + printf (ngettext ("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n", + "\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n", + cnt), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset, cnt); + + /* Compute floor(log16(cnt)). */ + size_t tmp = cnt; + int digits = 1; + while (tmp >= 16) + { + ++digits; + tmp >>= 4; + } + + for (size_t n = 0; n < cnt; ++n) + { + Dwarf_Arange *runp = dwarf_onearange (aranges, n); + if (unlikely (runp == NULL)) + { + printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1)); + return; + } + + Dwarf_Addr start; + Dwarf_Word length; + Dwarf_Off offset; + + if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0)) + printf (_(" [%*zu] ???\n"), digits, n); + else + printf (_(" [%*zu] start: %0#*" PRIx64 + ", length: %5" PRIu64 ", CU DIE offset: %6" + PRId64 "\n"), + digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18, + (uint64_t) start, (uint64_t) length, (int64_t) offset); + } +} + + +/* Print content of DWARF .debug_aranges section. */ +static void +print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr, Dwarf *dbg) +{ + if (decodedaranges) + { + print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg); + return; + } + + Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges] + ?: elf_rawdata (scn, NULL)); + + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_aranges content: %s"), + elf_errmsg (-1)); + return; + } + + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + const unsigned char *readp = data->d_buf; + const unsigned char *readendp = readp + data->d_size; + + while (readp < readendp) + { + const unsigned char *hdrstart = readp; + size_t start_offset = hdrstart - (const unsigned char *) data->d_buf; + + printf (_("\nTable at offset %zu:\n"), start_offset); + if (readp + 4 > readendp) + { + invalid_data: + error (0, 0, _("invalid data in section [%zu] '%s'"), + elf_ndxscn (scn), section_name (ebl, shdr)); + return; + } + + Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int length_bytes = 4; + if (length == DWARF3_LENGTH_64_BIT) + { + if (readp + 8 > readendp) + goto invalid_data; + length = read_8ubyte_unaligned_inc (dbg, readp); + length_bytes = 8; + } + + const unsigned char *nexthdr = readp + length; + printf (_("\n Length: %6" PRIu64 "\n"), + (uint64_t) length); + + if (unlikely (length > (size_t) (readendp - readp))) + goto invalid_data; + + if (length == 0) + continue; + + if (readp + 2 > readendp) + goto invalid_data; + uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" DWARF version: %6" PRIuFAST16 "\n"), + version); + if (version != 2) + { + error (0, 0, _("unsupported aranges version")); + goto next_table; + } + + Dwarf_Word offset; + if (readp + length_bytes > readendp) + goto invalid_data; + if (length_bytes == 8) + offset = read_8ubyte_unaligned_inc (dbg, readp); + else + offset = read_4ubyte_unaligned_inc (dbg, readp); + printf (_(" CU offset: %6" PRIx64 "\n"), + (uint64_t) offset); + + if (readp + 1 > readendp) + goto invalid_data; + unsigned int address_size = *readp++; + printf (_(" Address size: %6" PRIu64 "\n"), + (uint64_t) address_size); + if (address_size != 4 && address_size != 8) + { + error (0, 0, _("unsupported address size")); + goto next_table; + } + + if (readp + 1 > readendp) + goto invalid_data; + unsigned int segment_size = *readp++; + printf (_(" Segment size: %6" PRIu64 "\n\n"), + (uint64_t) segment_size); + if (segment_size != 0 && segment_size != 4 && segment_size != 8) + { + error (0, 0, _("unsupported segment size")); + goto next_table; + } + + /* Round the address to the next multiple of 2*address_size. */ + readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size))) + % (2 * address_size)); + + while (readp < nexthdr) + { + Dwarf_Word range_address; + Dwarf_Word range_length; + Dwarf_Word segment = 0; + if (readp + 2 * address_size + segment_size > readendp) + goto invalid_data; + if (address_size == 4) + { + range_address = read_4ubyte_unaligned_inc (dbg, readp); + range_length = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + range_address = read_8ubyte_unaligned_inc (dbg, readp); + range_length = read_8ubyte_unaligned_inc (dbg, readp); + } + + if (segment_size == 4) + segment = read_4ubyte_unaligned_inc (dbg, readp); + else if (segment_size == 8) + segment = read_8ubyte_unaligned_inc (dbg, readp); + + if (range_address == 0 && range_length == 0 && segment == 0) + break; + + printf (" "); + print_dwarf_addr (dwflmod, address_size, range_address, + range_address); + printf (".."); + print_dwarf_addr (dwflmod, address_size, + range_address + range_length - 1, + range_length); + if (segment_size != 0) + printf (" (%" PRIx64 ")\n", (uint64_t) segment); + else + printf ("\n"); + } + + next_table: + if (readp != nexthdr) + { + size_t padding = nexthdr - readp; + printf (_(" %zu padding bytes\n"), padding); + readp = nexthdr; + } + } +} + + +static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu); + +/* Returns true and sets cu and cu_base if the given Dwarf is a split + DWARF (.dwo) file. */ +static bool +split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base) +{ + uint64_t id; + if (is_split_dwarf (dbg, &id, cu)) + { + Dwarf_Die cudie; + if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0) + { + *cu_base = cudie_base (&cudie); + return true; + } + } + return false; +} + +/* Print content of DWARF .debug_rnglists section. */ +static void +print_debug_rnglists_section (Dwfl_Module *dwflmod, + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, + Dwarf *dbg __attribute__((unused))) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_rnglists content: %s"), + elf_errmsg (-1)); + return; + } + + /* For the listptr to get the base address/CU. */ + sort_listptr (&known_rnglistptr, "rnglistptr"); + size_t listptr_idx = 0; + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = ((unsigned char *) data->d_buf + + data->d_size); + while (readp < dataend) + { + if (unlikely (readp > dataend - 4)) + { + invalid_data: + error (0, 0, _("invalid data in section [%zu] '%s'"), + elf_ndxscn (scn), section_name (ebl, shdr)); + return; + } + + ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + printf (_("Table at Offset 0x%" PRIx64 ":\n\n"), + (uint64_t) offset); + + uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int offset_size = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp > dataend - 8)) + goto invalid_data; + + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + offset_size = 8; + } + printf (_(" Length: %8" PRIu64 "\n"), unit_length); + + /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8 + bytes to complete the header. And this unit cannot go beyond + the section data. */ + if (readp > dataend - 8 + || unit_length < 8 + || unit_length > (uint64_t) (dataend - readp)) + goto invalid_data; + + const unsigned char *nexthdr = readp + unit_length; + + uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" DWARF version: %8" PRIu16 "\n"), version); + + if (version != 5) + { + error (0, 0, _("Unknown version")); + goto next_table; + } + + uint8_t address_size = *readp++; + printf (_(" Address size: %8" PRIu64 "\n"), + (uint64_t) address_size); + + if (address_size != 4 && address_size != 8) + { + error (0, 0, _("unsupported address size")); + goto next_table; + } + + uint8_t segment_size = *readp++; + printf (_(" Segment size: %8" PRIu64 "\n"), + (uint64_t) segment_size); + + if (segment_size != 0 && segment_size != 4 && segment_size != 8) + { + error (0, 0, _("unsupported segment size")); + goto next_table; + } + + uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp); + printf (_(" Offset entries: %8" PRIu64 "\n"), + (uint64_t) offset_entry_count); + + /* We need the CU that uses this unit to get the initial base address. */ + Dwarf_Addr cu_base = 0; + struct Dwarf_CU *cu = NULL; + if (listptr_cu (&known_rnglistptr, &listptr_idx, + (Dwarf_Off) offset, + (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf), + &cu_base, &cu) + || split_dwarf_cu_base (dbg, &cu, &cu_base)) + { + Dwarf_Die cudie; + if (dwarf_cu_die (cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf (_(" Unknown CU base: ")); + else + printf (_(" CU [%6" PRIx64 "] base: "), + dwarf_dieoffset (&cudie)); + print_dwarf_addr (dwflmod, address_size, cu_base, cu_base); + printf ("\n"); + } + else + printf (_(" Not associated with a CU.\n")); + + printf ("\n"); + + const unsigned char *offset_array_start = readp; + if (offset_entry_count > 0) + { + uint64_t max_entries = (unit_length - 8) / offset_size; + if (offset_entry_count > max_entries) + { + error (0, 0, + _("too many offset entries for unit length")); + offset_entry_count = max_entries; + } + + printf (_(" Offsets starting at 0x%" PRIx64 ":\n"), + (uint64_t) (offset_array_start + - (unsigned char *) data->d_buf)); + for (uint32_t idx = 0; idx < offset_entry_count; idx++) + { + printf (" [%6" PRIu32 "] ", idx); + if (offset_size == 4) + { + uint32_t off = read_4ubyte_unaligned_inc (dbg, readp); + printf ("0x%" PRIx32 "\n", off); + } + else + { + uint64_t off = read_8ubyte_unaligned_inc (dbg, readp); + printf ("0x%" PRIx64 "\n", off); + } + } + printf ("\n"); + } + + Dwarf_Addr base = cu_base; + bool start_of_list = true; + while (readp < nexthdr) + { + uint8_t kind = *readp++; + uint64_t op1, op2; + + /* Skip padding. */ + if (start_of_list && kind == DW_RLE_end_of_list) + continue; + + if (start_of_list) + { + base = cu_base; + printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n", + (uint64_t) (readp - (unsigned char *) data->d_buf - 1), + (uint64_t) (readp - offset_array_start - 1)); + start_of_list = false; + } + + printf (" %s", dwarf_range_list_encoding_name (kind)); + switch (kind) + { + case DW_RLE_end_of_list: + start_of_list = true; + printf ("\n\n"); + break; + + case DW_RLE_base_addressx: + if ((uint64_t) (nexthdr - readp) < 1) + { + invalid_range: + error (0, 0, _("invalid range list data")); + goto next_table; + } + get_uleb128 (op1, readp, nexthdr); + printf (" %" PRIx64 "\n", op1); + if (! print_unresolved_addresses) + { + Dwarf_Addr addr; + if (get_indexed_addr (cu, op1, &addr) != 0) + printf (" ???\n"); + else + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, addr, addr); + printf ("\n"); + } + } + break; + + case DW_RLE_startx_endx: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op1, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op2, readp, nexthdr); + printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + Dwarf_Addr addr1; + Dwarf_Addr addr2; + if (get_indexed_addr (cu, op1, &addr1) != 0 + || get_indexed_addr (cu, op2, &addr2) != 0) + { + printf (" ???..\n"); + printf (" ???\n"); + } + else + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, addr1, addr1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, + addr2 - 1, addr2); + printf ("\n"); + } + } + break; + + case DW_RLE_startx_length: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op1, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op2, readp, nexthdr); + printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + Dwarf_Addr addr1; + Dwarf_Addr addr2; + if (get_indexed_addr (cu, op1, &addr1) != 0) + { + printf (" ???..\n"); + printf (" ???\n"); + } + else + { + addr2 = addr1 + op2; + printf (" "); + print_dwarf_addr (dwflmod, address_size, addr1, addr1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, + addr2 - 1, addr2); + printf ("\n"); + } + } + break; + + case DW_RLE_offset_pair: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op1, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op2, readp, nexthdr); + printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + op1 += base; + op2 += base; + printf (" "); + print_dwarf_addr (dwflmod, address_size, op1, op1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, op2 - 1, op2); + printf ("\n"); + } + break; + + case DW_RLE_base_address: + if (address_size == 4) + { + if ((uint64_t) (nexthdr - readp) < 4) + goto invalid_range; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + if ((uint64_t) (nexthdr - readp) < 8) + goto invalid_range; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + } + base = op1; + printf (" 0x%" PRIx64 "\n", base); + if (! print_unresolved_addresses) + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, base, base); + printf ("\n"); + } + break; + + case DW_RLE_start_end: + if (address_size == 4) + { + if ((uint64_t) (nexthdr - readp) < 8) + goto invalid_range; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + op2 = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + if ((uint64_t) (nexthdr - readp) < 16) + goto invalid_range; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + op2 = read_8ubyte_unaligned_inc (dbg, readp); + } + printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, op1, op1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, op2 - 1, op2); + printf ("\n"); + } + break; + + case DW_RLE_start_length: + if (address_size == 4) + { + if ((uint64_t) (nexthdr - readp) < 4) + goto invalid_range; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + if ((uint64_t) (nexthdr - readp) < 8) + goto invalid_range; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_range; + get_uleb128 (op2, readp, nexthdr); + printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + op2 = op1 + op2; + printf (" "); + print_dwarf_addr (dwflmod, address_size, op1, op1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, op2 - 1, op2); + printf ("\n"); + } + break; + + default: + goto invalid_range; + } + } + + next_table: + if (readp != nexthdr) + { + size_t padding = nexthdr - readp; + printf (_(" %zu padding bytes\n\n"), padding); + readp = nexthdr; + } + } +} + +/* Print content of DWARF .debug_ranges section. */ +static void +print_debug_ranges_section (Dwfl_Module *dwflmod, + Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, + Dwarf *dbg) +{ + Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_ranges content: %s"), + elf_errmsg (-1)); + return; + } + + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + sort_listptr (&known_rangelistptr, "rangelistptr"); + size_t listptr_idx = 0; + + uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + + bool first = true; + Dwarf_Addr base = 0; + unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; + unsigned char *readp = data->d_buf; + Dwarf_CU *last_cu = NULL; + while (readp < endp) + { + ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + Dwarf_CU *cu = last_cu; + + if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx, + &address_size, NULL, &base, &cu, + offset, &readp, endp, NULL)) + continue; + + if (last_cu != cu) + { + Dwarf_Die cudie; + if (dwarf_cu_die (cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf (_("\n Unknown CU base: ")); + else + printf (_("\n CU [%6" PRIx64 "] base: "), + dwarf_dieoffset (&cudie)); + print_dwarf_addr (dwflmod, address_size, base, base); + printf ("\n"); + } + last_cu = cu; + + if (unlikely (data->d_size - offset < (size_t) address_size * 2)) + { + printf (_(" [%6tx] \n"), offset); + break; + } + + Dwarf_Addr begin; + Dwarf_Addr end; + if (address_size == 8) + { + begin = read_8ubyte_unaligned_inc (dbg, readp); + end = read_8ubyte_unaligned_inc (dbg, readp); + } + else + { + begin = read_4ubyte_unaligned_inc (dbg, readp); + end = read_4ubyte_unaligned_inc (dbg, readp); + if (begin == (Dwarf_Addr) (uint32_t) -1) + begin = (Dwarf_Addr) -1l; + } + + if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ + { + if (first) + printf (" [%6tx] ", offset); + else + printf (" "); + puts (_("base address")); + printf (" "); + print_dwarf_addr (dwflmod, address_size, end, end); + printf ("\n"); + base = end; + first = false; + } + else if (begin == 0 && end == 0) /* End of list entry. */ + { + if (first) + printf (_(" [%6tx] empty list\n"), offset); + first = true; + } + else + { + /* We have an address range entry. */ + if (first) /* First address range entry in a list. */ + printf (" [%6tx] ", offset); + else + printf (" "); + + printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end); + if (! print_unresolved_addresses) + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, base + begin, + base + begin); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, + base + end - 1, base + end); + printf ("\n"); + } + + first = false; + } + } +} + +#define REGNAMESZ 16 +static const char * +register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc, + char name[REGNAMESZ], int *bits, int *type) +{ + const char *set; + const char *pfx; + int ignore; + ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set, + bits ?: &ignore, type ?: &ignore); + if (n <= 0) + { + if (loc != NULL) + snprintf (name, REGNAMESZ, "reg%u", loc->regno); + else + snprintf (name, REGNAMESZ, "??? 0x%x", regno); + if (bits != NULL) + *bits = loc != NULL ? loc->bits : 0; + if (type != NULL) + *type = DW_ATE_unsigned; + set = "??? unrecognized"; + } + else + { + if (bits != NULL && *bits <= 0) + *bits = loc != NULL ? loc->bits : 0; + if (type != NULL && *type == DW_ATE_void) + *type = DW_ATE_unsigned; + + } + return set; +} + +static const unsigned char * +read_encoded (unsigned int encoding, const unsigned char *readp, + const unsigned char *const endp, uint64_t *res, Dwarf *dbg) +{ + if ((encoding & 0xf) == DW_EH_PE_absptr) + encoding = gelf_getclass (dbg->elf) == ELFCLASS32 + ? DW_EH_PE_udata4 : DW_EH_PE_udata8; + + switch (encoding & 0xf) + { + case DW_EH_PE_uleb128: + get_uleb128 (*res, readp, endp); + break; + case DW_EH_PE_sleb128: + get_sleb128 (*res, readp, endp); + break; + case DW_EH_PE_udata2: + if (readp + 2 > endp) + goto invalid; + *res = read_2ubyte_unaligned_inc (dbg, readp); + break; + case DW_EH_PE_udata4: + if (readp + 4 > endp) + goto invalid; + *res = read_4ubyte_unaligned_inc (dbg, readp); + break; + case DW_EH_PE_udata8: + if (readp + 8 > endp) + goto invalid; + *res = read_8ubyte_unaligned_inc (dbg, readp); + break; + case DW_EH_PE_sdata2: + if (readp + 2 > endp) + goto invalid; + *res = read_2sbyte_unaligned_inc (dbg, readp); + break; + case DW_EH_PE_sdata4: + if (readp + 4 > endp) + goto invalid; + *res = read_4sbyte_unaligned_inc (dbg, readp); + break; + case DW_EH_PE_sdata8: + if (readp + 8 > endp) + goto invalid; + *res = read_8sbyte_unaligned_inc (dbg, readp); + break; + default: + invalid: + error (1, 0, + _("invalid encoding")); + } + + return readp; +} + +static const char * +regname (Ebl *ebl, unsigned int regno, char *regnamebuf) +{ + register_info (ebl, regno, NULL, regnamebuf, NULL, NULL); + + return regnamebuf; +} + +static void +print_cfa_program (const unsigned char *readp, const unsigned char *const endp, + Dwarf_Word vma_base, unsigned int code_align, + int data_align, + unsigned int version, unsigned int ptr_size, + unsigned int encoding, + Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg) +{ + char regnamebuf[REGNAMESZ]; + + puts ("\n Program:"); + Dwarf_Word pc = vma_base; + while (readp < endp) + { + unsigned int opcode = *readp++; + + if (opcode < DW_CFA_advance_loc) + /* Extended opcode. */ + switch (opcode) + { + uint64_t op1; + int64_t sop1; + uint64_t op2; + int64_t sop2; + + case DW_CFA_nop: + puts (" nop"); + break; + case DW_CFA_set_loc: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + readp = read_encoded (encoding, readp, endp, &op1, dbg); + printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n", + op1, pc = vma_base + op1); + break; + case DW_CFA_advance_loc1: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + printf (" advance_loc1 %u to %#" PRIx64 "\n", + *readp, pc += *readp * code_align); + ++readp; + break; + case DW_CFA_advance_loc2: + if ((uint64_t) (endp - readp) < 2) + goto invalid; + op1 = read_2ubyte_unaligned_inc (dbg, readp); + printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n", + op1, pc += op1 * code_align); + break; + case DW_CFA_advance_loc4: + if ((uint64_t) (endp - readp) < 4) + goto invalid; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n", + op1, pc += op1 * code_align); + break; + case DW_CFA_offset_extended: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op2, readp, endp); + printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64 + "\n", + op1, regname (ebl, op1, regnamebuf), op2 * data_align); + break; + case DW_CFA_restore_extended: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + printf (" restore_extended r%" PRIu64 " (%s)\n", + op1, regname (ebl, op1, regnamebuf)); + break; + case DW_CFA_undefined: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + printf (" undefined r%" PRIu64 " (%s)\n", op1, + regname (ebl, op1, regnamebuf)); + break; + case DW_CFA_same_value: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + printf (" same_value r%" PRIu64 " (%s)\n", op1, + regname (ebl, op1, regnamebuf)); + break; + case DW_CFA_register: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op2, readp, endp); + printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n", + op1, regname (ebl, op1, regnamebuf), op2, + regname (ebl, op2, regnamebuf)); + break; + case DW_CFA_remember_state: + puts (" remember_state"); + break; + case DW_CFA_restore_state: + puts (" restore_state"); + break; + case DW_CFA_def_cfa: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op2, readp, endp); + printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n", + op1, regname (ebl, op1, regnamebuf), op2); + break; + case DW_CFA_def_cfa_register: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + printf (" def_cfa_register r%" PRIu64 " (%s)\n", + op1, regname (ebl, op1, regnamebuf)); + break; + case DW_CFA_def_cfa_offset: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + printf (" def_cfa_offset %" PRIu64 "\n", op1); + break; + case DW_CFA_def_cfa_expression: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */ + printf (" def_cfa_expression %" PRIu64 "\n", op1); + if ((uint64_t) (endp - readp) < op1) + { + invalid: + fputs (_(" \n"), stdout); + return; + } + print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL, + op1, readp); + readp += op1; + break; + case DW_CFA_expression: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */ + printf (" expression r%" PRIu64 " (%s) \n", + op1, regname (ebl, op1, regnamebuf)); + if ((uint64_t) (endp - readp) < op2) + goto invalid; + print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL, + op2, readp); + readp += op2; + break; + case DW_CFA_offset_extended_sf: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_sleb128 (sop2, readp, endp); + printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+" + PRId64 "\n", + op1, regname (ebl, op1, regnamebuf), sop2 * data_align); + break; + case DW_CFA_def_cfa_sf: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_sleb128 (sop2, readp, endp); + printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n", + op1, regname (ebl, op1, regnamebuf), sop2 * data_align); + break; + case DW_CFA_def_cfa_offset_sf: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_sleb128 (sop1, readp, endp); + printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align); + break; + case DW_CFA_val_offset: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op2, readp, endp); + printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n", + op1, op2 * data_align); + break; + case DW_CFA_val_offset_sf: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_sleb128 (sop2, readp, endp); + printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n", + op1, sop2 * data_align); + break; + case DW_CFA_val_expression: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */ + printf (" val_expression r%" PRIu64 " (%s)\n", + op1, regname (ebl, op1, regnamebuf)); + if ((uint64_t) (endp - readp) < op2) + goto invalid; + print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, + NULL, op2, readp); + readp += op2; + break; + case DW_CFA_MIPS_advance_loc8: + if ((uint64_t) (endp - readp) < 8) + goto invalid; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n", + op1, pc += op1 * code_align); + break; + case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */ + if (ehdr->e_machine == EM_AARCH64) + puts (" AARCH64_negate_ra_state"); + else + puts (" GNU_window_save"); + break; + case DW_CFA_GNU_args_size: + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (op1, readp, endp); + printf (" args_size %" PRIu64 "\n", op1); + break; + default: + printf (" ??? (%u)\n", opcode); + break; + } + else if (opcode < DW_CFA_offset) + printf (" advance_loc %u to %#" PRIx64 "\n", + opcode & 0x3f, pc += (opcode & 0x3f) * code_align); + else if (opcode < DW_CFA_restore) + { + uint64_t offset; + if ((uint64_t) (endp - readp) < 1) + goto invalid; + get_uleb128 (offset, readp, endp); + printf (" offset r%u (%s) at cfa%+" PRId64 "\n", + opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf), + offset * data_align); + } + else + printf (" restore r%u (%s)\n", + opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf)); + } +} + + +static unsigned int +encoded_ptr_size (int encoding, unsigned int ptr_size) +{ + switch (encoding & 7) + { + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + case 0: + return ptr_size; + } + + fprintf (stderr, "Unsupported pointer encoding: %#x, " + "assuming pointer size of %d.\n", encoding, ptr_size); + return ptr_size; +} + + +static unsigned int +print_encoding (unsigned int val) +{ + switch (val & 0xf) + { + case DW_EH_PE_absptr: + fputs ("absptr", stdout); + break; + case DW_EH_PE_uleb128: + fputs ("uleb128", stdout); + break; + case DW_EH_PE_udata2: + fputs ("udata2", stdout); + break; + case DW_EH_PE_udata4: + fputs ("udata4", stdout); + break; + case DW_EH_PE_udata8: + fputs ("udata8", stdout); + break; + case DW_EH_PE_sleb128: + fputs ("sleb128", stdout); + break; + case DW_EH_PE_sdata2: + fputs ("sdata2", stdout); + break; + case DW_EH_PE_sdata4: + fputs ("sdata4", stdout); + break; + case DW_EH_PE_sdata8: + fputs ("sdata8", stdout); + break; + default: + /* We did not use any of the bits after all. */ + return val; + } + + return val & ~0xf; +} + + +static unsigned int +print_relinfo (unsigned int val) +{ + switch (val & 0x70) + { + case DW_EH_PE_pcrel: + fputs ("pcrel", stdout); + break; + case DW_EH_PE_textrel: + fputs ("textrel", stdout); + break; + case DW_EH_PE_datarel: + fputs ("datarel", stdout); + break; + case DW_EH_PE_funcrel: + fputs ("funcrel", stdout); + break; + case DW_EH_PE_aligned: + fputs ("aligned", stdout); + break; + default: + return val; + } + + return val & ~0x70; +} + + +static void +print_encoding_base (const char *pfx, unsigned int fde_encoding) +{ + printf ("(%s", pfx); + + if (fde_encoding == DW_EH_PE_omit) + puts ("omit)"); + else + { + unsigned int w = fde_encoding; + + w = print_encoding (w); + + if (w & 0x70) + { + if (w != fde_encoding) + fputc_unlocked (' ', stdout); + + w = print_relinfo (w); + } + + if (w != 0) + printf ("%s%x", w != fde_encoding ? " " : "", w); + + puts (")"); + } +} + + +static void +print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + size_t shstrndx; + /* We know this call will succeed since it did in the caller. */ + (void) elf_getshdrstrndx (ebl->elf, &shstrndx); + const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); + + /* Needed if we find PC-relative addresses. */ + GElf_Addr bias; + if (dwfl_module_getelf (dwflmod, &bias) == NULL) + { + error (0, 0, _("cannot get ELF: %s"), dwfl_errmsg (-1)); + return; + } + + bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0; + Elf_Data *data = (is_eh_frame + ? elf_rawdata (scn, NULL) + : (dbg->sectiondata[IDX_debug_frame] + ?: elf_rawdata (scn, NULL))); + + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get %s content: %s"), + scnname, elf_errmsg (-1)); + return; + } + + if (is_eh_frame) + printf (_("\ +\nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset); + else + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset); + + struct cieinfo + { + ptrdiff_t cie_offset; + const char *augmentation; + unsigned int code_alignment_factor; + unsigned int data_alignment_factor; + uint8_t address_size; + uint8_t fde_encoding; + uint8_t lsda_encoding; + struct cieinfo *next; + } *cies = NULL; + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = ((unsigned char *) data->d_buf + + data->d_size); + while (readp < dataend) + { + if (unlikely (readp + 4 > dataend)) + { + invalid_data: + error (0, 0, _("invalid data in section [%zu] '%s'"), + elf_ndxscn (scn), scnname); + return; + } + + /* At the beginning there must be a CIE. There can be multiple, + hence we test tis in a loop. */ + ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + + Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int length = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp + 8 > dataend)) + goto invalid_data; + + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + length = 8; + } + + if (unlikely (unit_length == 0)) + { + printf (_("\n [%6tx] Zero terminator\n"), offset); + continue; + } + + Dwarf_Word maxsize = dataend - readp; + if (unlikely (unit_length > maxsize)) + goto invalid_data; + + unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + + ptrdiff_t start = readp - (unsigned char *) data->d_buf; + const unsigned char *const cieend = readp + unit_length; + if (unlikely (cieend > dataend)) + goto invalid_data; + + Dwarf_Off cie_id; + if (length == 4) + { + if (unlikely (cieend - readp < 4)) + goto invalid_data; + cie_id = read_4ubyte_unaligned_inc (dbg, readp); + if (!is_eh_frame && cie_id == DW_CIE_ID_32) + cie_id = DW_CIE_ID_64; + } + else + { + if (unlikely (cieend - readp < 8)) + goto invalid_data; + cie_id = read_8ubyte_unaligned_inc (dbg, readp); + } + + uint_fast8_t version = 2; + unsigned int code_alignment_factor; + int data_alignment_factor; + unsigned int fde_encoding = 0; + unsigned int lsda_encoding = 0; + Dwarf_Word initial_location = 0; + Dwarf_Word vma_base = 0; + + if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64)) + { + if (unlikely (cieend - readp < 2)) + goto invalid_data; + version = *readp++; + const char *const augmentation = (const char *) readp; + readp = memchr (readp, '\0', cieend - readp); + if (unlikely (readp == NULL)) + goto invalid_data; + ++readp; + + uint_fast8_t segment_size = 0; + if (version >= 4) + { + if (cieend - readp < 5) + goto invalid_data; + ptr_size = *readp++; + segment_size = *readp++; + } + + if (cieend - readp < 1) + goto invalid_data; + get_uleb128 (code_alignment_factor, readp, cieend); + if (cieend - readp < 1) + goto invalid_data; + get_sleb128 (data_alignment_factor, readp, cieend); + + /* In some variant for unwind data there is another field. */ + if (strcmp (augmentation, "eh") == 0) + readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + + unsigned int return_address_register; + if (cieend - readp < 1) + goto invalid_data; + if (unlikely (version == 1)) + return_address_register = *readp++; + else + get_uleb128 (return_address_register, readp, cieend); + + printf ("\n [%6tx] CIE length=%" PRIu64 "\n" + " CIE_id: %" PRIu64 "\n" + " version: %u\n" + " augmentation: \"%s\"\n", + offset, (uint64_t) unit_length, (uint64_t) cie_id, + version, augmentation); + if (version >= 4) + printf (" address_size: %u\n" + " segment_size: %u\n", + ptr_size, segment_size); + printf (" code_alignment_factor: %u\n" + " data_alignment_factor: %d\n" + " return_address_register: %u\n", + code_alignment_factor, + data_alignment_factor, return_address_register); + + if (augmentation[0] == 'z') + { + unsigned int augmentationlen; + get_uleb128 (augmentationlen, readp, cieend); + + if (augmentationlen > (size_t) (cieend - readp)) + { + error (0, 0, _("invalid augmentation length")); + readp = cieend; + continue; + } + + const char *hdr = "Augmentation data:"; + const char *cp = augmentation + 1; + while (*cp != '\0' && cp < augmentation + augmentationlen + 1) + { + printf (" %-26s%#x ", hdr, *readp); + hdr = ""; + + if (*cp == 'R') + { + fde_encoding = *readp++; + print_encoding_base (_("FDE address encoding: "), + fde_encoding); + } + else if (*cp == 'L') + { + lsda_encoding = *readp++; + print_encoding_base (_("LSDA pointer encoding: "), + lsda_encoding); + } + else if (*cp == 'P') + { + /* Personality. This field usually has a relocation + attached pointing to __gcc_personality_v0. */ + const unsigned char *startp = readp; + unsigned int encoding = *readp++; + uint64_t val = 0; + readp = read_encoded (encoding, readp, + readp - 1 + augmentationlen, + &val, dbg); + + while (++startp < readp) + printf ("%#x ", *startp); + + putchar ('('); + print_encoding (encoding); + putchar (' '); + switch (encoding & 0xf) + { + case DW_EH_PE_sleb128: + case DW_EH_PE_sdata2: + case DW_EH_PE_sdata4: + printf ("%" PRId64 ")\n", val); + break; + default: + printf ("%#" PRIx64 ")\n", val); + break; + } + } + else + printf ("(%x)\n", *readp++); + + ++cp; + } + } + + if (likely (ptr_size == 4 || ptr_size == 8)) + { + struct cieinfo *newp = alloca (sizeof (*newp)); + newp->cie_offset = offset; + newp->augmentation = augmentation; + newp->fde_encoding = fde_encoding; + newp->lsda_encoding = lsda_encoding; + newp->address_size = ptr_size; + newp->code_alignment_factor = code_alignment_factor; + newp->data_alignment_factor = data_alignment_factor; + newp->next = cies; + cies = newp; + } + } + else + { + struct cieinfo *cie = cies; + while (cie != NULL) + if (is_eh_frame + ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset + : cie_id == (Dwarf_Off) cie->cie_offset) + break; + else + cie = cie->next; + if (unlikely (cie == NULL)) + { + puts ("invalid CIE reference in FDE"); + return; + } + + /* Initialize from CIE data. */ + fde_encoding = cie->fde_encoding; + lsda_encoding = cie->lsda_encoding; + ptr_size = encoded_ptr_size (fde_encoding, cie->address_size); + code_alignment_factor = cie->code_alignment_factor; + data_alignment_factor = cie->data_alignment_factor; + + const unsigned char *base = readp; + // XXX There are sometimes relocations for this value + initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp); + Dwarf_Word address_range + = read_addr_unaligned_inc (ptr_size, dbg, readp); + + /* pcrel for an FDE address is relative to the runtime + address of the start_address field itself. Sign extend + if necessary to make sure the calculation is done on the + full 64 bit address even when initial_location only holds + the lower 32 bits. */ + Dwarf_Addr pc_start = initial_location; + if (ptr_size == 4) + pc_start = (uint64_t) (int32_t) pc_start; + if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) + pc_start += ((uint64_t) shdr->sh_addr + + (base - (const unsigned char *) data->d_buf) + - bias); + + printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n" + " CIE_pointer: %" PRIu64 "\n" + " initial_location: ", + offset, (uint64_t) unit_length, + cie->cie_offset, (uint64_t) cie_id); + print_dwarf_addr (dwflmod, cie->address_size, + pc_start, initial_location); + if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) + { + vma_base = (((uint64_t) shdr->sh_offset + + (base - (const unsigned char *) data->d_buf) + + (uint64_t) initial_location) + & (ptr_size == 4 + ? UINT64_C (0xffffffff) + : UINT64_C (0xffffffffffffffff))); + printf (_(" (offset: %#" PRIx64 ")"), + (uint64_t) vma_base); + } + + printf ("\n address_range: %#" PRIx64, + (uint64_t) address_range); + if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) + printf (_(" (end offset: %#" PRIx64 ")"), + ((uint64_t) vma_base + (uint64_t) address_range) + & (ptr_size == 4 + ? UINT64_C (0xffffffff) + : UINT64_C (0xffffffffffffffff))); + putchar ('\n'); + + if (cie->augmentation[0] == 'z') + { + unsigned int augmentationlen; + if (cieend - readp < 1) + goto invalid_data; + get_uleb128 (augmentationlen, readp, cieend); + + if (augmentationlen > (size_t) (cieend - readp)) + { + error (0, 0, _("invalid augmentation length")); + readp = cieend; + continue; + } + + if (augmentationlen > 0) + { + const char *hdr = "Augmentation data:"; + const char *cp = cie->augmentation + 1; + unsigned int u = 0; + while (*cp != '\0' + && cp < cie->augmentation + augmentationlen + 1) + { + if (*cp == 'L') + { + uint64_t lsda_pointer; + const unsigned char *p + = read_encoded (lsda_encoding, &readp[u], + &readp[augmentationlen], + &lsda_pointer, dbg); + u = p - readp; + printf (_("\ + %-26sLSDA pointer: %#" PRIx64 "\n"), + hdr, lsda_pointer); + hdr = ""; + } + ++cp; + } + + while (u < augmentationlen) + { + printf (" %-26s%#x\n", hdr, readp[u++]); + hdr = ""; + } + } + + readp += augmentationlen; + } + } + + /* Handle the initialization instructions. */ + if (ptr_size != 4 && ptr_size !=8) + printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size); + else + print_cfa_program (readp, cieend, vma_base, code_alignment_factor, + data_alignment_factor, version, ptr_size, + fde_encoding, dwflmod, ebl, ehdr, dbg); + readp = cieend; + } +} + + +/* Returns the signedness (or false if it cannot be determined) and + the byte size (or zero if it cannot be gotten) of the given DIE + DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */ +static void +die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes) +{ + Dwarf_Attribute attr; + Dwarf_Die type; + + *bytes = 0; + *is_signed = false; + + if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die, + DW_AT_type, + &attr), &type), + &type) == 0) + { + Dwarf_Word val; + *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding, + &attr), &val) == 0 + && (val == DW_ATE_signed || val == DW_ATE_signed_char)); + + if (dwarf_aggregate_size (&type, &val) == 0) + *bytes = val; + } +} + +struct attrcb_args +{ + Dwfl_Module *dwflmod; + Dwarf *dbg; + Dwarf_Die *dies; + int level; + bool silent; + bool is_split; + unsigned int version; + unsigned int addrsize; + unsigned int offset_size; + struct Dwarf_CU *cu; +}; + + +static int +attr_callback (Dwarf_Attribute *attrp, void *arg) +{ + struct attrcb_args *cbargs = (struct attrcb_args *) arg; + const int level = cbargs->level; + Dwarf_Die *die = &cbargs->dies[level]; + bool is_split = cbargs->is_split; + + unsigned int attr = dwarf_whatattr (attrp); + if (unlikely (attr == 0)) + { + if (!cbargs->silent) + error (0, 0, _("DIE [%" PRIx64 "] " + "cannot get attribute code: %s"), + dwarf_dieoffset (die), dwarf_errmsg (-1)); + return DWARF_CB_ABORT; + } + + unsigned int form = dwarf_whatform (attrp); + if (unlikely (form == 0)) + { + if (!cbargs->silent) + error (0, 0, _("DIE [%" PRIx64 "] " + "cannot get attribute form: %s"), + dwarf_dieoffset (die), dwarf_errmsg (-1)); + return DWARF_CB_ABORT; + } + + switch (form) + { + case DW_FORM_addr: + case DW_FORM_addrx: + case DW_FORM_addrx1: + case DW_FORM_addrx2: + case DW_FORM_addrx3: + case DW_FORM_addrx4: + case DW_FORM_GNU_addr_index: + if (!cbargs->silent) + { + Dwarf_Addr addr; + if (unlikely (dwarf_formaddr (attrp, &addr) != 0)) + { + attrval_out: + if (!cbargs->silent) + error (0, 0, _("DIE [%" PRIx64 "] " + "cannot get attribute '%s' (%s) value: " + "%s"), + dwarf_dieoffset (die), + dwarf_attr_name (attr), + dwarf_form_name (form), + dwarf_errmsg (-1)); + /* Don't ABORT, it might be other attributes can be resolved. */ + return DWARF_CB_OK; + } + if (form != DW_FORM_addr ) + { + Dwarf_Word word; + if (dwarf_formudata (attrp, &word) != 0) + goto attrval_out; + printf (" %*s%-20s (%s) [%" PRIx64 "] ", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), word); + } + else + printf (" %*s%-20s (%s) ", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form)); + print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr); + printf ("\n"); + } + break; + + case DW_FORM_indirect: + case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + case DW_FORM_string: + case DW_FORM_GNU_strp_alt: + case DW_FORM_GNU_str_index: + if (cbargs->silent) + break; + const char *str = dwarf_formstring (attrp); + if (unlikely (str == NULL)) + goto attrval_out; + printf (" %*s%-20s (%s) \"%s\"\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), str); + break; + + case DW_FORM_ref_addr: + case DW_FORM_ref_udata: + case DW_FORM_ref8: + case DW_FORM_ref4: + case DW_FORM_ref2: + case DW_FORM_ref1: + case DW_FORM_GNU_ref_alt: + case DW_FORM_ref_sup4: + case DW_FORM_ref_sup8: + if (cbargs->silent) + break; + Dwarf_Die ref; + if (unlikely (dwarf_formref_die (attrp, &ref) == NULL)) + goto attrval_out; + + printf (" %*s%-20s (%s) ", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form)); + if (is_split) + printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref)); + else + printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref)); + break; + + case DW_FORM_ref_sig8: + if (cbargs->silent) + break; + printf (" %*s%-20s (%s) {%6" PRIx64 "}\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), + (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp)); + break; + + case DW_FORM_sec_offset: + case DW_FORM_rnglistx: + case DW_FORM_loclistx: + case DW_FORM_implicit_const: + case DW_FORM_udata: + case DW_FORM_sdata: + case DW_FORM_data8: /* Note no data16 here, we see that as block. */ + case DW_FORM_data4: + case DW_FORM_data2: + case DW_FORM_data1:; + Dwarf_Word num; + if (unlikely (dwarf_formudata (attrp, &num) != 0)) + goto attrval_out; + + const char *valuestr = NULL; + bool as_hex_id = false; + switch (attr) + { + /* This case can take either a constant or a loclistptr. */ + case DW_AT_data_member_location: + if (form != DW_FORM_sec_offset + && (cbargs->version >= 4 + || (form != DW_FORM_data4 && form != DW_FORM_data8))) + { + if (!cbargs->silent) + printf (" %*s%-20s (%s) %" PRIuMAX "\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); + return DWARF_CB_OK; + } + FALLTHROUGH; + + /* These cases always take a loclist[ptr] and no constant. */ + case DW_AT_location: + case DW_AT_data_location: + case DW_AT_vtable_elem_location: + case DW_AT_string_length: + case DW_AT_use_location: + case DW_AT_frame_base: + case DW_AT_return_addr: + case DW_AT_static_link: + case DW_AT_segment: + case DW_AT_GNU_call_site_value: + case DW_AT_GNU_call_site_data_value: + case DW_AT_GNU_call_site_target: + case DW_AT_GNU_call_site_target_clobbered: + case DW_AT_GNU_locviews: + { + bool nlpt; + if (cbargs->cu->version < 5) + { + if (! cbargs->is_split) + { + nlpt = notice_listptr (section_loc, &known_locsptr, + cbargs->addrsize, + cbargs->offset_size, + cbargs->cu, num, attr); + } + else + nlpt = true; + } + else + { + /* Only register for a real section offset. Otherwise + it is a DW_FORM_loclistx which is just an index + number and we should already have registered the + section offset for the index when we saw the + DW_AT_loclists_base CU attribute. */ + if (form == DW_FORM_sec_offset) + nlpt = notice_listptr (section_loc, &known_loclistsptr, + cbargs->addrsize, cbargs->offset_size, + cbargs->cu, num, attr); + else + nlpt = true; + + } + + if (!cbargs->silent) + { + if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset) + printf (" %*s%-20s (%s) location list [%6" + PRIxMAX "]%s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num, + nlpt ? "" : " "); + else + printf (" %*s%-20s (%s) location index [%6" + PRIxMAX "]\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); + } + } + return DWARF_CB_OK; + + case DW_AT_loclists_base: + { + bool nlpt = notice_listptr (section_loc, &known_loclistsptr, + cbargs->addrsize, cbargs->offset_size, + cbargs->cu, num, attr); + + if (!cbargs->silent) + printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num, + nlpt ? "" : " "); + } + return DWARF_CB_OK; + + case DW_AT_ranges: + case DW_AT_start_scope: + { + bool nlpt; + if (cbargs->cu->version < 5) + nlpt = notice_listptr (section_ranges, &known_rangelistptr, + cbargs->addrsize, cbargs->offset_size, + cbargs->cu, num, attr); + else + { + /* Only register for a real section offset. Otherwise + it is a DW_FORM_rangelistx which is just an index + number and we should already have registered the + section offset for the index when we saw the + DW_AT_rnglists_base CU attribute. */ + if (form == DW_FORM_sec_offset) + nlpt = notice_listptr (section_ranges, &known_rnglistptr, + cbargs->addrsize, cbargs->offset_size, + cbargs->cu, num, attr); + else + nlpt = true; + } + + if (!cbargs->silent) + { + if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset) + printf (" %*s%-20s (%s) range list [%6" + PRIxMAX "]%s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num, + nlpt ? "" : " "); + else + printf (" %*s%-20s (%s) range index [%6" + PRIxMAX "]\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); + } + } + return DWARF_CB_OK; + + case DW_AT_rnglists_base: + { + bool nlpt = notice_listptr (section_ranges, &known_rnglistptr, + cbargs->addrsize, cbargs->offset_size, + cbargs->cu, num, attr); + if (!cbargs->silent) + printf (" %*s%-20s (%s) range list [%6" + PRIxMAX "]%s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num, + nlpt ? "" : " "); + } + return DWARF_CB_OK; + + case DW_AT_addr_base: + case DW_AT_GNU_addr_base: + { + bool addrbase = notice_listptr (section_addr, &known_addrbases, + cbargs->addrsize, + cbargs->offset_size, + cbargs->cu, num, attr); + if (!cbargs->silent) + printf (" %*s%-20s (%s) address base [%6" + PRIxMAX "]%s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num, + addrbase ? "" : " "); + } + return DWARF_CB_OK; + + case DW_AT_str_offsets_base: + { + bool stroffbase = notice_listptr (section_str, &known_stroffbases, + cbargs->addrsize, + cbargs->offset_size, + cbargs->cu, num, attr); + if (!cbargs->silent) + printf (" %*s%-20s (%s) str offsets base [%6" + PRIxMAX "]%s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num, + stroffbase ? "" : " "); + } + return DWARF_CB_OK; + + case DW_AT_language: + valuestr = dwarf_lang_name (num); + break; + case DW_AT_encoding: + valuestr = dwarf_encoding_name (num); + break; + case DW_AT_accessibility: + valuestr = dwarf_access_name (num); + break; + case DW_AT_defaulted: + valuestr = dwarf_defaulted_name (num); + break; + case DW_AT_visibility: + valuestr = dwarf_visibility_name (num); + break; + case DW_AT_virtuality: + valuestr = dwarf_virtuality_name (num); + break; + case DW_AT_identifier_case: + valuestr = dwarf_identifier_case_name (num); + break; + case DW_AT_calling_convention: + valuestr = dwarf_calling_convention_name (num); + break; + case DW_AT_inline: + valuestr = dwarf_inline_name (num); + break; + case DW_AT_ordering: + valuestr = dwarf_ordering_name (num); + break; + case DW_AT_decl_file: + case DW_AT_call_file: + { + if (cbargs->silent) + break; + + /* Try to get the actual file, the current interface only + gives us full paths, but we only want to show the file + name for now. */ + Dwarf_Die cudie; + if (dwarf_cu_die (cbargs->cu, &cudie, + NULL, NULL, NULL, NULL, NULL, NULL) != NULL) + { + Dwarf_Files *files; + size_t nfiles; + if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0) + { + valuestr = dwarf_filesrc (files, num, NULL, NULL); + if (valuestr != NULL) + { + char *filename = strrchr (valuestr, '/'); + if (filename != NULL) + valuestr = filename + 1; + } + else + error (0, 0, _("invalid file (%" PRId64 "): %s"), + num, dwarf_errmsg (-1)); + } + else + error (0, 0, _("no srcfiles for CU [%" PRIx64 "]"), + dwarf_dieoffset (&cudie)); + } + else + error (0, 0, _("couldn't get DWARF CU: %s"), + dwarf_errmsg (-1)); + if (valuestr == NULL) + valuestr = "???"; + } + break; + case DW_AT_GNU_dwo_id: + as_hex_id = true; + break; + + default: + /* Nothing. */ + break; + } + + if (cbargs->silent) + break; + + /* When highpc is in constant form it is relative to lowpc. + In that case also show the address. */ + Dwarf_Addr highpc; + if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0) + { + printf (" %*s%-20s (%s) %" PRIuMAX " (", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); + print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc); + printf (")\n"); + } + else + { + if (as_hex_id) + { + printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), num); + } + else + { + Dwarf_Sword snum = 0; + bool is_signed; + int bytes = 0; + if (attr == DW_AT_const_value) + die_type_sign_bytes (die, &is_signed, &bytes); + else + is_signed = (form == DW_FORM_sdata + || form == DW_FORM_implicit_const); + + if (is_signed) + if (unlikely (dwarf_formsdata (attrp, &snum) != 0)) + goto attrval_out; + + if (valuestr == NULL) + { + printf (" %*s%-20s (%s) ", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form)); + } + else + { + printf (" %*s%-20s (%s) %s (", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), valuestr); + } + + switch (bytes) + { + case 1: + if (is_signed) + printf ("%" PRId8, (int8_t) snum); + else + printf ("%" PRIu8, (uint8_t) num); + break; + + case 2: + if (is_signed) + printf ("%" PRId16, (int16_t) snum); + else + printf ("%" PRIu16, (uint16_t) num); + break; + + case 4: + if (is_signed) + printf ("%" PRId32, (int32_t) snum); + else + printf ("%" PRIu32, (uint32_t) num); + break; + + case 8: + if (is_signed) + printf ("%" PRId64, (int64_t) snum); + else + printf ("%" PRIu64, (uint64_t) num); + break; + + default: + if (is_signed) + printf ("%" PRIdMAX, (intmax_t) snum); + else + printf ("%" PRIuMAX, (uintmax_t) num); + break; + } + + /* Make clear if we switched from a signed encoding to + an unsigned value. */ + if (attr == DW_AT_const_value + && (form == DW_FORM_sdata || form == DW_FORM_implicit_const) + && !is_signed) + printf (" (%" PRIdMAX ")", (intmax_t) num); + + if (valuestr == NULL) + printf ("\n"); + else + printf (")\n"); + } + } + break; + + case DW_FORM_flag: + if (cbargs->silent) + break; + bool flag; + if (unlikely (dwarf_formflag (attrp, &flag) != 0)) + goto attrval_out; + + printf (" %*s%-20s (%s) %s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), flag ? yes_str : no_str); + break; + + case DW_FORM_flag_present: + if (cbargs->silent) + break; + printf (" %*s%-20s (%s) %s\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), yes_str); + break; + + case DW_FORM_exprloc: + case DW_FORM_block4: + case DW_FORM_block2: + case DW_FORM_block1: + case DW_FORM_block: + case DW_FORM_data16: /* DWARF5 calls this a constant class. */ + if (cbargs->silent) + break; + Dwarf_Block block; + if (unlikely (dwarf_formblock (attrp, &block) != 0)) + goto attrval_out; + + printf (" %*s%-20s (%s) ", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form)); + + switch (attr) + { + default: + if (form != DW_FORM_exprloc) + { + print_block (block.length, block.data); + break; + } + FALLTHROUGH; + + case DW_AT_location: + case DW_AT_data_location: + case DW_AT_data_member_location: + case DW_AT_vtable_elem_location: + case DW_AT_string_length: + case DW_AT_use_location: + case DW_AT_frame_base: + case DW_AT_return_addr: + case DW_AT_static_link: + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_bit_size: + case DW_AT_bit_offset: + case DW_AT_bit_stride: + case DW_AT_byte_size: + case DW_AT_byte_stride: + case DW_AT_count: + case DW_AT_lower_bound: + case DW_AT_upper_bound: + case DW_AT_GNU_call_site_value: + case DW_AT_GNU_call_site_data_value: + case DW_AT_GNU_call_site_target: + case DW_AT_GNU_call_site_target_clobbered: + if (form == DW_FORM_exprloc + || (form != DW_FORM_data16 + && attrp->cu->version < 4)) /* blocks were expressions. */ + { + putchar ('\n'); + print_ops (cbargs->dwflmod, cbargs->dbg, + 12 + level * 2, 12 + level * 2, + cbargs->version, cbargs->addrsize, cbargs->offset_size, + attrp->cu, block.length, block.data); + } + else + print_block (block.length, block.data); + break; + + case DW_AT_discr_list: + if (block.length == 0) + puts (""); + else if (form != DW_FORM_data16) + { + const unsigned char *readp = block.data; + const unsigned char *readendp = readp + block.length; + + /* See if we are dealing with a signed or unsigned + values. If the parent of this variant DIE is a + variant_part then it will either have a discriminant + which points to the member which type is the + discriminant type. Or the variant_part itself has a + type representing the discriminant. */ + bool is_signed = false; + if (level > 0) + { + Dwarf_Die *parent = &cbargs->dies[level - 1]; + if (dwarf_tag (die) == DW_TAG_variant + && dwarf_tag (parent) == DW_TAG_variant_part) + { + Dwarf_Die member; + Dwarf_Attribute discr_attr; + int bytes; + if (dwarf_formref_die (dwarf_attr (parent, + DW_AT_discr, + &discr_attr), + &member) != NULL) + die_type_sign_bytes (&member, &is_signed, &bytes); + else + die_type_sign_bytes (parent, &is_signed, &bytes); + } + } + while (readp < readendp) + { + int d = (int) *readp++; + printf ("%s ", dwarf_discr_list_name (d)); + if (readp >= readendp) + goto attrval_out; + + Dwarf_Word val; + Dwarf_Sword sval; + if (d == DW_DSC_label) + { + if (is_signed) + { + get_sleb128 (sval, readp, readendp); + printf ("%" PRId64 "", sval); + } + else + { + get_uleb128 (val, readp, readendp); + printf ("%" PRIu64 "", val); + } + } + else if (d == DW_DSC_range) + { + if (is_signed) + { + get_sleb128 (sval, readp, readendp); + printf ("%" PRId64 "..", sval); + if (readp >= readendp) + goto attrval_out; + get_sleb128 (sval, readp, readendp); + printf ("%" PRId64 "", sval); + } + else + { + get_uleb128 (val, readp, readendp); + printf ("%" PRIu64 "..", val); + if (readp >= readendp) + goto attrval_out; + get_uleb128 (val, readp, readendp); + printf ("%" PRIu64 "", val); + } + } + else + { + print_block (readendp - readp, readp); + break; + } + if (readp < readendp) + printf (", "); + } + putchar ('\n'); + } + else + print_block (block.length, block.data); + break; + } + break; + + default: + if (cbargs->silent) + break; + printf (" %*s%-20s (%s) ???\n", + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form)); + break; + } + + return DWARF_CB_OK; +} + +static void +print_debug_units (Dwfl_Module *dwflmod, + Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, + Dwarf *dbg, bool debug_types) +{ + const bool silent = !(print_debug_sections & section_info) && !debug_types; + const char *secname = section_name (ebl, shdr); + + if (!silent) + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"), + elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset); + + /* If the section is empty we don't have to do anything. */ + if (!silent && shdr->sh_size == 0) + return; + + int maxdies = 20; + Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die)); + + /* New compilation unit. */ + Dwarf_Half version; + + Dwarf_Die result; + Dwarf_Off abbroffset; + uint8_t addrsize; + uint8_t offsize; + uint64_t unit_id; + Dwarf_Off subdie_off; + + int unit_res; + Dwarf_CU *cu; + Dwarf_CU cu_mem; + uint8_t unit_type; + Dwarf_Die cudie; + + /* We cheat a little because we want to see only the CUs from .debug_info + or .debug_types. We know the Dwarf_CU struct layout. Set it up at + the end of .debug_info if we want .debug_types only. Check the returned + Dwarf_CU is still in the expected section. */ + if (debug_types) + { + cu_mem.dbg = dbg; + cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size; + cu_mem.sec_idx = IDX_debug_info; + cu = &cu_mem; + } + else + cu = NULL; + + next_cu: + unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type, + &cudie, NULL); + if (unit_res == 1) + goto do_return; + + if (unit_res == -1) + { + if (!silent) + error (0, 0, _("cannot get next unit: %s"), dwarf_errmsg (-1)); + goto do_return; + } + + if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info)) + goto do_return; + + dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize, + &unit_id, &subdie_off); + + if (!silent) + { + Dwarf_Off offset = cu->start; + if (debug_types && version < 5) + { + Dwarf_Die typedie; + Dwarf_Off dieoffset; + dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, cu->start + + subdie_off, + &typedie)); + printf (_(" Type unit at offset %" PRIu64 ":\n" + " Version: %" PRIu16 + ", Abbreviation section offset: %" PRIu64 + ", Address size: %" PRIu8 + ", Offset size: %" PRIu8 + "\n Type signature: %#" PRIx64 + ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"), + (uint64_t) offset, version, abbroffset, addrsize, offsize, + unit_id, (uint64_t) subdie_off, dieoffset); + } + else + { + printf (_(" Compilation unit at offset %" PRIu64 ":\n" + " Version: %" PRIu16 + ", Abbreviation section offset: %" PRIu64 + ", Address size: %" PRIu8 + ", Offset size: %" PRIu8 "\n"), + (uint64_t) offset, version, abbroffset, addrsize, offsize); + + if (version >= 5 || (unit_type != DW_UT_compile + && unit_type != DW_UT_partial)) + { + printf (_(" Unit type: %s (%" PRIu8 ")"), + dwarf_unit_name (unit_type), unit_type); + if (unit_type == DW_UT_type + || unit_type == DW_UT_skeleton + || unit_type == DW_UT_split_compile + || unit_type == DW_UT_split_type) + printf (", Unit id: 0x%.16" PRIx64 "", unit_id); + if (unit_type == DW_UT_type + || unit_type == DW_UT_split_type) + { + Dwarf_Die typedie; + Dwarf_Off dieoffset; + dwarf_cu_info (cu, NULL, NULL, NULL, &typedie, + NULL, NULL, NULL); + dieoffset = dwarf_dieoffset (&typedie); + printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]", + subdie_off, dieoffset); + } + printf ("\n"); + } + } + } + + if (version < 2 || version > 5 + || unit_type < DW_UT_compile || unit_type > DW_UT_split_type) + { + if (!silent) + error (0, 0, _("unknown version (%d) or unit type (%d)"), + version, unit_type); + goto next_cu; + } + + struct attrcb_args args = + { + .dwflmod = dwflmod, + .silent = silent, + .version = version, + .addrsize = addrsize, + .offset_size = offsize + }; + + bool is_split = false; + int level = 0; + dies[0] = cudie; + args.cu = dies[0].cu; + args.dbg = dbg; + args.is_split = is_split; + + /* We might return here again for the split CU subdie. */ + do_cu: + do + { + Dwarf_Off offset = dwarf_dieoffset (&dies[level]); + if (unlikely (offset == (Dwarf_Off) -1)) + { + if (!silent) + error (0, 0, _("cannot get DIE offset: %s"), + dwarf_errmsg (-1)); + goto do_return; + } + + int tag = dwarf_tag (&dies[level]); + if (unlikely (tag == DW_TAG_invalid)) + { + if (!silent) + error (0, 0, _("cannot get tag of DIE at offset [%" PRIx64 + "] in section '%s': %s"), + (uint64_t) offset, secname, dwarf_errmsg (-1)); + goto do_return; + } + + if (!silent) + { + unsigned int code = dwarf_getabbrevcode (dies[level].abbrev); + if (is_split) + printf (" {%6" PRIx64 "} ", (uint64_t) offset); + else + printf (" [%6" PRIx64 "] ", (uint64_t) offset); + printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "", + dwarf_tag_name (tag), code); + } + + /* Print the attribute values. */ + args.level = level; + args.dies = dies; + (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0); + + /* Make room for the next level's DIE. */ + if (level + 1 == maxdies) + dies = (Dwarf_Die *) xrealloc (dies, + (maxdies += 10) + * sizeof (Dwarf_Die)); + + int res = dwarf_child (&dies[level], &dies[level + 1]); + if (res > 0) + { + while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1) + if (level-- == 0) + break; + + if (unlikely (res == -1)) + { + if (!silent) + error (0, 0, _("cannot get next DIE: %s\n"), + dwarf_errmsg (-1)); + goto do_return; + } + } + else if (unlikely (res < 0)) + { + if (!silent) + error (0, 0, _("cannot get next DIE: %s"), + dwarf_errmsg (-1)); + goto do_return; + } + else + ++level; + } + while (level >= 0); + + /* We might want to show the split compile unit if this was a skeleton. + We need to scan it if we are requesting printing .debug_ranges for + DWARF4 since GNU DebugFission uses "offsets" into the main ranges + section. */ + if (unit_type == DW_UT_skeleton + && ((!silent && show_split_units) + || (version < 5 && (print_debug_sections & section_ranges) != 0))) + { + Dwarf_Die subdie; + if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0 + || dwarf_tag (&subdie) == DW_TAG_invalid) + { + if (!silent) + { + Dwarf_Attribute dwo_at; + const char *dwo_name = + (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name, + &dwo_at)) + ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name, + &dwo_at)) + ?: "")); + fprintf (stderr, + "Could not find split unit '%s', id: %" PRIx64 "\n", + dwo_name, unit_id); + } + } + else + { + Dwarf_CU *split_cu = subdie.cu; + dwarf_cu_die (split_cu, &result, NULL, &abbroffset, + &addrsize, &offsize, &unit_id, &subdie_off); + Dwarf_Off offset = cu->start; + + if (!silent) + { + printf (_(" Split compilation unit at offset %" + PRIu64 ":\n" + " Version: %" PRIu16 + ", Abbreviation section offset: %" PRIu64 + ", Address size: %" PRIu8 + ", Offset size: %" PRIu8 "\n"), + (uint64_t) offset, version, abbroffset, + addrsize, offsize); + printf (_(" Unit type: %s (%" PRIu8 ")"), + dwarf_unit_name (unit_type), unit_type); + printf (", Unit id: 0x%.16" PRIx64 "", unit_id); + printf ("\n"); + } + + unit_type = DW_UT_split_compile; + is_split = true; + level = 0; + dies[0] = subdie; + args.cu = dies[0].cu; + args.dbg = split_cu->dbg; + args.is_split = is_split; + goto do_cu; + } + } + + /* And again... */ + goto next_cu; + + do_return: + free (dies); +} + +static void +print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false); +} + +static void +print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true); +} + + +static void +print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + size_t address_size + = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8; + + Dwarf_Lines *lines; + size_t nlines; + Dwarf_Off off, next_off = 0; + Dwarf_CU *cu = NULL; + while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL, + &lines, &nlines) == 0) + { + Dwarf_Die cudie; + if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie, + NULL, NULL, NULL, NULL) == 0) + printf (" CU [%" PRIx64 "] %s\n", + dwarf_dieoffset (&cudie), dwarf_diename (&cudie)); + else + { + /* DWARF5 lines can be independent of any CU, but they probably + are used by some CU. Determine the CU this block is for. */ + Dwarf_Off cuoffset; + Dwarf_Off ncuoffset = 0; + size_t hsize; + while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize, + NULL, NULL, NULL) == 0) + { + if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL) + continue; + Dwarf_Attribute stmt_list; + if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL) + continue; + Dwarf_Word lineoff; + if (dwarf_formudata (&stmt_list, &lineoff) != 0) + continue; + if (lineoff == off) + { + /* Found the CU. */ + cu = cudie.cu; + break; + } + } + + if (cu != NULL) + printf (" CU [%" PRIx64 "] %s\n", + dwarf_dieoffset (&cudie), dwarf_diename (&cudie)); + else + printf (" No CU\n"); + } + + printf (" line:col SBPE* disc isa op address" + " (Statement Block Prologue Epilogue *End)\n"); + const char *last_file = ""; + for (size_t n = 0; n < nlines; n++) + { + Dwarf_Line *line = dwarf_onesrcline (lines, n); + if (line == NULL) + { + printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1)); + continue; + } + Dwarf_Word mtime, length; + const char *file = dwarf_linesrc (line, &mtime, &length); + if (file == NULL) + { + printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1)); + last_file = ""; + } + else if (strcmp (last_file, file) != 0) + { + printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n", + file, mtime, length); + last_file = file; + } + + int lineno, colno; + bool statement, endseq, block, prologue_end, epilogue_begin; + unsigned int lineop, isa, disc; + Dwarf_Addr address; + dwarf_lineaddr (line, &address); + dwarf_lineno (line, &lineno); + dwarf_linecol (line, &colno); + dwarf_lineop_index (line, &lineop); + dwarf_linebeginstatement (line, &statement); + dwarf_lineendsequence (line, &endseq); + dwarf_lineblock (line, &block); + dwarf_lineprologueend (line, &prologue_end); + dwarf_lineepiloguebegin (line, &epilogue_begin); + dwarf_lineisa (line, &isa); + dwarf_linediscriminator (line, &disc); + + /* End sequence is special, it is one byte past. */ + printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ", + lineno, colno, + (statement ? 'S' : ' '), + (block ? 'B' : ' '), + (prologue_end ? 'P' : ' '), + (epilogue_begin ? 'E' : ' '), + (endseq ? '*' : ' '), + disc, isa, lineop); + print_dwarf_addr (dwflmod, address_size, + address - (endseq ? 1 : 0), address); + printf ("\n"); + + if (endseq) + printf("\n"); + } + } +} + + +/* Print the value of a form. + Returns new value of readp, or readendp on failure. */ +static const unsigned char * +print_form_data (Dwarf *dbg, int form, const unsigned char *readp, + const unsigned char *readendp, unsigned int offset_len, + Dwarf_Off str_offsets_base) +{ + Dwarf_Word val; + unsigned char *endp; + Elf_Data *data; + char *str; + switch (form) + { + case DW_FORM_data1: + if (readendp - readp < 1) + { + invalid_data: + error (0, 0, "invalid data"); + return readendp; + } + val = *readp++; + printf (" %" PRIx8, (unsigned int) val); + break; + + case DW_FORM_data2: + if (readendp - readp < 2) + goto invalid_data; + val = read_2ubyte_unaligned_inc (dbg, readp); + printf(" %" PRIx16, (unsigned int) val); + break; + + case DW_FORM_data4: + if (readendp - readp < 4) + goto invalid_data; + val = read_4ubyte_unaligned_inc (dbg, readp); + printf (" %" PRIx32, (unsigned int) val); + break; + + case DW_FORM_data8: + if (readendp - readp < 8) + goto invalid_data; + val = read_8ubyte_unaligned_inc (dbg, readp); + printf (" %" PRIx64, val); + break; + + case DW_FORM_sdata: + if (readendp - readp < 1) + goto invalid_data; + get_sleb128 (val, readp, readendp); + printf (" %" PRIx64, val); + break; + + case DW_FORM_udata: + if (readendp - readp < 1) + goto invalid_data; + get_uleb128 (val, readp, readendp); + printf (" %" PRIx64, val); + break; + + case DW_FORM_block: + if (readendp - readp < 1) + goto invalid_data; + get_uleb128 (val, readp, readendp); + if ((size_t) (readendp - readp) < val) + goto invalid_data; + print_bytes (val, readp); + readp += val; + break; + + case DW_FORM_block1: + if (readendp - readp < 1) + goto invalid_data; + val = *readp++; + if ((size_t) (readendp - readp) < val) + goto invalid_data; + print_bytes (val, readp); + readp += val; + break; + + case DW_FORM_block2: + if (readendp - readp < 2) + goto invalid_data; + val = read_2ubyte_unaligned_inc (dbg, readp); + if ((size_t) (readendp - readp) < val) + goto invalid_data; + print_bytes (val, readp); + readp += val; + break; + + case DW_FORM_block4: + if (readendp - readp < 4) + goto invalid_data; + val = read_4ubyte_unaligned_inc (dbg, readp); + if ((size_t) (readendp - readp) < val) + goto invalid_data; + print_bytes (val, readp); + readp += val; + break; + + case DW_FORM_data16: + if (readendp - readp < 16) + goto invalid_data; + print_bytes (16, readp); + readp += 16; + break; + + case DW_FORM_flag: + if (readendp - readp < 1) + goto invalid_data; + val = *readp++; + printf ("%s", val != 0 ? yes_str : no_str); + break; + + case DW_FORM_string: + endp = memchr (readp, '\0', readendp - readp); + if (endp == NULL) + goto invalid_data; + printf ("%s", readp); + readp = endp + 1; + break; + + case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_strp_sup: + if ((size_t) (readendp - readp) < offset_len) + goto invalid_data; + if (offset_len == 8) + val = read_8ubyte_unaligned_inc (dbg, readp); + else + val = read_4ubyte_unaligned_inc (dbg, readp); + if (form == DW_FORM_strp) + data = dbg->sectiondata[IDX_debug_str]; + else if (form == DW_FORM_line_strp) + data = dbg->sectiondata[IDX_debug_line_str]; + else /* form == DW_FORM_strp_sup */ + { + Dwarf *alt = dwarf_getalt (dbg); + data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL; + } + if (data == NULL || val >= data->d_size + || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL) + str = "???"; + else + str = (char *) data->d_buf + val; + printf ("%s (%" PRIu64 ")", str, val); + break; + + case DW_FORM_sec_offset: + if ((size_t) (readendp - readp) < offset_len) + goto invalid_data; + if (offset_len == 8) + val = read_8ubyte_unaligned_inc (dbg, readp); + else + val = read_4ubyte_unaligned_inc (dbg, readp); + printf ("[%" PRIx64 "]", val); + break; + + case DW_FORM_strx: + case DW_FORM_GNU_str_index: + if (readendp - readp < 1) + goto invalid_data; + get_uleb128 (val, readp, readendp); + strx_val: + data = dbg->sectiondata[IDX_debug_str_offsets]; + if (data == NULL + || data->d_size - str_offsets_base < val) + str = "???"; + else + { + const unsigned char *strreadp = data->d_buf + str_offsets_base + val; + const unsigned char *strreadendp = data->d_buf + data->d_size; + if ((size_t) (strreadendp - strreadp) < offset_len) + str = "???"; + else + { + Dwarf_Off idx; + if (offset_len == 8) + idx = read_8ubyte_unaligned (dbg, strreadp); + else + idx = read_4ubyte_unaligned (dbg, strreadp); + + data = dbg->sectiondata[IDX_debug_str]; + if (data == NULL || idx >= data->d_size + || memchr (data->d_buf + idx, '\0', + data->d_size - idx) == NULL) + str = "???"; + else + str = (char *) data->d_buf + idx; + } + } + printf ("%s (%" PRIu64 ")", str, val); + break; + + case DW_FORM_strx1: + if (readendp - readp < 1) + goto invalid_data; + val = *readp++; + goto strx_val; + + case DW_FORM_strx2: + if (readendp - readp < 2) + goto invalid_data; + val = read_2ubyte_unaligned_inc (dbg, readp); + goto strx_val; + + case DW_FORM_strx3: + if (readendp - readp < 3) + goto invalid_data; + val = read_3ubyte_unaligned_inc (dbg, readp); + goto strx_val; + + case DW_FORM_strx4: + if (readendp - readp < 4) + goto invalid_data; + val = read_4ubyte_unaligned_inc (dbg, readp); + goto strx_val; + + default: + error (0, 0, _("unknown form: %s"), dwarf_form_name (form)); + return readendp; + } + + return readp; +} + +static void +print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + if (decodedline) + { + print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg); + return; + } + + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + if (shdr->sh_size == 0) + return; + + /* There is no functionality in libdw to read the information in the + way it is represented here. Hardcode the decoder. */ + Elf_Data *data = (dbg->sectiondata[IDX_debug_line] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get line data section data: %s"), + elf_errmsg (-1)); + return; + } + + const unsigned char *linep = (const unsigned char *) data->d_buf; + const unsigned char *lineendp; + + while (linep + < (lineendp = (const unsigned char *) data->d_buf + data->d_size)) + { + size_t start_offset = linep - (const unsigned char *) data->d_buf; + + printf (_("\nTable at offset %zu:\n"), start_offset); + + if (unlikely (linep + 4 > lineendp)) + goto invalid_data; + Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); + unsigned int length = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (linep + 8 > lineendp)) + { + invalid_data: + error (0, 0, _("invalid data in section [%zu] '%s'"), + elf_ndxscn (scn), section_name (ebl, shdr)); + return; + } + unit_length = read_8ubyte_unaligned_inc (dbg, linep); + length = 8; + } + + /* Check whether we have enough room in the section. */ + if (unlikely (unit_length > (size_t) (lineendp - linep))) + goto invalid_data; + lineendp = linep + unit_length; + + /* The next element of the header is the version identifier. */ + if ((size_t) (lineendp - linep) < 2) + goto invalid_data; + uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); + + size_t address_size + = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8; + unsigned char segment_selector_size = 0; + if (version > 4) + { + if ((size_t) (lineendp - linep) < 2) + goto invalid_data; + address_size = *linep++; + segment_selector_size = *linep++; + } + + /* Next comes the header length. */ + Dwarf_Word header_length; + if (length == 4) + { + if ((size_t) (lineendp - linep) < 4) + goto invalid_data; + header_length = read_4ubyte_unaligned_inc (dbg, linep); + } + else + { + if ((size_t) (lineendp - linep) < 8) + goto invalid_data; + header_length = read_8ubyte_unaligned_inc (dbg, linep); + } + + /* Next the minimum instruction length. */ + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + uint_fast8_t minimum_instr_len = *linep++; + + /* Next the maximum operations per instruction, in version 4 format. */ + uint_fast8_t max_ops_per_instr; + if (version < 4) + max_ops_per_instr = 1; + else + { + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + max_ops_per_instr = *linep++; + } + + /* We need at least 4 more bytes. */ + if ((size_t) (lineendp - linep) < 4) + goto invalid_data; + + /* Then the flag determining the default value of the is_stmt + register. */ + uint_fast8_t default_is_stmt = *linep++; + + /* Now the line base. */ + int_fast8_t line_base = *linep++; + + /* And the line range. */ + uint_fast8_t line_range = *linep++; + + /* The opcode base. */ + uint_fast8_t opcode_base = *linep++; + + /* Print what we got so far. */ + printf (_("\n" + " Length: %" PRIu64 "\n" + " DWARF version: %" PRIuFAST16 "\n" + " Prologue length: %" PRIu64 "\n" + " Address size: %zd\n" + " Segment selector size: %zd\n" + " Min instruction length: %" PRIuFAST8 "\n" + " Max operations per instruction: %" PRIuFAST8 "\n" + " Initial value if 'is_stmt': %" PRIuFAST8 "\n" + " Line base: %" PRIdFAST8 "\n" + " Line range: %" PRIuFAST8 "\n" + " Opcode base: %" PRIuFAST8 "\n" + "\n" + "Opcodes:\n"), + (uint64_t) unit_length, version, (uint64_t) header_length, + address_size, (size_t) segment_selector_size, + minimum_instr_len, max_ops_per_instr, + default_is_stmt, line_base, + line_range, opcode_base); + + if (version < 2 || version > 5) + { + error (0, 0, _("cannot handle .debug_line version: %u\n"), + (unsigned int) version); + linep = lineendp; + continue; + } + + if (address_size != 4 && address_size != 8) + { + error (0, 0, _("cannot handle address size: %u\n"), + (unsigned int) address_size); + linep = lineendp; + continue; + } + + if (segment_selector_size != 0) + { + error (0, 0, _("cannot handle segment selector size: %u\n"), + (unsigned int) segment_selector_size); + linep = lineendp; + continue; + } + + if (unlikely (linep + opcode_base - 1 >= lineendp)) + { + invalid_unit: + error (0, 0, + _("invalid data at offset %tu in section [%zu] '%s'"), + linep - (const unsigned char *) data->d_buf, + elf_ndxscn (scn), section_name (ebl, shdr)); + linep = lineendp; + continue; + } + int opcode_base_l10 = 1; + unsigned int tmp = opcode_base; + while (tmp > 10) + { + tmp /= 10; + ++opcode_base_l10; + } + const uint8_t *standard_opcode_lengths = linep - 1; + for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt) + printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n", + " [%*" PRIuFAST8 "] %hhu arguments\n", + (int) linep[cnt - 1]), + opcode_base_l10, cnt, linep[cnt - 1]); + linep += opcode_base - 1; + + if (unlikely (linep >= lineendp)) + goto invalid_unit; + + Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL); + + puts (_("\nDirectory table:")); + if (version > 4) + { + struct encpair { uint16_t desc; uint16_t form; }; + struct encpair enc[256]; + + printf (_(" [")); + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + unsigned char directory_entry_format_count = *linep++; + for (int i = 0; i < directory_entry_format_count; i++) + { + uint16_t desc, form; + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (desc, linep, lineendp); + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (form, linep, lineendp); + + enc[i].desc = desc; + enc[i].form = form; + + printf ("%s(%s)", + dwarf_line_content_description_name (desc), + dwarf_form_name (form)); + if (i + 1 < directory_entry_format_count) + printf (", "); + } + printf ("]\n"); + + uint64_t directories_count; + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (directories_count, linep, lineendp); + + if (directory_entry_format_count == 0 + && directories_count != 0) + goto invalid_data; + + for (uint64_t i = 0; i < directories_count; i++) + { + printf (" %-5" PRIu64 " ", i); + for (int j = 0; j < directory_entry_format_count; j++) + { + linep = print_form_data (dbg, enc[j].form, + linep, lineendp, length, + str_offsets_base); + if (j + 1 < directory_entry_format_count) + printf (", "); + } + printf ("\n"); + if (linep >= lineendp) + goto invalid_unit; + } + } + else + { + while (linep < lineendp && *linep != 0) + { + unsigned char *endp = memchr (linep, '\0', lineendp - linep); + if (unlikely (endp == NULL)) + goto invalid_unit; + + printf (" %s\n", (char *) linep); + + linep = endp + 1; + } + if (linep >= lineendp || *linep != 0) + goto invalid_unit; + /* Skip the final NUL byte. */ + ++linep; + } + + if (unlikely (linep >= lineendp)) + goto invalid_unit; + + puts (_("\nFile name table:")); + if (version > 4) + { + struct encpair { uint16_t desc; uint16_t form; }; + struct encpair enc[256]; + + printf (_(" [")); + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + unsigned char file_name_format_count = *linep++; + for (int i = 0; i < file_name_format_count; i++) + { + uint64_t desc, form; + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (desc, linep, lineendp); + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (form, linep, lineendp); + + if (! libdw_valid_user_form (form)) + goto invalid_data; + + enc[i].desc = desc; + enc[i].form = form; + + printf ("%s(%s)", + dwarf_line_content_description_name (desc), + dwarf_form_name (form)); + if (i + 1 < file_name_format_count) + printf (", "); + } + printf ("]\n"); + + uint64_t file_name_count; + if ((size_t) (lineendp - linep) < 1) + goto invalid_data; + get_uleb128 (file_name_count, linep, lineendp); + + if (file_name_format_count == 0 + && file_name_count != 0) + goto invalid_data; + + for (uint64_t i = 0; i < file_name_count; i++) + { + printf (" %-5" PRIu64 " ", i); + for (int j = 0; j < file_name_format_count; j++) + { + linep = print_form_data (dbg, enc[j].form, + linep, lineendp, length, + str_offsets_base); + if (j + 1 < file_name_format_count) + printf (", "); + } + printf ("\n"); + if (linep > lineendp) + goto invalid_unit; + } + } + else + { + puts (_(" Entry Dir Time Size Name")); + for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt) + { + /* First comes the file name. */ + char *fname = (char *) linep; + unsigned char *endp = memchr (fname, '\0', lineendp - linep); + if (unlikely (endp == NULL)) + goto invalid_unit; + linep = endp + 1; + + /* Then the index. */ + unsigned int diridx; + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (diridx, linep, lineendp); + + /* Next comes the modification time. */ + unsigned int mtime; + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (mtime, linep, lineendp); + + /* Finally the length of the file. */ + unsigned int fsize; + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (fsize, linep, lineendp); + + printf (" %-5u %-5u %-9u %-9u %s\n", + cnt, diridx, mtime, fsize, fname); + } + if (linep >= lineendp || *linep != '\0') + goto invalid_unit; + /* Skip the final NUL byte. */ + ++linep; + } + + if (linep == lineendp) + { + puts (_("\nNo line number statements.")); + return; + } + + puts (_("\nLine number statements:")); + Dwarf_Word address = 0; + unsigned int op_index = 0; + size_t line = 1; + uint_fast8_t is_stmt = default_is_stmt; + + /* Apply the "operation advance" from a special opcode + or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ + unsigned int op_addr_advance; + inline void advance_pc (unsigned int op_advance) + { + op_addr_advance = minimum_instr_len * ((op_index + op_advance) + / max_ops_per_instr); + address += op_addr_advance; + op_index = (op_index + op_advance) % max_ops_per_instr; + } + + if (max_ops_per_instr == 0) + { + error (0, 0, + _("invalid maximum operations per instruction is zero")); + linep = lineendp; + continue; + } + + while (linep < lineendp) + { + size_t offset = linep - (const unsigned char *) data->d_buf; + unsigned int u128; + int s128; + + /* Read the opcode. */ + unsigned int opcode = *linep++; + + printf (" [%6" PRIx64 "]", (uint64_t)offset); + /* Is this a special opcode? */ + if (likely (opcode >= opcode_base)) + { + if (unlikely (line_range == 0)) + goto invalid_unit; + + /* Yes. Handling this is quite easy since the opcode value + is computed with + + opcode = (desired line increment - line_base) + + (line_range * address advance) + opcode_base + */ + int line_increment = (line_base + + (opcode - opcode_base) % line_range); + + /* Perform the increments. */ + line += line_increment; + advance_pc ((opcode - opcode_base) / line_range); + + printf (_(" special opcode %u: address+%u = "), + opcode, op_addr_advance); + print_dwarf_addr (dwflmod, 0, address, address); + if (op_index > 0) + printf (_(", op_index = %u, line%+d = %zu\n"), + op_index, line_increment, line); + else + printf (_(", line%+d = %zu\n"), + line_increment, line); + } + else if (opcode == 0) + { + /* This an extended opcode. */ + if (unlikely (linep + 2 > lineendp)) + goto invalid_unit; + + /* The length. */ + unsigned int len = *linep++; + + if (unlikely (linep + len > lineendp)) + goto invalid_unit; + + /* The sub-opcode. */ + opcode = *linep++; + + printf (_(" extended opcode %u: "), opcode); + + switch (opcode) + { + case DW_LNE_end_sequence: + puts (_(" end of sequence")); + + /* Reset the registers we care about. */ + address = 0; + op_index = 0; + line = 1; + is_stmt = default_is_stmt; + break; + + case DW_LNE_set_address: + op_index = 0; + if (unlikely ((size_t) (lineendp - linep) < address_size)) + goto invalid_unit; + if (address_size == 4) + address = read_4ubyte_unaligned_inc (dbg, linep); + else + address = read_8ubyte_unaligned_inc (dbg, linep); + { + printf (_(" set address to ")); + print_dwarf_addr (dwflmod, 0, address, address); + printf ("\n"); + } + break; + + case DW_LNE_define_file: + { + char *fname = (char *) linep; + unsigned char *endp = memchr (linep, '\0', + lineendp - linep); + if (unlikely (endp == NULL)) + goto invalid_unit; + linep = endp + 1; + + unsigned int diridx; + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (diridx, linep, lineendp); + Dwarf_Word mtime; + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (mtime, linep, lineendp); + Dwarf_Word filelength; + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (filelength, linep, lineendp); + + printf (_("\ + define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"), + diridx, (uint64_t) mtime, (uint64_t) filelength, + fname); + } + break; + + case DW_LNE_set_discriminator: + /* Takes one ULEB128 parameter, the discriminator. */ + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 1)) + goto invalid_unit; + + get_uleb128 (u128, linep, lineendp); + printf (_(" set discriminator to %u\n"), u128); + break; + + default: + /* Unknown, ignore it. */ + puts (_(" unknown opcode")); + linep += len - 1; + break; + } + } + else if (opcode <= DW_LNS_set_isa) + { + /* This is a known standard opcode. */ + switch (opcode) + { + case DW_LNS_copy: + /* Takes no argument. */ + puts (_(" copy")); + break; + + case DW_LNS_advance_pc: + /* Takes one uleb128 parameter which is added to the + address. */ + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (u128, linep, lineendp); + advance_pc (u128); + { + printf (_(" advance address by %u to "), + op_addr_advance); + print_dwarf_addr (dwflmod, 0, address, address); + if (op_index > 0) + printf (_(", op_index to %u"), op_index); + printf ("\n"); + } + break; + + case DW_LNS_advance_line: + /* Takes one sleb128 parameter which is added to the + line. */ + if (lineendp - linep < 1) + goto invalid_unit; + get_sleb128 (s128, linep, lineendp); + line += s128; + printf (_("\ + advance line by constant %d to %" PRId64 "\n"), + s128, (int64_t) line); + break; + + case DW_LNS_set_file: + /* Takes one uleb128 parameter which is stored in file. */ + if (lineendp - linep < 1) + goto invalid_unit; + get_uleb128 (u128, linep, lineendp); + printf (_(" set file to %" PRIu64 "\n"), + (uint64_t) u128); + break; + + case DW_LNS_set_column: + /* Takes one uleb128 parameter which is stored in column. */ + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 1)) + goto invalid_unit; + + get_uleb128 (u128, linep, lineendp); + printf (_(" set column to %" PRIu64 "\n"), + (uint64_t) u128); + break; + + case DW_LNS_negate_stmt: + /* Takes no argument. */ + is_stmt = 1 - is_stmt; + printf (_(" set '%s' to %" PRIuFAST8 "\n"), + "is_stmt", is_stmt); + break; + + case DW_LNS_set_basic_block: + /* Takes no argument. */ + puts (_(" set basic block flag")); + break; + + case DW_LNS_const_add_pc: + /* Takes no argument. */ + + if (unlikely (line_range == 0)) + goto invalid_unit; + + advance_pc ((255 - opcode_base) / line_range); + { + printf (_(" advance address by constant %u to "), + op_addr_advance); + print_dwarf_addr (dwflmod, 0, address, address); + if (op_index > 0) + printf (_(", op_index to %u"), op_index); + printf ("\n"); + } + break; + + case DW_LNS_fixed_advance_pc: + /* Takes one 16 bit parameter which is added to the + address. */ + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 2)) + goto invalid_unit; + + u128 = read_2ubyte_unaligned_inc (dbg, linep); + address += u128; + op_index = 0; + { + printf (_("\ + advance address by fixed value %u to \n"), + u128); + print_dwarf_addr (dwflmod, 0, address, address); + printf ("\n"); + } + break; + + case DW_LNS_set_prologue_end: + /* Takes no argument. */ + puts (_(" set prologue end flag")); + break; + + case DW_LNS_set_epilogue_begin: + /* Takes no argument. */ + puts (_(" set epilogue begin flag")); + break; + + case DW_LNS_set_isa: + /* Takes one uleb128 parameter which is stored in isa. */ + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 1)) + goto invalid_unit; + + get_uleb128 (u128, linep, lineendp); + printf (_(" set isa to %u\n"), u128); + break; + } + } + else + { + /* This is a new opcode the generator but not we know about. + Read the parameters associated with it but then discard + everything. Read all the parameters for this opcode. */ + printf (ngettext (" unknown opcode with %" PRIu8 " parameter:", + " unknown opcode with %" PRIu8 " parameters:", + standard_opcode_lengths[opcode]), + standard_opcode_lengths[opcode]); + for (int n = standard_opcode_lengths[opcode]; + n > 0 && linep < lineendp; --n) + { + get_uleb128 (u128, linep, lineendp); + if (n != standard_opcode_lengths[opcode]) + putc_unlocked (',', stdout); + printf (" %u", u128); + } + + /* Next round, ignore this opcode. */ + continue; + } + } + } + + /* There must only be one data block. */ + assert (elf_getdata (scn, data) == NULL); +} + + +static void +print_debug_loclists_section (Dwfl_Module *dwflmod, + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, + Dwarf *dbg) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_loclists content: %s"), + elf_errmsg (-1)); + return; + } + + /* For the listptr to get the base address/CU. */ + sort_listptr (&known_loclistsptr, "loclistsptr"); + size_t listptr_idx = 0; + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = ((unsigned char *) data->d_buf + + data->d_size); + while (readp < dataend) + { + if (unlikely (readp > dataend - 4)) + { + invalid_data: + error (0, 0, _("invalid data in section [%zu] '%s'"), + elf_ndxscn (scn), section_name (ebl, shdr)); + return; + } + + ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + printf (_("Table at Offset 0x%" PRIx64 ":\n\n"), + (uint64_t) offset); + + uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int offset_size = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp > dataend - 8)) + goto invalid_data; + + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + offset_size = 8; + } + printf (_(" Length: %8" PRIu64 "\n"), unit_length); + + /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8 + bytes to complete the header. And this unit cannot go beyond + the section data. */ + if (readp > dataend - 8 + || unit_length < 8 + || unit_length > (uint64_t) (dataend - readp)) + goto invalid_data; + + const unsigned char *nexthdr = readp + unit_length; + + uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" DWARF version: %8" PRIu16 "\n"), version); + + if (version != 5) + { + error (0, 0, _("Unknown version")); + goto next_table; + } + + uint8_t address_size = *readp++; + printf (_(" Address size: %8" PRIu64 "\n"), + (uint64_t) address_size); + + if (address_size != 4 && address_size != 8) + { + error (0, 0, _("unsupported address size")); + goto next_table; + } + + uint8_t segment_size = *readp++; + printf (_(" Segment size: %8" PRIu64 "\n"), + (uint64_t) segment_size); + + if (segment_size != 0) + { + error (0, 0, _("unsupported segment size")); + goto next_table; + } + + uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp); + printf (_(" Offset entries: %8" PRIu64 "\n"), + (uint64_t) offset_entry_count); + + /* We need the CU that uses this unit to get the initial base address. */ + Dwarf_Addr cu_base = 0; + struct Dwarf_CU *cu = NULL; + if (listptr_cu (&known_loclistsptr, &listptr_idx, + (Dwarf_Off) offset, + (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf), + &cu_base, &cu) + || split_dwarf_cu_base (dbg, &cu, &cu_base)) + { + Dwarf_Die cudie; + if (dwarf_cu_die (cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf (_(" Unknown CU base: ")); + else + printf (_(" CU [%6" PRIx64 "] base: "), + dwarf_dieoffset (&cudie)); + print_dwarf_addr (dwflmod, address_size, cu_base, cu_base); + printf ("\n"); + } + else + printf (_(" Not associated with a CU.\n")); + + printf ("\n"); + + const unsigned char *offset_array_start = readp; + if (offset_entry_count > 0) + { + uint64_t max_entries = (unit_length - 8) / offset_size; + if (offset_entry_count > max_entries) + { + error (0, 0, + _("too many offset entries for unit length")); + offset_entry_count = max_entries; + } + + printf (_(" Offsets starting at 0x%" PRIx64 ":\n"), + (uint64_t) (offset_array_start + - (unsigned char *) data->d_buf)); + for (uint32_t idx = 0; idx < offset_entry_count; idx++) + { + printf (" [%6" PRIu32 "] ", idx); + if (offset_size == 4) + { + uint32_t off = read_4ubyte_unaligned_inc (dbg, readp); + printf ("0x%" PRIx32 "\n", off); + } + else + { + uint64_t off = read_8ubyte_unaligned_inc (dbg, readp); + printf ("0x%" PRIx64 "\n", off); + } + } + printf ("\n"); + } + + Dwarf_Addr base = cu_base; + bool start_of_list = true; + while (readp < nexthdr) + { + Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf); + if (listptr_attr (&known_loclistsptr, listptr_idx, off, + DW_AT_GNU_locviews)) + { + Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr, + &listptr_idx, off); + const unsigned char *locp = readp; + const unsigned char *locendp; + if (next_off == 0 + || next_off > (size_t) (nexthdr - ((const unsigned char *) + data->d_buf))) + locendp = nexthdr; + else + locendp = (const unsigned char *) data->d_buf + next_off; + + printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n", + (uint64_t) (readp - (unsigned char *) data->d_buf), + (uint64_t) (readp - offset_array_start)); + + while (locp < locendp) + { + uint64_t v1, v2; + get_uleb128 (v1, locp, locendp); + if (locp >= locendp) + { + printf (_(" \n")); + break; + } + get_uleb128 (v2, locp, locendp); + printf (" view pair %" PRId64 ", %" PRId64 "\n", v1, v2); + } + + printf ("\n"); + readp = (unsigned char *) locendp; + continue; + } + + uint8_t kind = *readp++; + uint64_t op1, op2, len; + + /* Skip padding. */ + if (start_of_list && kind == DW_LLE_end_of_list) + continue; + + if (start_of_list) + { + base = cu_base; + printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n", + (uint64_t) (readp - (unsigned char *) data->d_buf - 1), + (uint64_t) (readp - offset_array_start - 1)); + start_of_list = false; + } + + printf (" %s", dwarf_loc_list_encoding_name (kind)); + switch (kind) + { + case DW_LLE_end_of_list: + start_of_list = true; + printf ("\n\n"); + break; + + case DW_LLE_base_addressx: + if ((uint64_t) (nexthdr - readp) < 1) + { + invalid_entry: + error (0, 0, _("invalid loclists data")); + goto next_table; + } + get_uleb128 (op1, readp, nexthdr); + printf (" %" PRIx64 "\n", op1); + if (! print_unresolved_addresses) + { + Dwarf_Addr addr; + if (get_indexed_addr (cu, op1, &addr) != 0) + printf (" ???\n"); + else + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, addr, addr); + printf ("\n"); + } + } + break; + + case DW_LLE_startx_endx: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op1, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op2, readp, nexthdr); + printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + Dwarf_Addr addr1; + Dwarf_Addr addr2; + if (get_indexed_addr (cu, op1, &addr1) != 0 + || get_indexed_addr (cu, op2, &addr2) != 0) + { + printf (" ???..\n"); + printf (" ???\n"); + } + else + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, addr1, addr1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, + addr2 - 1, addr2); + printf ("\n"); + } + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (len, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < len) + goto invalid_entry; + print_ops (dwflmod, dbg, 8, 8, version, + address_size, offset_size, cu, len, readp); + readp += len; + break; + + case DW_LLE_startx_length: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op1, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op2, readp, nexthdr); + printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + Dwarf_Addr addr1; + Dwarf_Addr addr2; + if (get_indexed_addr (cu, op1, &addr1) != 0) + { + printf (" ???..\n"); + printf (" ???\n"); + } + else + { + addr2 = addr1 + op2; + printf (" "); + print_dwarf_addr (dwflmod, address_size, addr1, addr1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, + addr2 - 1, addr2); + printf ("\n"); + } + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (len, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < len) + goto invalid_entry; + print_ops (dwflmod, dbg, 8, 8, version, + address_size, offset_size, cu, len, readp); + readp += len; + break; + + case DW_LLE_offset_pair: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op1, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op2, readp, nexthdr); + printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + op1 += base; + op2 += base; + printf (" "); + print_dwarf_addr (dwflmod, address_size, op1, op1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, op2 - 1, op2); + printf ("\n"); + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (len, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < len) + goto invalid_entry; + print_ops (dwflmod, dbg, 8, 8, version, + address_size, offset_size, cu, len, readp); + readp += len; + break; + + case DW_LLE_default_location: + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (len, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < len) + goto invalid_entry; + print_ops (dwflmod, dbg, 8, 8, version, + address_size, offset_size, cu, len, readp); + readp += len; + break; + + case DW_LLE_base_address: + if (address_size == 4) + { + if ((uint64_t) (nexthdr - readp) < 4) + goto invalid_entry; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + if ((uint64_t) (nexthdr - readp) < 8) + goto invalid_entry; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + } + base = op1; + printf (" 0x%" PRIx64 "\n", base); + if (! print_unresolved_addresses) + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, base, base); + printf ("\n"); + } + break; + + case DW_LLE_start_end: + if (address_size == 4) + { + if ((uint64_t) (nexthdr - readp) < 8) + goto invalid_entry; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + op2 = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + if ((uint64_t) (nexthdr - readp) < 16) + goto invalid_entry; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + op2 = read_8ubyte_unaligned_inc (dbg, readp); + } + printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + printf (" "); + print_dwarf_addr (dwflmod, address_size, op1, op1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, op2 - 1, op2); + printf ("\n"); + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (len, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < len) + goto invalid_entry; + print_ops (dwflmod, dbg, 8, 8, version, + address_size, offset_size, cu, len, readp); + readp += len; + break; + + case DW_LLE_start_length: + if (address_size == 4) + { + if ((uint64_t) (nexthdr - readp) < 4) + goto invalid_entry; + op1 = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + if ((uint64_t) (nexthdr - readp) < 8) + goto invalid_entry; + op1 = read_8ubyte_unaligned_inc (dbg, readp); + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (op2, readp, nexthdr); + printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2); + if (! print_unresolved_addresses) + { + op2 = op1 + op2; + printf (" "); + print_dwarf_addr (dwflmod, address_size, op1, op1); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, op2 - 1, op2); + printf ("\n"); + } + if ((uint64_t) (nexthdr - readp) < 1) + goto invalid_entry; + get_uleb128 (len, readp, nexthdr); + if ((uint64_t) (nexthdr - readp) < len) + goto invalid_entry; + print_ops (dwflmod, dbg, 8, 8, version, + address_size, offset_size, cu, len, readp); + readp += len; + break; + + default: + goto invalid_entry; + } + } + + next_table: + if (readp != nexthdr) + { + size_t padding = nexthdr - readp; + printf (_(" %zu padding bytes\n\n"), padding); + readp = nexthdr; + } + } +} + + +static void +print_debug_loc_section (Dwfl_Module *dwflmod, + Ebl *ebl, GElf_Ehdr *ehdr, + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + Elf_Data *data = (dbg->sectiondata[IDX_debug_loc] + ?: elf_rawdata (scn, NULL)); + + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_loc content: %s"), + elf_errmsg (-1)); + return; + } + + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + sort_listptr (&known_locsptr, "loclistptr"); + size_t listptr_idx = 0; + + uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + uint_fast8_t offset_size = 4; + + bool first = true; + Dwarf_Addr base = 0; + unsigned char *readp = data->d_buf; + unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; + Dwarf_CU *last_cu = NULL; + while (readp < endp) + { + ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + Dwarf_CU *cu = last_cu; + unsigned int attr = 0; + + if (first && skip_listptr_hole (&known_locsptr, &listptr_idx, + &address_size, &offset_size, &base, + &cu, offset, &readp, endp, &attr)) + continue; + + if (last_cu != cu) + { + Dwarf_Die cudie; + if (dwarf_cu_die (cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf (_("\n Unknown CU base: ")); + else + printf (_("\n CU [%6" PRIx64 "] base: "), + dwarf_dieoffset (&cudie)); + print_dwarf_addr (dwflmod, address_size, base, base); + printf ("\n"); + } + last_cu = cu; + + if (attr == DW_AT_GNU_locviews) + { + Dwarf_Off next_off = next_listptr_offset (&known_locsptr, + &listptr_idx, offset); + const unsigned char *locp = readp; + const unsigned char *locendp; + if (next_off == 0 + || next_off > (size_t) (endp + - (const unsigned char *) data->d_buf)) + locendp = endp; + else + locendp = (const unsigned char *) data->d_buf + next_off; + + while (locp < locendp) + { + uint64_t v1, v2; + get_uleb128 (v1, locp, locendp); + if (locp >= locendp) + { + printf (_(" [%6tx] \n"), offset); + break; + } + get_uleb128 (v2, locp, locendp); + if (first) /* First view pair in a list. */ + printf (" [%6tx] ", offset); + else + printf (" "); + printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2); + first = false; + } + + first = true; + readp = (unsigned char *) locendp; + continue; + } + + /* GNU DebugFission encoded addresses as addrx. */ + bool is_debugfission = ((cu != NULL + || split_dwarf_cu_base (dbg, &cu, &base)) + && (cu->version < 5 + && cu->unit_type == DW_UT_split_compile)); + if (!is_debugfission + && unlikely (data->d_size - offset < (size_t) address_size * 2)) + { + invalid_data: + printf (_(" [%6tx] \n"), offset); + break; + } + + Dwarf_Addr begin; + Dwarf_Addr end; + bool use_base = true; + if (is_debugfission) + { + const unsigned char *locp = readp; + const unsigned char *locendp = readp + data->d_size; + if (locp >= locendp) + goto invalid_data; + + Dwarf_Word idx; + unsigned char code = *locp++; + switch (code) + { + case DW_LLE_GNU_end_of_list_entry: + begin = 0; + end = 0; + break; + + case DW_LLE_GNU_base_address_selection_entry: + if (locp >= locendp) + goto invalid_data; + begin = (Dwarf_Addr) -1; + get_uleb128 (idx, locp, locendp); + if (get_indexed_addr (cu, idx, &end) != 0) + end = idx; /* ... */ + break; + + case DW_LLE_GNU_start_end_entry: + if (locp >= locendp) + goto invalid_data; + get_uleb128 (idx, locp, locendp); + if (get_indexed_addr (cu, idx, &begin) != 0) + begin = idx; /* ... */ + if (locp >= locendp) + goto invalid_data; + get_uleb128 (idx, locp, locendp); + if (get_indexed_addr (cu, idx, &end) != 0) + end = idx; /* ... */ + use_base = false; + break; + + case DW_LLE_GNU_start_length_entry: + if (locp >= locendp) + goto invalid_data; + get_uleb128 (idx, locp, locendp); + if (get_indexed_addr (cu, idx, &begin) != 0) + begin = idx; /* ... */ + if (locendp - locp < 4) + goto invalid_data; + end = read_4ubyte_unaligned_inc (dbg, locp); + end += begin; + use_base = false; + break; + + default: + goto invalid_data; + } + + readp = (unsigned char *) locp; + } + else if (address_size == 8) + { + begin = read_8ubyte_unaligned_inc (dbg, readp); + end = read_8ubyte_unaligned_inc (dbg, readp); + } + else + { + begin = read_4ubyte_unaligned_inc (dbg, readp); + end = read_4ubyte_unaligned_inc (dbg, readp); + if (begin == (Dwarf_Addr) (uint32_t) -1) + begin = (Dwarf_Addr) -1l; + } + + if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ + { + if (first) + printf (" [%6tx] ", offset); + else + printf (" "); + puts (_("base address")); + printf (" "); + print_dwarf_addr (dwflmod, address_size, end, end); + printf ("\n"); + base = end; + first = false; + } + else if (begin == 0 && end == 0) /* End of list entry. */ + { + if (first) + printf (_(" [%6tx] empty list\n"), offset); + first = true; + } + else + { + /* We have a location expression entry. */ + uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp); + + if (first) /* First entry in a list. */ + printf (" [%6tx] ", offset); + else + printf (" "); + + printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end); + if (! print_unresolved_addresses) + { + Dwarf_Addr dab = use_base ? base + begin : begin; + Dwarf_Addr dae = use_base ? base + end : end; + printf (" "); + print_dwarf_addr (dwflmod, address_size, dab, dab); + printf ("..\n "); + print_dwarf_addr (dwflmod, address_size, dae - 1, dae); + printf ("\n"); + } + + if (endp - readp <= (ptrdiff_t) len) + { + fputs (_(" \n"), stdout); + break; + } + + print_ops (dwflmod, dbg, 11, 11, + cu != NULL ? cu->version : 3, + address_size, offset_size, cu, len, readp); + + first = false; + readp += len; + } + } +} + +struct mac_culist +{ + Dwarf_Die die; + Dwarf_Off offset; + Dwarf_Files *files; + struct mac_culist *next; +}; + + +static int +mac_compare (const void *p1, const void *p2) +{ + struct mac_culist *m1 = (struct mac_culist *) p1; + struct mac_culist *m2 = (struct mac_culist *) p2; + + if (m1->offset < m2->offset) + return -1; + if (m1->offset > m2->offset) + return 1; + return 0; +} + + +static void +print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + putc_unlocked ('\n', stdout); + + /* There is no function in libdw to iterate over the raw content of + the section but it is easy enough to do. */ + Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get macro information section data: %s"), + elf_errmsg (-1)); + return; + } + + /* Get the source file information for all CUs. */ + Dwarf_Off offset; + Dwarf_Off ncu = 0; + size_t hsize; + struct mac_culist *culist = NULL; + size_t nculist = 0; + while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0) + { + Dwarf_Die cudie; + if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL) + continue; + + Dwarf_Attribute attr; + if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL) + continue; + + Dwarf_Word macoff; + if (dwarf_formudata (&attr, &macoff) != 0) + continue; + + struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); + newp->die = cudie; + newp->offset = macoff; + newp->files = NULL; + newp->next = culist; + culist = newp; + ++nculist; + } + + /* Convert the list into an array for easier consumption. */ + struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1) + * sizeof (*cus)); + /* Add sentinel. */ + cus[nculist].offset = data->d_size; + cus[nculist].files = (Dwarf_Files *) -1l; + if (nculist > 0) + { + for (size_t cnt = nculist - 1; culist != NULL; --cnt) + { + assert (cnt < nculist); + cus[cnt] = *culist; + culist = culist->next; + } + + /* Sort the array according to the offset in the .debug_macinfo + section. Note we keep the sentinel at the end. */ + qsort (cus, nculist, sizeof (*cus), mac_compare); + } + + const unsigned char *readp = (const unsigned char *) data->d_buf; + const unsigned char *readendp = readp + data->d_size; + int level = 1; + + while (readp < readendp) + { + unsigned int opcode = *readp++; + unsigned int u128; + unsigned int u128_2; + const unsigned char *endp; + + switch (opcode) + { + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + /* For the first two opcodes the parameters are + line, string + For the latter + number, string. + We can treat these cases together. */ + get_uleb128 (u128, readp, readendp); + + endp = memchr (readp, '\0', readendp - readp); + if (unlikely (endp == NULL)) + { + printf (_("\ +%*s*** non-terminated string at end of section"), + level, ""); + return; + } + + if (opcode == DW_MACINFO_define) + printf ("%*s#define %s, line %u\n", + level, "", (char *) readp, u128); + else if (opcode == DW_MACINFO_undef) + printf ("%*s#undef %s, line %u\n", + level, "", (char *) readp, u128); + else + printf (" #vendor-ext %s, number %u\n", (char *) readp, u128); + + readp = endp + 1; + break; + + case DW_MACINFO_start_file: + /* The two parameters are line and file index, in this order. */ + get_uleb128 (u128, readp, readendp); + if (readendp - readp < 1) + { + printf (_("\ +%*s*** missing DW_MACINFO_start_file argument at end of section"), + level, ""); + return; + } + get_uleb128 (u128_2, readp, readendp); + + /* Find the CU DIE for this file. */ + size_t macoff = readp - (const unsigned char *) data->d_buf; + const char *fname = "???"; + if (macoff >= cus[0].offset && cus[0].offset != data->d_size) + { + while (macoff >= cus[1].offset && cus[1].offset != data->d_size) + ++cus; + + if (cus[0].files == NULL + && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0) + cus[0].files = (Dwarf_Files *) -1l; + + if (cus[0].files != (Dwarf_Files *) -1l) + fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL) + ?: "???"); + } + + printf ("%*sstart_file %u, [%u] %s\n", + level, "", u128, u128_2, fname); + ++level; + break; + + case DW_MACINFO_end_file: + --level; + printf ("%*send_file\n", level, ""); + /* Nothing more to do. */ + break; + + default: + // XXX gcc seems to generate files with a trailing zero. + if (unlikely (opcode != 0 || readp != readendp)) + printf ("%*s*** invalid opcode %u\n", level, "", opcode); + break; + } + } +} + + +static void +print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + putc_unlocked ('\n', stdout); + + Elf_Data *data = elf_getdata (scn, NULL); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get macro information section data: %s"), + elf_errmsg (-1)); + return; + } + + /* Get the source file information for all CUs. Uses same + datastructure as macinfo. But uses offset field to directly + match .debug_line offset. And just stored in a list. */ + Dwarf_Off offset; + Dwarf_Off ncu = 0; + size_t hsize; + struct mac_culist *culist = NULL; + size_t nculist = 0; + while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0) + { + Dwarf_Die cudie; + if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL) + continue; + + Dwarf_Attribute attr; + if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL) + continue; + + Dwarf_Word lineoff; + if (dwarf_formudata (&attr, &lineoff) != 0) + continue; + + struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); + newp->die = cudie; + newp->offset = lineoff; + newp->files = NULL; + newp->next = culist; + culist = newp; + ++nculist; + } + + const unsigned char *readp = (const unsigned char *) data->d_buf; + const unsigned char *readendp = readp + data->d_size; + + while (readp < readendp) + { + printf (_(" Offset: 0x%" PRIx64 "\n"), + (uint64_t) (readp - (const unsigned char *) data->d_buf)); + + // Header, 2 byte version, 1 byte flag, optional .debug_line offset, + // optional vendor extension macro entry table. + if (readp + 2 > readendp) + { + invalid_data: + error (0, 0, _("invalid data")); + return; + } + const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" Version: %" PRIu16 "\n"), vers); + + // Version 4 is the GNU extension for DWARF4. DWARF5 will use version + // 5 when it gets standardized. + if (vers != 4 && vers != 5) + { + printf (_(" unknown version, cannot parse section\n")); + return; + } + + if (readp + 1 > readendp) + goto invalid_data; + const unsigned char flag = *readp++; + printf (_(" Flag: 0x%" PRIx8), flag); + if (flag != 0) + { + printf (" ("); + if ((flag & 0x01) != 0) + { + printf ("offset_size"); + if ((flag & 0xFE) != 0) + printf (", "); + } + if ((flag & 0x02) != 0) + { + printf ("debug_line_offset"); + if ((flag & 0xFC) != 0) + printf (", "); + } + if ((flag & 0x04) != 0) + { + printf ("operands_table"); + if ((flag & 0xF8) != 0) + printf (", "); + } + if ((flag & 0xF8) != 0) + printf ("unknown"); + printf (")"); + } + printf ("\n"); + + unsigned int offset_len = (flag & 0x01) ? 8 : 4; + printf (_(" Offset length: %" PRIu8 "\n"), offset_len); + Dwarf_Off line_offset = -1; + if (flag & 0x02) + { + if (offset_len == 8) + line_offset = read_8ubyte_unaligned_inc (dbg, readp); + else + line_offset = read_4ubyte_unaligned_inc (dbg, readp); + printf (_(" .debug_line offset: 0x%" PRIx64 "\n"), + line_offset); + } + + struct mac_culist *cu = NULL; + if (line_offset != (Dwarf_Off) -1) + { + cu = culist; + while (cu != NULL && line_offset != cu->offset) + cu = cu->next; + } + + Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL + ? cu->die.cu + : NULL)); + + const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1]; + memset (vendor, 0, sizeof vendor); + if (flag & 0x04) + { + // 1 byte length, for each item, 1 byte opcode, uleb128 number + // of arguments, for each argument 1 byte form code. + if (readp + 1 > readendp) + goto invalid_data; + unsigned int tlen = *readp++; + printf (_(" extension opcode table, %" PRIu8 " items:\n"), + tlen); + for (unsigned int i = 0; i < tlen; i++) + { + if (readp + 1 > readendp) + goto invalid_data; + unsigned int opcode = *readp++; + printf (_(" [%" PRIx8 "]"), opcode); + if (opcode < DW_MACRO_lo_user + || opcode > DW_MACRO_hi_user) + goto invalid_data; + // Record the start of description for this vendor opcode. + // uleb128 nr args, 1 byte per arg form. + vendor[opcode - DW_MACRO_lo_user] = readp; + if (readp + 1 > readendp) + goto invalid_data; + unsigned int args = *readp++; + if (args > 0) + { + printf (_(" %" PRIu8 " arguments:"), args); + while (args > 0) + { + if (readp + 1 > readendp) + goto invalid_data; + unsigned int form = *readp++; + printf (" %s", dwarf_form_name (form)); + if (! libdw_valid_user_form (form)) + goto invalid_data; + args--; + if (args > 0) + putchar_unlocked (','); + } + } + else + printf (_(" no arguments.")); + putchar_unlocked ('\n'); + } + } + putchar_unlocked ('\n'); + + int level = 1; + if (readp + 1 > readendp) + goto invalid_data; + unsigned int opcode = *readp++; + while (opcode != 0) + { + unsigned int u128; + unsigned int u128_2; + const unsigned char *endp; + uint64_t off; + + switch (opcode) + { + case DW_MACRO_start_file: + get_uleb128 (u128, readp, readendp); + if (readp >= readendp) + goto invalid_data; + get_uleb128 (u128_2, readp, readendp); + + /* Find the CU DIE that matches this line offset. */ + const char *fname = "???"; + if (cu != NULL) + { + if (cu->files == NULL + && dwarf_getsrcfiles (&cu->die, &cu->files, + NULL) != 0) + cu->files = (Dwarf_Files *) -1l; + + if (cu->files != (Dwarf_Files *) -1l) + fname = (dwarf_filesrc (cu->files, u128_2, + NULL, NULL) ?: "???"); + } + printf ("%*sstart_file %u, [%u] %s\n", + level, "", u128, u128_2, fname); + ++level; + break; + + case DW_MACRO_end_file: + --level; + printf ("%*send_file\n", level, ""); + break; + + case DW_MACRO_define: + get_uleb128 (u128, readp, readendp); + endp = memchr (readp, '\0', readendp - readp); + if (endp == NULL) + goto invalid_data; + printf ("%*s#define %s, line %u\n", + level, "", readp, u128); + readp = endp + 1; + break; + + case DW_MACRO_undef: + get_uleb128 (u128, readp, readendp); + endp = memchr (readp, '\0', readendp - readp); + if (endp == NULL) + goto invalid_data; + printf ("%*s#undef %s, line %u\n", + level, "", readp, u128); + readp = endp + 1; + break; + + case DW_MACRO_define_strp: + get_uleb128 (u128, readp, readendp); + if (readp + offset_len > readendp) + goto invalid_data; + if (offset_len == 8) + off = read_8ubyte_unaligned_inc (dbg, readp); + else + off = read_4ubyte_unaligned_inc (dbg, readp); + printf ("%*s#define %s, line %u (indirect)\n", + level, "", dwarf_getstring (dbg, off, NULL), u128); + break; + + case DW_MACRO_undef_strp: + get_uleb128 (u128, readp, readendp); + if (readp + offset_len > readendp) + goto invalid_data; + if (offset_len == 8) + off = read_8ubyte_unaligned_inc (dbg, readp); + else + off = read_4ubyte_unaligned_inc (dbg, readp); + printf ("%*s#undef %s, line %u (indirect)\n", + level, "", dwarf_getstring (dbg, off, NULL), u128); + break; + + case DW_MACRO_import: + if (readp + offset_len > readendp) + goto invalid_data; + if (offset_len == 8) + off = read_8ubyte_unaligned_inc (dbg, readp); + else + off = read_4ubyte_unaligned_inc (dbg, readp); + printf ("%*s#include offset 0x%" PRIx64 "\n", + level, "", off); + break; + + case DW_MACRO_define_sup: + get_uleb128 (u128, readp, readendp); + if (readp + offset_len > readendp) + goto invalid_data; + printf ("%*s#define ", level, ""); + readp = print_form_data (dbg, DW_FORM_strp_sup, + readp, readendp, offset_len, + str_offsets_base); + printf (", line %u (sup)\n", u128); + break; + + case DW_MACRO_undef_sup: + get_uleb128 (u128, readp, readendp); + if (readp + offset_len > readendp) + goto invalid_data; + printf ("%*s#undef ", level, ""); + readp = print_form_data (dbg, DW_FORM_strp_sup, + readp, readendp, offset_len, + str_offsets_base); + printf (", line %u (sup)\n", u128); + break; + + case DW_MACRO_import_sup: + if (readp + offset_len > readendp) + goto invalid_data; + if (offset_len == 8) + off = read_8ubyte_unaligned_inc (dbg, readp); + else + off = read_4ubyte_unaligned_inc (dbg, readp); + // XXX Needs support for reading from supplementary object file. + printf ("%*s#include offset 0x%" PRIx64 " (sup)\n", + level, "", off); + break; + + case DW_MACRO_define_strx: + get_uleb128 (u128, readp, readendp); + if (readp + offset_len > readendp) + goto invalid_data; + printf ("%*s#define ", level, ""); + readp = print_form_data (dbg, DW_FORM_strx, + readp, readendp, offset_len, + str_offsets_base); + printf (", line %u (strx)\n", u128); + break; + + case DW_MACRO_undef_strx: + get_uleb128 (u128, readp, readendp); + if (readp + offset_len > readendp) + goto invalid_data; + printf ("%*s#undef ", level, ""); + readp = print_form_data (dbg, DW_FORM_strx, + readp, readendp, offset_len, + str_offsets_base); + printf (", line %u (strx)\n", u128); + break; + + default: + printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode); + if (opcode < DW_MACRO_lo_user + || opcode > DW_MACRO_lo_user + || vendor[opcode - DW_MACRO_lo_user] == NULL) + goto invalid_data; + + const unsigned char *op_desc; + op_desc = vendor[opcode - DW_MACRO_lo_user]; + + // Just skip the arguments, we cannot really interpret them, + // but print as much as we can. + unsigned int args = *op_desc++; + while (args > 0 && readp < readendp) + { + unsigned int form = *op_desc++; + readp = print_form_data (dbg, form, readp, readendp, + offset_len, str_offsets_base); + args--; + if (args > 0) + printf (", "); + } + putchar_unlocked ('\n'); + } + + if (readp + 1 > readendp) + goto invalid_data; + opcode = *readp++; + if (opcode == 0) + putchar_unlocked ('\n'); + } + } +} + + +/* Callback for printing global names. */ +static int +print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, + void *arg) +{ + int *np = (int *) arg; + + printf (_(" [%5d] DIE offset: %6" PRId64 + ", CU DIE offset: %6" PRId64 ", name: %s\n"), + (*np)++, global->die_offset, global->cu_offset, global->name); + + return 0; +} + + +/* Print the known exported symbols in the DWARF section '.debug_pubnames'. */ +static void +print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + int n = 0; + (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0); +} + +/* Print the content of the DWARF string section '.debug_str'. */ +static void +print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, + Dwarf *dbg __attribute__ ((unused))) +{ + Elf_Data *data = elf_rawdata (scn, NULL); + const size_t sh_size = data ? data->d_size : 0; + + /* Compute floor(log16(shdr->sh_size)). */ + GElf_Addr tmp = sh_size; + int digits = 1; + while (tmp >= 16) + { + ++digits; + tmp >>= 4; + } + digits = MAX (4, digits); + + printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" + " %*s String\n"), + elf_ndxscn (scn), + section_name (ebl, shdr), (uint64_t) shdr->sh_offset, + /* TRANS: the debugstr| prefix makes the string unique. */ + digits + 2, sgettext ("debugstr|Offset")); + + Dwarf_Off offset = 0; + while (offset < sh_size) + { + size_t len; + const char *str = (const char *) data->d_buf + offset; + const char *endp = memchr (str, '\0', sh_size - offset); + if (unlikely (endp == NULL)) + { + printf (_(" *** error, missing string terminator\n")); + break; + } + + printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str); + len = endp - str; + offset += len + 1; + } +} + +static void +print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\ +\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset); + + if (shdr->sh_size == 0) + return; + + /* We like to get the section from libdw to make sure they are relocated. */ + Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets] + ?: elf_rawdata (scn, NULL)); + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get .debug_str_offsets section data: %s"), + elf_errmsg (-1)); + return; + } + + size_t idx = 0; + sort_listptr (&known_stroffbases, "str_offsets"); + + const unsigned char *start = (const unsigned char *) data->d_buf; + const unsigned char *readp = start; + const unsigned char *readendp = ((const unsigned char *) data->d_buf + + data->d_size); + + while (readp < readendp) + { + /* Most string offset tables will have a header. For split + dwarf unit GNU DebugFission didn't add one. But they were + also only defined for split units (main or skeleton units + didn't have indirect strings). So if we don't have a + DW_AT_str_offsets_base at all and this is offset zero, then + just start printing offsets immediately, if this is a .dwo + section. */ + Dwarf_Off off = (Dwarf_Off) (readp + - (const unsigned char *) data->d_buf); + + printf ("Table at offset %" PRIx64 " ", off); + + struct listptr *listptr = get_listptr (&known_stroffbases, idx++); + const unsigned char *next_unitp = readendp; + uint8_t offset_size; + bool has_header; + if (listptr == NULL) + { + /* This can happen for .dwo files. There is only an header + in the case this is a version 5 split DWARF file. */ + Dwarf_CU *cu; + uint8_t unit_type; + if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type, + NULL, NULL) != 0) + { + error (0, 0, "Warning: Cannot find any DWARF unit."); + /* Just guess some values. */ + has_header = false; + offset_size = 4; + } + else if (off == 0 + && (unit_type == DW_UT_split_type + || unit_type == DW_UT_split_compile)) + { + has_header = cu->version > 4; + offset_size = cu->offset_size; + } + else + { + error (0, 0, + "Warning: No CU references .debug_str_offsets after %" + PRIx64, off); + has_header = cu->version > 4; + offset_size = cu->offset_size; + } + printf ("\n"); + } + else + { + /* This must be DWARF5, since GNU DebugFission didn't define + DW_AT_str_offsets_base. */ + has_header = true; + + Dwarf_Die cudie; + if (dwarf_cu_die (listptr->cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf ("Unknown CU (%s):\n", dwarf_errmsg (-1)); + else + printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie)); + } + + if (has_header) + { + uint64_t unit_length; + uint16_t version; + uint16_t padding; + + unit_length = read_4ubyte_unaligned_inc (dbg, readp); + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (readp > readendp - 8)) + { + invalid_data: + error (0, 0, "Invalid data"); + return; + } + unit_length = read_8ubyte_unaligned_inc (dbg, readp); + offset_size = 8; + } + else + offset_size = 4; + + printf ("\n"); + printf (_(" Length: %8" PRIu64 "\n"), + unit_length); + printf (_(" Offset size: %8" PRIu8 "\n"), + offset_size); + + /* We need at least 2-bytes (version) + 2-bytes (padding) = + 4 bytes to complete the header. And this unit cannot go + beyond the section data. */ + if (readp > readendp - 4 + || unit_length < 4 + || unit_length > (uint64_t) (readendp - readp)) + goto invalid_data; + + next_unitp = readp + unit_length; + + version = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" DWARF version: %8" PRIu16 "\n"), version); + + if (version != 5) + { + error (0, 0, _("Unknown version")); + goto next_unit; + } + + padding = read_2ubyte_unaligned_inc (dbg, readp); + printf (_(" Padding: %8" PRIx16 "\n"), padding); + + if (listptr != NULL + && listptr->offset != (Dwarf_Off) (readp - start)) + { + error (0, 0, "String offsets index doesn't start after header"); + goto next_unit; + } + + printf ("\n"); + } + + int digits = 1; + size_t offsets = (next_unitp - readp) / offset_size; + while (offsets >= 10) + { + ++digits; + offsets /= 10; + } + + unsigned int uidx = 0; + size_t index_offset = readp - (const unsigned char *) data->d_buf; + printf (" Offsets start at 0x%zx:\n", index_offset); + while (readp <= next_unitp - offset_size) + { + Dwarf_Word offset; + if (offset_size == 4) + offset = read_4ubyte_unaligned_inc (dbg, readp); + else + offset = read_8ubyte_unaligned_inc (dbg, readp); + const char *str = dwarf_getstring (dbg, offset, NULL); + printf (" [%*u] [%*" PRIx64 "] \"%s\"\n", + digits, uidx++, (int) offset_size * 2, offset, str ?: "???"); + } + printf ("\n"); + + if (readp != next_unitp) + error (0, 0, "extra %zd bytes at end of unit", + (size_t) (next_unitp - readp)); + + next_unit: + readp = next_unitp; + } +} + + +/* Print the content of the call frame search table section + '.eh_frame_hdr'. */ +static void +print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\ +\nCall frame search table section [%2zu] '.eh_frame_hdr':\n"), + elf_ndxscn (scn)); + + Elf_Data *data = elf_rawdata (scn, NULL); + + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get %s content: %s"), + ".eh_frame_hdr", elf_errmsg (-1)); + return; + } + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = ((unsigned char *) data->d_buf + + data->d_size); + + if (unlikely (readp + 4 > dataend)) + { + invalid_data: + error (0, 0, _("invalid data")); + return; + } + + unsigned int version = *readp++; + unsigned int eh_frame_ptr_enc = *readp++; + unsigned int fde_count_enc = *readp++; + unsigned int table_enc = *readp++; + + printf (" version: %u\n" + " eh_frame_ptr_enc: %#x ", + version, eh_frame_ptr_enc); + print_encoding_base ("", eh_frame_ptr_enc); + printf (" fde_count_enc: %#x ", fde_count_enc); + print_encoding_base ("", fde_count_enc); + printf (" table_enc: %#x ", table_enc); + print_encoding_base ("", table_enc); + + uint64_t eh_frame_ptr = 0; + if (eh_frame_ptr_enc != DW_EH_PE_omit) + { + readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr, + dbg); + if (unlikely (readp == NULL)) + goto invalid_data; + + printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr); + if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel) + printf (" (offset: %#" PRIx64 ")", + /* +4 because of the 4 byte header of the section. */ + (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr); + + putchar_unlocked ('\n'); + } + + uint64_t fde_count = 0; + if (fde_count_enc != DW_EH_PE_omit) + { + readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg); + if (unlikely (readp == NULL)) + goto invalid_data; + + printf (" fde_count: %" PRIu64 "\n", fde_count); + } + + if (fde_count == 0 || table_enc == DW_EH_PE_omit) + return; + + puts (" Table:"); + + /* Optimize for the most common case. */ + if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + while (fde_count > 0 && readp + 8 <= dataend) + { + int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp); + uint64_t initial_offset = ((uint64_t) shdr->sh_offset + + (int64_t) initial_location); + int32_t address = read_4sbyte_unaligned_inc (dbg, readp); + // XXX Possibly print symbol name or section offset for initial_offset + printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32 + " fde=[%6" PRIx64 "]\n", + initial_location, initial_offset, + address, address - (eh_frame_ptr + 4)); + } + else + while (0 && readp < dataend) + { + + } +} + + +/* Print the content of the exception handling table section + '.eh_frame_hdr'. */ +static void +print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), + Ebl *ebl __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, + GElf_Shdr *shdr __attribute__ ((unused)), + Dwarf *dbg __attribute__ ((unused))) +{ + printf (_("\ +\nException handling table section [%2zu] '.gcc_except_table':\n"), + elf_ndxscn (scn)); + + Elf_Data *data = elf_rawdata (scn, NULL); + + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get %s content: %s"), + ".gcc_except_table", elf_errmsg (-1)); + return; + } + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = readp + data->d_size; + + if (unlikely (readp + 1 > dataend)) + { + invalid_data: + error (0, 0, _("invalid data")); + return; + } + unsigned int lpstart_encoding = *readp++; + printf (_(" LPStart encoding: %#x "), lpstart_encoding); + print_encoding_base ("", lpstart_encoding); + if (lpstart_encoding != DW_EH_PE_omit) + { + uint64_t lpstart; + readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg); + printf (" LPStart: %#" PRIx64 "\n", lpstart); + } + + if (unlikely (readp + 1 > dataend)) + goto invalid_data; + unsigned int ttype_encoding = *readp++; + printf (_(" TType encoding: %#x "), ttype_encoding); + print_encoding_base ("", ttype_encoding); + const unsigned char *ttype_base = NULL; + if (ttype_encoding != DW_EH_PE_omit) + { + unsigned int ttype_base_offset; + get_uleb128 (ttype_base_offset, readp, dataend); + printf (" TType base offset: %#x\n", ttype_base_offset); + if ((size_t) (dataend - readp) > ttype_base_offset) + ttype_base = readp + ttype_base_offset; + } + + if (unlikely (readp + 1 > dataend)) + goto invalid_data; + unsigned int call_site_encoding = *readp++; + printf (_(" Call site encoding: %#x "), call_site_encoding); + print_encoding_base ("", call_site_encoding); + unsigned int call_site_table_len; + get_uleb128 (call_site_table_len, readp, dataend); + + const unsigned char *const action_table = readp + call_site_table_len; + if (unlikely (action_table > dataend)) + goto invalid_data; + unsigned int u = 0; + unsigned int max_action = 0; + while (readp < action_table) + { + if (u == 0) + puts (_("\n Call site table:")); + + uint64_t call_site_start; + readp = read_encoded (call_site_encoding, readp, dataend, + &call_site_start, dbg); + uint64_t call_site_length; + readp = read_encoded (call_site_encoding, readp, dataend, + &call_site_length, dbg); + uint64_t landing_pad; + readp = read_encoded (call_site_encoding, readp, dataend, + &landing_pad, dbg); + unsigned int action; + get_uleb128 (action, readp, dataend); + max_action = MAX (action, max_action); + printf (_(" [%4u] Call site start: %#" PRIx64 "\n" + " Call site length: %" PRIu64 "\n" + " Landing pad: %#" PRIx64 "\n" + " Action: %u\n"), + u++, call_site_start, call_site_length, landing_pad, action); + } + if (readp != action_table) + goto invalid_data; + + unsigned int max_ar_filter = 0; + if (max_action > 0) + { + puts ("\n Action table:"); + + size_t maxdata = (size_t) (dataend - action_table); + if (max_action > maxdata || maxdata - max_action < 1) + { + invalid_action_table: + fputs (_(" \n"), stdout); + return; + } + + const unsigned char *const action_table_end + = action_table + max_action + 1; + + u = 0; + do + { + int ar_filter; + get_sleb128 (ar_filter, readp, action_table_end); + if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter) + max_ar_filter = ar_filter; + int ar_disp; + if (readp >= action_table_end) + goto invalid_action_table; + get_sleb128 (ar_disp, readp, action_table_end); + + printf (" [%4u] ar_filter: % d\n" + " ar_disp: % -5d", + u, ar_filter, ar_disp); + if (abs (ar_disp) & 1) + printf (" -> [%4u]\n", u + (ar_disp + 1) / 2); + else if (ar_disp != 0) + puts (" -> ???"); + else + putchar_unlocked ('\n'); + ++u; + } + while (readp < action_table_end); + } + + if (max_ar_filter > 0 && ttype_base != NULL) + { + unsigned char dsize; + puts ("\n TType table:"); + + // XXX Not *4, size of encoding; + switch (ttype_encoding & 7) + { + case DW_EH_PE_udata2: + case DW_EH_PE_sdata2: + dsize = 2; + break; + case DW_EH_PE_udata4: + case DW_EH_PE_sdata4: + dsize = 4; + break; + case DW_EH_PE_udata8: + case DW_EH_PE_sdata8: + dsize = 8; + break; + default: + dsize = 0; + error (1, 0, _("invalid TType encoding")); + } + + if (max_ar_filter + > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize) + goto invalid_data; + + readp = ttype_base - max_ar_filter * dsize; + do + { + uint64_t ttype; + readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype, + dbg); + printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype); + } + while (readp < ttype_base); + } +} + +/* Print the content of the '.gdb_index' section. + http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html +*/ +static void +print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, + GElf_Ehdr *ehdr __attribute__ ((unused)), + Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) +{ + printf (_("\nGDB section [%2zu] '%s' at offset %#" PRIx64 + " contains %" PRId64 " bytes :\n"), + elf_ndxscn (scn), section_name (ebl, shdr), + (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size); + + Elf_Data *data = elf_rawdata (scn, NULL); + + if (unlikely (data == NULL)) + { + error (0, 0, _("cannot get %s content: %s"), + ".gdb_index", elf_errmsg (-1)); + return; + } + + // .gdb_index is always in little endian. + Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB }; + dbg = &dummy_dbg; + + const unsigned char *readp = data->d_buf; + const unsigned char *const dataend = readp + data->d_size; + + if (unlikely (readp + 4 > dataend)) + { + invalid_data: + error (0, 0, _("invalid data")); + return; + } + + int32_t vers = read_4ubyte_unaligned (dbg, readp); + printf (_(" Version: %" PRId32 "\n"), vers); + + // The only difference between version 4 and version 5 is the + // hash used for generating the table. Version 6 contains symbols + // for inlined functions, older versions didn't. Version 7 adds + // symbol kinds. Version 8 just indicates that it correctly includes + // TUs for symbols. + if (vers < 4 || vers > 8) + { + printf (_(" unknown version, cannot parse section\n")); + return; + } + + readp += 4; + if (unlikely (readp + 4 > dataend)) + goto invalid_data; + + uint32_t cu_off = read_4ubyte_unaligned (dbg, readp); + printf (_(" CU offset: %#" PRIx32 "\n"), cu_off); + + readp += 4; + if (unlikely (readp + 4 > dataend)) + goto invalid_data; + + uint32_t tu_off = read_4ubyte_unaligned (dbg, readp); + printf (_(" TU offset: %#" PRIx32 "\n"), tu_off); + + readp += 4; + if (unlikely (readp + 4 > dataend)) + goto invalid_data; + + uint32_t addr_off = read_4ubyte_unaligned (dbg, readp); + printf (_(" address offset: %#" PRIx32 "\n"), addr_off); + + readp += 4; + if (unlikely (readp + 4 > dataend)) + goto invalid_data; + + uint32_t sym_off = read_4ubyte_unaligned (dbg, readp); + printf (_(" symbol offset: %#" PRIx32 "\n"), sym_off); + + readp += 4; + if (unlikely (readp + 4 > dataend)) + goto invalid_data; + + uint32_t const_off = read_4ubyte_unaligned (dbg, readp); + printf (_(" constant offset: %#" PRIx32 "\n"), const_off); + + if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf) + < const_off)) + goto invalid_data; + + readp = data->d_buf + cu_off; + + const unsigned char *nextp = data->d_buf + tu_off; + if (tu_off >= data->d_size) + goto invalid_data; + + size_t cu_nr = (nextp - readp) / 16; + + printf (_("\n CU list at offset %#" PRIx32 + " contains %zu entries:\n"), + cu_off, cu_nr); + + size_t n = 0; + while (dataend - readp >= 16 && n < cu_nr) + { + uint64_t off = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + uint64_t len = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + printf (" [%4zu] start: %0#8" PRIx64 + ", length: %5" PRIu64 "\n", n, off, len); + n++; + } + + readp = data->d_buf + tu_off; + nextp = data->d_buf + addr_off; + if (addr_off >= data->d_size) + goto invalid_data; + + size_t tu_nr = (nextp - readp) / 24; + + printf (_("\n TU list at offset %#" PRIx32 + " contains %zu entries:\n"), + tu_off, tu_nr); + + n = 0; + while (dataend - readp >= 24 && n < tu_nr) + { + uint64_t off = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + uint64_t type = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + uint64_t sig = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + printf (" [%4zu] CU offset: %5" PRId64 + ", type offset: %5" PRId64 + ", signature: %0#8" PRIx64 "\n", n, off, type, sig); + n++; + } + + readp = data->d_buf + addr_off; + nextp = data->d_buf + sym_off; + if (sym_off >= data->d_size) + goto invalid_data; + + size_t addr_nr = (nextp - readp) / 20; + + printf (_("\n Address list at offset %#" PRIx32 + " contains %zu entries:\n"), + addr_off, addr_nr); + + n = 0; + while (dataend - readp >= 20 && n < addr_nr) + { + uint64_t low = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + uint64_t high = read_8ubyte_unaligned (dbg, readp); + readp += 8; + + uint32_t idx = read_4ubyte_unaligned (dbg, readp); + readp += 4; + + printf (" [%4zu] ", n); + print_dwarf_addr (dwflmod, 8, low, low); + printf (".."); + print_dwarf_addr (dwflmod, 8, high - 1, high); + printf (", CU index: %5" PRId32 "\n", idx); + n++; + } + + const unsigned char *const_start = data->d_buf + const_off; + if (const_off >= data->d_size) + goto invalid_data; + + readp = data->d_buf + sym_off; + nextp = const_start; + size_t sym_nr = (nextp - readp) / 8; + + printf (_("\n Symbol table at offset %#" PRIx32 + " contains %zu slots:\n"), + addr_off, sym_nr); + + n = 0; + while (dataend - readp >= 8 && n < sym_nr) + { + uint32_t name = read_4ubyte_unaligned (dbg, readp); + readp += 4; + + uint32_t vector = read_4ubyte_unaligned (dbg, readp); + readp += 4; + + if (name != 0 || vector != 0) + { + const unsigned char *sym = const_start + name; + if (unlikely ((size_t) (dataend - const_start) < name + || memchr (sym, '\0', dataend - sym) == NULL)) + goto invalid_data; + + printf (" [%4zu] symbol: %s, CUs: ", n, sym); + + const unsigned char *readcus = const_start + vector; + if (unlikely ((size_t) (dataend - const_start) < vector)) + goto invalid_data; + uint32_t cus = read_4ubyte_unaligned (dbg, readcus); + while (cus--) + { + uint32_t cu_kind, cu, kind; + bool is_static; + readcus += 4; + if (unlikely (readcus + 4 > dataend)) + goto invalid_data; + cu_kind = read_4ubyte_unaligned (dbg, readcus); + cu = cu_kind & ((1 << 24) - 1); + kind = (cu_kind >> 28) & 7; + is_static = cu_kind & (1U << 31); + if (cu > cu_nr - 1) + printf ("%" PRId32 "T", cu - (uint32_t) cu_nr); + else + printf ("%" PRId32, cu); + if (kind != 0) + { + printf (" ("); + switch (kind) + { + case 1: + printf ("type"); + break; + case 2: + printf ("var"); + break; + case 3: + printf ("func"); + break; + case 4: + printf ("other"); + break; + default: + printf ("unknown-0x%" PRIx32, kind); + break; + } + printf (":%c)", (is_static ? 'S' : 'G')); + } + if (cus > 0) + printf (", "); + } + printf ("\n"); + } + n++; + } +} + +/* Returns true and sets split DWARF CU id if there is a split compile + unit in the given Dwarf, and no non-split units are found (before it). */ +static bool +is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu) +{ + Dwarf_CU *cu = NULL; + while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0) + { + uint8_t unit_type; + if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL, + id, NULL, NULL) != 0) + return false; + + if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type) + return false; + + /* We really only care about the split compile unit, the types + should be fine and self sufficient. Also they don't have an + id that we can match with a skeleton unit. */ + if (unit_type == DW_UT_split_compile) + { + *split_cu = cu; + return true; + } + } + + return false; +} + +/* Check that there is one and only one Dwfl_Module, return in arg. */ +static int +getone_dwflmod (Dwfl_Module *dwflmod, + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + void *arg) +{ + Dwfl_Module **m = (Dwfl_Module **) arg; + if (*m != NULL) + return DWARF_CB_ABORT; + *m = dwflmod; + return DWARF_CB_OK; +} + +static void +print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr) +{ + /* Used for skeleton file, if necessary for split DWARF. */ + Dwfl *skel_dwfl = NULL; + Dwfl_Module *skel_mod = NULL; + char *skel_name = NULL; + Dwarf *split_dbg = NULL; + Dwarf_CU *split_cu = NULL; + + /* Before we start the real work get a debug context descriptor. */ + Dwarf_Addr dwbias; + Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias); + Dwarf dummy_dbg = + { + .elf = ebl->elf, + .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA] + }; + if (dbg == NULL) + { + if ((print_debug_sections & ~(section_exception|section_frame)) != 0) + error (0, 0, _("cannot get debug context descriptor: %s"), + dwfl_errmsg (-1)); + dbg = &dummy_dbg; + } + else + { + /* If we are asked about a split dwarf (.dwo) file, use the user + provided, or find the corresponding skeleton file. If we got + a skeleton file, replace the given dwflmod and dbg, with one + derived from the skeleton file to provide enough context. */ + uint64_t split_id; + if (is_split_dwarf (dbg, &split_id, &split_cu)) + { + if (dwarf_skeleton != NULL) + skel_name = strdup (dwarf_skeleton); + else + { + /* Replace file.dwo with file.o and see if that matches. */ + const char *fname; + dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, + &fname, NULL); + if (fname != NULL) + { + size_t flen = strlen (fname); + if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0) + { + skel_name = strdup (fname); + if (skel_name != NULL) + { + skel_name[flen - 3] = 'o'; + skel_name[flen - 2] = '\0'; + } + } + } + } + + if (skel_name != NULL) + { + int skel_fd = open (skel_name, O_RDONLY); + if (skel_fd == -1) + fprintf (stderr, "Warning: Couldn't open DWARF skeleton file" + " '%s'\n", skel_name); + else + skel_dwfl = create_dwfl (skel_fd, skel_name); + + if (skel_dwfl != NULL) + { + if (dwfl_getmodules (skel_dwfl, &getone_dwflmod, + &skel_mod, 0) != 0) + { + fprintf (stderr, "Warning: Bad DWARF skeleton," + " multiple modules '%s'\n", skel_name); + dwfl_end (skel_dwfl); + skel_mod = NULL; + } + } + else if (skel_fd != -1) + fprintf (stderr, "Warning: Couldn't create skeleton dwfl for" + " '%s': %s\n", skel_name, dwfl_errmsg (-1)); + + if (skel_mod != NULL) + { + Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias); + if (skel_dbg != NULL) + { + /* First check the skeleton CU DIE, only fetch + the split DIE if we know the id matches to + not unnecessary search for any split DIEs we + don't need. */ + Dwarf_CU *cu = NULL; + while (dwarf_get_units (skel_dbg, cu, &cu, + NULL, NULL, NULL, NULL) == 0) + { + uint8_t unit_type; + uint64_t skel_id; + if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL, + &skel_id, NULL, NULL) == 0 + && unit_type == DW_UT_skeleton + && split_id == skel_id) + { + Dwarf_Die subdie; + if (dwarf_cu_info (cu, NULL, NULL, NULL, + &subdie, + NULL, NULL, NULL) == 0 + && dwarf_tag (&subdie) != DW_TAG_invalid) + { + split_dbg = dwarf_cu_getdwarf (subdie.cu); + if (split_dbg == NULL) + fprintf (stderr, + "Warning: Couldn't get split_dbg:" + " %s\n", dwarf_errmsg (-1)); + break; + } + else + { + /* Everything matches up, but not + according to libdw. Which means + the user knew better. So... + Terrible hack... We can never + destroy the underlying dwfl + because it would free the wrong + Dwarfs... So we leak memory...*/ + if (cu->split == NULL + && dwarf_skeleton != NULL) + { + do_not_close_dwfl = true; + __libdw_link_skel_split (cu, split_cu); + split_dbg = dwarf_cu_getdwarf (split_cu); + break; + } + else + fprintf (stderr, "Warning: Couldn't get" + " skeleton subdie: %s\n", + dwarf_errmsg (-1)); + } + } + } + if (split_dbg == NULL) + fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id); + } + else + fprintf (stderr, "Warning: Couldn't get skeleton DWARF:" + " %s\n", dwfl_errmsg (-1)); + } + } + + if (split_dbg != NULL) + { + dbg = split_dbg; + dwflmod = skel_mod; + } + else if (skel_name == NULL) + fprintf (stderr, + "Warning: split DWARF file, but no skeleton found.\n"); + } + else if (dwarf_skeleton != NULL) + fprintf (stderr, "Warning: DWARF skeleton given," + " but not a split DWARF file\n"); + } + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + /* If the .debug_info section is listed as implicitly required then + we must make sure to handle it before handling any other debug + section. Various other sections depend on the CU DIEs being + scanned (silently) first. */ + bool implicit_info = (implicit_debug_sections & section_info) != 0; + bool explicit_info = (print_debug_sections & section_info) != 0; + if (implicit_info) + { + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr != NULL && shdr->sh_type == SHT_PROGBITS) + { + const char *name = elf_strptr (ebl->elf, shstrndx, + shdr->sh_name); + if (name == NULL) + continue; + + if (strcmp (name, ".debug_info") == 0 + || strcmp (name, ".debug_info.dwo") == 0 + || strcmp (name, ".zdebug_info") == 0 + || strcmp (name, ".zdebug_info.dwo") == 0 + || strcmp (name, ".gnu.debuglto_.debug_info") == 0) + { + print_debug_info_section (dwflmod, ebl, ehdr, + scn, shdr, dbg); + break; + } + } + } + print_debug_sections &= ~section_info; + implicit_debug_sections &= ~section_info; + } + + /* Look through all the sections for the debugging sections to print. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr != NULL && shdr->sh_type == SHT_PROGBITS) + { + static const struct + { + const char *name; + enum section_e bitmask; + void (*fp) (Dwfl_Module *, Ebl *, + GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *); + } debug_sections[] = + { +#define NEW_SECTION(name) \ + { ".debug_" #name, section_##name, print_debug_##name##_section } + NEW_SECTION (abbrev), + NEW_SECTION (addr), + NEW_SECTION (aranges), + NEW_SECTION (frame), + NEW_SECTION (info), + NEW_SECTION (types), + NEW_SECTION (line), + NEW_SECTION (loc), + /* loclists is loc for DWARF5. */ + { ".debug_loclists", section_loc, + print_debug_loclists_section }, + NEW_SECTION (pubnames), + NEW_SECTION (str), + /* A DWARF5 specialised debug string section. */ + { ".debug_line_str", section_str, + print_debug_str_section }, + /* DWARF5 string offsets table. */ + { ".debug_str_offsets", section_str, + print_debug_str_offsets_section }, + NEW_SECTION (macinfo), + NEW_SECTION (macro), + NEW_SECTION (ranges), + /* rnglists is ranges for DWARF5. */ + { ".debug_rnglists", section_ranges, + print_debug_rnglists_section }, + { ".eh_frame", section_frame | section_exception, + print_debug_frame_section }, + { ".eh_frame_hdr", section_frame | section_exception, + print_debug_frame_hdr_section }, + { ".gcc_except_table", section_frame | section_exception, + print_debug_exception_table }, + { ".gdb_index", section_gdb_index, print_gdb_index_section } + }; + const int ndebug_sections = (sizeof (debug_sections) + / sizeof (debug_sections[0])); + const char *name = elf_strptr (ebl->elf, shstrndx, + shdr->sh_name); + if (name == NULL) + continue; + + int n; + for (n = 0; n < ndebug_sections; ++n) + { + size_t dbglen = strlen (debug_sections[n].name); + size_t scnlen = strlen (name); + if ((strncmp (name, debug_sections[n].name, dbglen) == 0 + && (dbglen == scnlen + || (scnlen == dbglen + 4 + && strstr (name, ".dwo") == name + dbglen))) + || (name[0] == '.' && name[1] == 'z' + && debug_sections[n].name[1] == 'd' + && strncmp (&name[2], &debug_sections[n].name[1], + dbglen - 1) == 0 + && (scnlen == dbglen + 1 + || (scnlen == dbglen + 5 + && strstr (name, ".dwo") == name + dbglen + 1))) + || (scnlen > 14 /* .gnu.debuglto_ prefix. */ + && startswith (name, ".gnu.debuglto_") + && strcmp (&name[14], debug_sections[n].name) == 0) +) + { + if ((print_debug_sections | implicit_debug_sections) + & debug_sections[n].bitmask) + debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg); + break; + } + } + } + } + + dwfl_end (skel_dwfl); + free (skel_name); + + /* Turn implicit and/or explicit back on in case we go over another file. */ + if (implicit_info) + implicit_debug_sections |= section_info; + if (explicit_info) + print_debug_sections |= section_info; + + reset_listptr (&known_locsptr); + reset_listptr (&known_loclistsptr); + reset_listptr (&known_rangelistptr); + reset_listptr (&known_rnglistptr); + reset_listptr (&known_addrbases); + reset_listptr (&known_stroffbases); +} + + +#define ITEM_INDENT 4 +#define WRAP_COLUMN 75 + +/* Print "NAME: FORMAT", wrapping when output text would make the line + exceed WRAP_COLUMN. Unpadded numbers look better for the core items + but this function is also used for registers which should be printed + aligned. Fortunately registers output uses fixed fields width (such + as %11d) for the alignment. + + Line breaks should not depend on the particular values although that + may happen in some cases of the core items. */ + +static unsigned int +__attribute__ ((format (printf, 6, 7))) +print_core_item (unsigned int colno, char sep, unsigned int wrap, + size_t name_width, const char *name, const char *format, ...) +{ + size_t len = strlen (name); + if (name_width < len) + name_width = len; + + char *out; + va_list ap; + va_start (ap, format); + int out_len = vasprintf (&out, format, ap); + va_end (ap); + if (out_len == -1) + error (EXIT_FAILURE, 0, _("memory exhausted")); + + size_t n = name_width + sizeof ": " - 1 + out_len; + + if (colno == 0) + { + printf ("%*s", ITEM_INDENT, ""); + colno = ITEM_INDENT + n; + } + else if (colno + 2 + n < wrap) + { + printf ("%c ", sep); + colno += 2 + n; + } + else + { + printf ("\n%*s", ITEM_INDENT, ""); + colno = ITEM_INDENT + n; + } + + printf ("%s: %*s%s", name, (int) (name_width - len), "", out); + + free (out); + + return colno; +} + +static const void * +convert (Elf *core, Elf_Type type, uint_fast16_t count, + void *value, const void *data, size_t size) +{ + Elf_Data valuedata = + { + .d_type = type, + .d_buf = value, + .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT), + .d_version = EV_CURRENT, + }; + Elf_Data indata = + { + .d_type = type, + .d_buf = (void *) data, + .d_size = valuedata.d_size, + .d_version = EV_CURRENT, + }; + + Elf_Data *d = (gelf_getclass (core) == ELFCLASS32 + ? elf32_xlatetom : elf64_xlatetom) + (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]); + if (d == NULL) + error (EXIT_FAILURE, 0, + _("cannot convert core note data: %s"), elf_errmsg (-1)); + + return data + indata.d_size; +} + +typedef uint8_t GElf_Byte; + +static unsigned int +handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, + unsigned int colno, size_t *repeated_size) +{ + uint_fast16_t count = item->count ?: 1; + /* Ebl_Core_Item count is always a small number. + Make sure the backend didn't put in some large bogus value. */ + assert (count < 128); + +#define TYPES \ + DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \ + DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \ + DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \ + DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \ + DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \ + DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64) + +#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name + typedef union { TYPES; } value_t; + void *data = alloca (count * sizeof (value_t)); +#undef DO_TYPE + +#define DO_TYPE(NAME, Name, hex, dec) \ + GElf_##Name *value_##Name __attribute__((unused)) = data + TYPES; +#undef DO_TYPE + + size_t size = gelf_fsize (core, item->type, count, EV_CURRENT); + size_t convsize = size; + if (repeated_size != NULL) + { + if (*repeated_size > size && (item->format == 'b' || item->format == 'B')) + { + data = alloca (*repeated_size); + count *= *repeated_size / size; + convsize = count * size; + *repeated_size -= convsize; + } + else if (item->count != 0 || item->format != '\n') + *repeated_size -= size; + } + + convert (core, item->type, count, data, desc + item->offset, convsize); + + Elf_Type type = item->type; + if (type == ELF_T_ADDR) + type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD; + + switch (item->format) + { + case 'd': + assert (count == 1); + switch (type) + { +#define DO_TYPE(NAME, Name, hex, dec) \ + case ELF_T_##NAME: \ + colno = print_core_item (colno, ',', WRAP_COLUMN, \ + 0, item->name, dec, value_##Name[0]); \ + break + TYPES; +#undef DO_TYPE + default: + abort (); + } + break; + + case 'x': + assert (count == 1); + switch (type) + { +#define DO_TYPE(NAME, Name, hex, dec) \ + case ELF_T_##NAME: \ + colno = print_core_item (colno, ',', WRAP_COLUMN, \ + 0, item->name, hex, value_##Name[0]); \ + break + TYPES; +#undef DO_TYPE + default: + abort (); + } + break; + + case 'b': + case 'B': + assert (size % sizeof (unsigned int) == 0); + unsigned int nbits = count * size * 8; + unsigned int pop = 0; + for (const unsigned int *i = data; (void *) i < data + count * size; ++i) + pop += __builtin_popcount (*i); + bool negate = pop > nbits / 2; + const unsigned int bias = item->format == 'b'; + + { + char printed[(negate ? nbits - pop : pop) * 16 + 1]; + char *p = printed; + *p = '\0'; + + if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int)) + { + assert (size == sizeof (unsigned int) * 2); + for (unsigned int *i = data; + (void *) i < data + count * size; i += 2) + { + unsigned int w = i[1]; + i[1] = i[0]; + i[0] = w; + } + } + + unsigned int lastbit = 0; + unsigned int run = 0; + for (const unsigned int *i = data; + (void *) i < data + count * size; ++i) + { + unsigned int bit = ((void *) i - data) * 8; + unsigned int w = negate ? ~*i : *i; + while (w != 0) + { + /* Note that a right shift equal to (or greater than) + the number of bits of w is undefined behaviour. In + particular when the least significant bit is bit 32 + (w = 0x8000000) then w >>= n is undefined. So + explicitly handle that case separately. */ + unsigned int n = ffs (w); + if (n < sizeof (w) * 8) + w >>= n; + else + w = 0; + bit += n; + + if (lastbit != 0 && lastbit + 1 == bit) + ++run; + else + { + if (lastbit == 0) + p += sprintf (p, "%u", bit - bias); + else if (run == 0) + p += sprintf (p, ",%u", bit - bias); + else + p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias); + run = 0; + } + + lastbit = bit; + } + } + if (lastbit > 0 && run > 0 && lastbit + 1 != nbits) + p += sprintf (p, "-%u", lastbit - bias); + + colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name, + negate ? "~<%s>" : "<%s>", printed); + } + break; + + case 'T': + case (char) ('T'|0x80): + assert (count == 2); + Dwarf_Word sec; + Dwarf_Word usec; + switch (type) + { +#define DO_TYPE(NAME, Name, hex, dec) \ + case ELF_T_##NAME: \ + sec = value_##Name[0]; \ + usec = value_##Name[1]; \ + break + TYPES; +#undef DO_TYPE + default: + abort (); + } + if (unlikely (item->format == (char) ('T'|0x80))) + { + /* This is a hack for an ill-considered 64-bit ABI where + tv_usec is actually a 32-bit field with 32 bits of padding + rounding out struct timeval. We've already converted it as + a 64-bit field. For little-endian, this just means the + high half is the padding; it's presumably zero, but should + be ignored anyway. For big-endian, it means the 32-bit + field went into the high half of USEC. */ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem); + if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)) + usec >>= 32; + else + usec &= UINT32_MAX; + } + colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name, + "%" PRIu64 ".%.6" PRIu64, sec, usec); + break; + + case 'c': + assert (count == 1); + colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name, + "%c", value_Byte[0]); + break; + + case 's': + colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name, + "%.*s", (int) count, value_Byte); + break; + + case '\n': + /* This is a list of strings separated by '\n'. */ + assert (item->count == 0); + assert (repeated_size != NULL); + assert (item->name == NULL); + if (unlikely (item->offset >= *repeated_size)) + break; + + const char *s = desc + item->offset; + size = *repeated_size - item->offset; + *repeated_size = 0; + while (size > 0) + { + const char *eol = memchr (s, '\n', size); + int len = size; + if (eol != NULL) + len = eol - s; + printf ("%*s%.*s\n", ITEM_INDENT, "", len, s); + if (eol == NULL) + break; + size -= eol + 1 - s; + s = eol + 1; + } + + colno = WRAP_COLUMN; + break; + + case 'h': + break; + + default: + error (0, 0, "XXX not handling format '%c' for %s", + item->format, item->name); + break; + } + +#undef TYPES + + return colno; +} + + +/* Sort items by group, and by layout offset within each group. */ +static int +compare_core_items (const void *a, const void *b) +{ + const Ebl_Core_Item *const *p1 = a; + const Ebl_Core_Item *const *p2 = b; + const Ebl_Core_Item *item1 = *p1; + const Ebl_Core_Item *item2 = *p2; + + return ((item1->group == item2->group ? 0 + : strcmp (item1->group, item2->group)) + ?: (int) item1->offset - (int) item2->offset); +} + +/* Sort item groups by layout offset of the first item in the group. */ +static int +compare_core_item_groups (const void *a, const void *b) +{ + const Ebl_Core_Item *const *const *p1 = a; + const Ebl_Core_Item *const *const *p2 = b; + const Ebl_Core_Item *const *group1 = *p1; + const Ebl_Core_Item *const *group2 = *p2; + const Ebl_Core_Item *item1 = *group1; + const Ebl_Core_Item *item2 = *group2; + + return (int) item1->offset - (int) item2->offset; +} + +static unsigned int +handle_core_items (Elf *core, const void *desc, size_t descsz, + const Ebl_Core_Item *items, size_t nitems) +{ + if (nitems == 0) + return 0; + unsigned int colno = 0; + + /* FORMAT '\n' makes sense to be present only as a single item as it + processes all the data of a note. FORMATs 'b' and 'B' have a special case + if present as a single item but they can be also processed with other + items below. */ + if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b' + || items[0].format == 'B')) + { + assert (items[0].offset == 0); + size_t size = descsz; + colno = handle_core_item (core, items, desc, colno, &size); + /* If SIZE is not zero here there is some remaining data. But we do not + know how to process it anyway. */ + return colno; + } + for (size_t i = 0; i < nitems; ++i) + assert (items[i].format != '\n'); + + /* Sort to collect the groups together. */ + const Ebl_Core_Item *sorted_items[nitems]; + for (size_t i = 0; i < nitems; ++i) + sorted_items[i] = &items[i]; + qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items); + + /* Collect the unique groups and sort them. */ + const Ebl_Core_Item **groups[nitems]; + groups[0] = &sorted_items[0]; + size_t ngroups = 1; + for (size_t i = 1; i < nitems; ++i) + if (sorted_items[i]->group != sorted_items[i - 1]->group + && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group)) + groups[ngroups++] = &sorted_items[i]; + qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups); + + /* Write out all the groups. */ + const void *last = desc; + do + { + for (size_t i = 0; i < ngroups; ++i) + { + for (const Ebl_Core_Item **item = groups[i]; + (item < &sorted_items[nitems] + && ((*item)->group == groups[i][0]->group + || !strcmp ((*item)->group, groups[i][0]->group))); + ++item) + colno = handle_core_item (core, *item, desc, colno, NULL); + + /* Force a line break at the end of the group. */ + colno = WRAP_COLUMN; + } + + if (descsz == 0) + break; + + /* This set of items consumed a certain amount of the note's data. + If there is more data there, we have another unit of the same size. + Loop to print that out too. */ + const Ebl_Core_Item *item = &items[nitems - 1]; + size_t eltsz = item->offset + gelf_fsize (core, item->type, + item->count ?: 1, EV_CURRENT); + + int reps = -1; + do + { + ++reps; + desc += eltsz; + descsz -= eltsz; + } + while (descsz >= eltsz && !memcmp (desc, last, eltsz)); + + if (reps == 1) + { + /* For just one repeat, print it unabridged twice. */ + desc -= eltsz; + descsz += eltsz; + } + else if (reps > 1) + printf (_("\n%*s... ..."), + ITEM_INDENT, "", reps); + + last = desc; + } + while (descsz > 0); + + return colno; +} + +static unsigned int +handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc, + unsigned int colno) +{ + desc += regloc->offset; + + abort (); /* XXX */ + return colno; +} + + +static unsigned int +handle_core_register (Ebl *ebl, Elf *core, int maxregname, + const Ebl_Register_Location *regloc, const void *desc, + unsigned int colno) +{ + if (regloc->bits % 8 != 0) + return handle_bit_registers (regloc, desc, colno); + + desc += regloc->offset; + + for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg) + { + char name[REGNAMESZ]; + int bits; + int type; + register_info (ebl, reg, regloc, name, &bits, &type); + +#define TYPES \ + BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \ + BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \ + BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \ + BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64) + +#define BITS(bits, xtype, sfmt, ufmt) \ + uint##bits##_t b##bits; int##bits##_t b##bits##s + union { TYPES; uint64_t b128[2]; } value; +#undef BITS + + switch (type) + { + case DW_ATE_unsigned: + case DW_ATE_signed: + case DW_ATE_address: + switch (bits) + { +#define BITS(bits, xtype, sfmt, ufmt) \ + case bits: \ + desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \ + if (type == DW_ATE_signed) \ + colno = print_core_item (colno, ' ', WRAP_COLUMN, \ + maxregname, name, \ + sfmt, value.b##bits##s); \ + else \ + colno = print_core_item (colno, ' ', WRAP_COLUMN, \ + maxregname, name, \ + ufmt, value.b##bits); \ + break + + TYPES; + + case 128: + assert (type == DW_ATE_unsigned); + desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0); + int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB; + colno = print_core_item (colno, ' ', WRAP_COLUMN, + maxregname, name, + "0x%.16" PRIx64 "%.16" PRIx64, + value.b128[!be], value.b128[be]); + break; + + default: + abort (); +#undef BITS + } + break; + + default: + /* Print each byte in hex, the whole thing in native byte order. */ + assert (bits % 8 == 0); + const uint8_t *bytes = desc; + desc += bits / 8; + char hex[bits / 4 + 1]; + hex[bits / 4] = '\0'; + int incr = 1; + if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB) + { + bytes += bits / 8 - 1; + incr = -1; + } + size_t idx = 0; + for (char *h = hex; bits > 0; bits -= 8, idx += incr) + { + *h++ = "0123456789abcdef"[bytes[idx] >> 4]; + *h++ = "0123456789abcdef"[bytes[idx] & 0xf]; + } + colno = print_core_item (colno, ' ', WRAP_COLUMN, + maxregname, name, "0x%s", hex); + break; + } + desc += regloc->pad; + +#undef TYPES + } + + return colno; +} + + +struct register_info +{ + const Ebl_Register_Location *regloc; + const char *set; + char name[REGNAMESZ]; + int regno; + int bits; + int type; +}; + +static int +register_bitpos (const struct register_info *r) +{ + return (r->regloc->offset * 8 + + ((r->regno - r->regloc->regno) + * (r->regloc->bits + r->regloc->pad * 8))); +} + +static int +compare_sets_by_info (const struct register_info *r1, + const struct register_info *r2) +{ + return ((int) r2->bits - (int) r1->bits + ?: register_bitpos (r1) - register_bitpos (r2)); +} + +/* Sort registers by set, and by size and layout offset within each set. */ +static int +compare_registers (const void *a, const void *b) +{ + const struct register_info *r1 = a; + const struct register_info *r2 = b; + + /* Unused elements sort last. */ + if (r1->regloc == NULL) + return r2->regloc == NULL ? 0 : 1; + if (r2->regloc == NULL) + return -1; + + return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set)) + ?: compare_sets_by_info (r1, r2)); +} + +/* Sort register sets by layout offset of the first register in the set. */ +static int +compare_register_sets (const void *a, const void *b) +{ + const struct register_info *const *p1 = a; + const struct register_info *const *p2 = b; + return compare_sets_by_info (*p1, *p2); +} + +static inline bool +same_set (const struct register_info *a, + const struct register_info *b, + const struct register_info *regs, + size_t maxnreg) +{ + return (a < ®s[maxnreg] && a->regloc != NULL + && b < ®s[maxnreg] && b->regloc != NULL + && a->bits == b->bits + && (a->set == b->set || !strcmp (a->set, b->set))); +} + +static unsigned int +handle_core_registers (Ebl *ebl, Elf *core, const void *desc, + const Ebl_Register_Location *reglocs, size_t nregloc) +{ + if (nregloc == 0) + return 0; + + ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL); + if (maxnreg <= 0) + { + for (size_t i = 0; i < nregloc; ++i) + if (maxnreg < reglocs[i].regno + reglocs[i].count) + maxnreg = reglocs[i].regno + reglocs[i].count; + assert (maxnreg > 0); + } + + struct register_info regs[maxnreg]; + memset (regs, 0, sizeof regs); + + /* Sort to collect the sets together. */ + int maxreg = 0; + for (size_t i = 0; i < nregloc; ++i) + for (int reg = reglocs[i].regno; + reg < reglocs[i].regno + reglocs[i].count; + ++reg) + { + assert (reg < maxnreg); + if (reg > maxreg) + maxreg = reg; + struct register_info *info = ®s[reg]; + info->regloc = ®locs[i]; + info->regno = reg; + info->set = register_info (ebl, reg, ®locs[i], + info->name, &info->bits, &info->type); + } + qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers); + + /* Collect the unique sets and sort them. */ + struct register_info *sets[maxreg + 1]; + sets[0] = ®s[0]; + size_t nsets = 1; + for (int i = 1; i <= maxreg; ++i) + if (regs[i].regloc != NULL + && !same_set (®s[i], ®s[i - 1], regs, maxnreg)) + sets[nsets++] = ®s[i]; + qsort (sets, nsets, sizeof sets[0], &compare_register_sets); + + /* Write out all the sets. */ + unsigned int colno = 0; + for (size_t i = 0; i < nsets; ++i) + { + /* Find the longest name of a register in this set. */ + size_t maxname = 0; + const struct register_info *end; + for (end = sets[i]; same_set (sets[i], end, regs, maxnreg); ++end) + { + size_t len = strlen (end->name); + if (len > maxname) + maxname = len; + } + + for (const struct register_info *reg = sets[i]; + reg < end; + reg += reg->regloc->count ?: 1) + colno = handle_core_register (ebl, core, maxname, + reg->regloc, desc, colno); + + /* Force a line break at the end of the group. */ + colno = WRAP_COLUMN; + } + + return colno; +} + +static void +handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos) +{ + Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV); + if (data == NULL) + elf_error: + error (EXIT_FAILURE, 0, + _("cannot convert core note data: %s"), elf_errmsg (-1)); + + const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT); + for (size_t i = 0; i < nauxv; ++i) + { + GElf_auxv_t av_mem; + GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem); + if (av == NULL) + goto elf_error; + + const char *name; + const char *fmt; + if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0) + { + /* Unknown type. */ + if (av->a_un.a_val == 0) + printf (" %" PRIu64 "\n", av->a_type); + else + printf (" %" PRIu64 ": %#" PRIx64 "\n", + av->a_type, av->a_un.a_val); + } + else + switch (fmt[0]) + { + case '\0': /* Normally zero. */ + if (av->a_un.a_val == 0) + { + printf (" %s\n", name); + break; + } + FALLTHROUGH; + case 'x': /* hex */ + case 'p': /* address */ + case 's': /* address of string */ + printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val); + break; + case 'u': + printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val); + break; + case 'd': + printf (" %s: %" PRId64 "\n", name, av->a_un.a_val); + break; + + case 'b': + printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val); + GElf_Xword bit = 1; + const char *pfx = "<"; + for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1) + { + if (av->a_un.a_val & bit) + { + printf ("%s%s", pfx, p); + pfx = " "; + } + bit <<= 1; + } + printf (">\n"); + break; + + default: + abort (); + } + } +} + +static bool +buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz) +{ + return ptr < end && (size_t) (end - ptr) >= sz; +} + +static bool +buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end, + int *retp) +{ + if (! buf_has_data (*ptrp, end, 4)) + return false; + + *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4); + return true; +} + +static bool +buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end, + uint64_t *retp) +{ + size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT); + if (! buf_has_data (*ptrp, end, sz)) + return false; + + union + { + uint64_t u64; + uint32_t u32; + } u; + + *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz); + + if (sz == 4) + *retp = u.u32; + else + *retp = u.u64; + return true; +} + +static void +handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos) +{ + Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE); + if (data == NULL) + error (EXIT_FAILURE, 0, + _("cannot convert core note data: %s"), elf_errmsg (-1)); + + unsigned char const *ptr = data->d_buf; + unsigned char const *const end = data->d_buf + data->d_size; + + /* Siginfo head is three ints: signal number, error number, origin + code. */ + int si_signo, si_errno, si_code; + if (! buf_read_int (core, &ptr, end, &si_signo) + || ! buf_read_int (core, &ptr, end, &si_errno) + || ! buf_read_int (core, &ptr, end, &si_code)) + { + fail: + printf (" Not enough data in NT_SIGINFO note.\n"); + return; + } + + /* Next is a pointer-aligned union of structures. On 64-bit + machines, that implies a word of padding. */ + if (gelf_getclass (core) == ELFCLASS64) + ptr += 4; + + printf (" si_signo: %d, si_errno: %d, si_code: %d\n", + si_signo, si_errno, si_code); + + if (si_code > 0) + switch (si_signo) + { + case CORE_SIGILL: + case CORE_SIGFPE: + case CORE_SIGSEGV: + case CORE_SIGBUS: + { + uint64_t addr; + if (! buf_read_ulong (core, &ptr, end, &addr)) + goto fail; + printf (" fault address: %#" PRIx64 "\n", addr); + break; + } + default: + ; + } + else if (si_code == CORE_SI_USER) + { + int pid, uid; + if (! buf_read_int (core, &ptr, end, &pid) + || ! buf_read_int (core, &ptr, end, &uid)) + goto fail; + printf (" sender PID: %d, sender UID: %d\n", pid, uid); + } +} + +static void +handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos) +{ + Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE); + if (data == NULL) + error (EXIT_FAILURE, 0, + _("cannot convert core note data: %s"), elf_errmsg (-1)); + + unsigned char const *ptr = data->d_buf; + unsigned char const *const end = data->d_buf + data->d_size; + + uint64_t count, page_size; + if (! buf_read_ulong (core, &ptr, end, &count) + || ! buf_read_ulong (core, &ptr, end, &page_size)) + { + fail: + printf (" Not enough data in NT_FILE note.\n"); + return; + } + + size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT); + uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize); + if (count > maxcount) + goto fail; + + /* Where file names are stored. */ + unsigned char const *const fstart = ptr + 3 * count * addrsize; + char const *fptr = (char *) fstart; + + printf (" %" PRId64 " files:\n", count); + for (uint64_t i = 0; i < count; ++i) + { + uint64_t mstart, mend, moffset; + if (! buf_read_ulong (core, &ptr, fstart, &mstart) + || ! buf_read_ulong (core, &ptr, fstart, &mend) + || ! buf_read_ulong (core, &ptr, fstart, &moffset)) + goto fail; + + const char *fnext = memchr (fptr, '\0', (char *) end - fptr); + if (fnext == NULL) + goto fail; + + int ct = printf (" %08" PRIx64 "-%08" PRIx64 + " %08" PRIx64 " %" PRId64, + mstart, mend, moffset * page_size, mend - mstart); + printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr); + + fptr = fnext + 1; + } +} + +static void +handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, + const char *name, const void *desc) +{ + GElf_Word regs_offset; + size_t nregloc; + const Ebl_Register_Location *reglocs; + size_t nitems; + const Ebl_Core_Item *items; + + if (! ebl_core_note (ebl, nhdr, name, desc, + ®s_offset, &nregloc, ®locs, &nitems, &items)) + return; + + /* Pass 0 for DESCSZ when there are registers in the note, + so that the ITEMS array does not describe the whole thing. + For non-register notes, the actual descsz might be a multiple + of the unit size, not just exactly the unit size. */ + unsigned int colno = handle_core_items (ebl->elf, desc, + nregloc == 0 ? nhdr->n_descsz : 0, + items, nitems); + if (colno != 0) + putchar_unlocked ('\n'); + + colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset, + reglocs, nregloc); + if (colno != 0) + putchar_unlocked ('\n'); +} + +static void +handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr, + GElf_Off start, Elf_Data *data) +{ + fputs_unlocked (_(" Owner Data size Type\n"), stdout); + + if (data == NULL) + goto bad_note; + + size_t offset = 0; + GElf_Nhdr nhdr; + size_t name_offset; + size_t desc_offset; + while (offset < data->d_size + && (offset = gelf_getnote (data, offset, + &nhdr, &name_offset, &desc_offset)) > 0) + { + const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset; + const char *desc = data->d_buf + desc_offset; + + /* GNU Build Attributes are weird, they store most of their data + into the owner name field. Extract just the owner name + prefix here, then use the rest later as data. */ + bool is_gnu_build_attr + = startswith (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX); + const char *print_name = (is_gnu_build_attr + ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name); + size_t print_namesz = (is_gnu_build_attr + ? strlen (print_name) : nhdr.n_namesz); + + char buf[100]; + char buf2[100]; + printf (_(" %-13.*s %9" PRId32 " %s\n"), + (int) print_namesz, print_name, nhdr.n_descsz, + ehdr->e_type == ET_CORE + ? ebl_core_note_type_name (ebl, nhdr.n_type, + buf, sizeof (buf)) + : ebl_object_note_type_name (ebl, name, nhdr.n_type, + nhdr.n_descsz, + buf2, sizeof (buf2))); + + /* Filter out invalid entries. */ + if (memchr (name, '\0', nhdr.n_namesz) != NULL + /* XXX For now help broken Linux kernels. */ + || 1) + { + if (ehdr->e_type == ET_CORE) + { + if (nhdr.n_type == NT_AUXV + && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */ + || (nhdr.n_namesz == 5 && name[4] == '\0')) + && !memcmp (name, "CORE", 4)) + handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz, + start + desc_offset); + else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0) + switch (nhdr.n_type) + { + case NT_SIGINFO: + handle_siginfo_note (ebl->elf, nhdr.n_descsz, + start + desc_offset); + break; + + case NT_FILE: + handle_file_note (ebl->elf, nhdr.n_descsz, + start + desc_offset); + break; + + default: + handle_core_note (ebl, &nhdr, name, desc); + } + else + handle_core_note (ebl, &nhdr, name, desc); + } + else + ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type, + nhdr.n_descsz, desc); + } + } + + if (offset == data->d_size) + return; + + bad_note: + error (0, 0, + _("cannot get content of note: %s"), + data != NULL ? "garbage data" : elf_errmsg (-1)); +} + +static void +handle_notes (Ebl *ebl, GElf_Ehdr *ehdr) +{ + /* If we have section headers, just look for SHT_NOTE sections. + In a debuginfo file, the program headers are not reliable. */ + if (shnum != 0) + { + /* Get the section header string table index. */ + size_t shstrndx; + if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL || shdr->sh_type != SHT_NOTE) + /* Not what we are looking for. */ + continue; + + if (notes_section != NULL) + { + char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); + if (sname == NULL || strcmp (sname, notes_section) != 0) + continue; + } + + printf (_("\ +\nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"), + elf_ndxscn (scn), + elf_strptr (ebl->elf, shstrndx, shdr->sh_name), + shdr->sh_size, shdr->sh_offset); + + handle_notes_data (ebl, ehdr, shdr->sh_offset, + elf_getdata (scn, NULL)); + } + return; + } + + /* We have to look through the program header to find the note + sections. There can be more than one. */ + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr mem; + GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); + + if (phdr == NULL || phdr->p_type != PT_NOTE) + /* Not what we are looking for. */ + continue; + + printf (_("\ +\nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"), + phdr->p_filesz, phdr->p_offset); + + handle_notes_data (ebl, ehdr, phdr->p_offset, + elf_getdata_rawchunk (ebl->elf, + phdr->p_offset, phdr->p_filesz, + (phdr->p_align == 8 + ? ELF_T_NHDR8 : ELF_T_NHDR))); + } +} + + +static void +hex_dump (const uint8_t *data, size_t len) +{ + size_t pos = 0; + while (pos < len) + { + printf (" 0x%08zx ", pos); + + const size_t chunk = MIN (len - pos, 16); + + for (size_t i = 0; i < chunk; ++i) + if (i % 4 == 3) + printf ("%02x ", data[pos + i]); + else + printf ("%02x", data[pos + i]); + + if (chunk < 16) + printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), ""); + + for (size_t i = 0; i < chunk; ++i) + { + unsigned char b = data[pos + i]; + printf ("%c", isprint (b) ? b : '.'); + } + + putchar ('\n'); + pos += chunk; + } +} + +static void +dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) +{ + if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS) + printf (_("\nSection [%zu] '%s' has no data to dump.\n"), + elf_ndxscn (scn), name); + else + { + if (print_decompress) + { + /* We try to decompress the section, but keep the old shdr around + so we can show both the original shdr size and the uncompressed + data size. */ + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (elf_compress (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + } + else if (startswith (name, ".zdebug")) + { + if (elf_compress_gnu (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + } + } + + Elf_Data *data = elf_rawdata (scn, NULL); + if (data == NULL) + error (0, 0, _("cannot get data for section [%zu] '%s': %s"), + elf_ndxscn (scn), name, elf_errmsg (-1)); + else + { + if (data->d_size == shdr->sh_size) + printf (_("\nHex dump of section [%zu] '%s', %" PRIu64 + " bytes at offset %#0" PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, shdr->sh_offset); + else + printf (_("\nHex dump of section [%zu] '%s', %" PRIu64 + " bytes (%zd uncompressed) at offset %#0" + PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, data->d_size, shdr->sh_offset); + hex_dump (data->d_buf, data->d_size); + } + } +} + +static void +print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) +{ + if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS) + printf (_("\nSection [%zu] '%s' has no strings to dump.\n"), + elf_ndxscn (scn), name); + else + { + if (print_decompress) + { + /* We try to decompress the section, but keep the old shdr around + so we can show both the original shdr size and the uncompressed + data size. */ + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + { + if (elf_compress (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + } + else if (startswith (name, ".zdebug")) + { + if (elf_compress_gnu (scn, 0, 0) < 0) + printf ("WARNING: %s [%zd]\n", + _("Couldn't uncompress section"), + elf_ndxscn (scn)); + } + } + + Elf_Data *data = elf_rawdata (scn, NULL); + if (data == NULL) + error (0, 0, _("cannot get data for section [%zu] '%s': %s"), + elf_ndxscn (scn), name, elf_errmsg (-1)); + else + { + if (data->d_size == shdr->sh_size) + printf (_("\nString section [%zu] '%s' contains %" PRIu64 + " bytes at offset %#0" PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, shdr->sh_offset); + else + printf (_("\nString section [%zu] '%s' contains %" PRIu64 + " bytes (%zd uncompressed) at offset %#0" + PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, data->d_size, shdr->sh_offset); + + const char *start = data->d_buf; + const char *const limit = start + data->d_size; + do + { + const char *end = memchr (start, '\0', limit - start); + const size_t pos = start - (const char *) data->d_buf; + if (unlikely (end == NULL)) + { + printf (" [%6zx]- %.*s\n", + pos, (int) (limit - start), start); + break; + } + printf (" [%6zx] %s\n", pos, start); + start = end + 1; + } while (start < limit); + } + } +} + +static void +for_each_section_argument (Elf *elf, const struct section_argument *list, + void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr, + const char *name)) +{ + /* Get the section header string table index. */ + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) < 0) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + for (const struct section_argument *a = list; a != NULL; a = a->next) + { + Elf_Scn *scn; + GElf_Shdr shdr_mem; + const char *name = NULL; + + char *endp = NULL; + unsigned long int shndx = strtoul (a->arg, &endp, 0); + if (endp != a->arg && *endp == '\0') + { + scn = elf_getscn (elf, shndx); + if (scn == NULL) + { + error (0, 0, _("\nsection [%lu] does not exist"), shndx); + continue; + } + + if (gelf_getshdr (scn, &shdr_mem) == NULL) + error (EXIT_FAILURE, 0, _("cannot get section header: %s"), + elf_errmsg (-1)); + name = elf_strptr (elf, shstrndx, shdr_mem.sh_name); + (*dump) (scn, &shdr_mem, name); + } + else + { + /* Need to look up the section by name. */ + scn = NULL; + bool found = false; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + if (gelf_getshdr (scn, &shdr_mem) == NULL) + continue; + name = elf_strptr (elf, shstrndx, shdr_mem.sh_name); + if (name == NULL) + continue; + if (!strcmp (name, a->arg)) + { + found = true; + (*dump) (scn, &shdr_mem, name); + } + } + + if (unlikely (!found) && !a->implicit) + error (0, 0, _("\nsection '%s' does not exist"), a->arg); + } + } +} + +static void +dump_data (Ebl *ebl) +{ + for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section); +} + +static void +dump_strings (Ebl *ebl) +{ + for_each_section_argument (ebl->elf, string_sections, &print_string_section); +} + +static void +print_strings (Ebl *ebl) +{ + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + Elf_Scn *scn; + GElf_Shdr shdr_mem; + const char *name; + scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + if (gelf_getshdr (scn, &shdr_mem) == NULL) + continue; + + if (shdr_mem.sh_type != SHT_PROGBITS + || !(shdr_mem.sh_flags & SHF_STRINGS)) + continue; + + name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name); + if (name == NULL) + continue; + + print_string_section (scn, &shdr_mem, name); + } +} + +static void +dump_archive_index (Elf *elf, const char *fname) +{ + size_t narsym; + const Elf_Arsym *arsym = elf_getarsym (elf, &narsym); + if (arsym == NULL) + { + int result = elf_errno (); + if (unlikely (result != ELF_E_NO_INDEX)) + error (EXIT_FAILURE, 0, + _("cannot get symbol index of archive '%s': %s"), + fname, elf_errmsg (result)); + else + printf (_("\nArchive '%s' has no symbol index\n"), fname); + return; + } + + printf (_("\nIndex of archive '%s' has %zu entries:\n"), + fname, narsym); + + size_t as_off = 0; + for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s) + { + if (s->as_off != as_off) + { + as_off = s->as_off; + + Elf *subelf = NULL; + if (unlikely (elf_rand (elf, as_off) == 0) + || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf)) + == NULL)) +#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7) + while (1) +#endif + error (EXIT_FAILURE, 0, + _("cannot extract member at offset %zu in '%s': %s"), + as_off, fname, elf_errmsg (-1)); + + const Elf_Arhdr *h = elf_getarhdr (subelf); + + printf (_("Archive member '%s' contains:\n"), h->ar_name); + + elf_end (subelf); + } + + printf ("\t%s\n", s->as_name); + } +} + +#include "debugpred.h" diff --git a/src/size.c b/src/size.c new file mode 100644 index 00000000..322ff53e --- /dev/null +++ b/src/size.c @@ -0,0 +1,667 @@ +/* Print size information from ELF file. + Copyright (C) 2000-2007,2009,2012,2014,2015 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Values for the parameters which have no short form. */ +#define OPT_FORMAT 0x100 +#define OPT_RADIX 0x101 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Output format:"), 0 }, + { "format", OPT_FORMAT, "FORMAT", 0, + N_("Use the output format FORMAT. FORMAT can be `bsd' or `sysv'. " + "The default is `bsd'"), 0 }, + { NULL, 'A', NULL, 0, N_("Same as `--format=sysv'"), 0 }, + { NULL, 'B', NULL, 0, N_("Same as `--format=bsd'"), 0 }, + { "radix", OPT_RADIX, "RADIX", 0, N_("Use RADIX for printing symbol values"), + 0}, + { NULL, 'd', NULL, 0, N_("Same as `--radix=10'"), 0 }, + { NULL, 'o', NULL, 0, N_("Same as `--radix=8'"), 0 }, + { NULL, 'x', NULL, 0, N_("Same as `--radix=16'"), 0 }, + { NULL, 'f', NULL, 0, + N_("Similar to `--format=sysv' output but in one line"), 0 }, + + { NULL, 0, NULL, 0, N_("Output options:"), 0 }, + { NULL, 'F', NULL, 0, + N_("Print size and permission flags for loadable segments"), 0 }, + { "totals", 't', NULL, 0, N_("Display the total sizes (bsd only)"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +List section sizes of FILEs (a.out by default)."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + + +/* Print symbols in file named FNAME. */ +static int process_file (const char *fname); + +/* Handle content of archive. */ +static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname); + +/* Handle ELF file. */ +static void handle_elf (Elf *elf, const char *fullname, const char *fname); + +/* Show total size. */ +static void show_bsd_totals (void); + +#define INTERNAL_ERROR(fname) \ + error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"), \ + fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)) + + +/* User-selectable options. */ + +/* The selected output format. */ +static enum +{ + format_bsd = 0, + format_sysv, + format_sysv_one_line, + format_segments +} format; + +/* Radix for printed numbers. */ +static enum +{ + radix_decimal = 0, + radix_hex, + radix_octal +} radix; + + +/* Mapping of radix and binary class to length. */ +static const int length_map[2][3] = +{ + [ELFCLASS32 - 1] = + { + [radix_hex] = 8, + [radix_decimal] = 10, + [radix_octal] = 11 + }, + [ELFCLASS64 - 1] = + { + [radix_hex] = 16, + [radix_decimal] = 20, + [radix_octal] = 22 + } +}; + +/* True if total sizes should be printed. */ +static bool totals; +/* To print the total sizes in a reasonable format remember the highest + "class" of ELF binaries processed. */ +static int totals_class; + + +int +main (int argc, char *argv[]) +{ + int remaining; + int result = 0; + + /* We use no threads here which can interfere with handling a stream. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + + /* Tell the library which version we are expecting. */ + elf_version (EV_CURRENT); + + if (remaining == argc) + /* The user didn't specify a name so we use a.out. */ + result = process_file ("a.out"); + else + /* Process all the remaining files. */ + do + result |= process_file (argv[remaining]); + while (++remaining < argc); + + /* Print the total sizes but only if the output format is BSD and at + least one file has been correctly read (i.e., we recognized the + class). */ + if (totals && format == format_bsd && totals_class != 0) + show_bsd_totals (); + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'd': + radix = radix_decimal; + break; + + case 'f': + format = format_sysv_one_line; + break; + + case 'o': + radix = radix_octal; + break; + + case 'x': + radix = radix_hex; + break; + + case 'A': + format = format_sysv; + break; + + case 'B': + format = format_bsd; + break; + + case 'F': + format = format_segments; + break; + + case OPT_FORMAT: + if (strcmp (arg, "bsd") == 0 || strcmp (arg, "berkeley") == 0) + format = format_bsd; + else if (likely (strcmp (arg, "sysv") == 0)) + format = format_sysv; + else + error (EXIT_FAILURE, 0, _("Invalid format: %s"), arg); + break; + + case OPT_RADIX: + if (strcmp (arg, "x") == 0 || strcmp (arg, "16") == 0) + radix = radix_hex; + else if (strcmp (arg, "d") == 0 || strcmp (arg, "10") == 0) + radix = radix_decimal; + else if (strcmp (arg, "o") == 0 || strcmp (arg, "8") == 0) + radix = radix_octal; + else + error (EXIT_FAILURE, 0, _("Invalid radix: %s"), arg); + break; + + case 't': + totals = true; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +/* Open the file and determine the type. */ +static int +process_file (const char *fname) +{ + int fd = open (fname, O_RDONLY); + if (unlikely (fd == -1)) + { + error (0, errno, _("cannot open '%s'"), fname); + return 1; + } + + /* Now get the ELF descriptor. */ + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (likely (elf != NULL)) + { + if (elf_kind (elf) == ELF_K_ELF) + { + handle_elf (elf, NULL, fname); + + if (unlikely (elf_end (elf) != 0)) + INTERNAL_ERROR (fname); + + if (unlikely (close (fd) != 0)) + error (EXIT_FAILURE, errno, _("while closing '%s'"), fname); + + return 0; + } + else if (likely (elf_kind (elf) == ELF_K_AR)) + { + int result = handle_ar (fd, elf, NULL, fname); + + if (unlikely (close (fd) != 0)) + error (EXIT_FAILURE, errno, _("while closing '%s'"), fname); + + return result; + } + + /* We cannot handle this type. Close the descriptor anyway. */ + if (unlikely (elf_end (elf) != 0)) + INTERNAL_ERROR (fname); + } + + if (unlikely (close (fd) != 0)) + error (EXIT_FAILURE, errno, _("while closing '%s'"), fname); + + error (0, 0, _("%s: file format not recognized"), fname); + + return 1; +} + + +/* Print the BSD-style header. This is done exactly once. */ +static void +print_header (Elf *elf) +{ + static int done; + + if (! done) + { + int ddigits = length_map[gelf_getclass (elf) - 1][radix_decimal]; + int xdigits = length_map[gelf_getclass (elf) - 1][radix_hex]; + + printf ("%*s %*s %*s %*s %*s %s\n", + ddigits - 2, sgettext ("bsd|text"), + ddigits - 2, sgettext ("bsd|data"), + ddigits - 2, sgettext ("bsd|bss"), + ddigits - 2, sgettext ("bsd|dec"), + xdigits - 2, sgettext ("bsd|hex"), + sgettext ("bsd|filename")); + + done = 1; + } +} + + +static int +handle_ar (int fd, Elf *elf, const char *prefix, const char *fname) +{ + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t fname_len = strlen (fname) + 1; + char new_prefix[prefix_len + 1 + fname_len]; + char *cp = new_prefix; + + /* Create the full name of the file. */ + if (prefix != NULL) + { + cp = mempcpy (cp, prefix, prefix_len); + *cp++ = ':'; + } + memcpy (cp, fname, fname_len); + + /* Process all the files contained in the archive. */ + int result = 0; + Elf *subelf; + Elf_Cmd cmd = ELF_C_READ_MMAP; + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + if (elf_kind (subelf) == ELF_K_ELF) + handle_elf (subelf, new_prefix, arhdr->ar_name); + else if (likely (elf_kind (subelf) == ELF_K_AR)) + result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name); + /* else signal error??? */ + + /* Get next archive element. */ + cmd = elf_next (subelf); + if (unlikely (elf_end (subelf) != 0)) + INTERNAL_ERROR (fname); + } + + /* Only close ELF handle if this was a "top level" ar file. */ + if (prefix == NULL) + if (unlikely (elf_end (elf) != 0)) + INTERNAL_ERROR (fname); + + return result; +} + + +/* Show sizes in SysV format. */ +static void +show_sysv (Elf *elf, const char *prefix, const char *fname, + const char *fullname) +{ + int maxlen = 10; + const int digits = length_map[gelf_getclass (elf) - 1][radix]; + + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + /* First round over the sections: determine the longest section name. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fullname); + + /* Ignore all sections which are not used at runtime. */ + const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (name != NULL && (shdr->sh_flags & SHF_ALLOC) != 0) + maxlen = MAX (maxlen, (int) strlen (name)); + } + + fputs_unlocked (fname, stdout); + if (prefix != NULL) + printf (_(" (ex %s)"), prefix); + printf (":\n%-*s %*s %*s\n", + maxlen, sgettext ("sysv|section"), + digits - 2, sgettext ("sysv|size"), + digits, sgettext ("sysv|addr")); + + /* Iterate over all sections. */ + GElf_Off total = 0; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fullname); + + /* Ignore all sections which are not used at runtime. */ + if ((shdr->sh_flags & SHF_ALLOC) != 0) + { + printf ((radix == radix_hex + ? "%-*s %*" PRIx64 " %*" PRIx64 "\n" + : (radix == radix_decimal + ? "%-*s %*" PRId64 " %*" PRId64 "\n" + : "%-*s %*" PRIo64 " %*" PRIo64 "\n")), + maxlen, elf_strptr (elf, shstrndx, shdr->sh_name), + digits - 2, shdr->sh_size, + digits, shdr->sh_addr); + + total += shdr->sh_size; + } + } + + if (radix == radix_hex) + printf ("%-*s %*" PRIx64 "\n\n\n", maxlen, sgettext ("sysv|Total"), + digits - 2, total); + else if (radix == radix_decimal) + printf ("%-*s %*" PRId64 "\n\n\n", maxlen, sgettext ("sysv|Total"), + digits - 2, total); + else + printf ("%-*s %*" PRIo64 "\n\n\n", maxlen, sgettext ("sysv|Total"), + digits - 2, total); +} + + +/* Show sizes in SysV format in one line. */ +static void +show_sysv_one_line (Elf *elf) +{ + /* Get the section header string table index. */ + size_t shstrndx; + if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0)) + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + + /* Iterate over all sections. */ + GElf_Off total = 0; + bool first = true; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (unlikely (shdr == NULL)) + error (EXIT_FAILURE, 0, _("cannot get section header")); + + /* Ignore all sections which are not used at runtime. */ + if ((shdr->sh_flags & SHF_ALLOC) == 0) + continue; + + if (! first) + fputs_unlocked (" + ", stdout); + first = false; + + printf ((radix == radix_hex ? "%" PRIx64 "(%s)" + : (radix == radix_decimal ? "%" PRId64 "(%s)" + : "%" PRIo64 "(%s)")), + shdr->sh_size, elf_strptr (elf, shstrndx, shdr->sh_name)); + + total += shdr->sh_size; + } + + if (radix == radix_hex) + printf (" = %#" PRIx64 "\n", total); + else if (radix == radix_decimal) + printf (" = %" PRId64 "\n", total); + else + printf (" = %" PRIo64 "\n", total); +} + + +/* Variables to add up the sizes of all files. */ +static uintmax_t total_textsize; +static uintmax_t total_datasize; +static uintmax_t total_bsssize; + + +/* Show sizes in BSD format. */ +static void +show_bsd (Elf *elf, const char *prefix, const char *fname, + const char *fullname) +{ + GElf_Off textsize = 0; + GElf_Off datasize = 0; + GElf_Off bsssize = 0; + const int ddigits = length_map[gelf_getclass (elf) - 1][radix_decimal]; + const int xdigits = length_map[gelf_getclass (elf) - 1][radix_hex]; + + /* Iterate over all sections. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + if (shdr == NULL) + INTERNAL_ERROR (fullname); + + /* Ignore all sections which are not marked as loaded. */ + if ((shdr->sh_flags & SHF_ALLOC) == 0) + continue; + + if ((shdr->sh_flags & SHF_WRITE) == 0) + textsize += shdr->sh_size; + else if (shdr->sh_type == SHT_NOBITS) + bsssize += shdr->sh_size; + else + datasize += shdr->sh_size; + } + + printf (radix == radix_decimal + ? "%*" PRId64 " %*" PRId64 " %*" PRId64 " %*" PRId64 " %*" PRIx64 " %s" + : radix == radix_hex + ? "%#*" PRIx64 " %#*" PRIx64 " %#*" PRIx64 " %*" PRId64 " %*" PRIx64 " %s" + : "%#*" PRIo64 " %#*" PRIo64 " %#*" PRIo64 " %*" PRId64 " %*" PRIx64 " %s", + ddigits - 2, textsize, + ddigits - 2, datasize, + ddigits - 2, bsssize, + ddigits - 2, textsize + datasize + bsssize, + xdigits - 2, textsize + datasize + bsssize, + fname); + if (prefix != NULL) + printf (_(" (ex %s)"), prefix); + fputs_unlocked ("\n", stdout); + + total_textsize += textsize; + total_datasize += datasize; + total_bsssize += bsssize; + + totals_class = MAX (totals_class, gelf_getclass (elf)); +} + + +/* Show total size. */ +static void +show_bsd_totals (void) +{ + int ddigits = length_map[totals_class - 1][radix_decimal]; + int xdigits = length_map[totals_class - 1][radix_hex]; + + printf ("%*" PRIuMAX " %*" PRIuMAX " %*" PRIuMAX " %*" PRIuMAX " %*" + PRIxMAX " %s", + ddigits - 2, total_textsize, + ddigits - 2, total_datasize, + ddigits - 2, total_bsssize, + ddigits - 2, total_textsize + total_datasize + total_bsssize, + xdigits - 2, total_textsize + total_datasize + total_bsssize, + _("(TOTALS)\n")); +} + + +/* Show size and permission of loadable segments. */ +static void +show_segments (Elf *elf, const char *fullname) +{ + size_t phnum; + if (elf_getphdrnum (elf, &phnum) != 0) + INTERNAL_ERROR (fullname); + + GElf_Off total = 0; + bool first = true; + for (size_t cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr; + + phdr = gelf_getphdr (elf, cnt, &phdr_mem); + if (phdr == NULL) + INTERNAL_ERROR (fullname); + + if (phdr->p_type != PT_LOAD) + /* Only load segments. */ + continue; + + if (! first) + fputs_unlocked (" + ", stdout); + first = false; + + printf (radix == radix_hex ? "%" PRIx64 "(%c%c%c)" + : (radix == radix_decimal ? "%" PRId64 "(%c%c%c)" + : "%" PRIo64 "(%c%c%c)"), + phdr->p_memsz, + (phdr->p_flags & PF_R) == 0 ? '-' : 'r', + (phdr->p_flags & PF_W) == 0 ? '-' : 'w', + (phdr->p_flags & PF_X) == 0 ? '-' : 'x'); + + total += phdr->p_memsz; + } + + if (radix == radix_hex) + printf (" = %#" PRIx64 "\n", total); + else if (radix == radix_decimal) + printf (" = %" PRId64 "\n", total); + else + printf (" = %" PRIo64 "\n", total); +} + + +static void +handle_elf (Elf *elf, const char *prefix, const char *fname) +{ + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t fname_len = strlen (fname) + 1; + char fullname[prefix_len + 1 + fname_len]; + char *cp = fullname; + + /* Create the full name of the file. */ + if (prefix != NULL) + { + cp = mempcpy (cp, prefix, prefix_len); + *cp++ = ':'; + } + memcpy (cp, fname, fname_len); + + if (format == format_sysv) + show_sysv (elf, prefix, fname, fullname); + else if (format == format_sysv_one_line) + show_sysv_one_line (elf); + else if (format == format_segments) + show_segments (elf, fullname); + else + { + print_header (elf); + + show_bsd (elf, prefix, fname, fullname); + } +} + + +#include "debugpred.h" diff --git a/src/stack.c b/src/stack.c new file mode 100644 index 00000000..534aa93c --- /dev/null +++ b/src/stack.c @@ -0,0 +1,763 @@ +/* Unwinding of frames like gstack/pstack. + Copyright (C) 2013-2014 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) + +#include +#include +#include + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* non-printable argp options. */ +#define OPT_DEBUGINFO 0x100 +#define OPT_COREFILE 0x101 + +static bool show_activation = false; +static bool show_module = false; +static bool show_build_id = false; +static bool show_source = false; +static bool show_one_tid = false; +static bool show_quiet = false; +static bool show_raw = false; +static bool show_modules = false; +static bool show_debugname = false; +static bool show_inlines = false; + +static int maxframes = 256; + +struct frame +{ + Dwarf_Addr pc; + bool isactivation; +}; + +struct frames +{ + int frames; + int allocated; + struct frame *frame; +}; + +static Dwfl *dwfl = NULL; +static pid_t pid = 0; +static int core_fd = -1; +static Elf *core = NULL; +static const char *exec = NULL; +static char *debuginfo_path = NULL; + +static const Dwfl_Callbacks proc_callbacks = + { + .find_elf = dwfl_linux_proc_find_elf, + .find_debuginfo = dwfl_standard_find_debuginfo, + .debuginfo_path = &debuginfo_path, + }; + +static const Dwfl_Callbacks core_callbacks = + { + .find_elf = dwfl_build_id_find_elf, + .find_debuginfo = dwfl_standard_find_debuginfo, + .debuginfo_path = &debuginfo_path, + }; + +#ifdef USE_DEMANGLE +static size_t demangle_buffer_len = 0; +static char *demangle_buffer = NULL; +#endif + +/* Whether any frames have been shown at all. Determines exit status. */ +static bool frames_shown = false; + +/* Program exit codes. All frames shown without any errors is GOOD. + Some frames shown with some non-fatal errors is an ERROR. A fatal + error or no frames shown at all is BAD. A command line USAGE exit + is generated by argp_error. */ +#define EXIT_OK 0 +#define EXIT_ERROR 1 +#define EXIT_BAD 2 +#define EXIT_USAGE 64 + +static int +get_addr_width (Dwfl_Module *mod) +{ + // Try to find the address wide if possible. + static int width = 0; + if (width == 0 && mod) + { + Dwarf_Addr bias; + Elf *elf = dwfl_module_getelf (mod, &bias); + if (elf) + { + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr) + width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16; + } + } + if (width == 0) + width = 16; + + return width; +} + +static int +module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)), + const char *name, Dwarf_Addr start, + void *arg __attribute__((unused))) +{ + /* Forces resolving of main elf and debug files. */ + Dwarf_Addr bias; + Elf *elf = dwfl_module_getelf (mod, &bias); + Dwarf *dwarf = dwfl_module_getdwarf (mod, &bias); + + Dwarf_Addr end; + const char *mainfile; + const char *debugfile; + const char *modname = dwfl_module_info (mod, NULL, NULL, &end, NULL, + NULL, &mainfile, &debugfile); + if (modname == NULL || strcmp (modname, name) != 0) + { + end = start + 1; + mainfile = NULL; + debugfile = NULL; + } + + int width = get_addr_width (mod); + printf ("0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n", + width, start, width, end, basename (name)); + + const unsigned char *id; + GElf_Addr id_vaddr; + int id_len = dwfl_module_build_id (mod, &id, &id_vaddr); + if (id_len > 0) + { + printf (" ["); + do + printf ("%02" PRIx8, *id++); + while (--id_len > 0); + printf ("]\n"); + } + + if (elf != NULL) + printf (" %s\n", mainfile != NULL ? mainfile : "-"); + if (dwarf != NULL) + printf (" %s\n", debugfile != NULL ? debugfile : "-"); + + return DWARF_CB_OK; +} + +static int +frame_callback (Dwfl_Frame *state, void *arg) +{ + struct frames *frames = (struct frames *) arg; + int nr = frames->frames; + if (! dwfl_frame_pc (state, &frames->frame[nr].pc, + &frames->frame[nr].isactivation)) + return -1; + + frames->frames++; + if (frames->frames == maxframes) + return DWARF_CB_ABORT; + + if (frames->frames == frames->allocated) + { + frames->allocated *= 2; + frames->frame = realloc (frames->frame, + sizeof (struct frame) * frames->allocated); + if (frames->frame == NULL) + error (EXIT_BAD, errno, "realloc frames.frame"); + } + + return DWARF_CB_OK; +} + +static const char* +die_name (Dwarf_Die *die) +{ + Dwarf_Attribute attr; + const char *name; + name = dwarf_formstring (dwarf_attr_integrate (die, + DW_AT_MIPS_linkage_name, + &attr) + ?: dwarf_attr_integrate (die, + DW_AT_linkage_name, + &attr)); + if (name == NULL) + name = dwarf_diename (die); + + return name; +} + +static void +print_frame (int nr, Dwarf_Addr pc, bool isactivation, + Dwarf_Addr pc_adjusted, Dwfl_Module *mod, + const char *symname, Dwarf_Die *cudie, + Dwarf_Die *die) +{ + int width = get_addr_width (mod); + printf ("#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc); + + if (show_activation) + printf ("%4s", ! isactivation ? "- 1" : ""); + + if (symname != NULL) + { +#ifdef USE_DEMANGLE + // Require GNU v3 ABI by the "_Z" prefix. + if (! show_raw && symname[0] == '_' && symname[1] == 'Z') + { + int status = -1; + char *dsymname = __cxa_demangle (symname, demangle_buffer, + &demangle_buffer_len, &status); + if (status == 0) + symname = demangle_buffer = dsymname; + } +#endif + printf (" %s", symname); + } + + const char* fname; + Dwarf_Addr start; + fname = dwfl_module_info(mod, NULL, &start, + NULL, NULL, NULL, NULL, NULL); + if (show_module) + { + if (fname != NULL) + printf (" - %s", fname); + } + + if (show_build_id) + { + const unsigned char *id; + GElf_Addr id_vaddr; + int id_len = dwfl_module_build_id (mod, &id, &id_vaddr); + if (id_len > 0) + { + printf ("\n ["); + do + printf ("%02" PRIx8, *id++); + while (--id_len > 0); + printf ("]@0x%0" PRIx64 "+0x%" PRIx64, + start, pc_adjusted - start); + } + } + + if (show_source) + { + int line, col; + const char* sname; + line = col = -1; + sname = NULL; + if (die != NULL) + { + Dwarf_Files *files; + if (dwarf_getsrcfiles (cudie, &files, NULL) == 0) + { + Dwarf_Attribute attr; + Dwarf_Word val; + if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file, &attr), + &val) == 0) + { + sname = dwarf_filesrc (files, val, NULL, NULL); + if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line, + &attr), &val) == 0) + { + line = val; + if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column, + &attr), &val) == 0) + col = val; + } + } + } + } + else + { + Dwfl_Line *lineobj = dwfl_module_getsrc(mod, pc_adjusted); + if (lineobj) + sname = dwfl_lineinfo (lineobj, NULL, &line, &col, NULL, NULL); + } + + if (sname != NULL) + { + printf ("\n %s", sname); + if (line > 0) + { + printf (":%d", line); + if (col > 0) + printf (":%d", col); + } + } + } + printf ("\n"); +} + +static void +print_inline_frames (int *nr, Dwarf_Addr pc, bool isactivation, + Dwarf_Addr pc_adjusted, Dwfl_Module *mod, + const char *symname, Dwarf_Die *cudie, Dwarf_Die *die) +{ + Dwarf_Die *scopes = NULL; + int nscopes = dwarf_getscopes_die (die, &scopes); + if (nscopes > 0) + { + /* scopes[0] == die, the lowest level, for which we already have + the name. This is the actual source location where it + happened. */ + print_frame ((*nr)++, pc, isactivation, pc_adjusted, mod, symname, + NULL, NULL); + + /* last_scope is the source location where the next frame/function + call was done. */ + Dwarf_Die *last_scope = &scopes[0]; + for (int i = 1; i < nscopes && (maxframes == 0 || *nr < maxframes); i++) + { + Dwarf_Die *scope = &scopes[i]; + int tag = dwarf_tag (scope); + if (tag != DW_TAG_inlined_subroutine + && tag != DW_TAG_entry_point + && tag != DW_TAG_subprogram) + continue; + + symname = die_name (scope); + print_frame ((*nr)++, pc, isactivation, pc_adjusted, mod, symname, + cudie, last_scope); + + /* Found the "top-level" in which everything was inlined? */ + if (tag == DW_TAG_subprogram) + break; + + last_scope = scope; + } + } + free (scopes); +} + +static void +print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) +{ + if (frames->frames > 0) + frames_shown = true; + + printf ("TID %lld:\n", (long long) tid); + int frame_nr = 0; + for (int nr = 0; nr < frames->frames && (maxframes == 0 + || frame_nr < maxframes); nr++) + { + Dwarf_Addr pc = frames->frame[nr].pc; + bool isactivation = frames->frame[nr].isactivation; + Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); + + /* Get PC->SYMNAME. */ + Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); + const char *symname = NULL; + Dwarf_Die die_mem; + Dwarf_Die *die = NULL; + Dwarf_Die *cudie = NULL; + if (mod && ! show_quiet) + { + if (show_debugname) + { + Dwarf_Addr bias = 0; + Dwarf_Die *scopes = NULL; + cudie = dwfl_module_addrdie (mod, pc_adjusted, &bias); + int nscopes = dwarf_getscopes (cudie, pc_adjusted - bias, + &scopes); + + /* Find the first function-like DIE with a name in scope. */ + for (int i = 0; symname == NULL && i < nscopes; i++) + { + Dwarf_Die *scope = &scopes[i]; + int tag = dwarf_tag (scope); + if (tag == DW_TAG_subprogram + || tag == DW_TAG_inlined_subroutine + || tag == DW_TAG_entry_point) + symname = die_name (scope); + + if (symname != NULL) + { + die_mem = *scope; + die = &die_mem; + } + } + free (scopes); + } + + if (symname == NULL) + symname = dwfl_module_addrname (mod, pc_adjusted); + } + + if (show_inlines && die != NULL) + print_inline_frames (&frame_nr, pc, isactivation, pc_adjusted, mod, + symname, cudie, die); + else + print_frame (frame_nr++, pc, isactivation, pc_adjusted, mod, symname, + NULL, NULL); + } + + if (frames->frames > 0 && frame_nr == maxframes) + error (0, 0, "tid %lld: shown max number of frames " + "(%d, use -n 0 for unlimited)", (long long) tid, maxframes); + else if (dwflerr != 0) + { + if (frames->frames > 0) + { + unsigned nr = frames->frames - 1; + Dwarf_Addr pc = frames->frame[nr].pc; + bool isactivation = frames->frame[nr].isactivation; + Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); + Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); + const char *mainfile = NULL; + const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, NULL, + NULL, &mainfile, NULL); + if (modname == NULL || modname[0] == '\0') + { + if (mainfile != NULL) + modname = mainfile; + else + modname = ""; + } + error (0, 0, "%s tid %lld at 0x%" PRIx64 " in %s: %s", what, + (long long) tid, pc_adjusted, modname, dwfl_errmsg (dwflerr)); + } + else + error (0, 0, "%s tid %lld: %s", what, (long long) tid, + dwfl_errmsg (dwflerr)); + } +} + +static int +thread_callback (Dwfl_Thread *thread, void *thread_arg) +{ + struct frames *frames = (struct frames *) thread_arg; + pid_t tid = dwfl_thread_tid (thread); + int err = 0; + frames->frames = 0; + switch (dwfl_thread_getframes (thread, frame_callback, thread_arg)) + { + case DWARF_CB_OK: + case DWARF_CB_ABORT: + break; + case -1: + err = dwfl_errno (); + break; + default: + abort (); + } + print_frames (frames, tid, err, "dwfl_thread_getframes"); + return DWARF_CB_OK; +} + +static error_t +parse_opt (int key, char *arg __attribute__ ((unused)), + struct argp_state *state) +{ + switch (key) + { + case 'p': + pid = atoi (arg); + if (pid == 0) + argp_error (state, N_("-p PID should be a positive process id.")); + break; + + case OPT_COREFILE: + core_fd = open (arg, O_RDONLY); + if (core_fd < 0) + error (EXIT_BAD, errno, N_("Cannot open core file '%s'"), arg); + elf_version (EV_CURRENT); + core = elf_begin (core_fd, ELF_C_READ_MMAP, NULL); + if (core == NULL) + error (EXIT_BAD, 0, "core '%s' elf_begin: %s", arg, elf_errmsg(-1)); + break; + + case 'e': + exec = arg; + break; + + case OPT_DEBUGINFO: + debuginfo_path = arg; + break; + + case 'm': + show_module = true; + break; + + case 's': + show_source = true; + break; + + case 'a': + show_activation = true; + break; + + case 'd': + show_debugname = true; + break; + + case 'i': + show_inlines = show_debugname = true; + break; + + case 'v': + show_activation = show_source = show_module = show_debugname = true; + show_inlines = true; + break; + + case 'b': + show_build_id = true; + break; + + case 'q': + show_quiet = true; + break; + + case 'r': + show_raw = true; + break; + + case '1': + show_one_tid = true; + break; + + case 'n': + maxframes = atoi (arg); + if (maxframes < 0) + { + argp_error (state, N_("-n MAXFRAMES should be 0 or higher.")); + return EINVAL; + } + break; + + case 'l': + show_modules = true; + break; + + case ARGP_KEY_END: + if (core == NULL && exec != NULL) + argp_error (state, + N_("-e EXEC needs a core given by --core.")); + + if (pid == 0 && show_one_tid == true) + argp_error (state, + N_("-1 needs a thread id given by -p.")); + + if ((pid == 0 && core == NULL) || (pid != 0 && core != NULL)) + argp_error (state, + N_("One of -p PID or --core COREFILE should be given.")); + + if (pid != 0) + { + dwfl = dwfl_begin (&proc_callbacks); + if (dwfl == NULL) + error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); + + int err = dwfl_linux_proc_report (dwfl, pid); + if (err < 0) + error (EXIT_BAD, 0, "dwfl_linux_proc_report pid %lld: %s", + (long long) pid, dwfl_errmsg (-1)); + else if (err > 0) + error (EXIT_BAD, err, "dwfl_linux_proc_report pid %lld", + (long long) pid); + } + + if (core != NULL) + { + dwfl = dwfl_begin (&core_callbacks); + if (dwfl == NULL) + error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); + if (dwfl_core_file_report (dwfl, core, exec) < 0) + error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1)); + } + + if (dwfl_report_end (dwfl, NULL, NULL) != 0) + error (EXIT_BAD, 0, "dwfl_report_end: %s", dwfl_errmsg (-1)); + + if (pid != 0) + { + int err = dwfl_linux_proc_attach (dwfl, pid, false); + if (err < 0) + error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %lld: %s", + (long long) pid, dwfl_errmsg (-1)); + else if (err > 0) + error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %lld", + (long long) pid); + } + + if (core != NULL) + { + if (dwfl_core_file_attach (dwfl, core) < 0) + error (EXIT_BAD, 0, "dwfl_core_file_attach: %s", dwfl_errmsg (-1)); + } + + /* Makes sure we are properly attached. */ + if (dwfl_pid (dwfl) < 0) + error (EXIT_BAD, 0, "dwfl_pid: %s\n", dwfl_errmsg (-1)); + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +int +main (int argc, char **argv) +{ + /* We use no threads here which can interfere with handling a stream. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + const struct argp_option options[] = + { + { NULL, 0, NULL, 0, N_("Input selection options:"), 0 }, + { "pid", 'p', "PID", 0, + N_("Show stack of process PID"), 0 }, + { "core", OPT_COREFILE, "COREFILE", 0, + N_("Show stack found in COREFILE"), 0 }, + { "executable", 'e', "EXEC", 0, N_("(optional) EXECUTABLE that produced COREFILE"), 0 }, + { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0, + N_("Search path for separate debuginfo files"), 0 }, + + { NULL, 0, NULL, 0, N_("Output selection options:"), 0 }, + { "activation", 'a', NULL, 0, + N_("Additionally show frame activation"), 0 }, + { "debugname", 'd', NULL, 0, + N_("Additionally try to lookup DWARF debuginfo name for frame address"), + 0 }, + { "inlines", 'i', NULL, 0, + N_("Additionally show inlined function frames using DWARF debuginfo if available (implies -d)"), 0 }, + { "module", 'm', NULL, 0, + N_("Additionally show module file information"), 0 }, + { "source", 's', NULL, 0, + N_("Additionally show source file information"), 0 }, + { "verbose", 'v', NULL, 0, + N_("Show all additional information (activation, debugname, inlines, module and source)"), 0 }, + { "quiet", 'q', NULL, 0, + N_("Do not resolve address to function symbol name"), 0 }, + { "raw", 'r', NULL, 0, + N_("Show raw function symbol names, do not try to demangle names"), 0 }, + { "build-id", 'b', NULL, 0, + N_("Show module build-id, load address and pc offset"), 0 }, + { NULL, '1', NULL, 0, + N_("Show the backtrace of only one thread"), 0 }, + { NULL, 'n', "MAXFRAMES", 0, + N_("Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"), 0 }, + { "list-modules", 'l', NULL, 0, + N_("Show module memory map with build-id, elf and debug files detected"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } + }; + + const struct argp argp = + { + .options = options, + .parser = parse_opt, + .doc = N_("Print a stack for each thread in a process or core file.\n\ +\n\ +Program exits with return code 0 if all frames were shown without \ +any errors. If some frames were shown, but there were some non-fatal \ +errors, possibly causing an incomplete backtrace, the program exits \ +with return code 1. If no frames could be shown, or a fatal error \ +occurred the program exits with return code 2. If the program was \ +invoked with bad or missing arguments it will exit with return code 64.") + }; + + argp_parse (&argp, argc, argv, 0, NULL, NULL); + + if (show_modules) + { + printf ("PID %lld - %s module memory map\n", (long long) dwfl_pid (dwfl), + pid != 0 ? "process" : "core"); + if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0) + error (EXIT_BAD, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1)); + } + + struct frames frames; + /* When maxframes is zero, then 2048 is just the initial allocation + that will be increased using realloc in framecallback (). */ + frames.allocated = maxframes == 0 ? 2048 : maxframes; + frames.frames = 0; + frames.frame = malloc (sizeof (struct frame) * frames.allocated); + if (frames.frame == NULL) + error (EXIT_BAD, errno, "malloc frames.frame"); + + if (show_one_tid) + { + int err = 0; + switch (dwfl_getthread_frames (dwfl, pid, frame_callback, &frames)) + { + case DWARF_CB_OK: + case DWARF_CB_ABORT: + break; + case -1: + err = dwfl_errno (); + break; + default: + abort (); + } + print_frames (&frames, pid, err, "dwfl_getthread_frames"); + } + else + { + printf ("PID %lld - %s\n", (long long) dwfl_pid (dwfl), + pid != 0 ? "process" : "core"); + switch (dwfl_getthreads (dwfl, thread_callback, &frames)) + { + case DWARF_CB_OK: + case DWARF_CB_ABORT: + break; + case -1: + error (0, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1)); + break; + default: + abort (); + } + } + free (frames.frame); + dwfl_end (dwfl); + + if (core != NULL) + elf_end (core); + + if (core_fd != -1) + close (core_fd); + +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif + + if (! frames_shown) + error (EXIT_BAD, 0, N_("Couldn't show any frames.")); + + return error_message_count != 0 ? EXIT_ERROR : EXIT_OK; +} diff --git a/src/strings.c b/src/strings.c new file mode 100644 index 00000000..eb278f8e --- /dev/null +++ b/src/strings.c @@ -0,0 +1,747 @@ +/* Print the strings of printable characters in files. + Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2005. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef MAP_POPULATE +# define MAP_POPULATE 0 +#endif + + +/* Prototypes of local functions. */ +static int read_fd (int fd, const char *fname, off_t fdlen); +static int read_elf (Elf *elf, int fd, const char *fname, off_t fdlen); + + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Output Selection:"), 0 }, + { "all", 'a', NULL, 0, N_("Scan entire file, not only loaded sections"), 0 }, + { "bytes", 'n', "MIN-LEN", 0, + N_("Only NUL-terminated sequences of MIN-LEN characters or more are printed"), 0 }, + { "encoding", 'e', "SELECTOR", 0, N_("\ +Select character size and endianness: s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit"), + 0}, + { "print-file-name", 'f', NULL, 0, + N_("Print name of the file before each string."), 0 }, + { "radix", 't', "{o,d,x}", 0, + N_("Print location of the string in base 8, 10, or 16 respectively."), 0 }, + { NULL, 'o', NULL, 0, N_("Alias for --radix=o"), 0 }, + + { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("\ +Print the strings of printable characters in files."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + + +/* Global variables. */ + +/* True if whole file and not only loaded sections are looked at. */ +static bool entire_file; + +/* Minimum length of any sequence reported. */ +static size_t min_len = 4; + +/* Number of bytes per character. */ +static size_t bytes_per_char = 1; + +/* Minimum length of any sequence reported in bytes. */ +static size_t min_len_bytes; + +/* True if multibyte characters are in big-endian order. */ +static bool big_endian; + +/* True unless 7-bit ASCII are expected. */ +static bool char_7bit; + +/* True if file names should be printed before strings. */ +static bool print_file_name; + +/* Radix for printed numbers. */ +static enum +{ + radix_none = 0, + radix_decimal, + radix_hex, + radix_octal +} radix = radix_none; + + +/* Page size in use. */ +static size_t ps; + + +/* Mapped parts of the ELF file. */ +static unsigned char *elfmap; +static unsigned char *elfmap_base; +static size_t elfmap_size; +static off_t elfmap_off; + + +int +main (int argc, char *argv[]) +{ + /* We use no threads. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + (void) textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + int remaining; + (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + /* Tell the library which version we are expecting. */ + elf_version (EV_CURRENT); + + /* Determine the page size. We will likely need it a couple of times. */ + ps = sysconf (_SC_PAGESIZE); + + struct stat st; + int result = 0; + if (remaining == argc) + /* We read from standard input. This we cannot do for a + structured file. */ + result = read_fd (STDIN_FILENO, + print_file_name ? "{standard input}" : NULL, + (fstat (STDIN_FILENO, &st) == 0 && S_ISREG (st.st_mode)) + ? st.st_size : INT64_C (0x7fffffffffffffff)); + else + do + { + int fd = (strcmp (argv[remaining], "-") == 0 + ? STDIN_FILENO : open (argv[remaining], O_RDONLY)); + if (unlikely (fd == -1)) + { + error (0, errno, _("cannot open '%s'"), argv[remaining]); + result = 1; + } + else + { + const char *fname = print_file_name ? argv[remaining] : NULL; + int fstat_fail = fstat (fd, &st); + off_t fdlen = (fstat_fail + ? INT64_C (0x7fffffffffffffff) : st.st_size); + if (fdlen > (off_t) min_len_bytes) + { + Elf *elf = NULL; + if (entire_file + || fstat_fail + || !S_ISREG (st.st_mode) + || (elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL + || elf_kind (elf) != ELF_K_ELF) + result |= read_fd (fd, fname, fdlen); + else + result |= read_elf (elf, fd, fname, fdlen); + + /* This call will succeed even if ELF is NULL. */ + elf_end (elf); + } + + if (strcmp (argv[remaining], "-") != 0) + close (fd); + } + + if (elfmap != NULL && elfmap != MAP_FAILED) + munmap (elfmap, elfmap_size); + elfmap = NULL; + } + while (++remaining < argc); + + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, + struct argp_state *state __attribute__ ((unused))) +{ + switch (key) + { + case 'a': + entire_file = true; + break; + + case 'e': + /* We expect a string of one character. */ + switch (arg[1] != '\0' ? '\0' : arg[0]) + { + case 's': + case 'S': + char_7bit = arg[0] == 's'; + bytes_per_char = 1; + break; + + case 'b': + case 'B': + big_endian = true; + FALLTHROUGH; + + case 'l': + case 'L': + bytes_per_char = isupper (arg[0]) ? 4 : 2; + break; + + default: + error (0, 0, _("invalid value '%s' for %s parameter"), + arg, "-e"); + argp_help (&argp, stderr, ARGP_HELP_SEE, "strings"); + return ARGP_ERR_UNKNOWN; + } + break; + + case 'f': + print_file_name = true; + break; + + case 'n': + min_len = atoi (arg); + break; + + case 'o': + goto octfmt; + + case 't': + switch (arg[0]) + { + case 'd': + radix = radix_decimal; + break; + + case 'o': + octfmt: + radix = radix_octal; + break; + + case 'x': + radix = radix_hex; + break; + + default: + error (0, 0, _("invalid value '%s' for %s parameter"), + arg, "-t"); + argp_help (&argp, stderr, ARGP_HELP_SEE, "strings"); + return ARGP_ERR_UNKNOWN; + } + break; + + case ARGP_KEY_FINI: + /* Compute the length in bytes of any match. */ + if (min_len <= 0 || min_len > INT_MAX / bytes_per_char) + error (EXIT_FAILURE, 0, + _("invalid minimum length of matched string size")); + min_len_bytes = min_len * bytes_per_char; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +static void +process_chunk_mb (const char *fname, const unsigned char *buf, off_t to, + size_t len, char **unprinted) +{ + size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted); + const unsigned char *start = buf; + while (len >= bytes_per_char) + { + uint32_t ch; + + if (bytes_per_char == 2) + { + if (big_endian) + ch = buf[0] << 8 | buf[1]; + else + ch = buf[1] << 8 | buf[0]; + } + else + { + if (big_endian) + ch = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; + else + ch = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; + } + + if (ch <= 255 && (isprint (ch) || ch == '\t')) + { + ++buf; + ++curlen; + } + else + { + if (curlen >= min_len) + { + /* We found a match. */ + if (unlikely (fname != NULL)) + { + fputs_unlocked (fname, stdout); + fputs_unlocked (": ", stdout); + } + + if (unlikely (radix != radix_none)) + printf ((radix == radix_octal ? "%7" PRIo64 " " + : (radix == radix_decimal ? "%7" PRId64 " " + : "%7" PRIx64 " ")), + (int64_t) to - len - (buf - start)); + + if (unlikely (*unprinted != NULL)) + { + fputs_unlocked (*unprinted, stdout); + free (*unprinted); + *unprinted = NULL; + } + + /* There is no sane way of printing the string. If we + assume the file data is encoded in UCS-2/UTF-16 or + UCS-4/UTF-32 respectively we could covert the string. + But there is no such guarantee. */ + fwrite_unlocked (start, 1, buf - start, stdout); + putc_unlocked ('\n', stdout); + } + + start = ++buf; + curlen = 0; + + if (len <= min_len) + break; + } + + --len; + } + + if (curlen != 0) + *unprinted = xstrndup ((const char *) start, curlen); +} + + +static void +process_chunk (const char *fname, const unsigned char *buf, off_t to, + size_t len, char **unprinted) +{ + /* We are not going to slow the check down for the 2- and 4-byte + encodings. Handle them special. */ + if (unlikely (bytes_per_char != 1)) + { + process_chunk_mb (fname, buf, to, len, unprinted); + return; + } + + size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted); + const unsigned char *start = buf; + while (len > 0) + { + if ((isprint (*buf) || *buf == '\t') && (! char_7bit || *buf <= 127)) + { + ++buf; + ++curlen; + } + else + { + if (curlen >= min_len) + { + /* We found a match. */ + if (likely (fname != NULL)) + { + fputs_unlocked (fname, stdout); + fputs_unlocked (": ", stdout); + } + + if (likely (radix != radix_none)) + printf ((radix == radix_octal ? "%7" PRIo64 " " + : (radix == radix_decimal ? "%7" PRId64 " " + : "%7" PRIx64 " ")), + (int64_t) to - len - (buf - start)); + + if (unlikely (*unprinted != NULL)) + { + fputs_unlocked (*unprinted, stdout); + free (*unprinted); + *unprinted = NULL; + } + fwrite_unlocked (start, 1, buf - start, stdout); + putc_unlocked ('\n', stdout); + } + + start = ++buf; + curlen = 0; + + if (len <= min_len) + break; + } + + --len; + } + + if (curlen != 0) + *unprinted = xstrndup ((const char *) start, curlen); +} + + +/* Map a file in as large chunks as possible. */ +static void * +map_file (int fd, off_t start_off, off_t fdlen, size_t *map_sizep) +{ + /* Maximum size we mmap. We use an #ifdef to avoid overflows on + 32-bit machines. 64-bit machines these days do not have usable + address spaces larger than about 43 bits. Not that any file + should be that large. */ +# if SIZE_MAX > 0xffffffff + const size_t mmap_max = 0x4000000000lu; +# else + const size_t mmap_max = 0x40000000lu; +# endif + + /* Try to mmap the file. */ + size_t map_size = MIN ((off_t) mmap_max, fdlen); + const size_t map_size_min = MAX (MAX (SIZE_MAX / 16, 2 * ps), + roundup (2 * min_len_bytes + 1, ps)); + void *mem; + while (1) + { + /* We map the memory for reading only here. Since we will + always look at every byte of the file it makes sense to + use MAP_POPULATE. */ + mem = mmap (NULL, map_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, + fd, start_off); + if (mem != MAP_FAILED) + { + /* We will go through the mapping sequentially. */ + (void) posix_madvise (mem, map_size, POSIX_MADV_SEQUENTIAL); + break; + } + if (errno != EINVAL && errno != ENOMEM) + /* This is an error other than the lack of address space. */ + break; + + /* Maybe the size of the mapping is too big. Try again. */ + map_size /= 2; + if (map_size < map_size_min) + /* That size should have fit. */ + break; + } + + *map_sizep = map_size; + return mem; +} + + +/* Read the file without mapping. */ +static int +read_block_no_mmap (int fd, const char *fname, off_t from, off_t fdlen) +{ + char *unprinted = NULL; +#define CHUNKSIZE 65536 + unsigned char *buf = xmalloc (CHUNKSIZE + min_len_bytes + + bytes_per_char - 1); + size_t ntrailer = 0; + int result = 0; + while (fdlen > 0) + { + ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + ntrailer, + MIN (fdlen, CHUNKSIZE))); + if (n == 0) + { + /* There are less than MIN_LEN+1 bytes left so there cannot be + another match. */ + assert (unprinted == NULL || ntrailer == 0); + break; + } + if (unlikely (n < 0)) + { + /* Something went wrong. */ + result = 1; + break; + } + + /* Account for the number of bytes read in this round. */ + fdlen -= n; + + /* Do not use the signed N value. Note that the addition cannot + overflow. */ + size_t nb = (size_t) n + ntrailer; + if (nb >= min_len_bytes) + { + /* We only use complete characters. */ + nb &= ~(bytes_per_char - 1); + + process_chunk (fname, buf, from + nb, nb, &unprinted); + + /* If the last bytes of the buffer (modulo the character + size) have been printed we are not copying them. */ + size_t to_keep = unprinted != NULL ? 0 : min_len_bytes; + + memmove (buf, buf + nb - to_keep, to_keep); + ntrailer = to_keep; + from += nb; + } + else + ntrailer = nb; + } + + free (buf); + + /* Don't print anything we collected so far. There is no + terminating NUL byte. */ + free (unprinted); + + return result; +} + + +static int +read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to) +{ + if (elfmap == NULL) + { + /* We need a completely new mapping. */ + elfmap_off = from & ~(ps - 1); + elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size); + + if (unlikely (elfmap == MAP_FAILED)) + /* Let the kernel know we are going to read everything in sequence. */ + (void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL); + } + + if (unlikely (elfmap == MAP_FAILED)) + { + /* Read from the file descriptor. For this we must position the + read pointer. */ + // XXX Eventually add flag which avoids this if the position + // XXX is known to match. + if (from != 0 && lseek (fd, from, SEEK_SET) != from) + error (EXIT_FAILURE, errno, _("lseek failed")); + + return read_block_no_mmap (fd, fname, from, to - from); + } + + assert ((off_t) min_len_bytes < fdlen); + + if (to < (off_t) elfmap_off || from > (off_t) (elfmap_off + elfmap_size)) + { + /* The existing mapping cannot fit at all. Map the new area. + We always map the full range of ELFMAP_SIZE bytes even if + this extend beyond the end of the file. The Linux kernel + handles this OK if the access pages are not touched. */ + elfmap_off = from & ~(ps - 1); + if (mmap (elfmap, elfmap_size, PROT_READ, + MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, from) + == MAP_FAILED) + error (EXIT_FAILURE, errno, _("re-mmap failed")); + elfmap_base = elfmap; + } + + char *unprinted = NULL; + + /* Use the existing mapping as much as possible. If necessary, map + new pages. */ + if (from >= (off_t) elfmap_off + && from < (off_t) (elfmap_off + elfmap_size)) + /* There are at least a few bytes in this mapping which we can + use. */ + process_chunk (fname, elfmap_base + (from - elfmap_off), + MIN (to, (off_t) (elfmap_off + elfmap_size)), + MIN (to, (off_t) (elfmap_off + elfmap_size)) - from, + &unprinted); + + if (to > (off_t) (elfmap_off + elfmap_size)) + { + unsigned char *remap_base = elfmap_base; + size_t read_now = elfmap_size - (elfmap_base - elfmap); + + assert (from >= (off_t) elfmap_off + && from < (off_t) (elfmap_off + elfmap_size)); + off_t handled_to = elfmap_off + elfmap_size; + assert (elfmap == elfmap_base + || (elfmap_base - elfmap + == (ptrdiff_t) ((min_len_bytes + ps - 1) & ~(ps - 1)))); + if (elfmap == elfmap_base) + { + size_t keep_area = (min_len_bytes + ps - 1) & ~(ps - 1); + assert (elfmap_size >= keep_area + ps); + /* The keep area is used for the content of the previous + buffer we have to keep. This means copying those bytes + and for this we have to make the data writable. */ + if (unlikely (mprotect (elfmap, keep_area, PROT_READ | PROT_WRITE) + != 0)) + error (EXIT_FAILURE, errno, _("mprotect failed")); + + elfmap_base = elfmap + keep_area; + } + + while (1) + { + /* Map the rest of the file, eventually again in pieces. + We speed things up with a nice Linux feature. Note + that we have at least two pages mapped. */ + size_t to_keep = unprinted != NULL ? 0 : min_len_bytes; + + assert (read_now >= to_keep); + memmove (elfmap_base - to_keep, + remap_base + read_now - to_keep, to_keep); + remap_base = elfmap_base; + + assert ((elfmap_size - (elfmap_base - elfmap)) % bytes_per_char + == 0); + read_now = MIN (to - handled_to, + (ptrdiff_t) elfmap_size - (elfmap_base - elfmap)); + + assert (handled_to % ps == 0); + assert (handled_to % bytes_per_char == 0); + if (mmap (remap_base, read_now, PROT_READ, + MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, handled_to) + == MAP_FAILED) + error (EXIT_FAILURE, errno, _("re-mmap failed")); + elfmap_off = handled_to; + + process_chunk (fname, remap_base - to_keep, + elfmap_off + (read_now & ~(bytes_per_char - 1)), + to_keep + (read_now & ~(bytes_per_char - 1)), + &unprinted); + handled_to += read_now; + if (handled_to >= to) + break; + } + } + + /* Don't print anything we collected so far. There is no + terminating NUL byte. */ + free (unprinted); + + return 0; +} + + +static int +read_fd (int fd, const char *fname, off_t fdlen) +{ + return read_block (fd, fname, fdlen, 0, fdlen); +} + + +static int +read_elf (Elf *elf, int fd, const char *fname, off_t fdlen) +{ + assert (fdlen >= 0); + + /* We will look at each section separately. The ELF file is not + mmapped. The libelf implementation will load the needed parts on + demand. Since we only iterate over the section header table the + memory consumption at this stage is kept minimal. */ + Elf_Scn *scn = elf_nextscn (elf, NULL); + if (scn == NULL) + return read_fd (fd, fname, fdlen); + + int result = 0; + do + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + + /* Only look in sections which are loaded at runtime and + actually have content. */ + if (shdr != NULL && shdr->sh_type != SHT_NOBITS + && (shdr->sh_flags & SHF_ALLOC) != 0) + { + if (shdr->sh_offset > (Elf64_Off) fdlen + || fdlen - shdr->sh_offset < shdr->sh_size) + { + size_t strndx = 0; + const char *sname; + if (unlikely (elf_getshdrstrndx (elf, &strndx) < 0)) + sname = ""; + else + sname = elf_strptr (elf, strndx, shdr->sh_name) ?: ""; + error (0, 0, + _("Skipping section %zd '%s' data outside file"), + elf_ndxscn (scn), sname); + result = 1; + } + else + result |= read_block (fd, fname, fdlen, shdr->sh_offset, + shdr->sh_offset + shdr->sh_size); + } + } + while ((scn = elf_nextscn (elf, scn)) != NULL); + + if (elfmap != NULL && elfmap != MAP_FAILED) + munmap (elfmap, elfmap_size); + elfmap = NULL; + + return result; +} + + +#include "debugpred.h" diff --git a/src/strip.c b/src/strip.c new file mode 100644 index 00000000..70fc8c03 --- /dev/null +++ b/src/strip.c @@ -0,0 +1,2769 @@ +/* Discard section not used at runtime from object files. + Copyright (C) 2000-2012, 2014, 2015, 2016, 2017, 2018 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2000. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "libdwelf.h" +#include +#include +#include + +typedef uint8_t GElf_Byte; + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + + +/* Values for the parameters which have no short form. */ +#define OPT_REMOVE_COMMENT 0x100 +#define OPT_PERMISSIVE 0x101 +#define OPT_STRIP_SECTIONS 0x102 +#define OPT_RELOC_DEBUG 0x103 +#define OPT_KEEP_SECTION 0x104 +#define OPT_RELOC_DEBUG_ONLY 0x105 + + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Output selection:"), 0 }, + { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 }, + { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 }, + { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 }, + + { NULL, 0, NULL, 0, N_("Output options:"), 0 }, + { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 }, + { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 }, + { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 }, + { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 }, + { "strip-sections", OPT_STRIP_SECTIONS, NULL, 0, + N_("Remove section headers (not recommended)"), 0 }, + { "preserve-dates", 'p', NULL, 0, + N_("Copy modified/access timestamps to the output"), 0 }, + { "reloc-debug-sections", OPT_RELOC_DEBUG, NULL, 0, + N_("Resolve all trivial relocations between debug sections if the removed sections are placed in a debug file (only relevant for ET_REL files, operation is not reversible, needs -f)"), 0 }, + { "reloc-debug-sections-only", OPT_RELOC_DEBUG_ONLY, NULL, 0, + N_("Similar to --reloc-debug-sections, but resolve all trivial relocations between debug sections in place. No other stripping is performed (operation is not reversible, incompatible with -f, -g, --remove-comment and --remove-section)"), 0 }, + { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0, + N_("Remove .comment section"), 0 }, + { "remove-section", 'R', "SECTION", 0, N_("Remove the named section. SECTION is an extended wildcard pattern. May be given more than once. Only non-allocated sections can be removed."), 0 }, + { "keep-section", OPT_KEEP_SECTION, "SECTION", 0, N_("Keep the named section. SECTION is an extended wildcard pattern. May be given more than once."), 0 }, + { "permissive", OPT_PERMISSIVE, NULL, 0, + N_("Relax a few rules to handle slightly broken ELF files"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +/* Short description of program. */ +static const char doc[] = N_("Discard symbols from object files."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, NULL, NULL +}; + + +/* Print symbols in file named FNAME. */ +static int process_file (const char *fname); + +/* Handle one ELF file. */ +static int handle_elf (int fd, Elf *elf, const char *prefix, + const char *fname, mode_t mode, struct timespec tvp[2]); + +/* Handle all files contained in the archive. */ +static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, + struct timespec tvp[2]) __attribute__ ((unused)); + +static int debug_fd = -1; +static char *tmp_debug_fname = NULL; + +/* Close debug file descriptor, if opened. And remove temporary debug file. */ +static void cleanup_debug (void); + +#define INTERNAL_ERROR(fname) \ + do { \ + cleanup_debug (); \ + error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"), \ + fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \ + } while (0) + + +/* Name of the output file. */ +static const char *output_fname; + +/* Name of the debug output file. */ +static const char *debug_fname; + +/* Name to pretend the debug output file has. */ +static const char *debug_fname_embed; + +/* If true output files shall have same date as the input file. */ +static bool preserve_dates; + +/* If true .comment sections will be removed. */ +static bool remove_comment; + +/* If true remove all debug sections. */ +static bool remove_debug; + +/* If true remove all section headers. */ +static bool remove_shdrs; + +/* If true relax some ELF rules for input files. */ +static bool permissive; + +/* If true perform relocations between debug sections. */ +static bool reloc_debug; + +/* If true perform relocations between debug sections only. */ +static bool reloc_debug_only; + +/* Sections the user explicitly wants to keep or remove. */ +struct section_pattern +{ + char *pattern; + struct section_pattern *next; +}; + +static struct section_pattern *keep_secs = NULL; +static struct section_pattern *remove_secs = NULL; + +static void +add_pattern (struct section_pattern **patterns, const char *pattern) +{ + struct section_pattern *p = xmalloc (sizeof *p); + p->pattern = xstrdup (pattern); + p->next = *patterns; + *patterns = p; +} + +static void +free_sec_patterns (struct section_pattern *patterns) +{ + struct section_pattern *pattern = patterns; + while (pattern != NULL) + { + struct section_pattern *p = pattern; + pattern = p->next; + free (p->pattern); + free (p); + } +} + +static void +free_patterns (void) +{ + free_sec_patterns (keep_secs); + free_sec_patterns (remove_secs); +} + +static bool +section_name_matches (struct section_pattern *patterns, const char *name) +{ + struct section_pattern *pattern = patterns; + while (pattern != NULL) + { + if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0) + return true; + pattern = pattern->next; + } + return false; +} + + +int +main (int argc, char *argv[]) +{ + int remaining; + int result = 0; + + /* We use no threads here which can interfere with handling a stream. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0) + return EXIT_FAILURE; + + if (reloc_debug && debug_fname == NULL) + error (EXIT_FAILURE, 0, + _("--reloc-debug-sections used without -f")); + + if (reloc_debug_only && + (debug_fname != NULL || remove_secs != NULL + || remove_comment == true || remove_debug == true)) + error (EXIT_FAILURE, 0, + _("--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --remove-section")); + + /* Tell the library which version we are expecting. */ + elf_version (EV_CURRENT); + + if (remaining == argc) + /* The user didn't specify a name so we use a.out. */ + result = process_file ("a.out"); + else + { + /* If we have seen the '-o' or '-f' option there must be exactly one + input file. */ + if ((output_fname != NULL || debug_fname != NULL) + && remaining + 1 < argc) + error (EXIT_FAILURE, 0, _("\ +Only one input file allowed together with '-o' and '-f'")); + + /* Process all the remaining files. */ + do + result |= process_file (argv[remaining]); + while (++remaining < argc); + } + + free_patterns (); + return result; +} + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'f': + if (debug_fname != NULL) + { + error (0, 0, _("-f option specified twice")); + return EINVAL; + } + debug_fname = arg; + break; + + case 'F': + if (debug_fname_embed != NULL) + { + error (0, 0, _("-F option specified twice")); + return EINVAL; + } + debug_fname_embed = arg; + break; + + case 'o': + if (output_fname != NULL) + { + error (0, 0, _("-o option specified twice")); + return EINVAL; + } + output_fname = arg; + break; + + case 'p': + preserve_dates = true; + break; + + case OPT_RELOC_DEBUG: + reloc_debug = true; + break; + + case OPT_RELOC_DEBUG_ONLY: + reloc_debug_only = true; + break; + + case OPT_REMOVE_COMMENT: + remove_comment = true; + break; + + case 'R': + if (fnmatch (arg, ".comment", FNM_EXTMATCH) == 0) + remove_comment = true; + add_pattern (&remove_secs, arg); + break; + + case OPT_KEEP_SECTION: + add_pattern (&keep_secs, arg); + break; + + case 'g': + case 'd': + case 'S': + remove_debug = true; + break; + + case OPT_STRIP_SECTIONS: + remove_shdrs = true; + break; + + case OPT_PERMISSIVE: + permissive = true; + break; + + case 's': /* Ignored for compatibility. */ + break; + + case ARGP_KEY_SUCCESS: + if (remove_comment == true + && section_name_matches (keep_secs, ".comment")) + { + argp_error (state, + _("cannot both keep and remove .comment section")); + return EINVAL; + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static const char * +secndx_name (Elf *elf, size_t ndx) +{ + size_t shstrndx; + GElf_Shdr mem; + Elf_Scn *sec = elf_getscn (elf, ndx); + GElf_Shdr *shdr = gelf_getshdr (sec, &mem); + if (shdr == NULL || elf_getshdrstrndx (elf, &shstrndx) < 0) + return "???"; + return elf_strptr (elf, shstrndx, shdr->sh_name) ?: "???"; +} + +/* Get the extended section index table data for a symbol table section. */ +static Elf_Data * +get_xndxdata (Elf *elf, Elf_Scn *symscn) +{ + Elf_Data *xndxdata = NULL; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem); + if (shdr != NULL && shdr->sh_type == SHT_SYMTAB) + { + size_t scnndx = elf_ndxscn (symscn); + Elf_Scn *xndxscn = NULL; + while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL) + { + GElf_Shdr xndxshdr_mem; + GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); + + if (xndxshdr != NULL + && xndxshdr->sh_type == SHT_SYMTAB_SHNDX + && xndxshdr->sh_link == scnndx) + { + xndxdata = elf_getdata (xndxscn, NULL); + break; + } + } + } + + return xndxdata; +} + +/* Updates the shdrstrndx for the given Elf by updating the Ehdr and + possibly the section zero extension field. Returns zero on success. */ +static int +update_shdrstrndx (Elf *elf, size_t shdrstrndx) +{ + GElf_Ehdr ehdr; + if (gelf_getehdr (elf, &ehdr) == 0) + return 1; + + if (shdrstrndx < SHN_LORESERVE) + ehdr.e_shstrndx = shdrstrndx; + else + { + ehdr.e_shstrndx = SHN_XINDEX; + Elf_Scn *scn0 = elf_getscn (elf, 0); + GElf_Shdr shdr0_mem; + GElf_Shdr *shdr0 = gelf_getshdr (scn0, &shdr0_mem); + if (shdr0 == NULL) + return 1; + + shdr0->sh_link = shdrstrndx; + if (gelf_update_shdr (scn0, shdr0) == 0) + return 1; + } + + if (unlikely (gelf_update_ehdr (elf, &ehdr) == 0)) + return 1; + + return 0; +} + + +/* Apply one relocation. Returns true when trivial + relocation actually done. */ +static bool +relocate (Elf *elf, GElf_Addr offset, const GElf_Sxword addend, + Elf_Data *tdata, unsigned int ei_data, const char *fname, + bool is_rela, GElf_Sym *sym, int addsub, Elf_Type type) +{ + /* These are the types we can relocate. */ +#define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \ + DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \ + DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword) + + size_t size; + +#define DO_TYPE(NAME, Name) GElf_##Name Name; + union { TYPES; } tmpbuf; +#undef DO_TYPE + + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + size = sizeof (GElf_##Name); \ + tmpbuf.Name = 0; \ + break; + TYPES; +#undef DO_TYPE + default: + return false; + } + + if (offset > tdata->d_size + || tdata->d_size - offset < size) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, _("bad relocation")); + } + + /* When the symbol value is zero then for SHT_REL + sections this is all that needs to be checked. + The addend is contained in the original data at + the offset already. So if the (section) symbol + address is zero and the given addend is zero + just remove the relocation, it isn't needed + anymore. */ + if (addend == 0 && sym->st_value == 0) + return true; + + Elf_Data tmpdata = + { + .d_type = type, + .d_buf = &tmpbuf, + .d_size = size, + .d_version = EV_CURRENT, + }; + Elf_Data rdata = + { + .d_type = type, + .d_buf = tdata->d_buf + offset, + .d_size = size, + .d_version = EV_CURRENT, + }; + + GElf_Addr value = sym->st_value; + if (is_rela) + { + /* For SHT_RELA sections we just take the + given addend and add it to the value. */ + value += addend; + /* For ADD/SUB relocations we need to fetch the + current section contents. */ + if (addsub != 0) + { + Elf_Data *d = gelf_xlatetom (elf, &tmpdata, + &rdata, + ei_data); + if (d == NULL) + INTERNAL_ERROR (fname); + assert (d == &tmpdata); + } + } + else + { + /* For SHT_REL sections we have to peek at + what is already in the section at the given + offset to get the addend. */ + Elf_Data *d = gelf_xlatetom (elf, &tmpdata, + &rdata, + ei_data); + if (d == NULL) + INTERNAL_ERROR (fname); + assert (d == &tmpdata); + } + + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + if (addsub < 0) \ + tmpbuf.Name -= (GElf_##Name) value; \ + else \ + tmpbuf.Name += (GElf_##Name) value; \ + break; + TYPES; +#undef DO_TYPE + default: + abort (); + } + + /* Now finally put in the new value. */ + Elf_Data *s = gelf_xlatetof (elf, &rdata, + &tmpdata, + ei_data); + if (s == NULL) + INTERNAL_ERROR (fname); + assert (s == &rdata); + + return true; +} + +/* Remove any relocations between debug sections in ET_REL + for the debug file when requested. These relocations are always + zero based between the unallocated sections. */ +static void +remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr, + const char *fname, size_t shstrndx) +{ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + /* We need the actual section and header from the elf + not just the cached original in shdr_info because we + might want to change the size. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) + { + /* Make sure that this relocation section points to a + section to relocate with contents, that isn't + allocated and that is a debug section. */ + Elf_Scn *tscn = elf_getscn (elf, shdr->sh_info); + GElf_Shdr tshdr_mem; + GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem); + if (tshdr->sh_type == SHT_NOBITS + || tshdr->sh_size == 0 + || (tshdr->sh_flags & SHF_ALLOC) != 0) + continue; + + const char *tname = elf_strptr (elf, shstrndx, + tshdr->sh_name); + if (! tname || ! ebl_debugscn_p (ebl, tname)) + continue; + + /* OK, lets relocate all trivial cross debug section + relocations. */ + Elf_Data *reldata = elf_getdata (scn, NULL); + if (reldata == NULL || reldata->d_buf == NULL) + INTERNAL_ERROR (fname); + + /* Make sure we adjust the uncompressed debug data + (and recompress if necessary at the end). */ + GElf_Chdr tchdr; + int tcompress_type = 0; + bool is_gnu_compressed = false; + if (startswith (tname, ".zdebug")) + { + is_gnu_compressed = true; + if (elf_compress_gnu (tscn, 0, 0) != 1) + INTERNAL_ERROR (fname); + } + else + { + if (gelf_getchdr (tscn, &tchdr) != NULL) + { + tcompress_type = tchdr.ch_type; + if (elf_compress (tscn, 0, 0) != 1) + INTERNAL_ERROR (fname); + } + } + + Elf_Data *tdata = elf_getdata (tscn, NULL); + if (tdata == NULL || tdata->d_buf == NULL + || tdata->d_type != ELF_T_BYTE) + INTERNAL_ERROR (fname); + + /* Pick up the symbol table and shndx table to + resolve relocation symbol indexes. */ + Elf64_Word symt = shdr->sh_link; + Elf_Data *symdata, *xndxdata; + Elf_Scn * symscn = elf_getscn (elf, symt); + symdata = elf_getdata (symscn, NULL); + xndxdata = get_xndxdata (elf, symscn); + if (symdata == NULL) + INTERNAL_ERROR (fname); + + if (shdr->sh_entsize == 0) + INTERNAL_ERROR (fname); + + size_t nrels = shdr->sh_size / shdr->sh_entsize; + size_t next = 0; + const bool is_rela = (shdr->sh_type == SHT_RELA); + const unsigned int ei_data = ehdr->e_ident[EI_DATA]; + + for (size_t relidx = 0; relidx < nrels; ++relidx) + { + int rtype, symndx, offset, addend; + union { GElf_Rela rela; GElf_Rel rel; } mem; + void *rel_p; /* Pointer to either rela or rel above */ + + if (is_rela) + { + GElf_Rela *r = gelf_getrela (reldata, relidx, &mem.rela); + offset = r->r_offset; + addend = r->r_addend; + rtype = GELF_R_TYPE (r->r_info); + symndx = GELF_R_SYM (r->r_info); + rel_p = r; + } + else + { + GElf_Rel *r = gelf_getrel (reldata, relidx, &mem.rel); + offset = r->r_offset; + addend = 0; + rtype = GELF_R_TYPE (r->r_info); + symndx = GELF_R_SYM (r->r_info); + rel_p = r; + } + + /* R_*_NONE relocs can always just be removed. */ + if (rtype == 0) + continue; + + /* We only do simple absolute relocations. */ + int addsub = 0; + Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub); + if (type == ELF_T_NUM) + goto relocate_failed; + + /* And only for relocations against other debug sections. */ + GElf_Sym sym_mem; + Elf32_Word xndx; + GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, + symndx, &sym_mem, + &xndx); + Elf32_Word sec = (sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx); + + bool dbg_scn = ebl_debugscn_p (ebl, secndx_name (elf, sec)); + + if (!dbg_scn) + goto relocate_failed; + + if (! relocate (elf, offset, addend, + tdata, ei_data, fname, is_rela, + sym, addsub, type)) + goto relocate_failed; + + continue; /* Next */ + +relocate_failed: + if (relidx != next) + { + if (is_rela) + gelf_update_rela (reldata, next, rel_p); + else + gelf_update_rel (reldata, next, rel_p); + } + ++next; + } + + nrels = next; + shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize; + gelf_update_shdr (scn, shdr); + + if (is_gnu_compressed) + { + if (elf_compress_gnu (tscn, 1, ELF_CHF_FORCE) != 1) + INTERNAL_ERROR (fname); + } + else if (tcompress_type != 0) + { + if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1) + INTERNAL_ERROR (fname); + } + } + } +} + +static int +process_file (const char *fname) +{ + /* If we have to preserve the modify and access timestamps get them + now. We cannot use fstat() after opening the file since the open + would change the access time. */ + struct stat pre_st; + struct timespec tv[2]; + again: + if (preserve_dates) + { + if (stat (fname, &pre_st) != 0) + { + error (0, errno, _("cannot stat input file '%s'"), fname); + return 1; + } + + /* If we have to preserve the timestamp, we need it in the + format utimes() understands. */ + tv[0] = pre_st.st_atim; + tv[1] = pre_st.st_mtim; + } + + /* Open the file. */ + int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY); + if (fd == -1) + { + error (0, errno, _("while opening '%s'"), fname); + return 1; + } + + /* We always use fstat() even if we called stat() before. This is + done to make sure the information returned by stat() is for the + same file. */ + struct stat st; + if (fstat (fd, &st) != 0) + { + error (0, errno, _("cannot stat input file '%s'"), fname); + return 1; + } + /* Paranoid mode on. */ + if (preserve_dates + && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev)) + { + /* We detected a race. Try again. */ + close (fd); + goto again; + } + + /* Now get the ELF descriptor. */ + Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ, + NULL); + int result; + switch (elf_kind (elf)) + { + case ELF_K_ELF: + result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS, + preserve_dates ? tv : NULL); + break; + + case ELF_K_AR: + /* It is not possible to strip the content of an archive direct + the output to a specific file. */ + if (unlikely (output_fname != NULL || debug_fname != NULL)) + { + error (0, 0, _("%s: cannot use -o or -f when stripping archive"), + fname); + result = 1; + } + else + { + /* We would like to support ar archives, but currently it just + doesn't work at all since we call elf_clone on the members + which doesn't really support ar members. + result = handle_ar (fd, elf, NULL, fname, + preserve_dates ? tv : NULL); + */ + error (0, 0, _("%s: no support for stripping archive"), + fname); + result = 1; + } + break; + + default: + error (0, 0, _("%s: File format not recognized"), fname); + result = 1; + break; + } + + if (unlikely (elf_end (elf) != 0)) + INTERNAL_ERROR (fname); + + close (fd); + + return result; +} + +/* Processing for --reloc-debug-sections-only. */ +static int +handle_debug_relocs (Elf *elf, Ebl *ebl, Elf *new_elf, + GElf_Ehdr *ehdr, const char *fname, size_t shstrndx, + GElf_Off *last_offset, GElf_Xword *last_size) +{ + + /* Copy over the ELF header. */ + if (gelf_update_ehdr (new_elf, ehdr) == 0) + { + error (0, 0, "couldn't update new ehdr: %s", elf_errmsg (-1)); + return 1; + } + + /* Copy over sections and record end of allocated sections. */ + GElf_Off lastoffset = 0; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + /* Get the header. */ + GElf_Shdr shdr; + if (gelf_getshdr (scn, &shdr) == NULL) + { + error (0, 0, "couldn't get shdr: %s", elf_errmsg (-1)); + return 1; + } + + /* Create new section. */ + Elf_Scn *new_scn = elf_newscn (new_elf); + if (new_scn == NULL) + { + error (0, 0, "couldn't create new section: %s", elf_errmsg (-1)); + return 1; + } + + if (gelf_update_shdr (new_scn, &shdr) == 0) + { + error (0, 0, "couldn't update shdr: %s", elf_errmsg (-1)); + return 1; + } + + /* Copy over section data. */ + Elf_Data *data = NULL; + while ((data = elf_getdata (scn, data)) != NULL) + { + Elf_Data *new_data = elf_newdata (new_scn); + if (new_data == NULL) + { + error (0, 0, "couldn't create new section data: %s", + elf_errmsg (-1)); + return 1; + } + *new_data = *data; + } + + /* Record last offset of allocated section. */ + if ((shdr.sh_flags & SHF_ALLOC) != 0) + { + GElf_Off filesz = (shdr.sh_type != SHT_NOBITS + ? shdr.sh_size : 0); + if (lastoffset < shdr.sh_offset + filesz) + lastoffset = shdr.sh_offset + filesz; + } + } + + /* Make sure section header name table is setup correctly, we'll + need it to determine whether to relocate sections. */ + if (update_shdrstrndx (new_elf, shstrndx) != 0) + { + error (0, 0, "error updating shdrstrndx: %s", elf_errmsg (-1)); + return 1; + } + + /* Adjust the relocation sections. */ + remove_debug_relocations (ebl, new_elf, ehdr, fname, shstrndx); + + /* Adjust the offsets of the non-allocated sections, so they come after + the allocated sections. */ + scn = NULL; + while ((scn = elf_nextscn (new_elf, scn)) != NULL) + { + /* Get the header. */ + GElf_Shdr shdr; + if (gelf_getshdr (scn, &shdr) == NULL) + { + error (0, 0, "couldn't get shdr: %s", elf_errmsg (-1)); + return 1; + } + + /* Adjust non-allocated section offsets to be after any allocated. */ + if ((shdr.sh_flags & SHF_ALLOC) == 0) + { + shdr.sh_offset = ((lastoffset + shdr.sh_addralign - 1) + & ~((GElf_Off) (shdr.sh_addralign - 1))); + if (gelf_update_shdr (scn, &shdr) == 0) + { + error (0, 0, "couldn't update shdr: %s", elf_errmsg (-1)); + return 1; + } + + GElf_Off filesz = (shdr.sh_type != SHT_NOBITS + ? shdr.sh_size : 0); + lastoffset = shdr.sh_offset + filesz; + *last_offset = shdr.sh_offset; + *last_size = filesz; + } + } + + return 0; +} + +/* Update section headers when the data size has changed. + We also update the SHT_NOBITS section in the debug + file so that the section headers match in sh_size. */ +static inline void +update_section_size (Elf_Scn *scn, + const Elf_Data *newdata, + Elf *debugelf, + size_t cnt, + const char *fname) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + shdr->sh_size = newdata->d_size; + (void) gelf_update_shdr (scn, shdr); + if (debugelf != NULL) + { + /* libelf will use d_size to set sh_size. */ + Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf, + cnt), NULL); + if (debugdata == NULL) + INTERNAL_ERROR (fname); + debugdata->d_size = newdata->d_size; + } +} + +/* Maximum size of array allocated on stack. */ +#define MAX_STACK_ALLOC (400 * 1024) + +static int +handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, + mode_t mode, struct timespec tvp[2]) +{ + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t fname_len = strlen (fname) + 1; + char *fullname = alloca (prefix_len + 1 + fname_len); + char *cp = fullname; + Elf *debugelf = NULL; + tmp_debug_fname = NULL; + int result = 0; + size_t shdridx = 0; + GElf_Off lastsec_offset = 0; + Elf64_Xword lastsec_size = 0; + size_t shstrndx; + struct shdr_info + { + Elf_Scn *scn; + GElf_Shdr shdr; + Elf_Data *data; + Elf_Data *debug_data; + const char *name; + Elf32_Word idx; /* Index in new file. */ + Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */ + Elf32_Word symtab_idx; + Elf32_Word version_idx; + Elf32_Word group_idx; + Elf32_Word group_cnt; + Elf_Scn *newscn; + Dwelf_Strent *se; + Elf32_Word *newsymidx; + } *shdr_info = NULL; + Elf_Scn *scn; + size_t cnt; + size_t idx; + bool changes; + GElf_Ehdr newehdr_mem; + GElf_Ehdr *newehdr; + GElf_Ehdr debugehdr_mem; + GElf_Ehdr *debugehdr; + Dwelf_Strtab *shst = NULL; + Elf_Data debuglink_crc_data; + bool any_symtab_changes = false; + Elf_Data *shstrtab_data = NULL; + void *debuglink_buf = NULL; + + /* Create the full name of the file. */ + if (prefix != NULL) + { + cp = mempcpy (cp, prefix, prefix_len); + *cp++ = ':'; + } + memcpy (cp, fname, fname_len); + + /* If we are not replacing the input file open a new file here. */ + if (output_fname != NULL) + { + fd = open (output_fname, O_RDWR | O_CREAT, mode); + if (unlikely (fd == -1)) + { + error (0, errno, _("cannot open '%s'"), output_fname); + return 1; + } + } + + debug_fd = -1; + + /* Get the EBL handling. Removing all debugging symbols with the -g + option or resolving all relocations between debug sections with + the --reloc-debug-sections option are currently the only reasons + we need EBL so don't open the backend unless necessary. */ + Ebl *ebl = NULL; + if (remove_debug || reloc_debug || reloc_debug_only) + { + ebl = ebl_openbackend (elf); + if (ebl == NULL) + { + error (0, errno, _("cannot open EBL backend")); + result = 1; + goto fail; + } + } + + /* Open the additional file the debug information will be stored in. */ + if (debug_fname != NULL) + { + /* Create a temporary file name. We do not want to overwrite + the debug file if the file would not contain any + information. */ + size_t debug_fname_len = strlen (debug_fname); + tmp_debug_fname = (char *) xmalloc (debug_fname_len + sizeof (".XXXXXX")); + strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len), + ".XXXXXX"); + + debug_fd = mkstemp (tmp_debug_fname); + if (unlikely (debug_fd == -1)) + { + error (0, errno, _("cannot open '%s'"), debug_fname); + result = 1; + goto fail; + } + } + + /* Get the information from the old file. */ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + INTERNAL_ERROR (fname); + + /* Get the section header string table index. */ + if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0)) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("cannot get section header string table index")); + } + + /* Get the number of phdrs in the old file. */ + size_t phnum; + if (elf_getphdrnum (elf, &phnum) != 0) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, _("cannot get number of phdrs")); + } + + /* We now create a new ELF descriptor for the same file. We + construct it almost exactly in the same way with some information + dropped. */ + Elf *newelf; + if (output_fname != NULL) + newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL); + else + newelf = elf_clone (elf, ELF_C_EMPTY); + + if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)) + { + error (0, 0, _("cannot create new ehdr for file '%s': %s"), + output_fname ?: fname, elf_errmsg (-1)); + goto fail; + } + + /* Copy over the old program header if needed. */ + if (phnum > 0) + { + if (unlikely (gelf_newphdr (newelf, phnum) == 0)) + { + error (0, 0, _("cannot create new phdr for file '%s': %s"), + output_fname ?: fname, elf_errmsg (-1)); + goto fail; + } + + for (cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); + if (phdr == NULL + || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0)) + INTERNAL_ERROR (fname); + } + } + + if (reloc_debug_only) + { + if (handle_debug_relocs (elf, ebl, newelf, ehdr, fname, shstrndx, + &lastsec_offset, &lastsec_size) != 0) + { + result = 1; + goto fail_close; + } + idx = shstrndx; + goto done; /* Skip all actual stripping operations. */ + } + + if (debug_fname != NULL) + { + /* Also create an ELF descriptor for the debug file */ + debugelf = elf_begin (debug_fd, ELF_C_WRITE, NULL); + if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)) + { + error (0, 0, _("cannot create new ehdr for file '%s': %s"), + debug_fname, elf_errmsg (-1)); + goto fail_close; + } + + /* Copy over the old program header if needed. */ + if (phnum > 0) + { + if (unlikely (gelf_newphdr (debugelf, phnum) == 0)) + { + error (0, 0, _("cannot create new phdr for file '%s': %s"), + debug_fname, elf_errmsg (-1)); + goto fail_close; + } + + for (cnt = 0; cnt < phnum; ++cnt) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); + if (phdr == NULL + || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0)) + INTERNAL_ERROR (fname); + } + } + } + + /* Number of sections. */ + size_t shnum; + if (unlikely (elf_getshdrnum (elf, &shnum) < 0)) + { + error (0, 0, _("cannot determine number of sections: %s"), + elf_errmsg (-1)); + goto fail_close; + } + + if (shstrndx >= shnum) + goto illformed; + +#define elf_assert(test) do { if (!(test)) goto illformed; } while (0) + + /* Storage for section information. We leave room for two more + entries since we unconditionally create a section header string + table. Maybe some weird tool created an ELF file without one. + The other one is used for the debug link section. */ + if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) + shdr_info = (struct shdr_info *) xcalloc (shnum + 2, + sizeof (struct shdr_info)); + else + { + shdr_info = (struct shdr_info *) alloca ((shnum + 2) + * sizeof (struct shdr_info)); + memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info)); + } + + /* Track whether allocated sections all come before non-allocated ones. */ + bool seen_allocated = false; + bool seen_unallocated = false; + bool mixed_allocated_unallocated = false; + + /* Prepare section information data structure. */ + scn = NULL; + cnt = 1; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + /* This should always be true (i.e., there should not be any + holes in the numbering). */ + elf_assert (elf_ndxscn (scn) == cnt); + + shdr_info[cnt].scn = scn; + + /* Get the header. */ + if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL) + INTERNAL_ERROR (fname); + + /* Normally (in non-ET_REL files) we see all allocated sections first, + then all non-allocated. */ + if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0) + seen_unallocated = true; + else + { + if (seen_unallocated && seen_allocated) + mixed_allocated_unallocated = true; + seen_allocated = true; + } + + /* Get the name of the section. */ + shdr_info[cnt].name = elf_strptr (elf, shstrndx, + shdr_info[cnt].shdr.sh_name); + if (shdr_info[cnt].name == NULL) + { + illformed: + error (0, 0, _("illformed file '%s'"), fname); + goto fail_close; + } + + /* Sanity check the user. */ + if (section_name_matches (remove_secs, shdr_info[cnt].name)) + { + if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0) + { + error (0, 0, + _("Cannot remove allocated section '%s'"), + shdr_info[cnt].name); + result = 1; + goto fail_close; + } + + if (section_name_matches (keep_secs, shdr_info[cnt].name)) + { + error (0, 0, + _("Cannot both keep and remove section '%s'"), + shdr_info[cnt].name); + result = 1; + goto fail_close; + } + } + + /* Mark them as present but not yet investigated. */ + shdr_info[cnt].idx = 1; + + /* Remember the shdr.sh_link value. */ + shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link; + if (shdr_info[cnt].old_sh_link >= shnum) + goto illformed; + + /* Sections in files other than relocatable object files which + not loaded can be freely moved by us. In theory we can also + freely move around allocated nobits sections. But we don't + to keep the layout of all allocated sections as similar as + possible to the original file. In relocatable object files + everything can be moved. */ + if (phnum == 0 + || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0) + shdr_info[cnt].shdr.sh_offset = 0; + + /* If this is an extended section index table store an + appropriate reference. */ + if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX)) + { + elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0); + shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt; + } + else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP)) + { + /* Cross-reference the sections contained in the section + group. */ + shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); + if (shdr_info[cnt].data == NULL + || shdr_info[cnt].data->d_size < sizeof (Elf32_Word)) + INTERNAL_ERROR (fname); + + /* XXX Fix for unaligned access. */ + Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; + size_t inner; + for (inner = 1; + inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); + ++inner) + { + if (grpref[inner] < shnum) + shdr_info[grpref[inner]].group_idx = cnt; + else + goto illformed; + } + + if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0)) + /* If the section group contains only one element and this + is n COMDAT section we can drop it right away. */ + shdr_info[cnt].idx = 0; + else + shdr_info[cnt].group_cnt = inner - 1; + } + else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)) + { + elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0); + shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt; + } + + /* If this section is part of a group make sure it is not + discarded right away. */ + if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0) + { + elf_assert (shdr_info[cnt].group_idx != 0); + + if (shdr_info[shdr_info[cnt].group_idx].idx == 0) + { + /* The section group section might be removed. + Don't remove the SHF_GROUP flag. The section is + either also removed, in which case the flag doesn't matter. + Or it moves with the group into the debug file, then + it will be reconnected with the new group and should + still have the flag set. */ + shdr_info[cnt].group_idx = 0; + } + } + + /* Increment the counter. */ + ++cnt; + } + + /* Now determine which sections can go away. The general rule is that + all sections which are not used at runtime are stripped out. But + there are a few exceptions: + + - special sections named ".comment" and ".note" are kept + - OS or architecture specific sections are kept since we might not + know how to handle them + - if a section is referred to from a section which is not removed + in the sh_link or sh_info element it cannot be removed either + - the user might have explicitly said to remove or keep a section + */ + for (cnt = 1; cnt < shnum; ++cnt) + /* Check whether the section can be removed. Since we will create + a new .shstrtab assume it will be removed too. */ + if (remove_shdrs ? !(shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) + : (ebl_section_strip_p (ebl, &shdr_info[cnt].shdr, + shdr_info[cnt].name, remove_comment, + remove_debug) + || cnt == shstrndx + || section_name_matches (remove_secs, shdr_info[cnt].name))) + { + /* The user might want to explicitly keep this one. */ + if (section_name_matches (keep_secs, shdr_info[cnt].name)) + continue; + + /* For now assume this section will be removed. */ + shdr_info[cnt].idx = 0; + + idx = shdr_info[cnt].group_idx; + while (idx != 0) + { + /* The section group data is already loaded. */ + elf_assert (shdr_info[idx].data != NULL + && shdr_info[idx].data->d_buf != NULL + && shdr_info[idx].data->d_size >= sizeof (Elf32_Word)); + + /* If the references section group is a normal section + group and has one element remaining, or if it is an + empty COMDAT section group it is removed. */ + bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0] + & GRP_COMDAT) != 0; + + --shdr_info[idx].group_cnt; + if ((!is_comdat && shdr_info[idx].group_cnt == 1) + || (is_comdat && shdr_info[idx].group_cnt == 0)) + { + shdr_info[idx].idx = 0; + /* Continue recursively. */ + idx = shdr_info[idx].group_idx; + } + else + break; + } + } + + /* Mark the SHT_NULL section as handled. */ + shdr_info[0].idx = 2; + + + /* Handle exceptions: section groups and cross-references. We might + have to repeat this a few times since the resetting of the flag + might propagate. */ + do + { + changes = false; + + for (cnt = 1; cnt < shnum; ++cnt) + { + if (shdr_info[cnt].idx == 0) + { + /* If a relocation section is marked as being removed make + sure the section it is relocating is removed, too. */ + if (shdr_info[cnt].shdr.sh_type == SHT_REL + || shdr_info[cnt].shdr.sh_type == SHT_RELA) + { + if (shdr_info[cnt].shdr.sh_info >= shnum) + goto illformed; + else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) + shdr_info[cnt].idx = 1; + } + + /* If a group section is marked as being removed make + sure all the sections it contains are being removed, too. */ + if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) + { + Elf32_Word *grpref; + grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; + for (size_t in = 1; + in < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); + ++in) + if (grpref[in] < shnum) + { + if (shdr_info[grpref[in]].idx != 0) + { + shdr_info[cnt].idx = 1; + break; + } + } + else + goto illformed; + } + } + + if (shdr_info[cnt].idx == 1) + { + /* The content of symbol tables we don't remove must not + reference any section which we do remove. Otherwise + we cannot remove the section. */ + if (debug_fname != NULL + && shdr_info[cnt].debug_data == NULL + && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM + || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)) + { + /* Make sure the data is loaded. */ + if (shdr_info[cnt].data == NULL) + { + shdr_info[cnt].data + = elf_getdata (shdr_info[cnt].scn, NULL); + if (shdr_info[cnt].data == NULL) + INTERNAL_ERROR (fname); + } + Elf_Data *symdata = shdr_info[cnt].data; + + /* If there is an extended section index table load it + as well. */ + if (shdr_info[cnt].symtab_idx != 0 + && shdr_info[shdr_info[cnt].symtab_idx].data == NULL) + { + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB); + + shdr_info[shdr_info[cnt].symtab_idx].data + = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, + NULL); + if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL) + INTERNAL_ERROR (fname); + } + Elf_Data *xndxdata + = shdr_info[shdr_info[cnt].symtab_idx].data; + + /* Go through all symbols and make sure the section they + reference is not removed. */ + size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + + for (size_t inner = 0; + inner < shdr_info[cnt].data->d_size / elsize; + ++inner) + { + GElf_Sym sym_mem; + Elf32_Word xndx; + GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, + inner, &sym_mem, + &xndx); + if (sym == NULL) + INTERNAL_ERROR (fname); + + size_t scnidx = sym->st_shndx; + if (scnidx == SHN_UNDEF || scnidx >= shnum + || (scnidx >= SHN_LORESERVE + && scnidx <= SHN_HIRESERVE + && scnidx != SHN_XINDEX) + /* Don't count in the section symbols. */ + || GELF_ST_TYPE (sym->st_info) == STT_SECTION) + /* This is no section index, leave it alone. */ + continue; + else if (scnidx == SHN_XINDEX) + scnidx = xndx; + + if (scnidx >= shnum) + goto illformed; + + if (shdr_info[scnidx].idx == 0) + /* This symbol table has a real symbol in + a discarded section. So preserve the + original table in the debug file. Unless + it is a redundant data marker to a debug + (data only) section. */ + if (! (ebl_section_strip_p (ebl, + &shdr_info[scnidx].shdr, + shdr_info[scnidx].name, + remove_comment, + remove_debug) + && ebl_data_marker_symbol (ebl, sym, + elf_strptr (elf, + shdr_info[cnt].shdr.sh_link, + sym->st_name)))) + shdr_info[cnt].debug_data = symdata; + } + } + + /* Cross referencing happens: + - for the cases the ELF specification says. That are + + SHT_DYNAMIC in sh_link to string table + + SHT_HASH in sh_link to symbol table + + SHT_REL and SHT_RELA in sh_link to symbol table + + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table + + SHT_GROUP in sh_link to symbol table + + SHT_SYMTAB_SHNDX in sh_link to symbol table + Other (OS or architecture-specific) sections might as + well use this field so we process it unconditionally. + - references inside section groups + - specially marked references in sh_info if the SHF_INFO_LINK + flag is set + */ + + if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0) + { + shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1; + changes |= shdr_info[cnt].shdr.sh_link < cnt; + } + + /* Handle references through sh_info. */ + if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) + { + if (shdr_info[cnt].shdr.sh_info >= shnum) + goto illformed; + else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) + { + shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1; + changes |= shdr_info[cnt].shdr.sh_info < cnt; + } + } + + /* Mark the section as investigated. */ + shdr_info[cnt].idx = 2; + } + + if (debug_fname != NULL + && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL)) + { + /* This section is being preserved in the debug file. + Sections it refers to must be preserved there too. + + In this pass we mark sections to be preserved in both + files by setting the .debug_data pointer to the original + file's .data pointer. Below, we'll copy the section + contents. */ + size_t shdr_indices[2] = { shdr_info[cnt].shdr.sh_link, 0 }; + int n = 1; + + if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) + { + shdr_indices[1] = shdr_info[cnt].shdr.sh_info; + n++; + } + + for (int j = 0; j < n; j++) + { + size_t i = shdr_indices[j]; + if (i != 0 && i < shnum + 2 && shdr_info[i].idx != 0 + && shdr_info[i].debug_data == NULL) + { + if (shdr_info[i].data == NULL) + shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL); + if (shdr_info[i].data == NULL) + INTERNAL_ERROR (fname); + + shdr_info[i].debug_data = shdr_info[i].data; + changes |= i < cnt; + } + } + } + } + } + while (changes); + + /* Copy the removed sections to the debug output file. + The ones that are not removed in the stripped file are SHT_NOBITS. */ + if (debug_fname != NULL) + { + for (cnt = 1; cnt < shnum; ++cnt) + { + scn = elf_newscn (debugelf); + if (scn == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("while generating output file: %s"), + elf_errmsg (-1)); + } + + bool discard_section = (shdr_info[cnt].idx > 0 + && shdr_info[cnt].debug_data == NULL + && shdr_info[cnt].shdr.sh_type != SHT_NOTE + && shdr_info[cnt].shdr.sh_type != SHT_GROUP + && cnt != shstrndx); + + /* Set the section header in the new file. */ + GElf_Shdr debugshdr = shdr_info[cnt].shdr; + if (discard_section) + debugshdr.sh_type = SHT_NOBITS; + + if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0)) + /* There cannot be any overflows. */ + INTERNAL_ERROR (fname); + + /* Get the data from the old file if necessary. */ + if (shdr_info[cnt].data == NULL) + { + shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); + if (shdr_info[cnt].data == NULL) + INTERNAL_ERROR (fname); + } + + /* Set the data. This is done by copying from the old file. */ + Elf_Data *debugdata = elf_newdata (scn); + if (debugdata == NULL) + INTERNAL_ERROR (fname); + + /* Copy the structure. This data may be modified in place + before we write out the file. */ + *debugdata = *shdr_info[cnt].data; + if (discard_section) + debugdata->d_buf = NULL; + else if (shdr_info[cnt].debug_data != NULL + || shdr_info[cnt].shdr.sh_type == SHT_GROUP) + { + /* Copy the original data before it gets modified. */ + shdr_info[cnt].debug_data = debugdata; + if (debugdata->d_buf == NULL) + INTERNAL_ERROR (fname); + debugdata->d_buf = memcpy (xmalloc (debugdata->d_size), + debugdata->d_buf, debugdata->d_size); + } + } + + /* Finish the ELF header. Fill in the fields not handled by + libelf from the old file. */ + debugehdr = gelf_getehdr (debugelf, &debugehdr_mem); + if (debugehdr == NULL) + INTERNAL_ERROR (fname); + + memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT); + debugehdr->e_type = ehdr->e_type; + debugehdr->e_machine = ehdr->e_machine; + debugehdr->e_version = ehdr->e_version; + debugehdr->e_entry = ehdr->e_entry; + debugehdr->e_flags = ehdr->e_flags; + + if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0)) + { + error (0, 0, _("%s: error while updating ELF header: %s"), + debug_fname, elf_errmsg (-1)); + result = 1; + goto fail_close; + } + + size_t shdrstrndx; + if (elf_getshdrstrndx (elf, &shdrstrndx) < 0) + { + error (0, 0, _("%s: error while getting shdrstrndx: %s"), + fname, elf_errmsg (-1)); + result = 1; + goto fail_close; + } + + if (update_shdrstrndx (debugelf, shdrstrndx) != 0) + { + error (0, 0, _("%s: error updating shdrstrndx: %s"), + debug_fname, elf_errmsg (-1)); + result = 1; + goto fail_close; + } + } + + /* Although we always create a new section header string table we + don't explicitly mark the existing one as unused. It can still + be used through a symbol table section we are keeping. If not it + will already be marked as unused. */ + + /* We need a string table for the section headers. */ + shst = dwelf_strtab_init (true); + if (shst == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, errno, _("while preparing output for '%s'"), + output_fname ?: fname); + } + + /* Assign new section numbers. */ + shdr_info[0].idx = 0; + for (cnt = idx = 1; cnt < shnum; ++cnt) + if (shdr_info[cnt].idx > 0) + { + shdr_info[cnt].idx = idx++; + + /* Create a new section. */ + shdr_info[cnt].newscn = elf_newscn (newelf); + if (shdr_info[cnt].newscn == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("while generating output file: %s"), + elf_errmsg (-1)); + } + + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); + + /* Add this name to the section header string table. */ + shdr_info[cnt].se = dwelf_strtab_add (shst, shdr_info[cnt].name); + } + + /* Test whether we are doing anything at all. Either all removable + sections are already gone. Or the only section we would remove is + the .shstrtab section which we would add again. */ + bool removing_sections = !(cnt == idx + || (cnt == idx + 1 + && shdr_info[shstrndx].idx == 0)); + if (output_fname == NULL && !removing_sections) + goto fail_close; + + /* Create the reference to the file with the debug info (if any). */ + if (debug_fname != NULL && !remove_shdrs && removing_sections) + { + /* Add the section header string table section name. */ + shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".gnu_debuglink", 15); + shdr_info[cnt].idx = idx++; + + /* Create the section header. */ + shdr_info[cnt].shdr.sh_type = SHT_PROGBITS; + shdr_info[cnt].shdr.sh_flags = 0; + shdr_info[cnt].shdr.sh_addr = 0; + shdr_info[cnt].shdr.sh_link = SHN_UNDEF; + shdr_info[cnt].shdr.sh_info = SHN_UNDEF; + shdr_info[cnt].shdr.sh_entsize = 0; + shdr_info[cnt].shdr.sh_addralign = 4; + /* We set the offset to zero here. Before we write the ELF file the + field must have the correct value. This is done in the final + loop over all section. Then we have all the information needed. */ + shdr_info[cnt].shdr.sh_offset = 0; + + /* Create the section. */ + shdr_info[cnt].newscn = elf_newscn (newelf); + if (shdr_info[cnt].newscn == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("while create section header section: %s"), + elf_errmsg (-1)); + } + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); + + shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn); + if (shdr_info[cnt].data == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, _("cannot allocate section data: %s"), + elf_errmsg (-1)); + } + + char *debug_basename = basename (debug_fname_embed ?: debug_fname); + off_t crc_offset = strlen (debug_basename) + 1; + /* Align to 4 byte boundary */ + crc_offset = ((crc_offset - 1) & ~3) + 4; + + shdr_info[cnt].data->d_align = 4; + shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size + = crc_offset + 4; + debuglink_buf = xcalloc (1, shdr_info[cnt].data->d_size); + shdr_info[cnt].data->d_buf = debuglink_buf; + + strcpy (shdr_info[cnt].data->d_buf, debug_basename); + + /* Cache this Elf_Data describing the CRC32 word in the section. + We'll fill this in when we have written the debug file. */ + debuglink_crc_data = *shdr_info[cnt].data; + debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf + + crc_offset); + debuglink_crc_data.d_size = 4; + + /* One more section done. */ + ++cnt; + } + + /* Index of the section header table in the shdr_info array. */ + shdridx = cnt; + + /* Add the section header string table section name. */ + shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".shstrtab", 10); + shdr_info[cnt].idx = idx; + + /* Create the section header. */ + shdr_info[cnt].shdr.sh_type = SHT_STRTAB; + shdr_info[cnt].shdr.sh_flags = 0; + shdr_info[cnt].shdr.sh_addr = 0; + shdr_info[cnt].shdr.sh_link = SHN_UNDEF; + shdr_info[cnt].shdr.sh_info = SHN_UNDEF; + shdr_info[cnt].shdr.sh_entsize = 0; + /* We set the offset to zero here. Before we write the ELF file the + field must have the correct value. This is done in the final + loop over all section. Then we have all the information needed. */ + shdr_info[cnt].shdr.sh_offset = 0; + shdr_info[cnt].shdr.sh_addralign = 1; + + /* Create the section. */ + shdr_info[cnt].newscn = elf_newscn (newelf); + if (shdr_info[cnt].newscn == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("while create section header section: %s"), + elf_errmsg (-1)); + } + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx); + + /* Finalize the string table and fill in the correct indices in the + section headers. */ + shstrtab_data = elf_newdata (shdr_info[cnt].newscn); + if (shstrtab_data == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("while create section header string table: %s"), + elf_errmsg (-1)); + } + if (dwelf_strtab_finalize (shst, shstrtab_data) == NULL) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, + _("no memory to create section header string table")); + } + + /* We have to set the section size. */ + shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size; + + /* Update the section information. */ + GElf_Off lastoffset = 0; + for (cnt = 1; cnt <= shdridx; ++cnt) + if (shdr_info[cnt].idx > 0) + { + Elf_Data *newdata; + + scn = elf_getscn (newelf, shdr_info[cnt].idx); + elf_assert (scn != NULL); + + /* Update the name. */ + shdr_info[cnt].shdr.sh_name = dwelf_strent_off (shdr_info[cnt].se); + + /* Update the section header from the input file. Some fields + might be section indices which now have to be adjusted. Keep + the index to the "current" sh_link in case we need it to lookup + symbol table names. */ + size_t sh_link = shdr_info[cnt].shdr.sh_link; + if (shdr_info[cnt].shdr.sh_link != 0) + shdr_info[cnt].shdr.sh_link = + shdr_info[shdr_info[cnt].shdr.sh_link].idx; + + if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) + { + elf_assert (shdr_info[cnt].data != NULL + && shdr_info[cnt].data->d_buf != NULL); + + Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; + /* First word is the section group flag. + Followed by section indexes, that need to be renumbered. */ + for (size_t inner = 1; + inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); + ++inner) + if (grpref[inner] < shnum) + grpref[inner] = shdr_info[grpref[inner]].idx; + else + goto illformed; + } + + /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */ + if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) + shdr_info[cnt].shdr.sh_info = + shdr_info[shdr_info[cnt].shdr.sh_info].idx; + + /* Get the data from the old file if necessary. We already + created the data for the section header string table. */ + if (cnt < shnum) + { + if (shdr_info[cnt].data == NULL) + { + shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); + if (shdr_info[cnt].data == NULL) + INTERNAL_ERROR (fname); + } + + /* Set the data. This is done by copying from the old file. */ + newdata = elf_newdata (scn); + if (newdata == NULL) + INTERNAL_ERROR (fname); + + /* Copy the structure. */ + *newdata = *shdr_info[cnt].data; + + /* We know the size. */ + shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size; + + /* We have to adjust symbol tables. The st_shndx member might + have to be updated. */ + if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM + || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) + { + Elf_Data *versiondata = NULL; + Elf_Data *shndxdata = NULL; + + size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + + if (shdr_info[cnt].symtab_idx != 0) + { + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX); + /* This section has extended section information. + We have to modify that information, too. */ + shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, + NULL); + + elf_assert (shndxdata != NULL + && shndxdata->d_buf != NULL + && ((shndxdata->d_size / sizeof (Elf32_Word)) + >= shdr_info[cnt].data->d_size / elsize)); + } + + if (shdr_info[cnt].version_idx != 0) + { + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM); + /* This section has associated version + information. We have to modify that + information, too. */ + versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn, + NULL); + + elf_assert (versiondata != NULL + && versiondata->d_buf != NULL + && ((versiondata->d_size / sizeof (GElf_Versym)) + >= shdr_info[cnt].data->d_size / elsize)); + } + + shdr_info[cnt].newsymidx + = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size + / elsize, sizeof (Elf32_Word)); + + bool last_was_local = true; + size_t destidx; + size_t inner; + for (destidx = inner = 1; + inner < shdr_info[cnt].data->d_size / elsize; + ++inner) + { + Elf32_Word sec; + GElf_Sym sym_mem; + Elf32_Word xshndx; + GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data, + shndxdata, inner, + &sym_mem, &xshndx); + if (sym == NULL) + INTERNAL_ERROR (fname); + + if (sym->st_shndx == SHN_UNDEF + || (sym->st_shndx >= SHN_LORESERVE + && sym->st_shndx != SHN_XINDEX)) + { + /* This is no section index, leave it alone + unless it is moved. */ + if (destidx != inner + && gelf_update_symshndx (shdr_info[cnt].data, + shndxdata, + destidx, sym, + xshndx) == 0) + INTERNAL_ERROR (fname); + + shdr_info[cnt].newsymidx[inner] = destidx++; + + if (last_was_local + && GELF_ST_BIND (sym->st_info) != STB_LOCAL) + { + last_was_local = false; + shdr_info[cnt].shdr.sh_info = destidx - 1; + } + + continue; + } + + /* Get the full section index, if necessary from the + XINDEX table. */ + if (sym->st_shndx == SHN_XINDEX) + elf_assert (shndxdata != NULL + && shndxdata->d_buf != NULL); + size_t sidx = (sym->st_shndx != SHN_XINDEX + ? sym->st_shndx : xshndx); + elf_assert (sidx < shnum); + sec = shdr_info[sidx].idx; + + if (sec != 0) + { + GElf_Section nshndx; + Elf32_Word nxshndx; + + if (sec < SHN_LORESERVE) + { + nshndx = sec; + nxshndx = 0; + } + else + { + nshndx = SHN_XINDEX; + nxshndx = sec; + } + + elf_assert (sec < SHN_LORESERVE || shndxdata != NULL); + + if ((inner != destidx || nshndx != sym->st_shndx + || (shndxdata != NULL && nxshndx != xshndx)) + && (sym->st_shndx = nshndx, + gelf_update_symshndx (shdr_info[cnt].data, + shndxdata, + destidx, sym, + nxshndx) == 0)) + INTERNAL_ERROR (fname); + + shdr_info[cnt].newsymidx[inner] = destidx++; + + if (last_was_local + && GELF_ST_BIND (sym->st_info) != STB_LOCAL) + { + last_was_local = false; + shdr_info[cnt].shdr.sh_info = destidx - 1; + } + } + else if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0 + && GELF_ST_TYPE (sym->st_info) != STT_SECTION + && shdr_info[sidx].shdr.sh_type != SHT_GROUP) + { + /* Removing a real symbol from an allocated + symbol table is hard and probably a + mistake. Really removing it means + rewriting the dynamic segment and hash + sections. Just warn and set the symbol + section to UNDEF. */ + error (0, 0, + _("Cannot remove symbol [%zd] from allocated symbol table [%zd]"), inner, cnt); + sym->st_shndx = SHN_UNDEF; + if (gelf_update_sym (shdr_info[cnt].data, destidx, + sym) == 0) + INTERNAL_ERROR (fname); + shdr_info[cnt].newsymidx[inner] = destidx++; + } + else if (debug_fname != NULL + && shdr_info[cnt].debug_data == NULL) + /* The symbol points to a section that is discarded + but isn't preserved in the debug file. Check that + this is a section or group signature symbol + for a section which has been removed. Or a special + data marker symbol to a debug section. */ + { + elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION + || ((shdr_info[sidx].shdr.sh_type + == SHT_GROUP) + && (shdr_info[sidx].shdr.sh_info + == inner)) + || ebl_data_marker_symbol (ebl, sym, + elf_strptr (elf, sh_link, + sym->st_name))); + } + } + + if (destidx != inner) + { + /* The size of the symbol table changed. */ + shdr_info[cnt].shdr.sh_size = newdata->d_size + = destidx * elsize; + any_symtab_changes = true; + } + else + { + /* The symbol table didn't really change. */ + free (shdr_info[cnt].newsymidx); + shdr_info[cnt].newsymidx = NULL; + } + } + } + + /* If we have to, compute the offset of the section. + If allocate and unallocated sections are mixed, we only update + the allocated ones now. The unallocated ones come second. */ + if (! mixed_allocated_unallocated + || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0) + { + if (shdr_info[cnt].shdr.sh_offset == 0) + shdr_info[cnt].shdr.sh_offset + = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1) + & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1))); + + /* Set the section header in the new file. */ + if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0)) + /* There cannot be any overflows. */ + INTERNAL_ERROR (fname); + + /* Remember the last section written so far. */ + GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS + ? shdr_info[cnt].shdr.sh_size : 0); + if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz) + lastoffset = shdr_info[cnt].shdr.sh_offset + filesz; + } + } + + /* We might have to update the unallocated sections after we done the + allocated ones. lastoffset is set to right after the last allocated + section. */ + if (mixed_allocated_unallocated) + for (cnt = 1; cnt <= shdridx; ++cnt) + if (shdr_info[cnt].idx > 0) + { + scn = elf_getscn (newelf, shdr_info[cnt].idx); + if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0) + { + if (shdr_info[cnt].shdr.sh_offset == 0) + shdr_info[cnt].shdr.sh_offset + = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1) + & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1))); + + /* Set the section header in the new file. */ + if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0)) + /* There cannot be any overflows. */ + INTERNAL_ERROR (fname); + + /* Remember the last section written so far. */ + GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS + ? shdr_info[cnt].shdr.sh_size : 0); + if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz) + lastoffset = shdr_info[cnt].shdr.sh_offset + filesz; + } + } + + /* Adjust symbol references if symbol tables changed. */ + if (any_symtab_changes) + /* Find all relocation sections which use this symbol table. */ + for (cnt = 1; cnt <= shdridx; ++cnt) + { + struct shdr_info *info = &shdr_info[cnt]; + if (info->idx == 0 && debug_fname == NULL) + /* Ignore sections which are discarded. When we are saving a + relocation section in a separate debug file, we must fix up + the symbol table references. */ + continue; + + const Elf32_Word symtabidx = info->old_sh_link; + elf_assert (symtabidx < shnum + 2); + const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx; + + /* If the symbol table hasn't changed, do not do anything. */ + if (newsymidx == NULL) + continue; + + /* If the symbol table is not discarded, but additionally + duplicated in the separate debug file and this section + is discarded, don't adjust anything. */ + if (info->idx == 0 && shdr_info[symtabidx].debug_data != NULL) + continue; + + switch (info->shdr.sh_type) + { + case SHT_REL: + case SHT_RELA: + scn = (info->idx == 0 + ? elf_getscn (debugelf, cnt) + : elf_getscn (newelf, info->idx)); + Elf_Data *d = elf_getdata (scn, NULL); + elf_assert (d != NULL && d->d_buf != NULL + && info->shdr.sh_entsize != 0); + size_t nrels = (info->shdr.sh_size / info->shdr.sh_entsize); + + size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + const Elf32_Word symidxn = (shdr_info[symtabidx].data->d_size + / symsize); + if (info->shdr.sh_type == SHT_REL) + for (size_t relidx = 0; relidx < nrels; ++relidx) + { + GElf_Rel rel_mem; + if (gelf_getrel (d, relidx, &rel_mem) == NULL) + INTERNAL_ERROR (fname); + + size_t symidx = GELF_R_SYM (rel_mem.r_info); + elf_assert (symidx < symidxn); + if (newsymidx[symidx] != symidx) + { + rel_mem.r_info + = GELF_R_INFO (newsymidx[symidx], + GELF_R_TYPE (rel_mem.r_info)); + + if (gelf_update_rel (d, relidx, &rel_mem) == 0) + INTERNAL_ERROR (fname); + } + } + else + for (size_t relidx = 0; relidx < nrels; ++relidx) + { + GElf_Rela rel_mem; + if (gelf_getrela (d, relidx, &rel_mem) == NULL) + INTERNAL_ERROR (fname); + + size_t symidx = GELF_R_SYM (rel_mem.r_info); + elf_assert (symidx < symidxn); + if (newsymidx[symidx] != symidx) + { + rel_mem.r_info + = GELF_R_INFO (newsymidx[symidx], + GELF_R_TYPE (rel_mem.r_info)); + + if (gelf_update_rela (d, relidx, &rel_mem) == 0) + INTERNAL_ERROR (fname); + } + } + break; + + case SHT_HASH: + /* We have to recompute the hash table. */ + + elf_assert (info->idx > 0); + + /* The hash section in the new file. */ + scn = elf_getscn (newelf, info->idx); + + /* The symbol table data. */ + Elf_Data *symd = elf_getdata (elf_getscn (newelf, + shdr_info[symtabidx].idx), + NULL); + elf_assert (symd != NULL && symd->d_buf != NULL); + + /* The hash table data. */ + Elf_Data *hashd = elf_getdata (scn, NULL); + elf_assert (hashd != NULL && hashd->d_buf != NULL); + + if (info->shdr.sh_entsize == sizeof (Elf32_Word)) + { + /* Sane arches first. */ + elf_assert (hashd->d_size >= 2 * sizeof (Elf32_Word)); + Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf; + + size_t strshndx = shdr_info[symtabidx].old_sh_link; + size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + + Elf32_Word nchain = bucket[1]; + Elf32_Word nbucket = bucket[0]; + uint64_t used_buf = ((2ULL + nchain + nbucket) + * sizeof (Elf32_Word)); + elf_assert (used_buf <= hashd->d_size); + + /* Adjust the nchain value. The symbol table size + changed. We keep the same size for the bucket array. */ + bucket[1] = symd->d_size / elsize; + bucket += 2; + Elf32_Word *chain = bucket + nbucket; + + /* New size of the section. */ + size_t n_size = ((2 + symd->d_size / elsize + nbucket) + * sizeof (Elf32_Word)); + elf_assert (n_size <= hashd->d_size); + hashd->d_size = n_size; + update_section_size (scn, hashd, debugelf, cnt, fname); + + /* Clear the arrays. */ + memset (bucket, '\0', + (symd->d_size / elsize + nbucket) + * sizeof (Elf32_Word)); + + for (size_t inner = shdr_info[symtabidx].shdr.sh_info; + inner < symd->d_size / elsize; ++inner) + { + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); + elf_assert (sym != NULL); + + const char *name = elf_strptr (elf, strshndx, + sym->st_name); + elf_assert (name != NULL && nbucket != 0); + size_t hidx = elf_hash (name) % nbucket; + + if (bucket[hidx] == 0) + bucket[hidx] = inner; + else + { + hidx = bucket[hidx]; + + while (chain[hidx] != 0 && chain[hidx] < nchain) + hidx = chain[hidx]; + + chain[hidx] = inner; + } + } + } + else + { + /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */ + elf_assert (info->shdr.sh_entsize == sizeof (Elf64_Xword)); + + Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf; + + size_t strshndx = shdr_info[symtabidx].old_sh_link; + size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + + elf_assert (symd->d_size >= 2 * sizeof (Elf64_Xword)); + Elf64_Xword nbucket = bucket[0]; + Elf64_Xword nchain = bucket[1]; + uint64_t maxwords = hashd->d_size / sizeof (Elf64_Xword); + elf_assert (maxwords >= 2 + && maxwords - 2 >= nbucket + && maxwords - 2 - nbucket >= nchain); + + /* Adjust the nchain value. The symbol table size + changed. We keep the same size for the bucket array. */ + bucket[1] = symd->d_size / elsize; + bucket += 2; + Elf64_Xword *chain = bucket + nbucket; + + /* New size of the section. */ + size_t n_size = ((2 + symd->d_size / elsize + nbucket) + * sizeof (Elf64_Xword)); + elf_assert (n_size <= hashd->d_size); + hashd->d_size = n_size; + update_section_size (scn, hashd, debugelf, cnt, fname); + + /* Clear the arrays. */ + memset (bucket, '\0', + (symd->d_size / elsize + nbucket) + * sizeof (Elf64_Xword)); + + for (size_t inner = shdr_info[symtabidx].shdr.sh_info; + inner < symd->d_size / elsize; ++inner) + { + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); + elf_assert (sym != NULL); + + const char *name = elf_strptr (elf, strshndx, + sym->st_name); + elf_assert (name != NULL && nbucket != 0); + size_t hidx = elf_hash (name) % nbucket; + + if (bucket[hidx] == 0) + bucket[hidx] = inner; + else + { + hidx = bucket[hidx]; + + while (chain[hidx] != 0 && chain[hidx] < nchain) + hidx = chain[hidx]; + + chain[hidx] = inner; + } + } + } + break; + + case SHT_GNU_versym: + /* If the symbol table changed we have to adjust the entries. */ + elf_assert (info->idx > 0); + + /* The symbol version section in the new file. */ + scn = elf_getscn (newelf, info->idx); + + /* The symbol table data. */ + symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx), + NULL); + elf_assert (symd != NULL && symd->d_buf != NULL); + size_t symz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + const Elf32_Word syms = (shdr_info[symtabidx].data->d_size / symz); + + /* The version symbol data. */ + Elf_Data *verd = elf_getdata (scn, NULL); + elf_assert (verd != NULL && verd->d_buf != NULL); + + /* The symbol version array. */ + GElf_Half *verstab = (GElf_Half *) verd->d_buf; + + /* Walk through the list and */ + size_t elsize = gelf_fsize (elf, verd->d_type, 1, EV_CURRENT); + Elf32_Word vers = verd->d_size / elsize; + for (size_t inner = 1; inner < vers && inner < syms; ++inner) + if (newsymidx[inner] != 0 && newsymidx[inner] < vers) + /* Overwriting the same array works since the + reordering can only move entries to lower indices + in the array. */ + verstab[newsymidx[inner]] = verstab[inner]; + + /* New size of the section. */ + verd->d_size = gelf_fsize (newelf, verd->d_type, + symd->d_size + / gelf_fsize (elf, symd->d_type, 1, + EV_CURRENT), + EV_CURRENT); + update_section_size (scn, verd, debugelf, cnt, fname); + break; + + case SHT_GROUP: + /* Yes, the symbol table changed. + Update the section header of the section group. */ + scn = elf_getscn (newelf, info->idx); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + elf_assert (shdr != NULL); + + size_t symsz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); + const Elf32_Word symn = (shdr_info[symtabidx].data->d_size + / symsz); + elf_assert (shdr->sh_info < symn); + shdr->sh_info = newsymidx[shdr->sh_info]; + + (void) gelf_update_shdr (scn, shdr); + break; + } + } + + /* Remove any relocations between debug sections in ET_REL + for the debug file when requested. These relocations are always + zero based between the unallocated sections. */ + if (debug_fname != NULL && removing_sections + && reloc_debug && ehdr->e_type == ET_REL) + remove_debug_relocations (ebl, debugelf, ehdr, fname, shstrndx); + + /* Now that we have done all adjustments to the data, + we can actually write out the debug file. */ + if (debug_fname != NULL && removing_sections) + { + /* Finally write the file. */ + if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1)) + { + error (0, 0, _("while writing '%s': %s"), + tmp_debug_fname, elf_errmsg (-1)); + result = 1; + goto fail_close; + } + + /* Create the real output file. First rename, then change the + mode. */ + if (rename (tmp_debug_fname, debug_fname) != 0 + || fchmod (debug_fd, mode) != 0) + { + error (0, errno, _("while creating '%s'"), debug_fname); + result = 1; + goto fail_close; + } + + /* The temporary file does not exist anymore. */ + free (tmp_debug_fname); + tmp_debug_fname = NULL; + + if (!remove_shdrs) + { + uint32_t debug_crc; + Elf_Data debug_crc_data = + { + .d_type = ELF_T_WORD, + .d_buf = &debug_crc, + .d_size = sizeof (debug_crc), + .d_version = EV_CURRENT + }; + + /* Compute the checksum which we will add to the executable. */ + if (crc32_file (debug_fd, &debug_crc) != 0) + { + error (0, errno, _("\ +while computing checksum for debug information")); + unlink (debug_fname); + result = 1; + goto fail_close; + } + + /* Store it in the debuglink section data. */ + if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data, + &debug_crc_data, ehdr->e_ident[EI_DATA]) + != &debuglink_crc_data)) + INTERNAL_ERROR (fname); + } + } + + lastsec_offset = shdr_info[shdridx].shdr.sh_offset; + lastsec_size = shdr_info[shdridx].shdr.sh_size; + + done: + /* Finally finish the ELF header. Fill in the fields not handled by + libelf from the old file. */ + newehdr = gelf_getehdr (newelf, &newehdr_mem); + if (newehdr == NULL) + INTERNAL_ERROR (fname); + + memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT); + newehdr->e_type = ehdr->e_type; + newehdr->e_machine = ehdr->e_machine; + newehdr->e_version = ehdr->e_version; + newehdr->e_entry = ehdr->e_entry; + newehdr->e_flags = ehdr->e_flags; + newehdr->e_phoff = ehdr->e_phoff; + + /* We need to position the section header table. */ + const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT); + newehdr->e_shoff = ((lastsec_offset + lastsec_size + offsize - 1) + & ~((GElf_Off) (offsize - 1))); + newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT); + + if (gelf_update_ehdr (newelf, newehdr) == 0) + { + error (0, 0, _("%s: error while creating ELF header: %s"), + output_fname ?: fname, elf_errmsg (-1)); + cleanup_debug (); + return 1; + } + + /* The new section header string table index. */ + if (update_shdrstrndx (newelf, idx) != 0) + { + error (0, 0, _("%s: error updating shdrstrndx: %s"), + output_fname ?: fname, elf_errmsg (-1)); + cleanup_debug (); + return 1; + } + + /* We have everything from the old file. */ + if (elf_cntl (elf, ELF_C_FDDONE) != 0) + { + error (0, 0, _("%s: error while reading the file: %s"), + fname, elf_errmsg (-1)); + cleanup_debug (); + return 1; + } + + /* The ELF library better follows our layout when this is not a + relocatable object file. */ + elf_flagelf (newelf, ELF_C_SET, + (phnum > 0 ? ELF_F_LAYOUT : 0) + | (permissive ? ELF_F_PERMISSIVE : 0)); + + /* Finally write the file. */ + if (elf_update (newelf, ELF_C_WRITE) == -1) + { + error (0, 0, _("while writing '%s': %s"), + output_fname ?: fname, elf_errmsg (-1)); + result = 1; + } + + if (remove_shdrs) + { + /* libelf can't cope without the section headers being properly intact. + So we just let it write them normally, and then we nuke them later. */ + + if (newehdr->e_ident[EI_CLASS] == ELFCLASS32) + { + assert (offsetof (Elf32_Ehdr, e_shentsize) + sizeof (Elf32_Half) + == offsetof (Elf32_Ehdr, e_shnum)); + assert (offsetof (Elf32_Ehdr, e_shnum) + sizeof (Elf32_Half) + == offsetof (Elf32_Ehdr, e_shstrndx)); + const Elf32_Off zero_off = 0; + const Elf32_Half zero[3] = { 0, 0, SHN_UNDEF }; + if (pwrite_retry (fd, &zero_off, sizeof zero_off, + offsetof (Elf32_Ehdr, e_shoff)) != sizeof zero_off + || (pwrite_retry (fd, zero, sizeof zero, + offsetof (Elf32_Ehdr, e_shentsize)) + != sizeof zero) + || ftruncate (fd, lastsec_offset) < 0) + { + error (0, errno, _("while writing '%s'"), + output_fname ?: fname); + result = 1; + } + } + else + { + assert (offsetof (Elf64_Ehdr, e_shentsize) + sizeof (Elf64_Half) + == offsetof (Elf64_Ehdr, e_shnum)); + assert (offsetof (Elf64_Ehdr, e_shnum) + sizeof (Elf64_Half) + == offsetof (Elf64_Ehdr, e_shstrndx)); + const Elf64_Off zero_off = 0; + const Elf64_Half zero[3] = { 0, 0, SHN_UNDEF }; + if (pwrite_retry (fd, &zero_off, sizeof zero_off, + offsetof (Elf64_Ehdr, e_shoff)) != sizeof zero_off + || (pwrite_retry (fd, zero, sizeof zero, + offsetof (Elf64_Ehdr, e_shentsize)) + != sizeof zero) + || ftruncate (fd, lastsec_offset) < 0) + { + error (0, errno, _("while writing '%s'"), + output_fname ?: fname); + result = 1; + } + } + } + + fail_close: + if (shdr_info != NULL) + { + /* For some sections we might have created an table to map symbol + table indices. Or we might kept (original) data around to put + into the .debug file. */ + for (cnt = 1; cnt <= shdridx; ++cnt) + { + free (shdr_info[cnt].newsymidx); + if (shdr_info[cnt].debug_data != NULL) + free (shdr_info[cnt].debug_data->d_buf); + } + + /* Free data we allocated for the .gnu_debuglink section. */ + free (debuglink_buf); + + /* Free the memory. */ + if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) + free (shdr_info); + } + + /* Free other resources. */ + if (shstrtab_data != NULL) + free (shstrtab_data->d_buf); + if (shst != NULL) + dwelf_strtab_free (shst); + + /* That was it. Close the descriptors. */ + if (elf_end (newelf) != 0) + { + error (0, 0, _("error while finishing '%s': %s"), + output_fname ?: fname, elf_errmsg (-1)); + result = 1; + } + + if (debugelf != NULL && elf_end (debugelf) != 0) + { + error (0, 0, _("error while finishing '%s': %s"), debug_fname, + elf_errmsg (-1)); + result = 1; + } + + fail: + /* Close the EBL backend. */ + if (ebl != NULL) + ebl_closebackend (ebl); + + cleanup_debug (); + + /* If requested, preserve the timestamp. */ + if (tvp != NULL) + { + if (futimens (fd, tvp) != 0) + { + error (0, errno, _("\ +cannot set access and modification date of '%s'"), + output_fname ?: fname); + result = 1; + } + } + + /* Close the file descriptor if we created a new file. */ + if (output_fname != NULL) + { + close (fd); + if (result != 0) + unlink (output_fname); + } + + return result; +} + +static void +cleanup_debug (void) +{ + if (debug_fd >= 0) + { + if (tmp_debug_fname != NULL) + { + unlink (tmp_debug_fname); + free (tmp_debug_fname); + tmp_debug_fname = NULL; + } + close (debug_fd); + debug_fd = -1; + } +} + +static int +handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, + struct timespec tvp[2]) +{ + size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); + size_t fname_len = strlen (fname) + 1; + char new_prefix[prefix_len + 1 + fname_len]; + char *cp = new_prefix; + + /* Create the full name of the file. */ + if (prefix != NULL) + { + cp = mempcpy (cp, prefix, prefix_len); + *cp++ = ':'; + } + memcpy (cp, fname, fname_len); + + + /* Process all the files contained in the archive. */ + Elf *subelf; + Elf_Cmd cmd = ELF_C_RDWR; + int result = 0; + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + if (elf_kind (subelf) == ELF_K_ELF) + result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); + else if (elf_kind (subelf) == ELF_K_AR) + result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL); + + /* Get next archive element. */ + cmd = elf_next (subelf); + if (unlikely (elf_end (subelf) != 0)) + INTERNAL_ERROR (fname); + } + + if (tvp != NULL) + { + if (unlikely (futimens (fd, tvp) != 0)) + { + error (0, errno, _("\ +cannot set access and modification date of '%s'"), fname); + result = 1; + } + } + + if (unlikely (close (fd) != 0)) + error (EXIT_FAILURE, errno, _("while closing '%s'"), fname); + + return result; +} + + +#include "debugpred.h" diff --git a/src/unstrip.c b/src/unstrip.c new file mode 100644 index 00000000..e488e810 --- /dev/null +++ b/src/unstrip.c @@ -0,0 +1,2632 @@ +/* Combine stripped files with separate symbols and debug information. + Copyright (C) 2007-2012, 2014, 2015 Red Hat, Inc. + This file is part of elfutils. + Written by Roland McGrath , 2007. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +/* TODO: + + * SHX_XINDEX + + * prelink vs .debug_* linked addresses + + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "system.h" +#include "libdwelf.h" +#include "libeu.h" +#include "printversion.h" + +/* Name and version of program. */ +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + +/* Bug report address. */ +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + /* Group 2 will follow group 1 from dwfl_standard_argp. */ + { "match-file-names", 'f', NULL, 0, + N_("Match MODULE against file names, not module names"), 2 }, + { "ignore-missing", 'i', NULL, 0, N_("Silently skip unfindable files"), 0 }, + + { NULL, 0, NULL, 0, N_("Output options:"), 0 }, + { "output", 'o', "FILE", 0, N_("Place output into FILE"), 0 }, + { "output-directory", 'd', "DIRECTORY", + 0, N_("Create multiple output files under DIRECTORY"), 0 }, + { "module-names", 'm', NULL, 0, N_("Use module rather than file names"), 0 }, + { "all", 'a', NULL, 0, + N_("Create output for modules that have no separate debug information"), + 0 }, + { "relocate", 'R', NULL, 0, + N_("Apply relocations to section contents in ET_REL files"), 0 }, + { "list-only", 'n', NULL, 0, + N_("Only list module and file names, build IDs"), 0 }, + { "force", 'F', NULL, 0, + N_("Force combining files even if some ELF headers don't seem to match"), + 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +struct arg_info +{ + const char *output_file; + const char *output_dir; + Dwfl *dwfl; + char **args; + bool list; + bool all; + bool ignore; + bool modnames; + bool match_files; + bool relocate; + bool force; +}; + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + struct arg_info *info = state->input; + + switch (key) + { + case ARGP_KEY_INIT: + state->child_inputs[0] = &info->dwfl; + break; + + case 'o': + if (info->output_file != NULL) + { + argp_error (state, _("-o option specified twice")); + return EINVAL; + } + info->output_file = arg; + break; + + case 'd': + if (info->output_dir != NULL) + { + argp_error (state, _("-d option specified twice")); + return EINVAL; + } + info->output_dir = arg; + break; + + case 'm': + info->modnames = true; + break; + case 'f': + info->match_files = true; + break; + case 'a': + info->all = true; + break; + case 'i': + info->ignore = true; + break; + case 'n': + info->list = true; + break; + case 'R': + info->relocate = true; + break; + case 'F': + info->force = true; + break; + + case ARGP_KEY_ARGS: + case ARGP_KEY_NO_ARGS: + /* We "consume" all the arguments here. */ + info->args = &state->argv[state->next]; + + if (info->output_file != NULL && info->output_dir != NULL) + { + argp_error (state, _("only one of -o or -d allowed")); + return EINVAL; + } + + if (info->list && (info->dwfl == NULL + || info->output_dir != NULL + || info->output_file != NULL)) + { + argp_error (state, + _("-n cannot be used with explicit files or -o or -d")); + return EINVAL; + } + + if (info->output_dir != NULL) + { + struct stat st; + error_t fail = 0; + if (stat (info->output_dir, &st) < 0) + fail = errno; + else if (!S_ISDIR (st.st_mode)) + fail = ENOTDIR; + if (fail) + { + argp_failure (state, EXIT_FAILURE, fail, + _("output directory '%s'"), info->output_dir); + return fail; + } + } + + if (info->dwfl == NULL) + { + if (state->next + 2 != state->argc) + { + argp_error (state, _("exactly two file arguments are required")); + return EINVAL; + } + + if (info->ignore || info->all || info->modnames || info->relocate) + { + argp_error (state, _("\ +-m, -a, -R, and -i options not allowed with explicit files")); + return EINVAL; + } + + /* Bail out immediately to prevent dwfl_standard_argp's parser + from defaulting to "-e a.out". */ + return ENOSYS; + } + else if (info->output_file == NULL && info->output_dir == NULL + && !info->list) + { + argp_error (state, + _("-o or -d is required when using implicit files")); + return EINVAL; + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +#define ELF_CHECK(call, msg) \ + do \ + { \ + if (unlikely (!(call))) \ + error (EXIT_FAILURE, 0, msg, elf_errmsg (-1)); \ + } while (0) + +/* Copy INELF to newly-created OUTELF, exit via error for any problems. */ +static void +copy_elf (Elf *outelf, Elf *inelf) +{ + ELF_CHECK (gelf_newehdr (outelf, gelf_getclass (inelf)), + _("cannot create ELF header: %s")); + + size_t shstrndx; + ELF_CHECK (elf_getshdrstrndx (inelf, &shstrndx) == 0, + _("cannot get shdrstrndx:%s")); + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (inelf, &ehdr_mem); + ELF_CHECK (ehdr != NULL, _("cannot get ELF header: %s")); + if (shstrndx < SHN_LORESERVE) + ehdr->e_shstrndx = shstrndx; + else + { + ehdr->e_shstrndx = SHN_XINDEX; + Elf_Scn *scn0 = elf_getscn (outelf, 0); + GElf_Shdr shdr0_mem; + GElf_Shdr *shdr0 = gelf_getshdr (scn0, &shdr0_mem); + ELF_CHECK (shdr0 != NULL, + _("cannot get new zero section: %s")); + shdr0->sh_link = shstrndx; + ELF_CHECK (gelf_update_shdr (scn0, shdr0), + _("cannot update new zero section: %s")); + } + + ELF_CHECK (gelf_update_ehdr (outelf, ehdr), + _("cannot copy ELF header: %s")); + + size_t phnum; + ELF_CHECK (elf_getphdrnum (inelf, &phnum) == 0, + _("cannot get number of program headers: %s")); + + if (phnum > 0) + { + ELF_CHECK (gelf_newphdr (outelf, phnum), + _("cannot create program headers: %s")); + + GElf_Phdr phdr_mem; + for (size_t i = 0; i < phnum; ++i) + ELF_CHECK (gelf_update_phdr (outelf, i, + gelf_getphdr (inelf, i, &phdr_mem)), + _("cannot copy program header: %s")); + } + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (inelf, scn)) != NULL) + { + Elf_Scn *newscn = elf_newscn (outelf); + + GElf_Shdr shdr_mem; + ELF_CHECK (gelf_update_shdr (newscn, gelf_getshdr (scn, &shdr_mem)), + _("cannot copy section header: %s")); + + Elf_Data *data = elf_getdata (scn, NULL); + ELF_CHECK (data != NULL, _("cannot get section data: %s")); + Elf_Data *newdata = elf_newdata (newscn); + ELF_CHECK (newdata != NULL, _("cannot copy section data: %s")); + *newdata = *data; + elf_flagdata (newdata, ELF_C_SET, ELF_F_DIRTY); + } +} + +/* Create directories containing PATH. */ +static void +make_directories (const char *path) +{ + const char *lastslash = strrchr (path, '/'); + if (lastslash == NULL) + return; + + while (lastslash > path && lastslash[-1] == '/') + --lastslash; + if (lastslash == path) + return; + + char *dir = strndup (path, lastslash - path); + if (dir == NULL) + error(EXIT_FAILURE, errno, _("memory exhausted")); + + while (mkdir (dir, ACCESSPERMS) < 0 && errno != EEXIST) + { + if (errno == ENOENT) + make_directories (dir); + else + error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir); + } + free (dir); +} + +/* Keep track of new section data we are creating, so we can free it + when done. */ +struct data_list +{ + void *data; + struct data_list *next; +}; + +struct data_list *new_data_list; + +static void +record_new_data (void *data) +{ + struct data_list *next = new_data_list; + new_data_list = xmalloc (sizeof (struct data_list)); + new_data_list->data = data; + new_data_list->next = next; +} + +static void +free_new_data (void) +{ + struct data_list *list = new_data_list; + while (list != NULL) + { + struct data_list *next = list->next; + free (list->data); + free (list); + list = next; + } + new_data_list = NULL; +} + +/* The binutils linker leaves gratuitous section symbols in .symtab + that strip has to remove. Older linkers likewise include a + symbol for every section, even unallocated ones, in .dynsym. + Because of this, the related sections can shrink in the stripped + file from their original size. Older versions of strip do not + adjust the sh_size field in the debuginfo file's SHT_NOBITS + version of the section header, so it can appear larger. */ +static bool +section_can_shrink (const GElf_Shdr *shdr) +{ + switch (shdr->sh_type) + { + case SHT_SYMTAB: + case SHT_DYNSYM: + case SHT_HASH: + case SHT_GNU_versym: + return true; + } + return false; +} + +/* See if this symbol table has a leading section symbol for every single + section, in order. The binutils linker produces this. While we're here, + update each section symbol's st_value. */ +static size_t +symtab_count_leading_section_symbols (Elf *elf, Elf_Scn *scn, size_t shnum, + Elf_Data *newsymdata) +{ + Elf_Data *data = elf_getdata (scn, NULL); + Elf_Data *shndxdata = NULL; /* XXX */ + + for (size_t i = 1; i < shnum; ++i) + { + GElf_Sym sym_mem; + GElf_Word shndx = SHN_UNDEF; + GElf_Sym *sym = gelf_getsymshndx (data, shndxdata, i, &sym_mem, &shndx); + ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, i), &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + if (sym->st_shndx != SHN_XINDEX) + shndx = sym->st_shndx; + + if (shndx != i || GELF_ST_TYPE (sym->st_info) != STT_SECTION) + return i; + + sym->st_value = shdr->sh_addr; + if (sym->st_shndx != SHN_XINDEX) + shndx = SHN_UNDEF; + ELF_CHECK (gelf_update_symshndx (newsymdata, shndxdata, i, sym, shndx), + _("cannot update symbol table: %s")); + } + + return shnum; +} + +static void +update_shdr (Elf_Scn *outscn, GElf_Shdr *newshdr) +{ + ELF_CHECK (gelf_update_shdr (outscn, newshdr), + _("cannot update section header: %s")); +} + +/* We expanded the output section, so update its header. */ +static void +update_sh_size (Elf_Scn *outscn, const Elf_Data *data) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem); + ELF_CHECK (newshdr != NULL, _("cannot get section header: %s")); + + newshdr->sh_size = data->d_size; + + update_shdr (outscn, newshdr); +} + +static inline void +adjust_reloc (GElf_Xword *info, + size_t map[], size_t map_size) +{ + size_t ndx = GELF_R_SYM (*info); + if (ndx != STN_UNDEF) + { + if (ndx > map_size) + error (EXIT_FAILURE, 0, "bad symbol ndx section"); + *info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info)); + } +} + +/* Update relocation sections using the symbol table. */ +static void +adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr, + size_t map[], size_t map_size, const GElf_Shdr *symshdr) +{ + Elf_Data *data = elf_getdata (outscn, NULL); + + switch (shdr->sh_type) + { + case SHT_REL: + if (shdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, "REL section cannot have zero sh_entsize"); + + for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i) + { + GElf_Rel rel_mem; + GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); + adjust_reloc (&rel->r_info, map, map_size); + ELF_CHECK (gelf_update_rel (data, i, rel), + _("cannot update relocation: %s")); + } + break; + + case SHT_RELA: + if (shdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, "RELA section cannot have zero sh_entsize"); + + for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i) + { + GElf_Rela rela_mem; + GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); + adjust_reloc (&rela->r_info, map, map_size); + ELF_CHECK (gelf_update_rela (data, i, rela), + _("cannot update relocation: %s")); + } + break; + + case SHT_GROUP: + { + GElf_Shdr shdr_mem; + GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem); + ELF_CHECK (newshdr != NULL, _("cannot get section header: %s")); + if (newshdr->sh_info != STN_UNDEF) + { + newshdr->sh_info = map[newshdr->sh_info - 1]; + update_shdr (outscn, newshdr); + } + break; + } + + case SHT_HASH: + /* We must expand the table and rejigger its contents. */ + { + if (shdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, "HASH section cannot have zero sh_entsize"); + if (symshdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize"); + const size_t nsym = symshdr->sh_size / symshdr->sh_entsize; + const size_t onent = shdr->sh_size / shdr->sh_entsize; + if (data->d_size != shdr->sh_size) + error (EXIT_FAILURE, 0, "HASH section has inconsistent size"); + +#define CONVERT_HASH(Hash_Word) \ + { \ + const Hash_Word *const old_hash = data->d_buf; \ + const size_t nbucket = old_hash[0]; \ + const size_t nchain = old_hash[1]; \ + const Hash_Word *const old_bucket = &old_hash[2]; \ + const Hash_Word *const old_chain = &old_bucket[nbucket]; \ + if (onent != 2 + nbucket + nchain) \ + error (EXIT_FAILURE, 0, "HASH section has inconsistent entsize"); \ + \ + const size_t nent = 2 + nbucket + nsym; \ + Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]); \ + Hash_Word *const new_bucket = &new_hash[2]; \ + Hash_Word *const new_chain = &new_bucket[nbucket]; \ + \ + new_hash[0] = nbucket; \ + new_hash[1] = nsym; \ + for (size_t i = 0; i < nbucket; ++i) \ + if (old_bucket[i] != STN_UNDEF) \ + new_bucket[i] = map[old_bucket[i] - 1]; \ + \ + for (size_t i = 1; i < nchain; ++i) \ + if (old_chain[i] != STN_UNDEF) \ + new_chain[map[i - 1]] = map[old_chain[i] - 1]; \ + \ + record_new_data (new_hash); \ + data->d_buf = new_hash; \ + data->d_size = nent * sizeof new_hash[0]; \ + } + + switch (shdr->sh_entsize) + { + case 4: + CONVERT_HASH (Elf32_Word); + break; + case 8: + CONVERT_HASH (Elf64_Xword); + break; + default: + abort (); + } + + elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY); + update_sh_size (outscn, data); + +#undef CONVERT_HASH + } + break; + + case SHT_GNU_versym: + /* We must expand the table and move its elements around. */ + { + if (shdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, + "GNU_versym section cannot have zero sh_entsize"); + if (symshdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize"); + const size_t nent = symshdr->sh_size / symshdr->sh_entsize; + const size_t onent = shdr->sh_size / shdr->sh_entsize; + assert (nent >= onent); + + /* We don't bother using gelf_update_versym because there is + really no conversion to be done. */ + assert (sizeof (Elf32_Versym) == sizeof (GElf_Versym)); + assert (sizeof (Elf64_Versym) == sizeof (GElf_Versym)); + GElf_Versym *versym = xcalloc (nent, sizeof versym[0]); + + for (size_t i = 1; i < onent; ++i) + { + GElf_Versym *v = gelf_getversym (data, i, &versym[map[i - 1]]); + ELF_CHECK (v != NULL, _("cannot get symbol version: %s")); + } + + record_new_data (versym); + data->d_buf = versym; + data->d_size = nent * sizeof versym[0]; + elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY); + update_sh_size (outscn, data); + } + break; + + default: + error (EXIT_FAILURE, 0, + _("unexpected section type in [%zu] with sh_link to symtab"), + elf_ndxscn (inscn)); + } +} + +/* Adjust all the relocation sections in the file. */ +static void +adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr, + size_t map[], size_t map_size) +{ + size_t new_sh_link = elf_ndxscn (symtab); + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + if (scn != symtab) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + /* Don't redo SHT_GROUP, groups are in both the stripped and debug, + it will already have been done by adjust_relocs for the + stripped_symtab. */ + if (shdr->sh_type != SHT_NOBITS && shdr->sh_type != SHT_GROUP + && shdr->sh_link == new_sh_link) + adjust_relocs (scn, scn, shdr, map, map_size, symshdr); + } +} + +/* The original file probably had section symbols for all of its + sections, even the unallocated ones. To match it as closely as + possible, add in section symbols for the added sections. */ +static Elf_Data * +add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum, + Elf *elf, bool rel, Elf_Scn *symscn, size_t shnum) +{ + const size_t added = shnum - old_shnum; + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + if (shdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, "Symbol table section cannot have zero sh_entsize"); + + const size_t nsym = shdr->sh_size / shdr->sh_entsize; + size_t symndx_map[nsym - 1]; + + shdr->sh_info += added; + shdr->sh_size += added * shdr->sh_entsize; + update_shdr (symscn, shdr); + + Elf_Data *symdata = elf_getdata (symscn, NULL); + Elf_Data *shndxdata = NULL; /* XXX */ + + symdata->d_size = shdr->sh_size; + symdata->d_buf = xmalloc (symdata->d_size); + record_new_data (symdata->d_buf); + + /* Copy the existing section symbols. */ + Elf_Data *old_symdata = elf_getdata (old_symscn, NULL); + for (size_t i = 0; i < old_shnum; ++i) + { + GElf_Sym sym_mem; + GElf_Word shndx = SHN_UNDEF; + GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata, + i, &sym_mem, &shndx); + ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); + ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i, + sym, shndx), + _("cannot update symbol table: %s")); + + if (i > 0) + symndx_map[i - 1] = i; + } + + /* Add in the new section symbols. */ + for (size_t i = old_shnum; i < shnum; ++i) + { + GElf_Shdr i_shdr_mem; + GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem); + ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s")); + GElf_Sym sym = + { + .st_value = rel ? 0 : i_shdr->sh_addr, + .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION), + .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX + }; + GElf_Word shndx = i < SHN_LORESERVE ? SHN_UNDEF : i; + ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i, + &sym, shndx), + _("cannot update symbol table: %s")); + } + + /* Now copy the rest of the existing symbols. */ + for (size_t i = old_shnum; i < nsym; ++i) + { + GElf_Sym sym_mem; + GElf_Word shndx = SHN_UNDEF; + GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata, + i, &sym_mem, &shndx); + ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); + ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, + i + added, sym, shndx), + _("cannot update symbol table: %s")); + + symndx_map[i - 1] = i + added; + } + + /* Adjust any relocations referring to the old symbol table. */ + adjust_all_relocs (elf, symscn, shdr, symndx_map, nsym - 1); + + return symdata; +} + +/* This has the side effect of updating STT_SECTION symbols' values, + in case of prelink adjustments. */ +static Elf_Data * +check_symtab_section_symbols (Elf *elf, bool rel, Elf_Scn *scn, + size_t shnum, size_t shstrndx, + Elf_Scn *oscn, size_t oshnum, size_t oshstrndx, + size_t debuglink) +{ + size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum, + elf_getdata (scn, NULL)); + + if (n == oshnum) + return add_new_section_symbols (oscn, n, elf, rel, scn, shnum); + + if (n == oshstrndx || (n == debuglink && n == oshstrndx - 1)) + return add_new_section_symbols (oscn, n, elf, rel, scn, shstrndx); + + return NULL; +} + +struct section +{ + Elf_Scn *scn; + const char *name; + const char *sig; + Elf_Scn *outscn; + Dwelf_Strent *strent; + GElf_Shdr shdr; +}; + +static int +compare_alloc_sections (const struct section *s1, const struct section *s2, + bool rel) +{ + if (!rel) + { + /* Sort by address. */ + if (s1->shdr.sh_addr < s2->shdr.sh_addr) + return -1; + if (s1->shdr.sh_addr > s2->shdr.sh_addr) + return 1; + } + + /* At the same address, preserve original section order. */ + return (ssize_t) elf_ndxscn (s1->scn) - (ssize_t) elf_ndxscn (s2->scn); +} + +static int +compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2, + const char *name1, const char *name2, + const char *sig1, const char *sig2) +{ + /* Sort by sh_flags as an arbitrary ordering. */ + if (shdr1->sh_flags < shdr2->sh_flags) + return -1; + if (shdr1->sh_flags > shdr2->sh_flags) + return 1; + + /* Sizes should be the same. */ + if (shdr1->sh_size < shdr2->sh_size) + return -1; + if (shdr1->sh_size > shdr2->sh_size) + return 1; + + /* Are they both SHT_GROUP sections? Then compare signatures. */ + if (sig1 != NULL && sig2 != NULL) + return strcmp (sig1, sig2); + + /* Sort by name as last resort. */ + return strcmp (name1, name2); +} + +static int +compare_sections (const void *a, const void *b, bool rel) +{ + const struct section *s1 = a; + const struct section *s2 = b; + + /* Sort all non-allocated sections last. */ + if ((s1->shdr.sh_flags ^ s2->shdr.sh_flags) & SHF_ALLOC) + return (s1->shdr.sh_flags & SHF_ALLOC) ? -1 : 1; + + return ((s1->shdr.sh_flags & SHF_ALLOC) + ? compare_alloc_sections (s1, s2, rel) + : compare_unalloc_sections (&s1->shdr, &s2->shdr, + s1->name, s2->name, + s1->sig, s2->sig)); +} + +static int +compare_sections_rel (const void *a, const void *b) +{ + return compare_sections (a, b, true); +} + +static int +compare_sections_nonrel (const void *a, const void *b) +{ + return compare_sections (a, b, false); +} + + +struct symbol +{ + size_t *map; + + union + { + const char *name; + Dwelf_Strent *strent; + }; + union + { + struct + { + GElf_Addr value; + GElf_Xword size; + GElf_Word shndx; + union + { + struct + { + uint8_t info; + uint8_t other; + } info; + int16_t compare; + }; + }; + + /* For a symbol discarded after first sort, this matches its better's + map pointer. */ + size_t *duplicate; + }; +}; + +/* Collect input symbols into our internal form. */ +static void +collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn, + const size_t nent, const GElf_Addr bias, + const size_t scnmap[], struct symbol *table, size_t *map, + struct section *split_bss) +{ + Elf_Data *symdata = elf_getdata (symscn, NULL); + ELF_CHECK (symdata != NULL, _("cannot get symbol section data: %s")); + Elf_Data *strdata = elf_getdata (strscn, NULL); + ELF_CHECK (strdata != NULL, _("cannot get string section data: %s")); + Elf_Data *shndxdata = NULL; /* XXX */ + + for (size_t i = 1; i < nent; ++i) + { + GElf_Sym sym_mem; + GElf_Word shndx = SHN_UNDEF; + GElf_Sym *sym = gelf_getsymshndx (symdata, shndxdata, i, + &sym_mem, &shndx); + ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); + if (sym->st_shndx != SHN_XINDEX) + shndx = sym->st_shndx; + + if (sym->st_name >= strdata->d_size + || memrchr (strdata->d_buf + sym->st_name, '\0', + strdata->d_size - sym->st_name) == NULL) + error (EXIT_FAILURE, 0, + _("invalid string offset in symbol [%zu]"), i); + + struct symbol *s = &table[i - 1]; + s->map = &map[i - 1]; + s->name = strdata->d_buf + sym->st_name; + s->value = sym->st_value + bias; + s->size = sym->st_size; + s->shndx = shndx; + s->info.info = sym->st_info; + s->info.other = sym->st_other; + + if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE) + s->shndx = scnmap[shndx - 1]; + + if (GELF_ST_TYPE (s->info.info) == STT_SECTION && !rel) + { + /* Update the value to match the output section. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, s->shndx), + &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + s->value = shdr->sh_addr; + } + else if (split_bss != NULL + && s->value < split_bss->shdr.sh_addr + && s->value >= split_bss[-1].shdr.sh_addr + && shndx == elf_ndxscn (split_bss->outscn)) + /* This symbol was in .bss and was split into .dynbss. */ + s->shndx = elf_ndxscn (split_bss[-1].outscn); + } +} + + +#define CMP(value) \ + if (s1->value < s2->value) \ + return -1; \ + if (s1->value > s2->value) \ + return 1 + +/* Compare symbols with a consistent ordering, + but one only meaningful for equality. */ +static int +compare_symbols (const void *a, const void *b) +{ + const struct symbol *s1 = a; + const struct symbol *s2 = b; + + CMP (value); + CMP (size); + CMP (shndx); + + return (s1->compare - s2->compare) ?: strcmp (s1->name, s2->name); +} + +/* Compare symbols for output order after slots have been assigned. */ +static int +compare_symbols_output (const void *a, const void *b) +{ + const struct symbol *s1 = a; + const struct symbol *s2 = b; + int cmp; + + /* Sort discarded symbols last. */ + cmp = (s1->name == NULL) - (s2->name == NULL); + + if (cmp == 0) + /* Local symbols must come first. */ + cmp = ((GELF_ST_BIND (s2->info.info) == STB_LOCAL) + - (GELF_ST_BIND (s1->info.info) == STB_LOCAL)); + + if (cmp == 0) + /* binutils always puts section symbols first. */ + cmp = ((GELF_ST_TYPE (s2->info.info) == STT_SECTION) + - (GELF_ST_TYPE (s1->info.info) == STT_SECTION)); + + if (cmp == 0) + { + if (GELF_ST_TYPE (s1->info.info) == STT_SECTION) + { + /* binutils always puts section symbols in section index order. */ + CMP (shndx); + else if (s1 != s2) + error (EXIT_FAILURE, 0, "section symbols in unexpected order"); + } + + /* Nothing really matters, so preserve the original order. */ + CMP (map); + else if (s1 != s2) + error (EXIT_FAILURE, 0, "found two identical symbols"); + } + + return cmp; +} + +#undef CMP + +/* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK + flag if the section contains relocation information. */ +static bool +sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2, + Elf64_Word sh_type) +{ + if (sh_type == SHT_REL || sh_type == SHT_RELA) + { + sh_flags1 &= ~SHF_INFO_LINK; + sh_flags2 &= ~SHF_INFO_LINK; + } + + return sh_flags1 == sh_flags2; +} + +/* Return true iff the flags, size, and name match. */ +static bool +sections_match (const struct section *sections, size_t i, + const GElf_Shdr *shdr, const char *name) +{ + return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags, + sections[i].shdr.sh_type) + && (sections[i].shdr.sh_size == shdr->sh_size + || (sections[i].shdr.sh_size < shdr->sh_size + && section_can_shrink (§ions[i].shdr))) + && !strcmp (sections[i].name, name)); +} + +/* Locate a matching allocated section in SECTIONS. */ +static struct section * +find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name, + struct section sections[], size_t nalloc) +{ + const GElf_Addr addr = shdr->sh_addr + bias; + size_t l = 0, u = nalloc; + while (l < u) + { + size_t i = (l + u) / 2; + if (addr < sections[i].shdr.sh_addr) + u = i; + else if (addr > sections[i].shdr.sh_addr) + l = i + 1; + else + { + /* We've found allocated sections with this address. + Find one with matching size, flags, and name. */ + while (i > 0 && sections[i - 1].shdr.sh_addr == addr) + --i; + for (; i < nalloc && sections[i].shdr.sh_addr == addr; + ++i) + if (sections_match (sections, i, shdr, name)) + return §ions[i]; + break; + } + } + return NULL; +} + +static inline const char * +get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab) +{ + if (shdr->sh_name >= shstrtab->d_size) + error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"), + ndx, elf_errmsg (-1)); + return shstrtab->d_buf + shdr->sh_name; +} + +/* Returns the signature of a group section, or NULL if the given + section isn't a group. */ +static const char * +get_group_sig (Elf *elf, GElf_Shdr *shdr) +{ + if (shdr->sh_type != SHT_GROUP) + return NULL; + + Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link); + if (symscn == NULL) + error (EXIT_FAILURE, 0, _("bad sh_link for group section: %s"), + elf_errmsg (-1)); + + GElf_Shdr symshdr_mem; + GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); + if (symshdr == NULL) + error (EXIT_FAILURE, 0, _("couldn't get shdr for group section: %s"), + elf_errmsg (-1)); + + Elf_Data *symdata = elf_getdata (symscn, NULL); + if (symdata == NULL) + error (EXIT_FAILURE, 0, _("bad data for group symbol section: %s"), + elf_errmsg (-1)); + + GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem); + if (sym == NULL) + error (EXIT_FAILURE, 0, _("couldn't get symbol for group section: %s"), + elf_errmsg (-1)); + + const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name); + if (sig == NULL) + error (EXIT_FAILURE, 0, _("bad symbol name for group section: %s"), + elf_errmsg (-1)); + + return sig; +} + +static inline bool +check_match (bool match, Elf_Scn *scn, const char *name) +{ + if (!match) + { + error (0, 0, _("cannot find matching section for [%zu] '%s'"), + elf_ndxscn (scn), name); + return true; + } + + return false; +} + + +/* Fix things up when prelink has moved some allocated sections around + and the debuginfo file's section headers no longer match up. + This fills in SECTIONS[0..NALLOC-1].outscn or exits. + If there was a .bss section that was split into two sections + with the new one preceding it in sh_addr, we return that pointer. */ +static struct section * +find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, + Elf *main, const GElf_Ehdr *main_ehdr, + Elf_Data *main_shstrtab, GElf_Addr bias, + struct section *sections, + size_t nalloc, size_t nsections) +{ + Elf_Scn *undo = NULL; + for (size_t i = nalloc; i < nsections; ++i) + { + const struct section *sec = §ions[i]; + if (sec->shdr.sh_type == SHT_PROGBITS + && !(sec->shdr.sh_flags & SHF_ALLOC) + && !strcmp (sec->name, ".gnu.prelink_undo")) + { + undo = sec->scn; + break; + } + } + + /* Find the original allocated sections before prelinking. */ + struct section *undo_sections = NULL; + size_t undo_nalloc = 0; + if (undo != NULL) + { + /* Clear assignments that might have been bogus. */ + for (size_t i = 0; i < nalloc; ++i) + sections[i].outscn = NULL; + + Elf_Data *undodata = elf_rawdata (undo, NULL); + ELF_CHECK (undodata != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); + + union + { + Elf32_Ehdr e32; + Elf64_Ehdr e64; + } ehdr; + Elf_Data dst = + { + .d_buf = &ehdr, + .d_size = sizeof ehdr, + .d_type = ELF_T_EHDR, + .d_version = EV_CURRENT + }; + Elf_Data src = *undodata; + src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT); + src.d_type = ELF_T_EHDR; + ELF_CHECK (gelf_xlatetom (main, &dst, &src, + main_ehdr->e_ident[EI_DATA]) != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); + + uint_fast16_t phnum; + uint_fast16_t shnum; /* prelink doesn't handle > SHN_LORESERVE. */ + if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) + { + phnum = ehdr.e32.e_phnum; + shnum = ehdr.e32.e_shnum; + } + else + { + phnum = ehdr.e64.e_phnum; + shnum = ehdr.e64.e_shnum; + } + + bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; + size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr); + if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1)) + error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"), + (size_t) shnum, ".gnu.prelink_undo"); + + --shnum; + + size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT); + src.d_buf += src.d_size + phsize; + src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum, EV_CURRENT); + src.d_type = ELF_T_SHDR; + if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size + || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size) + error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"), + ".gnu.prelink_undo"); + + const size_t shdr_bytes = shnum * shsize; + void *shdr = xmalloc (shdr_bytes); + dst.d_buf = shdr; + dst.d_size = shdr_bytes; + ELF_CHECK (gelf_xlatetom (main, &dst, &src, + main_ehdr->e_ident[EI_DATA]) != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); + + undo_sections = xmalloc (shnum * sizeof undo_sections[0]); + for (size_t i = 0; i < shnum; ++i) + { + struct section *sec = &undo_sections[undo_nalloc]; + Elf32_Shdr (*s32)[shnum] = shdr; + Elf64_Shdr (*s64)[shnum] = shdr; + if (class32) + { +#define COPY(field) sec->shdr.field = (*s32)[i].field + COPY (sh_name); + COPY (sh_type); + COPY (sh_flags); + COPY (sh_addr); + COPY (sh_offset); + COPY (sh_size); + COPY (sh_link); + COPY (sh_info); + COPY (sh_addralign); + COPY (sh_entsize); +#undef COPY + } + else + sec->shdr = (*s64)[i]; + if (sec->shdr.sh_flags & SHF_ALLOC) + { + sec->shdr.sh_addr += bias; + sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab); + sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */ + sec->outscn = NULL; + sec->strent = NULL; + sec->sig = get_group_sig (main, &sec->shdr); + ++undo_nalloc; + } + } + qsort (undo_sections, undo_nalloc, + sizeof undo_sections[0], compare_sections_nonrel); + free (shdr); + } + + bool fail = false; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (debug, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + if (!(shdr->sh_flags & SHF_ALLOC)) + continue; + + const char *name = get_section_name (elf_ndxscn (scn), shdr, + debug_shstrtab); + + if (undo_sections != NULL) + { + struct section *sec = find_alloc_section (shdr, 0, name, + undo_sections, + undo_nalloc); + if (sec != NULL) + { + sec->outscn = scn; + continue; + } + } + + /* If there is no prelink info, we are just here to find + the sections to give error messages about. */ + for (size_t i = 0; shdr != NULL && i < nalloc; ++i) + if (sections[i].outscn == scn) + shdr = NULL; + fail |= check_match (shdr == NULL, scn, name); + } + + if (fail) + exit (EXIT_FAILURE); + + /* Now we have lined up output sections for each of the original sections + before prelinking. Translate those to the prelinked sections. + This matches what prelink's undo_sections does. */ + struct section *split_bss = NULL; + for (size_t i = 0; i < undo_nalloc; ++i) + { + const struct section *undo_sec = &undo_sections[i]; + + const char *name = undo_sec->name; + scn = undo_sec->scn; /* This is just for elf_ndxscn. */ + + for (size_t j = 0; j < nalloc; ++j) + { + struct section *sec = §ions[j]; +#define RELA_SCALED(field) \ + (2 * sec->shdr.field == 3 * undo_sec->shdr.field) + if (sec->outscn == NULL + && sec->shdr.sh_name == undo_sec->shdr.sh_name + && sec->shdr.sh_flags == undo_sec->shdr.sh_flags + && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign + && (((sec->shdr.sh_type == undo_sec->shdr.sh_type + && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize + && (sec->shdr.sh_size == undo_sec->shdr.sh_size + || (sec->shdr.sh_size > undo_sec->shdr.sh_size + && main_ehdr->e_type == ET_EXEC + && !strcmp (sec->name, ".dynstr")))) + || (sec->shdr.sh_size == undo_sec->shdr.sh_size + && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize + && undo_sec->shdr.sh_type == SHT_NOBITS) + || undo_sec->shdr.sh_type == SHT_PROGBITS) + && !strcmp (sec->name, ".plt"))) + || (sec->shdr.sh_type == SHT_RELA + && undo_sec->shdr.sh_type == SHT_REL + && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size)) + || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize + && (sec->shdr.sh_type == undo_sec->shdr.sh_type + || (sec->shdr.sh_type == SHT_PROGBITS + && undo_sec->shdr.sh_type == SHT_NOBITS)) + && sec->shdr.sh_size <= undo_sec->shdr.sh_size + && (!strcmp (sec->name, ".bss") + || !strcmp (sec->name, ".sbss")) + && (sec->shdr.sh_size == undo_sec->shdr.sh_size + || (split_bss = sec) > sections)))) + { + sec->outscn = undo_sec->outscn; + undo_sec = NULL; + break; + } + } + + fail |= check_match (undo_sec == NULL, scn, name); + } + + free (undo_sections); + + if (fail) + exit (EXIT_FAILURE); + + return split_bss; +} + +/* Create new .shstrtab contents, subroutine of copy_elided_sections. + This can't be open coded there and still use variable-length auto arrays, + since the end of our block would free other VLAs too. */ +static Elf_Data * +new_shstrtab (Elf *unstripped, size_t unstripped_shnum, + Elf_Data *shstrtab, size_t unstripped_shstrndx, + struct section *sections, size_t stripped_shnum, + Dwelf_Strtab *strtab) +{ + if (strtab == NULL) + return NULL; + + Dwelf_Strent *unstripped_strent[unstripped_shnum]; + memset (unstripped_strent, 0, sizeof unstripped_strent); + for (struct section *sec = sections; + sec < §ions[stripped_shnum - 1]; + ++sec) + if (sec->outscn != NULL) + { + if (sec->strent == NULL) + { + sec->strent = dwelf_strtab_add (strtab, sec->name); + ELF_CHECK (sec->strent != NULL, + _("cannot add section name to string table: %s")); + } + unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent; + } + + /* Add names of sections we aren't touching. */ + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + if (unstripped_strent[i] == NULL) + { + Elf_Scn *scn = elf_getscn (unstripped, i + 1); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + const char *name = get_section_name (i + 1, shdr, shstrtab); + unstripped_strent[i] = dwelf_strtab_add (strtab, name); + ELF_CHECK (unstripped_strent[i] != NULL, + _("cannot add section name to string table: %s")); + } + else + unstripped_strent[i] = NULL; + + /* Now finalize the string table so we can get offsets. */ + Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped, + unstripped_shstrndx), NULL); + ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY), + _("cannot update section header string table data: %s")); + if (dwelf_strtab_finalize (strtab, strtab_data) == NULL) + error (EXIT_FAILURE, 0, "Not enough memory to create string table"); + + /* Update the sh_name fields of sections we aren't modifying later. */ + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + if (unstripped_strent[i] != NULL) + { + Elf_Scn *scn = elf_getscn (unstripped, i + 1); + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + shdr->sh_name = dwelf_strent_off (unstripped_strent[i]); + if (i + 1 == unstripped_shstrndx) + shdr->sh_size = strtab_data->d_size; + update_shdr (scn, shdr); + } + + return strtab_data; +} + +/* Fill in any SHT_NOBITS sections in UNSTRIPPED by + copying their contents and sh_type from STRIPPED. */ +static void +copy_elided_sections (Elf *unstripped, Elf *stripped, + const GElf_Ehdr *stripped_ehdr, GElf_Addr bias) +{ + size_t unstripped_shstrndx; + ELF_CHECK (elf_getshdrstrndx (unstripped, &unstripped_shstrndx) == 0, + _("cannot get section header string table section index: %s")); + + size_t stripped_shstrndx; + ELF_CHECK (elf_getshdrstrndx (stripped, &stripped_shstrndx) == 0, + _("cannot get section header string table section index: %s")); + + size_t unstripped_shnum; + ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0, + _("cannot get section count: %s")); + + size_t stripped_shnum; + ELF_CHECK (elf_getshdrnum (stripped, &stripped_shnum) == 0, + _("cannot get section count: %s")); + + if (unlikely (stripped_shnum > unstripped_shnum)) + error (EXIT_FAILURE, 0, _("\ +more sections in stripped file than debug file -- arguments reversed?")); + + if (unlikely (stripped_shnum == 0)) + error (EXIT_FAILURE, 0, _("no sections in stripped file")); + + /* Used as sanity check for allocated section offset, if the section + offset needs to be preserved. We want to know the max size of the + ELF file, to check if any existing section offsets are OK. */ + int64_t max_off = -1; + if (stripped_ehdr->e_type != ET_REL) + { + elf_flagelf (stripped, ELF_C_SET, ELF_F_LAYOUT); + max_off = elf_update (stripped, ELF_C_NULL); + } + + /* Cache the stripped file's section details. */ + struct section sections[stripped_shnum - 1]; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (stripped, scn)) != NULL) + { + size_t i = elf_ndxscn (scn) - 1; + GElf_Shdr *shdr = gelf_getshdr (scn, §ions[i].shdr); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + sections[i].name = elf_strptr (stripped, stripped_shstrndx, + shdr->sh_name); + if (sections[i].name == NULL) + error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"), + elf_ndxscn (scn), elf_errmsg (-1)); + sections[i].scn = scn; + sections[i].outscn = NULL; + sections[i].strent = NULL; + sections[i].sig = get_group_sig (stripped, shdr); + } + + const struct section *stripped_symtab = NULL; + + /* Sort the sections, allocated by address and others after. */ + qsort (sections, stripped_shnum - 1, sizeof sections[0], + stripped_ehdr->e_type == ET_REL + ? compare_sections_rel : compare_sections_nonrel); + size_t nalloc = stripped_shnum - 1; + while (nalloc > 0 && !(sections[nalloc - 1].shdr.sh_flags & SHF_ALLOC)) + { + --nalloc; + if (sections[nalloc].shdr.sh_type == SHT_SYMTAB) + stripped_symtab = §ions[nalloc]; + } + + Elf_Data *shstrtab = elf_getdata (elf_getscn (unstripped, + unstripped_shstrndx), NULL); + ELF_CHECK (shstrtab != NULL, + _("cannot read section header string table: %s")); + + /* Match each debuginfo section with its corresponding stripped section. */ + bool check_prelink = false; + Elf_Scn *unstripped_symtab = NULL; + size_t unstripped_strndx = 0; + size_t alloc_avail = 0; + scn = NULL; + while ((scn = elf_nextscn (unstripped, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + if (shdr->sh_type == SHT_SYMTAB) + { + unstripped_symtab = scn; + unstripped_strndx = shdr->sh_link; + continue; + } + + const size_t ndx = elf_ndxscn (scn); + if (ndx == unstripped_shstrndx || ndx == unstripped_strndx) + continue; + + const char *name = get_section_name (ndx, shdr, shstrtab); + + struct section *sec = NULL; + if (shdr->sh_flags & SHF_ALLOC) + { + if (stripped_ehdr->e_type != ET_REL) + { + /* Look for the section that matches. */ + sec = find_alloc_section (shdr, bias, name, sections, nalloc); + if (sec == NULL) + { + /* We couldn't figure it out. It may be a prelink issue. */ + check_prelink = true; + continue; + } + } + else + { + /* The sh_addr of allocated sections does not help us, + but the order usually matches. */ + if (likely (sections_match (sections, alloc_avail, shdr, name))) + sec = §ions[alloc_avail++]; + else + for (size_t i = alloc_avail + 1; i < nalloc; ++i) + if (sections_match (sections, i, shdr, name)) + { + sec = §ions[i]; + break; + } + } + } + else + { + /* Locate a matching unallocated section in SECTIONS. */ + const char *sig = get_group_sig (unstripped, shdr); + size_t l = nalloc, u = stripped_shnum - 1; + while (l < u) + { + size_t i = (l + u) / 2; + struct section *section = §ions[i]; + int cmp = compare_unalloc_sections (shdr, §ion->shdr, + name, section->name, + sig, section->sig); + if (cmp < 0) + u = i; + else if (cmp > 0) + l = i + 1; + else + { + sec = section; + break; + } + } + + if (sec == NULL) + { + /* An additional unallocated section is fine if not SHT_NOBITS. + We looked it up anyway in case it's an unallocated section + copied in both files (e.g. SHT_NOTE), and don't keep both. */ + if (shdr->sh_type != SHT_NOBITS) + continue; + + /* Somehow some old .debug files wound up with SHT_NOBITS + .comment sections, so let those pass. */ + if (!strcmp (name, ".comment")) + continue; + } + } + + if (sec == NULL) + error (EXIT_FAILURE, 0, + _("cannot find matching section for [%zu] '%s'"), + elf_ndxscn (scn), name); + + sec->outscn = scn; + } + + /* If that failed due to changes made by prelink, we take another tack. + We keep track of a .bss section that was partly split into .dynbss + so that collect_symbols can update symbols' st_shndx fields. */ + struct section *split_bss = NULL; + if (check_prelink) + { + Elf_Data *data = elf_getdata (elf_getscn (stripped, stripped_shstrndx), + NULL); + ELF_CHECK (data != NULL, + _("cannot read section header string table: %s")); + split_bss = find_alloc_sections_prelink (unstripped, shstrtab, + stripped, stripped_ehdr, + data, bias, sections, + nalloc, stripped_shnum - 1); + } + + /* Make sure each main file section has a place to go. */ + const struct section *stripped_dynsym = NULL; + size_t debuglink = SHN_UNDEF; + size_t ndx_sec_num = stripped_shnum - 1; + size_t ndx_section[ndx_sec_num]; + Dwelf_Strtab *strtab = NULL; + for (struct section *sec = sections; + sec < §ions[ndx_sec_num]; + ++sec) + { + size_t secndx = elf_ndxscn (sec->scn); + + if (sec->outscn == NULL) + { + /* We didn't find any corresponding section for this. */ + + if (secndx == stripped_shstrndx) + { + /* We only need one .shstrtab. */ + ndx_section[secndx - 1] = unstripped_shstrndx; + continue; + } + + if (unstripped_symtab != NULL && sec == stripped_symtab) + { + /* We don't need a second symbol table. */ + ndx_section[secndx - 1] = elf_ndxscn (unstripped_symtab); + continue; + } + + if (unstripped_symtab != NULL && stripped_symtab != NULL + && secndx == stripped_symtab->shdr.sh_link + && unstripped_strndx != 0) + { + /* ... nor its string table. */ + ndx_section[secndx - 1] = unstripped_strndx; + continue; + } + + if (!(sec->shdr.sh_flags & SHF_ALLOC) + && !strcmp (sec->name, ".gnu_debuglink")) + { + /* This was created by stripping. We don't want it. */ + debuglink = secndx; + ndx_section[secndx - 1] = SHN_UNDEF; + continue; + } + + sec->outscn = elf_newscn (unstripped); + Elf_Data *newdata = elf_newdata (sec->outscn); + ELF_CHECK (newdata != NULL && gelf_update_shdr (sec->outscn, + &sec->shdr), + _("cannot add new section: %s")); + + if (strtab == NULL) + strtab = dwelf_strtab_init (true); + sec->strent = dwelf_strtab_add (strtab, sec->name); + ELF_CHECK (sec->strent != NULL, + _("cannot add section name to string table: %s")); + } + + /* Cache the mapping of original section indices to output sections. */ + ndx_section[secndx - 1] = elf_ndxscn (sec->outscn); + } + + /* We added some sections, so we need a new shstrtab. */ + Elf_Data *strtab_data = new_shstrtab (unstripped, unstripped_shnum, + shstrtab, unstripped_shstrndx, + sections, stripped_shnum, + strtab); + + /* Get the updated section count. */ + ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0, + _("cannot get section count: %s")); + + bool placed[unstripped_shnum - 1]; + memset (placed, 0, sizeof placed); + + /* Now update the output sections and copy in their data. */ + GElf_Off offset = 0; + for (const struct section *sec = sections; + sec < §ions[stripped_shnum - 1]; + ++sec) + if (sec->outscn != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (sec->outscn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + /* In an ET_REL file under --relocate, the sh_addr of SHF_ALLOC + sections will have been set nonzero by relocation. This + touched the shdrs of whichever file had the symtab. sh_addr + is still zero in the corresponding shdr. The relocated + address is what we want to use. */ + if (stripped_ehdr->e_type != ET_REL + || !(shdr_mem.sh_flags & SHF_ALLOC) + || shdr_mem.sh_addr == 0) + shdr_mem.sh_addr = sec->shdr.sh_addr; + + shdr_mem.sh_type = sec->shdr.sh_type; + shdr_mem.sh_size = sec->shdr.sh_size; + shdr_mem.sh_info = sec->shdr.sh_info; + shdr_mem.sh_link = sec->shdr.sh_link; + + /* Buggy binutils objdump might have stripped the SHF_INFO_LINK + put it back if necessary. */ + if ((sec->shdr.sh_type == SHT_REL || sec->shdr.sh_type == SHT_RELA) + && sec->shdr.sh_flags != shdr_mem.sh_flags + && (sec->shdr.sh_flags & SHF_INFO_LINK) != 0) + shdr_mem.sh_flags |= SHF_INFO_LINK; + + if (sec->shdr.sh_link != SHN_UNDEF) + { + if (sec->shdr.sh_link > ndx_sec_num) + error (EXIT_FAILURE, 0, + "section [%zd] has invalid sh_link %" PRId32, + elf_ndxscn (sec->scn), sec->shdr.sh_link); + shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1]; + } + if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0) + { + if (sec->shdr.sh_info > ndx_sec_num) + error (EXIT_FAILURE, 0, + "section [%zd] has invalid sh_info %" PRId32, + elf_ndxscn (sec->scn), sec->shdr.sh_info); + shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1]; + } + + if (strtab != NULL) + shdr_mem.sh_name = dwelf_strent_off (sec->strent); + + Elf_Data *indata = elf_getdata (sec->scn, NULL); + ELF_CHECK (indata != NULL, _("cannot get section data: %s")); + Elf_Data *outdata = elf_getdata (sec->outscn, NULL); + ELF_CHECK (outdata != NULL, _("cannot copy section data: %s")); + *outdata = *indata; + elf_flagdata (outdata, ELF_C_SET, ELF_F_DIRTY); + + /* Preserve the file layout of the allocated sections. */ + if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC)) + { + if (max_off > 0 && sec->shdr.sh_offset > (Elf64_Off) max_off) + error (EXIT_FAILURE, 0, + "allocated section offset too large [%zd] %" PRIx64, + elf_ndxscn (sec->scn), sec->shdr.sh_offset); + + shdr_mem.sh_offset = sec->shdr.sh_offset; + placed[elf_ndxscn (sec->outscn) - 1] = true; + + const GElf_Off end_offset = (shdr_mem.sh_offset + + (shdr_mem.sh_type == SHT_NOBITS + ? 0 : shdr_mem.sh_size)); + if (end_offset > offset) + offset = end_offset; + } + + update_shdr (sec->outscn, &shdr_mem); + + if (shdr_mem.sh_type == SHT_SYMTAB || shdr_mem.sh_type == SHT_DYNSYM) + { + /* We must adjust all the section indices in the symbol table. */ + + Elf_Data *shndxdata = NULL; /* XXX */ + + if (shdr_mem.sh_entsize == 0) + error (EXIT_FAILURE, 0, + "SYMTAB section cannot have zero sh_entsize"); + for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i) + { + GElf_Sym sym_mem; + GElf_Word shndx = SHN_UNDEF; + GElf_Sym *sym = gelf_getsymshndx (outdata, shndxdata, + i, &sym_mem, &shndx); + ELF_CHECK (sym != NULL, + _("cannot get symbol table entry: %s")); + if (sym->st_shndx != SHN_XINDEX) + shndx = sym->st_shndx; + + if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE) + { + if (shndx >= stripped_shnum) + error (EXIT_FAILURE, 0, + _("symbol [%zu] has invalid section index"), i); + + shndx = ndx_section[shndx - 1]; + if (shndx < SHN_LORESERVE) + { + sym->st_shndx = shndx; + shndx = SHN_UNDEF; + } + else + sym->st_shndx = SHN_XINDEX; + + ELF_CHECK (gelf_update_symshndx (outdata, shndxdata, + i, sym, shndx), + _("cannot update symbol table: %s")); + } + } + + if (shdr_mem.sh_type == SHT_SYMTAB) + stripped_symtab = sec; + if (shdr_mem.sh_type == SHT_DYNSYM) + stripped_dynsym = sec; + } + + if (shdr_mem.sh_type == SHT_GROUP) + { + /* We must adjust all the section indices in the group. + Skip the first word, which is the section group flag. + Everything else is a section index. */ + Elf32_Word *shndx = (Elf32_Word *) outdata->d_buf; + for (size_t i = 1; i < shdr_mem.sh_size / sizeof (Elf32_Word); ++i) + if (shndx[i] == SHN_UNDEF || shndx[i] >= stripped_shnum) + error (EXIT_FAILURE, 0, + _("group has invalid section index [%zd]"), i); + else + shndx[i] = ndx_section[shndx[i] - 1]; + } + } + + /* We may need to update the symbol table. */ + Elf_Data *symdata = NULL; + Dwelf_Strtab *symstrtab = NULL; + Elf_Data *symstrdata = NULL; + if (unstripped_symtab != NULL && (stripped_symtab != NULL + || check_prelink /* Section adjustments. */ + || (stripped_ehdr->e_type != ET_REL + && bias != 0))) + { + /* Merge the stripped file's symbol table into the unstripped one. */ + const size_t stripped_nsym = (stripped_symtab == NULL ? 1 + : (stripped_symtab->shdr.sh_size + / (stripped_symtab->shdr.sh_entsize == 0 + ? 1 + : stripped_symtab->shdr.sh_entsize))); + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + if (shdr->sh_entsize == 0) + error (EXIT_FAILURE, 0, + "unstripped SYMTAB section cannot have zero sh_entsize"); + const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize; + + /* First collect all the symbols from both tables. */ + + const size_t total_syms = stripped_nsym - 1 + unstripped_nsym - 1; + struct symbol *symbols = xmalloc (total_syms * sizeof (struct symbol)); + size_t *symndx_map = xmalloc (total_syms * sizeof (size_t)); + + if (stripped_symtab != NULL) + collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL, + stripped_symtab->scn, + elf_getscn (stripped, stripped_symtab->shdr.sh_link), + stripped_nsym, 0, ndx_section, + symbols, symndx_map, NULL); + + Elf_Scn *unstripped_strtab = elf_getscn (unstripped, shdr->sh_link); + collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL, + unstripped_symtab, unstripped_strtab, unstripped_nsym, + stripped_ehdr->e_type == ET_REL ? 0 : bias, NULL, + &symbols[stripped_nsym - 1], + &symndx_map[stripped_nsym - 1], split_bss); + + /* Next, sort our array of all symbols. */ + qsort (symbols, total_syms, sizeof symbols[0], compare_symbols); + + /* Now we can weed out the duplicates. Assign remaining symbols + new slots, collecting a map from old indices to new. */ + size_t nsym = 0; + for (struct symbol *s = symbols; s < &symbols[total_syms]; ++s) + { + /* Skip a section symbol for a removed section. */ + if (s->shndx == SHN_UNDEF + && GELF_ST_TYPE (s->info.info) == STT_SECTION) + { + s->name = NULL; /* Mark as discarded. */ + *s->map = STN_UNDEF; + s->duplicate = NULL; + continue; + } + + struct symbol *n = s; + while (n + 1 < &symbols[total_syms] && !compare_symbols (s, n + 1)) + ++n; + + while (s < n) + { + /* This is a duplicate. Its twin will get the next slot. */ + s->name = NULL; /* Mark as discarded. */ + s->duplicate = n->map; + ++s; + } + + /* Allocate the next slot. */ + *s->map = ++nsym; + } + + /* Now we sort again, to determine the order in the output. */ + qsort (symbols, total_syms, sizeof symbols[0], compare_symbols_output); + + if (nsym < total_syms) + /* The discarded symbols are now at the end of the table. */ + assert (symbols[nsym].name == NULL); + + /* Now a final pass updates the map with the final order, + and builds up the new string table. */ + symstrtab = dwelf_strtab_init (true); + for (size_t i = 0; i < nsym; ++i) + { + assert (symbols[i].name != NULL); + assert (*symbols[i].map != 0); + *symbols[i].map = 1 + i; + symbols[i].strent = dwelf_strtab_add (symstrtab, symbols[i].name); + } + + /* Scan the discarded symbols too, just to update their slots + in SYMNDX_MAP to refer to their live duplicates. */ + for (size_t i = nsym; i < total_syms; ++i) + { + assert (symbols[i].name == NULL); + if (symbols[i].duplicate == NULL) + assert (*symbols[i].map == STN_UNDEF); + else + { + assert (*symbols[i].duplicate != STN_UNDEF); + *symbols[i].map = *symbols[i].duplicate; + } + } + + /* Now we are ready to write the new symbol table. */ + symdata = elf_getdata (unstripped_symtab, NULL); + symstrdata = elf_getdata (unstripped_strtab, NULL); + Elf_Data *shndxdata = NULL; /* XXX */ + + /* If symtab and the section header table share the string table + add the section names to the strtab and then (after finalizing) + fixup the section header sh_names. Also dispose of the old data. */ + Dwelf_Strent *unstripped_strent[unstripped_shnum - 1]; + if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab)) + { + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + { + Elf_Scn *sec = elf_getscn (unstripped, i + 1); + GElf_Shdr mem; + GElf_Shdr *hdr = gelf_getshdr (sec, &mem); + const char *name = get_section_name (i + 1, hdr, shstrtab); + unstripped_strent[i] = dwelf_strtab_add (symstrtab, name); + ELF_CHECK (unstripped_strent[i] != NULL, + _("cannot add section name to string table: %s")); + } + + if (strtab != NULL) + { + dwelf_strtab_free (strtab); + free (strtab_data->d_buf); + strtab = NULL; + } + } + + if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL) + error (EXIT_FAILURE, 0, "Not enough memory to create symbol table"); + + elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY); + + /* And update the section header names if necessary. */ + if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab)) + { + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + { + Elf_Scn *sec = elf_getscn (unstripped, i + 1); + GElf_Shdr mem; + GElf_Shdr *hdr = gelf_getshdr (sec, &mem); + shdr->sh_name = dwelf_strent_off (unstripped_strent[i]); + update_shdr (sec, hdr); + } + } + + /* Now update the symtab shdr. Reload symtab shdr because sh_name + might have changed above. */ + shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize; + symdata->d_buf = xmalloc (symdata->d_size); + record_new_data (symdata->d_buf); + + GElf_Sym sym; + memset (&sym, 0, sizeof sym); + ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 0, &sym, SHN_UNDEF), + _("cannot update symbol table: %s")); + + shdr->sh_info = 1; + for (size_t i = 0; i < nsym; ++i) + { + struct symbol *s = &symbols[i]; + + /* Fill in the symbol details. */ + sym.st_name = dwelf_strent_off (s->strent); + sym.st_value = s->value; /* Already biased to output address. */ + sym.st_size = s->size; + sym.st_shndx = s->shndx; /* Already mapped to output index. */ + sym.st_info = s->info.info; + sym.st_other = s->info.other; + + /* Keep track of the number of leading local symbols. */ + if (GELF_ST_BIND (sym.st_info) == STB_LOCAL) + { + assert (shdr->sh_info == 1 + i); + shdr->sh_info = 1 + i + 1; + } + + ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 1 + i, + &sym, SHN_UNDEF), + _("cannot update symbol table: %s")); + + } + elf_flagdata (symdata, ELF_C_SET, ELF_F_DIRTY); + update_shdr (unstripped_symtab, shdr); + + if (stripped_symtab != NULL) + { + /* Adjust any relocations referring to the old symbol table. */ + const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn); + for (const struct section *sec = sections; + sec < §ions[stripped_shnum - 1]; + ++sec) + if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link) + adjust_relocs (sec->outscn, sec->scn, &sec->shdr, + symndx_map, total_syms, shdr); + } + + /* Also adjust references to the other old symbol table. */ + adjust_all_relocs (unstripped, unstripped_symtab, shdr, + &symndx_map[stripped_nsym - 1], + total_syms - (stripped_nsym - 1)); + + free (symbols); + free (symndx_map); + } + else if (stripped_symtab != NULL && stripped_shnum != unstripped_shnum) + check_symtab_section_symbols (unstripped, + stripped_ehdr->e_type == ET_REL, + stripped_symtab->scn, + unstripped_shnum, unstripped_shstrndx, + stripped_symtab->outscn, + stripped_shnum, stripped_shstrndx, + debuglink); + + if (stripped_dynsym != NULL) + (void) check_symtab_section_symbols (unstripped, + stripped_ehdr->e_type == ET_REL, + stripped_dynsym->outscn, + unstripped_shnum, + unstripped_shstrndx, + stripped_dynsym->scn, stripped_shnum, + stripped_shstrndx, debuglink); + + /* We need to preserve the layout of the stripped file so the + phdrs will match up. This requires us to do our own layout of + the added sections. We do manual layout even for ET_REL just + so we can try to match what the original probably had. */ + + elf_flagelf (unstripped, ELF_C_SET, ELF_F_LAYOUT); + + if (offset == 0) + /* For ET_REL we are starting the layout from scratch. */ + offset = gelf_fsize (unstripped, ELF_T_EHDR, 1, EV_CURRENT); + + bool skip_reloc = false; + do + { + skip_reloc = !skip_reloc; + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + if (!placed[i]) + { + scn = elf_getscn (unstripped, 1 + i); + + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + + /* We must make sure we have read in the data of all sections + beforehand and marked them to be written out. When we're + modifying the existing file in place, we might overwrite + this part of the file before we get to handling the section. */ + + ELF_CHECK (elf_flagdata (elf_getdata (scn, NULL), + ELF_C_SET, ELF_F_DIRTY), + _("cannot read section data: %s")); + + if (skip_reloc + && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)) + continue; + + GElf_Off align = shdr->sh_addralign ?: 1; + offset = (offset + align - 1) & -align; + shdr->sh_offset = offset; + if (shdr->sh_type != SHT_NOBITS) + offset += shdr->sh_size; + + update_shdr (scn, shdr); + + if (unstripped_shstrndx == 1 + i) + { + /* Place the section headers immediately after + .shstrtab, and update the ELF header. */ + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (unstripped, &ehdr_mem); + ELF_CHECK (ehdr != NULL, _("cannot get ELF header: %s")); + + GElf_Off sh_align = gelf_getclass (unstripped) * 4; + offset = (offset + sh_align - 1) & -sh_align; + ehdr->e_shnum = unstripped_shnum; + ehdr->e_shoff = offset; + offset += unstripped_shnum * ehdr->e_shentsize; + ELF_CHECK (gelf_update_ehdr (unstripped, ehdr), + _("cannot update ELF header: %s")); + } + + placed[i] = true; + } + } + while (skip_reloc); + + size_t phnum; + ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0, + _("cannot get number of program headers: %s")); + + if (phnum > 0) + ELF_CHECK (gelf_newphdr (unstripped, phnum), + _("cannot create program headers: %s")); + + /* Copy each program header from the stripped file. */ + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem); + ELF_CHECK (phdr != NULL, _("cannot get program header: %s")); + + ELF_CHECK (gelf_update_phdr (unstripped, i, phdr), + _("cannot update program header: %s")); + } + + /* Finally, write out the file. */ + ELF_CHECK (elf_update (unstripped, ELF_C_WRITE) > 0, + _("cannot write output file: %s")); + + if (strtab != NULL) + { + dwelf_strtab_free (strtab); + free (strtab_data->d_buf); + } + + if (symstrtab != NULL) + { + dwelf_strtab_free (symstrtab); + free (symstrdata->d_buf); + } + free_new_data (); +} + +/* Process one pair of files, already opened. */ +static void +handle_file (const char *output_file, bool create_dirs, + Elf *stripped, const GElf_Ehdr *stripped_ehdr, + Elf *unstripped) +{ + size_t phnum; + ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0, + _("cannot get number of program headers: %s")); + + /* Determine the address bias between the debuginfo file and the main + file, which may have been modified by prelinking. */ + GElf_Addr bias = 0; + if (unstripped != NULL) + for (size_t i = 0; i < phnum; ++i) + { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem); + ELF_CHECK (phdr != NULL, _("cannot get program header: %s")); + if (phdr->p_type == PT_LOAD) + { + GElf_Phdr unstripped_phdr_mem; + GElf_Phdr *unstripped_phdr = gelf_getphdr (unstripped, i, + &unstripped_phdr_mem); + ELF_CHECK (unstripped_phdr != NULL, + _("cannot get program header: %s")); + bias = phdr->p_vaddr - unstripped_phdr->p_vaddr; + break; + } + } + + /* One day we could adjust all the DWARF data (like prelink itself does). */ + if (bias != 0) + { + if (output_file == NULL) + error (0, 0, _("\ +DWARF data not adjusted for prelinking bias; consider prelink -u")); + else + error (0, 0, _("\ +DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"), + output_file); + } + + if (output_file == NULL) + /* Modify the unstripped file in place. */ + copy_elided_sections (unstripped, stripped, stripped_ehdr, bias); + else + { + if (create_dirs) + make_directories (output_file); + + /* Copy the unstripped file and then modify it. */ + int outfd = open (output_file, O_RDWR | O_CREAT, + (stripped_ehdr->e_type == ET_REL + ? DEFFILEMODE : ACCESSPERMS)); + if (outfd < 0) + error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file); + Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL); + ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s")); + + if (unstripped == NULL) + { + /* Actually, we are just copying out the main file as it is. */ + copy_elf (outelf, stripped); + if (stripped_ehdr->e_type != ET_REL) + elf_flagelf (outelf, ELF_C_SET, ELF_F_LAYOUT); + ELF_CHECK (elf_update (outelf, ELF_C_WRITE) > 0, + _("cannot write output file: %s")); + } + else + { + copy_elf (outelf, unstripped); + copy_elided_sections (outelf, stripped, stripped_ehdr, bias); + } + + elf_end (outelf); + close (outfd); + } +} + +static int +open_file (const char *file, bool writable) +{ + int fd = open (file, writable ? O_RDWR : O_RDONLY); + if (fd < 0) + error (EXIT_FAILURE, errno, _("cannot open '%s'"), file); + return fd; +} + +/* Warn, and exit if not forced to continue, if some ELF header + sanity check for the stripped and unstripped files failed. */ +static void +warn (const char *msg, bool force, + const char *stripped_file, const char *unstripped_file) +{ + error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.", + force ? _("WARNING: ") : "", + stripped_file, unstripped_file, msg, + force ? "" : _(", use --force")); +} + +/* Handle a pair of files we need to open by name. */ +static void +handle_explicit_files (const char *output_file, bool create_dirs, bool force, + const char *stripped_file, const char *unstripped_file) +{ + int stripped_fd = open_file (stripped_file, false); + Elf *stripped = elf_begin (stripped_fd, ELF_C_READ, NULL); + GElf_Ehdr stripped_ehdr; + ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr), + _("cannot create ELF descriptor: %s")); + + int unstripped_fd = -1; + Elf *unstripped = NULL; + if (unstripped_file != NULL) + { + unstripped_fd = open_file (unstripped_file, output_file == NULL); + unstripped = elf_begin (unstripped_fd, + (output_file == NULL ? ELF_C_RDWR : ELF_C_READ), + NULL); + GElf_Ehdr unstripped_ehdr; + ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr), + _("cannot create ELF descriptor: %s")); + + if (memcmp (stripped_ehdr.e_ident, + unstripped_ehdr.e_ident, EI_NIDENT) != 0) + warn (_("ELF header identification (e_ident) different"), force, + stripped_file, unstripped_file); + + if (stripped_ehdr.e_type != unstripped_ehdr.e_type) + warn (_("ELF header type (e_type) different"), force, + stripped_file, unstripped_file); + + if (stripped_ehdr.e_machine != unstripped_ehdr.e_machine) + warn (_("ELF header machine type (e_machine) different"), force, + stripped_file, unstripped_file); + + if (stripped_ehdr.e_phnum < unstripped_ehdr.e_phnum) + warn (_("stripped program header (e_phnum) smaller than unstripped"), + force, stripped_file, unstripped_file); + } + + handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped); + + elf_end (stripped); + close (stripped_fd); + + elf_end (unstripped); + close (unstripped_fd); +} + + +/* Handle a pair of files opened implicitly by libdwfl for one module. */ +static void +handle_dwfl_module (const char *output_file, bool create_dirs, bool force, + Dwfl_Module *mod, bool all, bool ignore, bool relocate) +{ + GElf_Addr bias; + Elf *stripped = dwfl_module_getelf (mod, &bias); + if (stripped == NULL) + { + if (ignore) + return; + + const char *file; + const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, + NULL, NULL, &file, NULL); + if (file == NULL) + error (EXIT_FAILURE, 0, + _("cannot find stripped file for module '%s': %s"), + modname, dwfl_errmsg (-1)); + else + error (EXIT_FAILURE, 0, + _("cannot open stripped file '%s' for module '%s': %s"), + modname, file, dwfl_errmsg (-1)); + } + + Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias)); + if (debug == NULL && !all) + { + if (ignore) + return; + + const char *file; + const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, + NULL, NULL, NULL, &file); + if (file == NULL) + error (EXIT_FAILURE, 0, + _("cannot find debug file for module '%s': %s"), + modname, dwfl_errmsg (-1)); + else + error (EXIT_FAILURE, 0, + _("cannot open debug file '%s' for module '%s': %s"), + modname, file, dwfl_errmsg (-1)); + } + + if (debug == stripped) + { + if (all) + debug = NULL; + else + { + const char *file; + const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, + NULL, NULL, &file, NULL); + error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"), + modname, file); + } + } + + GElf_Ehdr stripped_ehdr; + ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr), + _("cannot create ELF descriptor: %s")); + + if (stripped_ehdr.e_type == ET_REL) + { + if (!relocate) + { + /* We can't use the Elf handles already open, + because the DWARF sections have been relocated. */ + + const char *stripped_file = NULL; + const char *unstripped_file = NULL; + (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, + &stripped_file, &unstripped_file); + + handle_explicit_files (output_file, create_dirs, force, + stripped_file, unstripped_file); + return; + } + + /* Relocation is what we want! This ensures that all sections that can + get sh_addr values assigned have them, even ones not used in DWARF. + They might still be used in the symbol table. */ + if (dwfl_module_relocations (mod) < 0) + error (EXIT_FAILURE, 0, + _("cannot cache section addresses for module '%s': %s"), + dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL), + dwfl_errmsg (-1)); + } + + handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug); +} + +/* Handle one module being written to the output directory. */ +static void +handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool force, + bool all, bool ignore, bool modnames, bool relocate) +{ + if (! modnames) + { + /* Make sure we've searched for the ELF file. */ + GElf_Addr bias; + (void) dwfl_module_getelf (mod, &bias); + } + + const char *file; + const char *name = dwfl_module_info (mod, NULL, NULL, NULL, + NULL, NULL, &file, NULL); + + if (file == NULL && ignore) + return; + + char *output_file; + if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file) < 0) + error (EXIT_FAILURE, 0, _("memory exhausted")); + + handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate); + + free (output_file); +} + + +static void +list_module (Dwfl_Module *mod) +{ + /* Make sure we have searched for the files. */ + GElf_Addr bias; + bool have_elf = dwfl_module_getelf (mod, &bias) != NULL; + bool have_dwarf = dwfl_module_getdwarf (mod, &bias) != NULL; + + const char *file; + const char *debug; + Dwarf_Addr start; + Dwarf_Addr end; + const char *name = dwfl_module_info (mod, NULL, &start, &end, + NULL, NULL, &file, &debug); + if (file != NULL && debug != NULL && (debug == file || !strcmp (debug, file))) + debug = "."; + + const unsigned char *id; + GElf_Addr id_vaddr; + int id_len = dwfl_module_build_id (mod, &id, &id_vaddr); + + printf ("%#" PRIx64 "+%#" PRIx64 " ", start, end - start); + + if (id_len > 0) + { + do + printf ("%02" PRIx8, *id++); + while (--id_len > 0); + if (id_vaddr != 0) + printf ("@%#" PRIx64, id_vaddr); + } + else + putchar ('-'); + + printf (" %s %s %s\n", + file ?: have_elf ? "." : "-", + debug ?: have_dwarf ? "." : "-", + name); +} + + +struct match_module_info +{ + char **patterns; + Dwfl_Module *found; + bool match_files; +}; + +static int +match_module (Dwfl_Module *mod, + void **userdata __attribute__ ((unused)), + const char *name, + Dwarf_Addr start __attribute__ ((unused)), + void *arg) +{ + struct match_module_info *info = arg; + + if (info->patterns[0] == NULL) /* Match all. */ + { + match: + info->found = mod; + return DWARF_CB_ABORT; + } + + if (info->match_files) + { + /* Make sure we've searched for the ELF file. */ + GElf_Addr bias; + (void) dwfl_module_getelf (mod, &bias); + + const char *file; + const char *check = dwfl_module_info (mod, NULL, NULL, NULL, + NULL, NULL, &file, NULL); + if (check == NULL || strcmp (check, name) != 0 || file == NULL) + return DWARF_CB_OK; + + name = file; + } + + for (char **p = info->patterns; *p != NULL; ++p) + if (fnmatch (*p, name, 0) == 0) + goto match; + + return DWARF_CB_OK; +} + +/* Handle files opened implicitly via libdwfl. */ +static void +handle_implicit_modules (const struct arg_info *info) +{ + struct match_module_info mmi = { info->args, NULL, info->match_files }; + ptrdiff_t offset = dwfl_getmodules (info->dwfl, &match_module, &mmi, 0); + if (offset == 0) + error (EXIT_FAILURE, 0, _("no matching modules found")); + + if (info->list) + do + list_module (mmi.found); + while ((offset = dwfl_getmodules (info->dwfl, &match_module, &mmi, + offset)) > 0); + else if (info->output_dir == NULL) + { + if (dwfl_getmodules (info->dwfl, &match_module, &mmi, offset) != 0) + error (EXIT_FAILURE, 0, _("matched more than one module")); + handle_dwfl_module (info->output_file, false, info->force, mmi.found, + info->all, info->ignore, info->relocate); + } + else + do + handle_output_dir_module (info->output_dir, mmi.found, info->force, + info->all, info->ignore, + info->modnames, info->relocate); + while ((offset = dwfl_getmodules (info->dwfl, &match_module, &mmi, + offset)) > 0); +} + +int +main (int argc, char **argv) +{ + /* We use no threads here which can interfere with handling a stream. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + setlocale (LC_ALL, ""); + + /* Make sure the message catalog can be found. */ + bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); + + /* Initialize the message catalog. */ + textdomain (PACKAGE_TARNAME); + + /* Parse and process arguments. */ + const struct argp_child argp_children[] = + { + { + .argp = dwfl_standard_argp (), + .header = N_("Input selection options:"), + .group = 1, + }, + { .argp = NULL }, + }; + const struct argp argp = + { + .options = options, + .parser = parse_opt, + .children = argp_children, + .args_doc = N_("STRIPPED-FILE DEBUG-FILE\n[MODULE...]"), + .doc = N_("\ +Combine stripped files with separate symbols and debug information.\n\ +\n\ +The first form puts the result in DEBUG-FILE if -o was not given.\n\ +\n\ +MODULE arguments give file name patterns matching modules to process.\n\ +With -f these match the file name of the main (stripped) file \ +(slashes are never special), otherwise they match the simple module names. \ +With no arguments, process all modules found.\n\ +\n\ +Multiple modules are written to files under OUTPUT-DIRECTORY, \ +creating subdirectories as needed. \ +With -m these files have simple module names, otherwise they have the \ +name of the main file complete with directory underneath OUTPUT-DIRECTORY.\n\ +\n\ +With -n no files are written, but one line to standard output for each module:\ +\n\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n\ +START and SIZE are hexadecimal giving the address bounds of the module. \ +BUILDID is hexadecimal for the build ID bits, or - if no ID is known; \ +the hexadecimal may be followed by @0xADDR giving the address where the \ +ID resides if that is known. \ +FILE is the file name found for the module, or - if none was found, \ +or . if an ELF image is available but not from any named file. \ +DEBUGFILE is the separate debuginfo file name, \ +or - if no debuginfo was found, or . if FILE contains the debug information.\ +") + }; + + int remaining; + struct arg_info info = { .args = NULL }; + error_t result = argp_parse (&argp, argc, argv, 0, &remaining, &info); + if (result == ENOSYS) + assert (info.dwfl == NULL); + else if (result) + return EXIT_FAILURE; + assert (info.args != NULL); + + /* Tell the library which version we are expecting. */ + elf_version (EV_CURRENT); + + if (info.dwfl == NULL) + { + assert (result == ENOSYS); + + if (info.output_dir != NULL) + { + char *file; + if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0) + error (EXIT_FAILURE, 0, _("memory exhausted")); + handle_explicit_files (file, true, info.force, + info.args[0], info.args[1]); + free (file); + } + else + handle_explicit_files (info.output_file, false, info.force, + info.args[0], info.args[1]); + } + else + { + /* parse_opt checked this. */ + assert (info.output_file != NULL || info.output_dir != NULL || info.list); + + handle_implicit_modules (&info); + + dwfl_end (info.dwfl); + } + + return 0; +} + + +#include "debugpred.h" diff --git a/tests/ChangeLog b/tests/ChangeLog new file mode 100644 index 00000000..38e92659 --- /dev/null +++ b/tests/ChangeLog @@ -0,0 +1,4263 @@ +2021-05-14 Frank Ch. Eigler + + PR27859 + * run-debuginfod-find.sh: Test absence of 404-latch bug in client + curl handle reuse. + +2021-04-19 Martin Liska + + * dwelf_elf_e_machine_string.c (main): Use startswith. + * dwelfgnucompressed.c (main): Likewise. + * elfgetchdr.c (main): Likewise. + * elfputzdata.c (main): Likewise. + * vdsosyms.c (module_callback): Likewise. + +2021-05-04 Alice Zhang + + * run-debuginfod-find.sh: Added tests for negative cache files. + +2021-04-26 Frank Ch. Eigler + + PR27571 + * run-debuginfod-find.sh: Add test case for unwriteable cache files. + +2021-04-23 Omar Sandoval + + * run-low_high_pc-dw-form-indirect.sh: New file. + * run-readelf-dw-form-indirect.sh: New file. + * testfile-dw-form-indirect.bz2: New file. + * Makefile.am (TESTS): Add run-low_high_pc-dw-form-indirect.sh and + run-readelf-dw-form-indirect.sh. + (EXTRA_DIST): Add run-low_high_pc-dw-form-indirect.sh, + run-readelf-dw-form-indirect.sh, and testfile-dw-form-indirect.bz2. + +2021-04-26 Frank Ch. Eigler + + PR26125 + * run-debuginfod-find.sh: Add test case for cache cleanup rmdir. + +2021-04-23 Frank Ch. Eigler + + * run-debuginfod-find.sh: Add a tiny test for client object reuse. + Add an "errfiles" test construct to ask the framework to print + various files in the case of an error. + +2021-03-30 Frank Ch. Eigler + + * run-debuginfod-find.sh: Add thread comm checks. + +2021-02-17 Timm Bäder + + * elfstrmerge.c (main): Move new_data_buf function to... + (new_data_buf): ...top-level static function adding fname, + ndx, shdrstrnd and shdrnum as arguments. + +2021-02-17 Timm Bäder + + * elfstrmerge.c (main): Move newsecndx function to... + (newsecndx): ...top-level static function adding shdrstrndx, + shdrnum and fname as arguments. + +2021-02-25 Frank Ch. Eigler + + * run-debuginfod-find.sh: Add bad webapi artifacttype test. + +2021-02-17 Frank Ch. Eigler + + * run-debuginfod-find.sh: Tweak wait_ready() to also print -vvv log of + appropriate debuginfod if metric timeout occurs. Focus grooming + test carefully at a more deterministic metric. + +2021-02-12 Mark Wielaard + + * run-readelf-types.sh: Add CU start to type offset reference. + +2021-02-07 Alexander Miller + + * Makefile.am (TESTS_ENVIRONMENT): Quote variables. + (valgrind_cmd): Unquote variable. + +2021-02-08 Érico Nogueira + + * run-debuginfod-find.sh: Check for cpio availability. + +2021-02-04 Frank Ch. Eigler + + * run-debuginfod-find.sh: Smoke test --fdcache-mintmp option handling. + +2021-01-31 Sergei Trofimovich + + * Makefile.am (TESTS_ENVIRONMENT): export CC variable + to tests for use instead of 'gcc'. + * run-disasm-x86-64.sh: use ${CC} instead of 'gcc'. + * run-disasm-x86.sh: Likewise. + * run-strip-g.sh: Likewise. + * run-strip-nothing.sh: Likewise. + * run-test-includes.sh: Likewise. + +2021-01-06 Timm Bäder + + * zstrptr.c (main): Lift print_strings function up to ... + (print_strings): ... here. New file scope function taking + Elf_Scn*, Elf* and ndx as arguments. + +2020-12-20 Dmitry V. Levin + + * .gitignore: New file. + +2020-12-12 Mark Wielaard + + * testfile-retain.o.bz2: New test file. + * run-retain.sh: New test. + * Makefile.am (TESTS): Add run-retain.sh. + (EXTRA_DIST): Add run-retain.sh and testfile-retain.o.bz2 + +2020-12-16 Dmitry V. Levin + + * dwflmodtest.c (N_): Remove. + +2020-12-12 Dmitry V. Levin + + * dwarf-die-addr-die.c (main): Fix spelling typo in error diagnostics. + * run-lfs-symbols.sh: Likewise. + * elfstrmerge.c (main): Fix spelling typos in comments. + * dwfl-bug-fd-leak.c: Likewise. + * run-readelf-line.sh: Likewise. + * run-stack-demangled-test.sh: Likewise. + * sectiondump.c (main): Likewise. + * varlocs.c (handle_die): Likewise. + +2020-12-11 Dmitry V. Levin + + * configure.ac: Remove. + * Makefile.am [STANDALONE]: Remove. + (check_PROGRAMS): Add msg_tst, system-elf-libelf-test, and $(asm_TESTS) + unconditionally. + (TESTS): Add msg_tst, system-elf-libelf-test, $(asm_TESTS), and + run-disasm-bpf.sh unconditionally. + +2020-11-23 Frank Ch. Eigler + + * run-debuginfod-find.sh: Add sqlite error injection & stats. + +2020-11-02 Mark Wielaard + + * run-debuginfod-find.sh: Create bogus R/nothing.rpm with cyclic + symlink instead of chmod 000. + +2020-11-19 Frank Ch. Eigler + + * run-debuginfod-find.sh: Look for http-* metrics. + +2020-11-01 Érico N. Rolim + Mark Wielaard + + * alldts.c (main): Use DEFFILEMODE for open with O_CREAT. + * arextract.c (main): Likewise. + * ecp.c (main): Likewise for creat. + * elfstrtab.c (check_elf): Use DEFFILEMODE for open with O_CREAT, + remove mode from open calls without O_CREAT. + * emptyfile.c (check_elf): Likewise. + * fillfile.c (check_elf): Likewise. + * vendorelf.c (check_elf): Likewise. + * newdata.c (checkelf): Use DEFFILEMODE for open with O_CREAT. + * update{1,2,3,4}.c (main): Likewise. + * + +2020-10-31 Mark Wielaard + + * dwfl-proc-attach.c (dlopen): New external function override. + +2020-10-31 Mark Wielaard + + * test-wrapper.sh: Use =, not == for string compare. + +2020-10-29 Mark Wielaard + + * test-wrapper.sh: Determine whether the test is a script or not + and run binaries directly under valgrind. + * dwfl-bug-fd-leak.c (main): Call getrlimit before calling setrlimit. + * dwfl-proc-attach.c (main): Call dwfl_end, pthread_cancel and + pthread_join. + * vdsosyms.c (main): Call dwfl_end. + +2020-10-31 Frank Ch. Eigler + + * run-debuginfod-find.sh: Modify for tweaked/new metrics. + +2020-10-30 Frank Ch. Eigler + + PR26775 + * run-debuginfod-find.sh: Modify test for restored + thread_work_total semantics for grooming. + +2020-10-29 Frank Ch. Eigler + + PR26775 + * run-debuginfod-find.sh: Modify test for different + thread_work_total semantics for grooming. + +2020-10-29 Frank Ch. Eigler + + PR26810 + * run-debuginfod-find.sh: Add tests for successful archive fetches across + renamed RPMs, even without grooming. + +2020-10-25 Mark Wielaard + + * read_unaligned.c: New test. + * Makefile.am (check_PROGRAMS, TESTS): Add read_unaligned. + (read_unaligned_LDADD): New variable. + +2020-10-28 Tom Tromey + + PR26773 + * Makefile.am (check_PROGRAMS, TESTS): Add leb128. + (leb128_LDADD): New variable. + * leb128.c: New file. + +2020-10-19 Mark Wielaard + + * addrcfi.c (print_register): Make ops_mem 3 elements. + +2020-10-19 Mark Wielaard + + * testfile60.bz2: Removed. + * Makefile.am (EXTRA_DIST): Remove testfile60.bz2. + * run-allregs.sh: Remove tilegx testfile60 testcase. + +2020-10-20 Frank Ch. Eigler + + PR26756: more prometheus metrics + * run-debuginfod-find.sh: Trigger some errors with dummy "nothing.rpm" + and check for new metrics. + +2020-09-18 Mark Wielaard + + * run-readelf-compressed-zstd.sh: New test. + * Makefile.am (EXTRA_DISTS): Add run-readelf-compressed-zstd.sh. + (TESTS): Add run-readelf-compressed-zstd.sh if HAVE_ZSTD. + +2020-09-03 Mark Wielaard + + * run-readelf-frames.sh: New test. + * Makefile.am (TESTS): Add run-readelf-frames.sh. + (EXTRA_DIST): Likewise. + +2020-09-03 Mark Wielaard + + * testfile-gnu-property-note-aarch64.bz2: New file. + * run-readelf-n.sh: Handle testfile-gnu-property-note-aarch64. + * Makefile.am (EXTRA_DIST): Add + testfile-gnu-property-note-aarch64.bz2. + +2020-07-19 Mark Wielaard + + * asm-tst1.c: Include libebl.h after libasm.h. + * asm-tst2.c: Likewise. + * asm-tst3.c: Likewise. + * asm-tst4.c: Likewise. + * asm-tst5.c: Likewise. + * asm-tst6.c: Likewise. + * asm-tst7.c: Likewise. + * asm-tst8.c: Likewise. + * asm-tst9.c: Likewise. + +2020-07-05 Mark Wielaard + + * run-test-includes.sh: New test. + * Makefile.am (TESTS): Add run-test-includes.sh. + (EXTRA_DIST): Likewise. + +2020-07-03 Alice Zhang + + * run-debuginfod-find.sh: Add scheme free url testcase. + +2020-06-19 Mark Wielaard + + * Makefile.am (TESTS): Don't add run-debuginfod-find.sh when + DUMMY_LIBDEBUGINFOD. + +2020-06-16 Mark Wielaard + + * coverage.sh: Use /usr/bin/env bash. + * run-ar.sh: Likewise. + * run-backtrace-core-aarch64.sh: Likewise. + * run-backtrace-core-i386.sh: Likewise. + * run-backtrace-core-ppc.sh: Likewise. + * run-backtrace-core-s390.sh: Likewise. + * run-backtrace-core-s390x.sh: Likewise. + * run-backtrace-core-sparc.sh: Likewise. + * run-backtrace-core-x32.sh: Likewise. + * run-backtrace-core-x86_64.sh: Likewise. + * run-backtrace-data.sh: Likewise. + * run-backtrace-demangle.sh: Likewise. + * run-backtrace-dwarf.sh: Likewise. + * run-backtrace-fp-core-aarch64.sh: Likewise. + * run-backtrace-fp-core-i386.sh: Likewise. + * run-backtrace-fp-core-ppc64le.sh: Likewise. + * run-backtrace-fp-core-x86_64.sh: Likewise. + * run-backtrace-native-biarch.sh: Likewise. + * run-backtrace-native-core-biarch.sh: Likewise. + * run-backtrace-native-core.sh: Likewise. + * run-backtrace-native.sh: Likewise. + * run-debuginfod-find.sh: Likewise. + * run-deleted.sh: Likewise. + * run-dwelf_elf_e_machine_string.sh: Likewise. + * run-large-elf-file.sh: Likewise. + * run-lfs-symbols.sh: Likewise. + * run-linkmap-cut.sh: Likewise. + +2020-06-11 Mark Wielaard + + * Makefile.am (nlist-test): Add GCOV flags when necessary. + +2020-06-06 Mark Wielaard + + * testfilesyms32.bz2: New test file. + * testfilesyms64.bz2: Likewise. + * run-nm-syms.sh: New test. + * Makefile.am (TESTS): Add run-nm-syms.sh. + (EXTRA_DIST): run-nm-syms.sh, testfilesyms32.bz2 and + testfilesyms64.bz2 + +2020-05-08 Mark Wielaard + + * elfputzdata.c (main): Explicitly check orig_buf is not NULL + before calling memcmp. + +2020-05-05 Mark Wielaard + + * testfile-lto-gcc8.bz2: New test file. + * testfile-lto-gcc9.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add testfile-lto-gcc8.bz2 and + testfile-lto-gcc9.bz2. + * run-allfcts.sh: Add testfile-lto-gcc9 and testfile-lto-gcc8 + tests. + +2020-05-05 Mark Wielaard + + * testfile-lto-gcc10.bz2: New test file. + * Makefile.am (EXTRA_DIST): Add testfile-lto-gcc10.bz2. + * run-allfcts.sh: Add testfile-lto-gcc10 test. + +2020-04-17 Mark Wielaard + + * test-subr.sh (testrun_on_self_obj): New function. + * run-varlocs-self.sh: Run testrun_on_self_exe and + testrun_on_self_lib with -e, run testrun_on_self_obj with + --exprlocs -e. + +2020-04-17 Mark Wielaard + + * Makefile.am (test-nlist$): New goal with minimal CFLAGS. + (test_nlist_CFLAGS): New variable. + +2020-03-28 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test timestamps of archive-origin files. + +2020-03-27 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test /path/-based debuginfod-find. + +2020-03-24 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test relay of UA and XFF headers across + federating debuginfods. + +2020-03-26 Frank Ch. Eigler + + * run-debuginfod-find.sh: Look for debuginfod's new + http_responses_* metrics. + +2020-03-26 Frank Ch. Eigler + + * run-debuginfod-find.sh: Look for bsdtar instead of dpkg. + +2020-03-26 Frank Ch. Eigler + + * run-debuginfod-find.sh: Check for bsdtar zstd capability + for running tests against zstd-compressed fedora31 rpms. + +2020-03-26 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add + debuginfod-rpms/fedora31/hello3-1.0-2.src.rpm, + debuginfod-rpms/fedora31/hello3-1.0-2.x86_64.rpm, + debuginfod-rpms/fedora31/hello3-debuginfo-1.0-2.x86_64.rpm, + debuginfod-rpms/fedora31/hello3-debugsource-1.0-2.x86_64.rpm, + debuginfod-rpms/fedora31/hello3-two-1.0-2.x86_64.rpm, + debuginfod-rpms/fedora31/hello3-two-debuginfo-1.0-2.x86_64.rpm + +2020-03-24 Frank Ch. Eigler + + * debuginfod-rpms/hello3.spec., /fedora31/*: New files with + uncanonicalized source paths. + * run-debuginfod-find.sh: Test them. + +2020-03-24 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test the more detailed debuginfod + webapi log format. + +2020-03-23 Mark Wielaard + + * getphdrnum.c: Include config.h. + * run-lfs-symbols.sh: Also check that file exists. Add more logs. + Remove ebl modules check. + +2020-03-22 Omar Sandoval + Mark Wielaard + + * getphdrnum.c: New file. + * run-getphdrnum.sh: New test. + * testfile-phdrs.elf.bz2: New test file. + * Makefile.am (check_PROGRAMS): Add getphdrnum. + (TESTS): Add run-getphdrnum.sh. + (EXTRA_DIST): Add run-getphdrnum.sh and testfile-phdrs.elf.bz2. + (getphdrnum_LDADD): New variable. + +2020-03-22 Frank Ch. Eigler + + * run-debuginfod-find.sh: Look for URL in default progressfn + and from debuginfod-find -v. + +2020-02-19 Aaron Merey + + * run-debuginfod-find.sh: Run tests for verifying default + client cache locations. + +2020-02-26 Konrad Kleine + + * run-debuginfod-find.sh: added tests for DEBUGINFOD_URLS beginning + with "file://" + +2020-02-21 Mark Wielaard + + * Makefile.am (TESTS_ENVIRONMENT): Explicitly unset DEBUGINFOD_URLS. + (installed_TESTS_ENVIRONMENT): Likewise. + +2020-02-19 Aaron Merey + + * run-debuginfod-find.sh: Test that files unrelated to debuginfod + survive cache cleaning. + +2020-02-08 Mark Wielaard + + * run-pt_gnu_prop-tests.sh: New test. + * testfile_pt_gnu_prop.bz2: New test file. + * testfile_pt_gnu_prop32.bz2: Likewise. + * Makefile.am (TESTS): Add run-pt_gnu_prop-tests.sh + (EXTRA_DISTS): Likewise. Add testfile_pt_gnu_prop.bz2 and + testfile_pt_gnu_prop32.bz2. + +2020-02-05 Frank Ch. Eigler + + * debuginfo-tars/*: New test files from Eli Schwartz of ArchLinux. + * Makefile.am (EXTRA_DIST): Package them. + * run-debuginfod-find.sh: Run basic archive extraction tests. + +2020-02-03 Frank Ch. Eigler + + * run-debuginfod-find.sh: Protect against missing curl & rpm2cpio. + +2020-01-19 Frank Ch. Eigler + + * run-debuginfod-find.sh: Check for proper groom completion count. + +2020-01-18 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test empty source_paths[]. + +2020-01-08 Mark Wielaard + + * asm-test?.c: include libebl.h. + +2020-01-11 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test --fdcache* options. + +2020-01-11 Frank Ch. Eigler + + * run-debuginfod-find.sh: Adjust to new work-queue metrics. + +2020-01-02 Mark Wielaard + + * run-debuginfod-find.sh: Set DEBUGINFOD_TIMEOUT to 10. + +2019-12-22 Frank Ch. Eigler + + * debuginfod-debs/*: New test files, based on + https://wiki.debian.org/Packaging/Intro. + * run-debuginfod-find.sh: Test deb file processing (if dpkg + installed). + +2019-12-04 Frank Ch. Eigler + + * run-debuinfod-find.sh: Test $DEBUGINFOD_PROGRESS. + +2019-12-11 Omar Sandoval + + * dwfl-report-segment-coalesce.c: New test. + * Makefile.am: Add dwfl-report-segment-coalesce + +2019-12-06 Mark Wielaard + + * run-debuginfod-find.sh: Force -Wl,--build-id. + +2019-12-05 Mark Wielaard + + * run-findinfod-find.sh: Run strip under testrun. + +2019-12-06 Mark Wielaard + + * backtrace-data.c (main): Add break after assert. + +2019-12-05 Mark Wielaard + + * run-elfclassify.sh: Run elfcompress under testrun. + +2019-11-26 Mark Wielaard + + * Makefile.am (BUILD_STATIC): Add libraries needed for libdw. + * coverage.sh: Add debuginfod directory, check whether source + is .c or cxx. + +2019-11-24 Mark Wielaard + + * run-debuginfod-find.sh: Reduce verbosity. Add new cleanup + function to use with trap. Add wait_ready function to query + metrics instead of sleeping. Calculate rpms and sourcefiles + to check. + +2019-11-23 Mark Wielaard + + * run-debuginfod-find.sh: Replace all localhost with 127.0.0.1. + +2019-11-07 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test debuginfod metrics via curl. + Fix federated testing, asserted by metrics. + +2019-11-06 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test debuginfod -L mode. Drop + plain debuginfo-find help-output-comparison. + +2019-11-04 Frank Ch. Eigler + + * run-debuginfod-find.sh: Test debuginfod-find -v progress mode. + +2019-10-28 Aaron Merey + Frank Ch. Eigler + + * run-debuginfod-find.sh, debuginfod_build_id_find.c: New test. + * testfile-debuginfod-*.rpm.bz2: New data files for test. + * Makefile.am: Run it. + +2019-11-14 Andreas Schwab + + * run-large-elf-file.sh: Skip if available memory cannot be + determined. + +2019-11-14 Andreas Schwab + + * dwelf_elf_e_machine_string.c (main): Clear errno before calling + strtol. + +2019-09-02 Mark Wielaard + + * run-readelf-s.sh: Add --dyn-syms case. + +2019-09-07 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add run-disasm-riscv64.sh, + testfile-riscv64-dis1.o.bz2 and testfile-riscv64-dis1.expect.bz2. + +2019-08-27 Mark Wielaard + + * run-readelf-test2.sh: Add -x num testcase. + +2019-08-29 Mark Wielaard + + * test-subr.sh (self_test_files_exe): replace elfcmp, objdump and + readelf with elfclassify, stack and unstrip. + (self_test_files_lib): Replace libdw.so with libasm.so. + +2019-07-05 Omar Sandoval + + * Makefile.am: Remove -ldl. + * tests-subr.sh (self_test_files): Remove libebl_{i386,x86_64}.so. + +2019-07-26 Florian Weimer + Mark Wielaard + + * run-elfclassify.sh: New test. + * run-elfclassify-self.sh: Likewise. + * Makefile.sh (TESTS): Add run-elfclassify.sh and + run-elfclassify-self.sh. + (EXTRA_DIST): Likewise. + +2019-07-16 Mao Han + + * hello_csky.ko.bz2: New testfile. + * run-addrcfi.sh: Add C-SKY testfile. + * run-strip-reloc.sh: Likewise. + * testfilecsky.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add hello_csky.ko.bz2 and + testfilecsky.bz2. + +2019-06-28 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add dwelf_elf_e_machine_string. + (TESTS): Add run-dwelf_elf_e_machine_string.sh. + (EXTRA_DIST): Likewise. + (dwelf_elf_e_machine_string_LDADD): New variable. + * dwelf_elf_e_machine_string.c: New file. + * run-dwelf_elf_e_machine_string.sh: New test. + +2019-07-01 Mark Wielaard + + * run-large-elf-file.sh: Add 2GB to mem_needed when running under + valgrind. + +2019-06-18 Mark Wielaard + + * Makefile.am (TESTS): Add run-large-elf-file.sh. + (EXTRA_DIST): Likewise. + * addsections.c (add_sections): Add sec_size argument, use it + as the size of the section data. + (main): Handle extra sec_size argument. Pass to add_sections. + * run-large-elf-file.sh: New test. + +2019-06-03 Mark Wielaard + + * elfcopy.c (copy_elf): When swapping the sh_offsets of two sections, + make sure they are actually next to each other. + +2019-05-12 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add elfrdwrnop. + (TESTS): Add run-reverse-sections.sh and + run-reverse-sections-self.sh. + (EXTRA_DIST): Likewise. + (elfrdwrnop): New variable. + * elfcopy.c (copy_elf): Add reverse_off argument. Record offsets + of sections and swap them when possible. + (main): Check for --reverse-off argument. Pass reverse_offs to + copy_elf. + * run-reverse-sections.sh: New test. + * run-reverse-sections-self.sh: Likewise. + * elfrdwrnop.c: New file. + +2019-05-10 Mark Wielaard + + * Makefile.am (TESTS): Add run-readelf-discr.sh. + (EXTRA_DIST): Likewise and add testfile-rng.debug.bz2 and + testfile-urng.debug.bz2. + * run-readelf-discr.sh: New test. + * testfile-rng.debug.bz2: New test file. + * testfile-urng.debug.bz2: Likewise. + +2019-04-30 Mark Wielaard + + * xlate_notes.c: New file. + * run-xlate-note.sh: New test. + * Makefile.am (check_PROGRAMS): Add xlate_notes. + (TESTS): Add run-xlate-note.sh. + (EXTRA_DIST): Likewise. + (xlate_notes_LDADD): New variable. + +2019-04-30 Mark Wielaard + + * backtrace-dwarf.c (frame_callback): Explicitly check symname is + NULL. + +2019-04-30 Mark Wielaard + + * backtrace.c (frame_callback): Explicitly check symname is NULL. + +2019-03-04 Mark Wielaard + + * backtrace.c (tgkill): Remove define. + +2019-01-24 Mark Wielaard + + * Makefile.am (system_elf_libelf_test_CPPFLAGS): Guard by + !INSTALL_ELFH. + +2019-01-31 Mark Wielaard + + * backtrace-child.c (stdarg): Remove assert (errno == 0). + (main): Likewise. + * backtrace-data.c (maps_lookup): Likewise. + (set_initial_registers): Likewise. + (main): Likewise. + * backtrace.c (prepare_thread): Likewise. + (exec_dump): Likewise. + +2019-01-29 Yonghong Song + + * backtrace-data.c (maps_lookup): Use %*u, not %*x, to parse + inode number. + +2019-01-18 Ulf Hermann + + * run-annobingroup.sh: Use different files for strip output. + * run-strip-test-many.sh: Use different files for strip output, + check results of strip, unstrip, elflint. + +2019-01-24 Mark Wielaard + + * addsections.c (add_sections): Change the name of the old shstrtab + section to ".old_shstrtab" and give the old shstrtab name to the + new shstrtab section. + +2019-01-09 Ulf Hermann + + * run-readelf-compressed.sh: Skip if USE_BZIP2 not found. + +2018-12-27 Jim Wilson + + * run-readelf-mixed-corenote.sh: Update with new riscv64 output. + +2018-12-02 Mark Wielaard + + * testfile_gnu_props.32le.o.bz2: New testfile. + * testfile_gnu_props.64le.o.bz2: Likewise. + * testfile_gnu_props.32be.o.bz2: Likewise. + * testfile_gnu_props.64be.o.bz2: Likewise. + * Makefile (EXTRA_DIST): Add new testfiles. + * run-readelf-n.sh: Run tests on new testfiles. + +2018-11-28 Mark Wielaard + + * backtrace-data.c (main): Improve error message. + * run-backtrace-data.sh: Skip exit 77 return. + +2018-11-21 Mark Wielaard + + * backtrace-subr.sh (check_unsupported): Call test_cleanup before + exit. + +2018-11-17 Mark Wielaard + + * run-strip-version.sh: New test. + * testfile-version.bz2: New test file. + * Makefile.am (TESTS): Add run-strip-version.sh. + (EXTRA_DIST): Add run-strip-version.sh and testfile-version.bz2. + +2018-11-09 Mark Wielaard + + * run-strip-reloc.sh: Also test testfile-debug-rel-ppc64-z.o + testfile-debug-rel-ppc64-g.o. + +2018-11-12 Mark Wielaard + + * run-readelf-n.sh: Add testfile-annobingroup.o test. + +2018-11-11 Mark Wielaard + + * run-readelf-n.sh: Fix NT_GNU_ABI_TAG type. Add testfile11 test + for NT_VERSION. + +2018-11-04 Mark Wielaard + + * testfile-bpf-reloc.expect.bz2: Update with new expected jump + variants. + +2018-10-20 Mark Wielaard + + * run-readelf-compressed.sh: New test. + * Makefile.am (TESTS): Add run-readelf-compressed.sh. + (EXTRA_DIST): Likewise. + +2018-11-09 Mark Wielaard + + * testfile-debug-rel-ppc64-g.o.bz2: New test file. + * testfile-debug-rel-ppc64-z.o.bz2: Likewise. + * testfile-debug-rel-ppc64.o.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add testfile-debug-rel-ppc64-g.o.bz2, + testfile-debug-rel-ppc64-z.o.bz2 and testfile-debug-rel-ppc64.o.bz2. + * run-strip-reloc.sh: Also test on testfile-debug-rel-ppc64.o. + * run-readelf-zdebug-rel.sh: Also test on testfile-debug-rel-ppc64*.o. + +2018-10-26 Mark Wielaard + + * run-strip-reloc.sh: Add a test for --reloc-debug-sections-only. + +2018-10-18 Mark Wielaard + + * run-readelf-n.sh: New test. + * testfile-gnu-property-note.bz2: New testfile. + * testfile-gnu-property-note.o.bz2: Likewise. + * Makefile.am (TESTS): Add run-readelf-n.sh. + (EXTRA_DIST): Likewise and testfile-gnu-property-note.bz2, + testfile-gnu-property-note.o.bz2. + +2018-10-12 Mark Wielaard + + * run-readelf-zdebug.sh: Adjust flags output. + * run-readelf-macro.sh: Likewise. + * run-readelf-macros.sh: New test. + * testfile-macros-object.o.bz2: New test file. + * Makefile.am (TESTS): Add run-readelf-macros.sh. + (EXTRA_DIST): Add run-readelf-macros.sh and + testfile-macros-object.o.bz2. + +2018-09-12 Mark Wielaard + + * run-annobingroup.sh: Add x86_64 ET_REL testcase. + * testfile-annobingroup-x86_64.o.bz2: New test file. + * Makefile.am (EXTRA_DIST): Add testfile-annobingroup-x86_64.o.bz2. + +2018-09-18 Mark Wielaard + + * backtrace-dwarf.c (thread_callback): Only error when + dwfl_thread_getframes returns an error. + (main): Don't call abort or assert but print an error when + something unexpected happens. + +2018-09-13 Mark Wielaard + + * run-strip-test-many.sh: New test. + * Makefile.am (TESTS): Add run-strip-test-many.sh. + (EXTRA_DIST): Likewise. + +2018-09-13 Mark Wielaard + + * run-typeiter-many.sh: New test. + * Makefile.am (TESTS): Add run-typeiter-many.sh. + (EXTRA_DIST): Likewise. + +2018-09-13 Mark Wielaard + + * run-copymany-sections.sh: New test. + * Makefile.am (TESTS): Add run-copymany-sections.sh. + (EXTRA_DIST): Likewise. + +2018-09-12 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add elfcopy and addsections. + (TESTS): Add run-copyadd-sections.sh. + (EXTRA_DIST): Likewise. + (elfcopy_LDADD): New variable. + (addsections_LDADD): Likewise. + * addsections.c: New file. + * elfcopy.c: Likewise. + * run-copyadd-sections.sh: New test. + +2018-09-11 Mark Wielaard + + * backtrace-dwarf.c (main): Add section attribute. + +2018-07-24 Mark Wielaard + + * run-annobingroup.sh: Add testfile-annobingroup-i386.o tests. + * testfile-annobingroup-i386.o.bz2: New test file. + * Makefile.am (EXTRA_DIST): Add testfile-annobingroup-i386.o.bz2. + +2018-07-21 Mark Wielaard + + * run-annobingroup.sh: New test. + * testfile-annobingroup.o.bz2: New test file. + * Makefile.am (TESTS): Add run-annobingroup.sh. + (EXTRA_DIST): Add run-annobingroup.sh and + testfile-annobingroup.o.bz2. + +2018-07-19 Andreas Schwab + + * Makefile.am (TESTS): Add run-strip-test12.sh. + (EXTRA_DIST): Add run-strip-test12.sh, testfile-riscv64.bz2, + testfile-riscv64-s.bz2, testfile-riscv64-core.bz2. + (run-strip-test11.sh): New file. + (testfile-riscv64.bz2): New file. + (testfile-riscv64-s.bz2): New file. + (testfile-riscv64-core.bz2): New file. + * run-allregs.sh: Add test for testfile-riscv64-core. + * run-readelf-mixed-corenote.sh: Likewise. + +2018-07-16 Ulf Hermann + + * run-strip-reloc.sh: Remove previous testfiles before running the + next test. + +2018-07-17 Mark Wielaard + + * hello_riscv64.ko.bz2: Updated with debuginfo. + * run-strip-reloc.sh: Add documentation on CONFIG_DEBUG_INFO=y. + +2018-07-05 Mark Wielaard + + * next_cfi.c (handle_section): Take a new argument name. Check + whether the section is compressed and uncompress if so. + (main): Check also for .zdebug_frame and pass the name of the + section to handle_section. + +2018-07-04 Ross Burton + + * addrscopes.c: Remove error.h include, add system.h include. + * allregs.c: Likewise. + * backtrace-data.c: Likewise. + * backtrace-dwarf.c: Likewise. + * backtrace.c: Likewise. + * buildid.c: Likewise. + * debugaltlink.c: Likewise. + * debuglink.c: Likewise. + * deleted.c : Likewise. + * dwarfcfi.c: Likewise. + * dwfl-addr-sect.c: Likewise. + * dwfl-bug-addr-overflow.c: Likewise. + * dwfl-bug-fd-leak.c: Likewise. + * dwfl-bug-getmodules.c: Likewise. + * dwfl-proc-attach.c: Likewise. + * dwfl-report-elf-align.c: Likewise. + * dwfllines.c: Likewise. + * dwflmodtest.c: Likewise. + * dwflsyms.c: Likewise. + * early-offscn.c: Likewise + * ecp.c: Likewise. + * elfstrmerge.c: Likewise. + * find-prologues.c: Likewise. + * funcretval.c: Likewise. + * funcscopes.c: Likewise. + * getsrc_die.c: Likewise. + * line2addr.c: Likewise. + * low_high_pc.c: Likewise. + * next_cfi.c: Likewise. + * rdwrmmap.c: Likewise. + * saridx.c: Likewise. + * sectiondump.c: Likewise. + * varlocs.c: Likewise. + * vdsosyms.c: Likewise. + +2018-06-28 Mark Wielaard + + * next_cfi.c: New file. + * run-next-cfi.sh: New test. + * run-next-cfi-self.sh: Likewise. + * Makefile.am (check_PROGRAMS): Add next_cfi. + (TESTS): Add run-next-cfi.sh and run-next-cfi-self.sh. + (EXTRA_DIST): Likewise. + (next_cfi_LDADD): New variable. + +2018-06-27 Mark Wielaard + + * dwarf_cfi.c: New file. + * run-dwarfcfi.sh: New test. + * testfile11-debugframe.bz2: New testfile. + * testfile12-debugframe.bz2: Likewise. + * testfileaarch64-debugframe.bz2: Likewise. + * testfilearm-debugframe.bz2: Likewise. + * testfileppc32-debugframe.bz2: Likewise. + * testfileppc64-debugframe.bz2: Likewise. + * Makefile.am (check_PROGRAMS): Add dwarfcfi. + (TESTS): Add run-dwarfcfi.sh. + (EXTRA_DIST): Add run-dwarfcfi.sh, testfile11-debugframe.bz2, + testfile12-debugframe.bz2, testfileaarch64-debugframe.bz2, + testfilearm-debugframe.bz2, testfileppc32-debugframe.bz2 and + testfileppc64-debugframe.bz2. + +2018-06-23 Mark Wielaard + + * varlocs.c (print_expr): Take a new depth argument. Check it isn't + greater than MAX_DEPTH (64). Pass on to print_expr_block. + (print_expr_block): Take a new depth argument. Pass it to print_expr. + (print_expr_block_addrs): Call print_expr_block with zero depth. + +2018-06-25 Mark Wielaard + + * next-files.c: New file. + * next-lines.c: Likewise. + * run-next-files.sh: New test. + * run-next-lines.sh: Likewise. + * testfile-only-debug-line.bz2: New test file. + * Makefile.am (check_PROGRAMS): Add next-files and next-lines. + (TESTS): Add run-next-files.sh and run-next-lines.sh. + (EXTRA_DIST): Add run-next-files.sh, run-next-lines.sh and + testfile-only-debug-line.bz2. + (next_lines_LDADD): New variable. + (next_files_LDADD): Likewise. + +2018-06-16 Yonghong Song + + * run-reloc-bpf.sh: New test. + * testfile-bpf-reloc.o.bz2: New test file. + * testfile-bpf-reloc.expect.bz2: New test file. + * Makefile.am (TESTS): Add run-reloc-bpf.sh. + (EXTRA_DIST): Add run-reloc-bpf.sh, testfile-bpf-reloc.o.bz2 and + testfile-bpf-reloc.expect.bz2. + +2018-06-13 Mark Wielaard + + * run-readelf-const-values.sh: New test. + * testfile-const-values.debug.bz2: New test file. + * run-readelf-zdebug-rel.sh: Adjust expected const_value. + * Makefile.am (TESTS): Add run-readelf-const-values.sh. + (EXTRA_DIST): Add run-readelf-const-values.sh and + testfile-const-values.debug.bz2. + +2018-06-08 Mark Wielaard + + * varlocs.c (print_expr): Error on bad DW_OP_GNU_parameter_ref + target, do not assert. + +2018-06-08 Mark Wielaard + + * get-units-invalid.c (main): Check invalid dwarf_getabbrev call. + * show-abbrev.c (main): Check illegal dwarf_getabbrev offset call. + +2018-06-08 Mark Wielaard + + * varlocs.c (main): Only assert when cfi_debug_bias != 0 if there + actually is a cfi_debug. + +2018-06-07 Mark Wielaard + + * run-readelf-loc.sh: Fix expected output for startx_length. + +2018-06-06 Mark Wielaard + + * varlocs.c (print_base_type): Use error, not assert when the DIE + isn't a base type. + +2018-06-02 Mark Wielaard + + * test-subr.sh (self_test_files_exe): Drop shared libraries. + Keep addr2line, elfcmp, objdump and readelf. + +2018-05-31 Mark Wielaard + + * run-readelf-types.sh: New test. + * Makefile.am (TESTS): Add run-readelf-types.sh. + (EXTRA_DIST): Likewise. + +2018-05-31 Mark Wielaard + + * splitdwarf4-not-split4.dwo.bz2: New test file. + * testfile-splitdwarf4-not-split4.debug.bz2: Likewise. + * run-readelf-loc.sh: Add test for splitdwarf4-not-split4.dwo + and testfile-splitdwarf4-not-split4.debug. + * run-varlocs.sh: Test testfile-splitdwarf4-not-split4.debug. + * Makefile.am (EXTRA_DIST): Add splitdwarf4-not-split4.dwo.bz2 + and testfile-splitdwarf4-not-split4.debug.bz2. + +2018-05-31 Mark Wielaard + + * test-subr.sh (self_test_files): Split into self_test_files_exe, + self_test_files_lib and self_test_obj. + (testrun_on_self_exe): New function. + (testrun_on_self_lib): Likewise. + * run-get-units-split.sh: Replace testrun_on_self with + testrun_on_self_exe and testrun_on_self_lib. + * run-unit-info.sh: Likewise. + +2018-05-31 Mark Wielaard + + * low_high_pc.c (handle_die): Handle NULL name. Print offset and + name of die. + (main): Check if the cu DIE is a skeleton, then get and handle + the split subdie. + * run-low-high-pc.sh: Run on testfile-splitdwarf-4 and + testfile-splitdwarf-5. Run on all selftest files. + +2018-05-31 Mark Wielaard + + * get-units-invalid.c (main): Check dwarf_cuoffset and + dwarf_dieoffset. + +2018-05-29 Mark Wielaard + + * dwarf-die-addr-die.c (check_dbg): Also check subdies, split or + type, gotten through dwarf_get_units. + * run-dwarf-die-addr-die.sh: Add tests for dwarf-4, dwarf-5, + split-dwarf-4, split-dwarf-5 and dwo files. + +2018-05-29 Mark Wielaard + + * run-readelf-loc.sh: Add GNU DebugFission split-dwarf variant. + * run-varlocs.sh: Likewise. + +2018-05-29 Mark Wielaard + + * run-readelf-twofiles.sh: Add --debug-dump=loc testcase. + +2018-05-28 Mark Wielaard + + * run-readelf-info-plus.sh: New test. + * Makefile.am (TESTS): Add run-readelf-info-plus.sh. + (EXTRA_DIST): Likewise. + +2018-04-29 Mark Wielaard + + * run-readelf-addr.sh: New test. + * Makefile.am (TESTS): Add run-readelf-addr.sh. + (EXTRA_DIST): Likewise. + +2018-04-27 Mark Wielaard + + * run-readelf-ranges.sh: Adjust expected output for address base. + * run-readelf-addr.sh: New test. + * Makefile.am (TESTS): Add run-readelf-addr.sh. + (EXTRA_DIST): Likewise. + +2018-04-07 Mark Wielaard + + * run-varlocs.sh: Run on testfileranges5.debug and + testsplitfileranges5.debug. + * varlocs.c (is_debug): New bool. + (print_expr): Don't fail on missing CFI for is_debug. + (main): Parse --debug, set is_debug. + +2018-04-12 Mark Wielaard + + * run-readelf-loc.sh: Add new testcases. + +2018-04-06 Mark Wielaard + + * testfileranges5.debug.bz2: New testfile. + * testfilesplitranges5.debug.bz2: Likewise. + * testfile-ranges-hello5.dwo.bz2: Likewise. + * testfile-ranges-world5.dwo.bz2: Likewise. + * run-dwarf-ranges.sh: Run on testfileranges5.debug. + * run-all-dwarf-ranges.sh: Run on testfilesplitranges5.debug. + * tests/Makefile.am (EXTRA_DIST): Add testfileranges5.debug.bz2, + testfilesplitranges5.debug.bz2, testfile-ranges-hello5.dwo.bz2 and + testfile-ranges-world5.dwo.bz2. + +2018-04-11 Mark Wielaard + + * run-readelf-ranges.sh: New test. + * Makefile.am (TESTS): Add run-readelf-ranges.sh. + (EXTRA_DIST): Likewise. + +2018-05-21 Mark Wielaard + + * addrx_constx-4.dwo.bz2: New testfile. + * addrx_constx-5.dwo.bz2: Likewise. + * testfile-addrx_constx-4.bz2: Likewise. + * testfile-addrx_constx-5.bz2: Likewise + * Makefile.am (EXTRA_DIST): Add addrx_constx-5.dwo.bz2 + testfile-addrx_constx-4\ .bz2 testfile-addrx_constx-5.bz2. + * run-varlocs.sh: Add addrx_constx tests for DWARF4 and DWARF5. + * varlocx.c (print_expr): Handle DW_OP_GNU_addr_index, + DW_OP_addrx, DW_OP_GNU_const_index and DW_OP_constx. + (main): Handle split DWARF. + * run-all-dwarf-ranges.sh: Add new ranges for addrx low/highpc. + +2018-05-20 Mark Wielaard + + * unit-info.c: New test. + * run-unit-info.sh: New test runner. + * Makefile.am (check_PROGRAMS): Add unit-info. + (TESTS): Add run-unit-info.sh + (EXTRA_INFO): Likewise. + (unit_info_LDADD): New variable. + +2018-05-24 Mark Wielaard + + * get-units-invalid.c (main): Add check for invalid dwarf_ranges. + * run-all-dwarf-ranges.sh: Correct expected output. + +2018-05-18 Mark Wielaard + + * Makefiles.am (check_PROGRAMS): Add all-dwarf-ranges. + (TESTS): Add run-all-dwarf-ranges.sh. + (EXTRA_DIST): Add run-all-dwarf-ranges.sh, + testfilesplitranges4.debug.bz2, testfile-ranges-hello.dwo.bz2 + and testfile-ranges-world.dwo.bz2. + (all_dwarf_ranges_LDADD): New variable. + * all-dwarf-ranges.c: New test program. + * run-all-dwarf-ranges: New test runner. + * testfile-ranges-hello.dwo.bz2: New test file. + * testfile-ranges-world.dwo.bz2: Likewise. + * testfilesplitranges4.debug.bz2: Likewise. + +2018-05-18 Mark Wielaard + + * run-get-files.sh: Add testcases for testfile-splitdwarf-4, + testfile-hello4.dwo, testfile-world4.dwo and testfile-splitdwarf-5, + testfile-hello5.dwo, testfile-world5.dwo. + +2018-05-17 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add attr-integrate-skel. + (TESTS): Add run-attr-integrate-skel. + (EXTRA_DIST): Likewise. + (attr_integrate_skel_LDADD): New variable. + * attr-integrate-skel.c: New test. + * run-attr-integrate-skel.sh: New test runner. + +2018-05-16 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add get-units-split. + (TESTS): Add run-get-units-split.sh. + (EXTRA_DIST): Add run-get-units-split.sh, testfile-hello4.dwo.bz2, + testfile-hello5.dwo.bz2, testfile-splitdwarf-4.bz2, + testfile-splitdwarf-5.bz2, testfile-world5.dwo.bz2 and + testfile-world4.dwo.bz2. + (get_units_split_LDADD): New variable. + * get-units-split.c: New test. + * run-get-units-split.sh: New test runner. + * testfile-dwarf-45.source: Extend with build instructions for new + test files. + * testfile-hello4.dwo.bz2: New test file. + * testfile-hello5.dwo.bz2: Likewise. + * testfile-splitdwarf-4.bz2: Likewise. + * testfile-splitdwarf-5.bz2: Likewise. + * testfile-world5.dwo.bz2 and: Likewise. + * testfile-world4.dwo.bz2: Likewise. + +2018-05-09 Mark Wielaard + + * run-readelf-zdebug.sh: Adjust test output for new header layout. + * run-readelf-line.sh: Likewise. Add new tests for testfile-dwarf-4 + and testfile-dwarf-5. + +2018-05-11 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add get-units-invalid. + (TESTS): Add run-get-units-invalid.sh. + (EXTRA_DIST): Likewise. + (get_units_invalid_LDADD): New variable. + * get-units-invalid.c: New test program. + * run-get-units-invalid.sh: New test program runner. + +2018-05-05 Mark Wielaard + + * testfile-dwarf-45.source: New file. + * testfile-dwarf-4.bz2: New test file. + * testfile-dwarf-5.bz2: Likewise. + * run-readelf-line.sh: Add testcases for testfile-dwarf-4 and + testfile-dwarf-5. + * Makefile (EXTRA_DIST): Add testfile-dwarf-45.source, + testfile-dwarf-4.bz2 and testfile-dwarf-5.bz2. + +2018-04-19 Andreas Schwab + + * hello_riscv64.ko.bz2: New file. + * run-strip-reloc.sh: Test it. + * Makefile.am (EXTRA_DIST): Add it. + +2018-04-16 Mark Wielaard + + * testfile-ppc64-min-instr.bz2: New testfile. + * run-readelf-line.sh: Run against testfile-ppc64-min-instr.bz2. + * Makefile.am (EXTRA_DIST): Add testfile-ppc64-min-instr.bz2. + +2018-04-11 Mark Wielaard + + * run-addrcfi.sh: Adjust expected rule for aarch64 sp. + +2018-04-03 Mark Wielaard + + * testfileranges4.debug.bz2: New testfile. + * run-dwarf-ranges.sh: Run on testfileranges4.debug. + * tests/Makefile.am (EXTRA_DIST): Add testfileranges4.debug.bz2. + +2018-03-06 Mark Wielaard + + * varlocs.c (print_expr): Handle DW_OP_implicit_pointer, + DW_OP_entry_value, DW_OP_convert, DW_OP_reinterpret, + DW_OP_regval_type, DW_OP_deref_type, DW_OP_xderef_type and + DW_OP_const_type. + +2018-02-16 Mark Wielaard + + * backtrace-subr.sh (check_native_core): Check if there is any core, + if so, use it. + +2018-02-15 Mark Wielaard + + * backtrace-child.c: Include signal.h after sys/ptrace.h. + * backtrace-dwarf.c: Include sys/wait.h and signal.h after + sys/ptrace.h. + +2018-01-25 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add dwarf-die-addr-die. + (TESTS): Add run-dwarf-die-addr-die.sh. + (EXTRA_DIST): Likewise. + (dwarf_die_addr_die_LDADD): New variable. + * dwarf-die-addr-die.c: New file. + * run-dwarf-die-addr-die.sh: New test. + +2018-02-09 Joshua Watt + + * elfstrmerge.c (main): Use FALLTHROUGH macro instead of comment. + +2018-01-22 Mark Wielaard + + * allfcts.c (setup_alt): Print warning when alt file couldn't be + found. + * run-allfcts-multi.sh: Add testcase where alt file is in a subdir + where it cannot be found by allfcts itself (but it can by libdw). + +2018-01-25 Mark Wielaard + + * elfstrmerge.c (main): Initialize and check symtabshdr instead of + symtabndx. + +2018-01-14 Petr Machata + + * testfile-sizes4.o.bz2: New test file. + * testfile-sizes4.s: New test source. + * run-aggregate-size.sh: Check testfile-sizes4.o v size 257. + +2017-12-23 Mark Wielaard + + * backtrace-subr.sh (check_native_core): Use a lock file and try + to extract core using coredumpctl. + * Makefile.am (CLEANFILES): Clean core-dump-backtrace.lock. + +2017-12-11 Dima Kogan + + * run-aggregate-size.sh: Added check for multi-dimensional arrays. + * run-peel-type.sh: Likewise. + * testfile-sizes3.o.bz2: Likewise. + +2017-12-07 Mark Wielaard + + * run-readelf-variant.sh: New test. + * testfile-ada-variant.bz2: New testfile. + * Makefile.am (TESTS): Add run-readelf-variant.sh. + (EXTRA_DISTS): Add run-readelf-variant.sh and + testfile-ada-variant.bz2. + +2017-11-29 Mark Wielaard + + * run-readelf-loc.sh: Adjust expected loc list output. + * run-readelf-zdebug-rel.sh: Likewise. + * run-readelf-zdebug.sh: Likewise. + +2017-11-29 Mark Wielaard + + * run-readelf-loc.sh: Adjust expected range list output. + * run-readelf-zdebug.sh: Likewise. + +2017-11-29 Mark Wielaard + + * run-readelf-dwz-multi.sh: Add expected file names. + * run-readelf-zdebug-rel.sh: Likewise. + +2017-11-29 Mark Wielaard + + * run-readelf-dwz-multi.sh: Add expected abbrev codes. + * run-readelf-zdebug-rel.sh: Likewise. + +2017-11-29 Mark Wielaard + + * run-readelf-dwz-multi.sh: Adjust expected ops index spaces. + * run-readelf-loc.sh: Likewise. + * run-readelf-zdebug-rel.sh: Likewise. + * run-readelf-zdebug.sh: Likewise. + +2017-11-16 Mark Wielaard + + * varlocs.c (main): Fix cfi_debug => cfi_debug_bias typo in assert. + +2017-11-10 Mark Wielaard + + * run-exprlocs-self.sh: New test. + * run-varlocs-self.sh: Likewise. + * Makefile.am (TESTS) Add run-exprlocs-self.sh and + run-varlocs-self.sh. + (EXTRA_DIST): Likewise. + * varlocs.c (cfi_debug_bias): New global variable. + (is_ET_REL): Likewise. + (print_expr): Don't crash and burn when CFI cannot be found for an + ET_REL file for DW_OP_call_frame_cfa. + (handle_die): If there is no entry_pc pick the lowest pc start range + for the DIE. + (main): Check at least one CU was found. Use dwfl_module_dwarf_cfi + and dwfl_module_eh_cfi to fix memory leak. Set is_ET_REL. + +2017-11-03 Mark Wielaard + + * run-exprlocs.sh: New test. + * testfile-stridex.bz2: New testfile. + * Makefile.am (TESTS): Add run-exprlocs.sh. + (EXTRA_DIST): Add run-exprlocs.sh and testfile-stridex.bz2. + * varlocs.c (dwarf_tag_string): New function. + (dwarf_attr_string): Likewise. + (dwarf_form_string): Likewise. + (print_expr): Fix typo in error message.r + Handle DW_OP_GNU_variable_value. + (attr_arg): New struct. + (handle_attr): New function. + (handle_die): Likewise. + (main): Handle --exprlocs argument. Call handle_die. + +2017-10-16 Mark Wielaard + + * md5-sha1-test.c: Removed. + * Makefile.am (check_PROGRAMS): Remove md5-sha1-test. + (TESTS): Likewise. + (md5_sha1_test_LDADD): Removed. + +2017-10-04 Mark Wielaard + + * msg_tst.c: Handle ELF_E_INVALID_ELF. + +2017-09-10 Mark Wielaard + + * run-ar.sh: New test. + * Makefile.am (TESTS): Add run-ar.sh. + (EXTRA_DIST): Likewise. + +2017-08-18 Ulf Hermann + + * Makefile.am: Drop -rdynamic from deleted_lib_so_LDFLAGS. + +2017-04-27 Ulf Hermann + + * Makefile.am: Use fpie_CFLAGS and fpic_CFLAGS. + +2017-08-08 Dmitry V. Levin + + * run-strip-nothing.sh: Add -s. + +2017-07-26 Mark Wielaard + + * dwarf-getmacros.c (mac): Use DW_MACRO names instead of DW_MACRO_GNU. + +2016-10-27 Mark Wielaard + + * dwarf_default_lower_bound.c: New test. + * Makefile.am (check_PROGRAMS): Add dwarf_default_lower_bound. + (TESTS): Likewise. + (dwarf_default_lower_bound_LDADD): New variable. + +2017-07-21 Mark Wielaard + + * get-lines.c (main): Add dwarf_line_file test. + +2017-07-19 Gustavo Romero + + * run-addrcfi.sh: Update generic SPRs names to HTM SPRs names + * run-allregs.sh: Update generic SPRs names to HTM SPRs names + +2017-07-20 Mark Wielaard + + * run-strip-g.sh: New test. + * Makefile.am (TESTS): Add run-strip-g.sh. + (EXTRA_DIST): Likewise. + +2017-07-18 Mark Wielaard + + * Makefile.am (TESTS): Always add run-disasm-bpf.sh if HAVE_LIBASM. + +2017-05-04 Ulf Hermann + + * elfshphehdr.c: For writing, use /dev/null rather than /dev/zero. + +2017-07-14 Mark Wielaard + + * run-strip-remove-keep.sh: New test. + * Makefile.am (TESTS): Add run-strip-remove-keep.sh. + (EXTRA_DIST): Likewise. + +2017-06-07 Mark Wielaard + + * run-strip-nothing.sh: New test. + * Makefile.am (TESTS): Add run-strip-nothing.sh. + (EXTRA_DIST): Likewise. + +2017-06-06 Mark Wielaard + + * run-strip-test.sh: Test strip -g doesn't introduce extra .shstrtab. + +2017-05-30 Mark Wielaard + + * run-backtrace-fp-core-ppc64le.sh: New test. + * backtrace.ppc64le.fp.core.bz2: New test file. + * backtrace.ppc64le.fp.exec.bz2: New testfile. + * backtrace-subr.sh (check_backtracegen): Accept '(null)'. + * Makefile.am (TESTS): Add run-backtrace-fp-core-ppc64le.sh. + (EXTRA_DIST): Add run-backtrace-fp-core-ppc64le.sh, + backtrace.ppc64le.fp.core.bz2 and backtrace.ppc64le.fp.exec.bz2. + +2017-02-13 Ulf Hermann + Mark Wielaard + + * Makefile.am: Add test for unwinding with frame pointers on aarch64 + * backtrace.aarch64.fp.core.bz2: New file + * backtrace.aarch64.fp.exec.bz2: New file + * run-backtrace-fp-core-aarch64.sh: New file + * backtrace-subr.sh (check_err): Allow Invalid register. + * backtrace.c (callback_verify): Allow duplicate_sigusr2 frames. + +2017-04-06 Mark Wielaard + + * run-backtrace-fp-core-i386.sh: New test. + * backtrace.i386.fp.core.bz2: New test file. + * backtrace.i386.fp.exec.bz2: New testfile. + * Makefile.am (TESTS): Add run-backtrace-fp-core-i386.sh. + (EXTRA_DIST): Add run-backtrace-fp-core-i386.sh, + backtrace.i386.fp.core.bz2 and backtrace.i386.fp.exec.bz2. + +2017-02-09 Ulf Hermann + + * Makefile.am: Add test for unwinding with frame pointers on x86_64 + * backtrace.x86_64.fp.core.bz2: New file + * backtrace.x86_64.fp.exec.bz2: New file + * run-backtrace-fp-core-x86_64.sh: New file + +2017-04-25 Mark Wielaard + + * backtrace-subr.sh (check_backtracegen): New function. + (check_core): Add check_backtracegen call. + * backtrace.ppc.exec.bz2: Regenerated. + * backtrace.ppc.core.bz2: Likewise. + +2017-04-24 Mark Wielaard + + * backtrace.c: Remove option to allow unknown symbols in the trace. + * backtrace-substr.sh: Remove option to allow unknown symbols + to check_core() and allow failed symbol lookups in check_err(). + +2017-04-20 Ulf Hermann + + * run-readelf-dwz-multi.sh: Expect readelf to output "yes" for flags + that are set. + * run-readelf-zdebug-rel.sh: Likewise. + +2017-04-20 Ulf Hermann + + * backtrace-child.c: Include sys/ptrace.h only on linux. + * backtrace-dwarf.c: Likewise. + +2017-04-05 Mark Wielaard + + * test-subr.sh (testrun_on_self_compressed): New function. + * run-elflint-self.sh: Call testrun_on_self_compressed. + * run-elflint-test.sh: Add testfile42z and testfile-s390x-hash-bothz. + +2017-03-30 Mark Wielaard + + * peel_type.c: New file. + * run-peel-type.sh: New test. + * Makefile.am (check_PROGRAMS): Add peel_type.c. + (TESTS): Add run-peel-type.sh. + (EXTRA_DIST): Likewise. + (peel_type_LDADD): New variable. + +2017-03-27 Mark Wielaard + + * fillfile.c: New file. + * Makefile.am (check_PROGRAMS): Add fillfile. + (TESTS): Likewise. + (fillfile_LDADD): New variable. + +2017-02-15 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add testfileppc64attrs.o.bz2. + * run-readelf-A.sh: Add testfileppc64.o test. + +2017-02-15 Ulf Hermann + + * elfstrmerge.c: Include system.h. + +2017-02-09 Ulf Hermann + + * backtrace.c: Add an option to allow unknown symbols in the trace + * backtrace-substr.sh: Add an option to allow unknown symbols + to check_core() and allow failed symbol lookups in check_err() + +2017-02-09 Ulf Hermann + + * backtrace-data.c: Don't assert that symbols are found. + The unwinder is allowed to ask for invalid addresses. We deny + such requests, rather than make the test fail. + +2016-11-17 Mark Wielaard + + * run-readelf-s.sh: Add --symbols=.dynsym and --symbols=.symtab tests. + +2016-11-02 Mark Wielaard + + * backtrace-data.c (thread_callback): Add explicit break after error. + * backtrace.c (callback_verify): Change PASSTHRU to FALLTHRU. + +2016-10-22 Kevin Cernekee + + * Makefile.am (TESTS): Add run-unstrip-test4.sh. + (EXTRA_DIST): Add run-unstrip-test4.sh, testfile-strtab.bz2, + testfile-strtab.stripped.bz2, testfile-strtab.debuginfo.bz2. + (run-unstrip-test4.sh): New file. + (testfile-strtab.bz2): New file. + (testfile-strtab.stripped.bz2): New file. + (testfile-strtab.debuginfo.bz2): New file. + +2016-10-11 Akihiko Odaki + + * arextract.c: Remove sys/param.h include, add system.h include. + +2016-08-30 Mark Wielaard + + * Makefile.am (asm_tst?_LDADD): Add libdw. + +2016-08-25 Mark Wielaard + + * backtrace-child.c: Disable and add documentation about why we disable + RAISE_JMP_PATCHING even on x86_64. + * backtrace.c (is_x86_64_native): Rename to... + (use_raise_jmp_patching): ... this. + (callback_verify): Use use_raise_jmp_patching instead of + is_x86_64_native. + (see_exec_module): Return DWARF_CB_ABORT after finding the correct exe + path. + (prepare_thread): Use RAISE_JMP_PATCHING instead of __x86_64__ + conditional. + (exec_dump): Only assert on data.mod != NULL. Drop ptrdiff. Use + RAISE_JMP_PATCHING instead of __x86_64__ conditional. Use + use_raise_jmp_patching instead of is_x86_64_native. + +2016-08-24 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add testfilesparc64attrs.o.bz2. + +2016-08-09 Jose E. Marchesi + + * testfilesparc64attrs.o.bz2: New file. + * run-readelf-A.sh: Check attributes in a sparc object. + +2016-08-06 Mark Wielaard + + * run-strip-reloc.sh: Add explicit compressed and uncompressed + test cases. + +2016-08-10 Richard Henderson + + * file-bpf-dis1.expect.bz2: Fix expected mod and endian operations + output. + +2016-07-08 Mark Wielaard + + * update3_LDADD: Use libdw instead of libebl. + * update4_LDADD: Likewise. + * alldts_LDADD: Likewise. + * elfstrmerge_LDADD: Likewise. + * alldts.c (main): Use dwelf_strtab instead of ebl_strtab. + * elfstrmerge.c (release): Likewise. + (main): Likewise. + * update3.c (main): Likewise. + * update4.c (main): Likewise. + +2016-07-10 Andreas Schwab + + * Makefile.am (TESTS): Add run-strip-test11.sh. + (EXTRA_DIST): Add run-strip-test11.sh, hello_m68k.ko.bz2, + testfile-m86k-core.bz2, testfile-m68k.bz2, testfile-m68k-s.bz2. + (run-strip-test11.sh): New file. + (hello_m68k.ko.bz2): New file. + (testfile-m68k-core.bz2): New file. + (testfile-m68k.bz2): New file. + (testfile-m68k-s.bz2): New file. + * run-allregs.sh: Add test for testfile-m68k-core. + * run-readelf-mixed-corenote.sh: Likewise. + * run-strip-reloc.sh: Add test for hello_m68k.ko. + +2016-07-06 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add vendorelf. + (TESTS): Likewise. + (vendorelf_LDADD): New variable. + * vendorelf.c: New test. + * elfshphehdr.c (test): Check elf_getphdrnum succeeds. + +2016-06-24 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add emptyfile. + (TESTS): Likewise. + (emptyfile_LDADD): New variable. + * emptyfile.c: New test. + +2016-06-28 Richard Henderson + + * Makefile.am (TESTS): Add run-disasm-bpf.sh, conditionally. + (EXTRA_DIST): Add run-disasm-bpf.sh, testfile-bpf-dis1.expect.bz2, + testfile-bpf-dis1.o.bz2 + (run-disasm-bpf.sh): New file. + (testfile-bpf-dis1.expect.bz2): New file. + (testfile-bpf-dis1.o.bz2): New file. + +2016-02-09 Mark Wielaard + + * testfile-s390x-hash-both.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add testfile-s390x-hash-both.bz2. + * run-elflint-test.sh: Add elflint testfile-s390x-hash-both test. + +2016-02-04 Mark Wielaard + + * run-strip-nobitsalign.sh: New test. + * testfile-nobitsalign.bz2: New testfile. + * testfile-nobitsalign.strip.bz2: Likewise. + * Makefile.am (TESTS): Add run-strip-nobitsalign.sh. + (EXTRA_DIST): Add run-strip-nobitsalign.sh, testfile-nobitsalign.bz2 + and testfile-nobitsalign.strip.bz2. + * run-strip-test.sh: Add --gnu to elflint calls. + +2016-01-13 Mark Wielaard + + * dwfl-bug-fd-leak.c: Skip test unless on __linux__. + +2016-01-13 Mark Wielaard + + * dwfl-proc-attach.c: Guard linux specific header. + +2016-01-13 Mark Wielaard + + * system-elf-libelf-test.c: New test. + * Makefile.am (TESTS): Add system-elf-libelf-test, if !STANDALONE. + (check_PROGRAMS): Likewise. + (system_elf_libelf_test_CPPFLAGS): New variable. + (system_elf_libelf_test_LDADD): Likewise. + +2016-01-08 Mark Wielaard + + * elfputzdata.c (main): Fix parentheses in strncmp test. + +2016-01-08 Mark Wielaard + + * elfputzdata.c (main): Use PRId64 to print 64 bit value. + +2016-01-08 Mark Wielaard + + * Makefile.am (TESTS): Always unconditionally add + run-readelf-zdebug.sh and run-readelf-zdebug-rel.sh. + +2015-12-16 Mark Wielaard + + * run-compress-test.sh: New test. + * Makefile.am (TESTS): Add run-compress-test.sh. + (EXTRA_DISTS): Likewise. + +2015-11-26 Mark Wielaard + + * zstrptr.c: New file. + * run-zstrptr.sh: New test. + * elfputzdata.c (main): (re)compress .shstrtab. + * run-elfputzdata.sh: Expect .shstrtab compression. + * Makefile.am (check_PROGRAMS): Add zstrptr. + (TESTS): Add run-zstrptr.sh. + (EXTRA_DIST): Likewise. + (zstrptr_LDADD): New variable. + +2015-10-20 Mark Wielaard + + * run-readelf-zx.sh: New test. + * run-readelf-zp.sh: Likewise. + * Makefile.am (TESTS): Add run-readelf-zx.sh and run-readelf-zp.sh. + (EXTRA_DIST): Likewise. + +2015-10-21 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add elfgetzdata and elfputzdata. + (TESTS): Add run-elfgetzdata.sh and run-elfputzdata.sh. + (EXTRA_DIST: Likewise. + (elfgetzdata_LDADD): New variable. + (elfputzdata_LDADD): Likewise. + * elfgetzdata.c: New file. + * elfputzdata.c: Likewise. + * msg_tst.c: Handle ELF_E_ALREADY_COMPRESSED, + ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and + ELF_E_DECOMPRESS_ERROR. + * run-elfgetzdata.sh: New test. + * run-elfputzdata.sh: Likewise. + +2015-10-28 Mark Wielaard + + * run-readelf-z.sh: New test. + * Makefile.am (TESTS): Add run-readelf-z.sh. + (EXTRA_DIST): Likewise. + +2015-10-28 Mark Wielaard + + * elfgetchdr.c: New file. + * run-elfgetchdr.sh: New test. + * testfile-zgabi32.bz2: New testfile. + * testfile-zgabi32be.bz2: Likewise. + * testfile-zgabi64.bz2: Likewise. + * testfile-zgabi64be.bz2: Likewise. + * Makefile.am (check_PROGRAMS): Add elfgetchdr. + (TESTS): Add run-elfgetchdr.sh. + (EXTRA_DIST): Add run-elfgetchdr.sh, testfile-zgabi32.bz2, + testfile-zgabi32be.bz2, testfile-zgabi64.bz2, testfile-zgabi64be.bz2. + (welfgetchdr_LDADD): New variable. + * msg_tst.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE + and ELF_E_INVALID_SECTION_FLAGS, + + +2015-10-28 Mark Wielaard + + * dwelfgnucompressed.c: New file. + * run-dwelfgnucompressed.sh: New test. + * testfile-zgnu32.bz2: New testfile. + * testfile-zgnu64.bz2: Likewise. + * Makefile.am (check_PROGRAMS): Add dwelfgnucompressed. + (TESTS): Add run-dwelfgnucompressed.sh. + (EXTRA_DIST): Add run-dwelfgnucompressed.sh, testfile-zgnu32.bz2, + testfile-zgnu64.bz2, testfile-zgnu32be.bz2, testfile-zgnu64be.bz2. + (dwelfgnucompressed_LDADD): New variable. + +2015-12-31 Mark Wielaard + + * elfstrmerge.c (main): Warn about STT_SECTION symbol for shstrhndx. + * run-elfstrmerge-test.sh: New test. + * Makefile.am (TESTS): Add run-elfstrmerge-test.sh + (EXTRA_DIST): Likewise. + +2015-12-08 Jose E. Marchesi + + * run-backtrace-core-sparc.sh: New file. + * backtrace.sparc.core.bz2: New file. + * backtrace.sparc.exec.bz2: New file. + * Makefile.am (EXTRA_DIST): ... and added all here. + (TESTS): Added run-backtrace-core-sparc.sh. + +2015-12-02 Mark Wielaard + + * Makefile.am (valgrind_cmd): Use --leak-check=full. + * run-backtrace-demangle.sh: Disable valgrind. + * run-stack-demangled-test.sh: Likewise. + * run-stack-d-test.sh: Likewise. + * run-stack-i-test.sh: Likewise. + +2015-12-01 Mark Wielaard + + * test-flag-nobits.c (main): Call elf_end. + * rerequest_tag.c (main): Call dwarf_end. + * funcscopes.c (handle_function): Free scopes. + * dwarf-getstring.c (main): Call dwarf_end. + * allregs.c (main): Free state.info. + * alldts.c (main): Free dyn. + * addrcfi.c (handle_address): Free stuff.frame between handle_cfi + calls. + * addrscopes.c (handle_address): Free scopes. + +2015-10-16 Mark Wielaard + + * Makefile.am [BUILD_STATIC] (libdw): Add -lz. + [BUILD_STATIC] (libelf): Likewise. + +2015-10-16 Mark Wielaard + + * Makefile.am (dwfl_proc_attach_LDFLAGS): Add AM_LDFLAGS. + +2015-10-09 Josh Stone + + * lfs-symbols: New list of LFS-related symbols from lintian. + * testfile-nolfs.bz2: New test binary for sanity checking. + * run-lfs-symbols.sh: New test. + * Makefile.am (TESTS): Add run-lfs-symbols.sh. + (EXTRA_DIST): Add lfs-symbols, testfile-nolfs.bz2, and + run-lfs-symbols.sh. + * alldts.c (main): Replace open64 with open. + * dwarf-getstring.c (main): Likewise. + * arls.c: Include config.h. + * ecp.c: Likewise. + * rdwrmmap.c: Likewise. + * test-elf_cntl_gelf_getshdr.c: Likewise. + * test-flag-nobits.c: Include config.h. + (main): Replace open64 with open. + +2015-10-09 Mark Wielaard + + * elfshphehdr.c (check): Rename argument from check to statement. + (check_elf): Likewise. + +2015-10-05 Josh Stone + + * Makefile.am (backtrace-child-biarch): Add AM_V_CC silencer. + +2015-10-02 Mark Wielaard + + * elfstrmerge.c: New check program. + * run-strip-strmerge.sh: New test. + * Makefile.am (check_PROGRAMS): Add elfstrmerge. + (EXTRA_DIST): Add run-strip-strmerge.sh + (elfstrmerge_LDADD): New variable. + +2015-09-29 Mark Wielaard + + * elfshphehdr.c: New test. + * Makefile.am (check_PROGRAMS): Add elfshphehdr. + (TESTS): Likewise. + (elfshphehdr_LDADD): New variable. + +2015-09-08 Mark Wielaard + + * dwfl-proc-attach.c: New test. + * Makefile.am (check_PROGRAMS): Add dwfl-proc-attach. + (TESTS): Likewise. + (dwfl_proc_attach_LDADD): New variable. + (dwfl_proc_attach_LDFLAGS): Likewise. + +2015-09-04 Chih-Hung Hsieh + + * varlocs.c (print_base_type): Initialize enctype. + +2015-09-04 Chih-Hung Hsieh + + * md5-sha1-test.c (md5_expected): Removed. + (sha1_expected): Likewise. + +2015-09-04 Chih-Hung Hsieh + + * asm-tst1.c (main): Replace %Z length modifier with %z. + * asm-tst2.c (main): Likewise. + * asm-tst3.c (main): Likewise. + * asm-tst4.c (main): Likewise. + * asm-tst5.c (main): Likewise. + * asm-tst6.c (main): Likewise. + * asm-tst7.c (main): Likewise. + * asm-tst8.c (main): Likewise. + * asm-tst9.c (main): Likewise. + * sectiondump.c (print_bytes): Likewise. + +2015-08-14 Mark Wielaard + + * run-addr2line-alt-debugpath.sh: New test. + * Makefile.am (TESTS): Add run-addr2line-alt-debugpath.sh + (EXTRA_DIST): Likewise. + +2015-07-29 Mark Wielaard + + * run-unstrip-test3.sh: New test. + * testfile-info-link.bz2: New file. + * testfile-info-link.debuginfo.bz2: Likewise. + * testfile-info-link.stripped.bz2: Likewise. + * Makefile.am (TESTS): Add run-unstrip-test3.sh. + (EXTRA_DIST): Add run-unstrip-test3.sh, testfile-info-link.bz2, + testfile-info-link.debuginfo.bz2, testfile-info-link.stripped.bz2. + +2015-06-27 Pino Toscano + + * tests/run-deleted.sh: Skip when detecting a not implemented + dwfl_linux_proc_attach. + +2015-06-27 Pino Toscano + + * tests/dwfl-bug-fd-leak.c (elfutils_open): Check for null results of + dwfl_addrmodule. + +2015-06-26 Pino Toscano + + * tests/vdsosyms.c [!__linux__] (main): Mark argv as unused. + +2015-06-26 Pino Toscano + + * tests/backtrace-data.c: Reduce scope of some includes to match their + usage. + * tests/backtrace.c: Likewise. + * tests/deleted.c: Likewise. + +2015-06-16 Mark Wielaard + + * run-strip-test.sh: Add strip-in-place (eu-strip without -o) test + for non-ET_REL files. + +2015-05-30 Mark Wielaard + + * backtrace-subr.sh (check_native_core): Notice core file couldn't be + generated before skipping. + * run-addr2line-i-demangle-test.sh: Notice demangler is unsupported + before skipping. + * run-backtrace-demangle.sh: Likewise. + * run-stack-demangled-test.sh: Likewise. + * run-backtrace-native-biarch.sh: Notice biarch testing is disabled + before skipping. + * run-backtrace-native-core-biarch.sh: Likewise. + * test-subr.sh (testfiles): Notice how bunzip2 fails before skipping. + +2015-05-20 Mark Wielaard + + * run-addr2line-i-test.sh: Add pretty test. + * run-addr2line-test.sh: Likewise. + +2015-05-20 Mark Wielaard + + * run-addr2line-i-demangle-test.sh: New test. + * Makefile.am (TESTS): Add run-addr2line-i-demangle-test.sh. + (EXTRA_DIST): Likewise. + +2015-05-20 Mark Wielaard + + * run-addr2line-test.sh: Add -a test variants. + * run-addr2line-i-test.sh: Likewise. + +2015-05-20 Mark Wielaard + + * run-addrname-test.sh: Make sure all input addresses are hex. + +2015-05-04 Max Filippov + + * backtrace-child.c (stdarg, main): Replace assert_perror with assert. + * backtrace-data.c (memory_read, maps_lookup, set_initial_registers) + (main): Likewise. + * backtrace-dwarf.c (main): Likewise. + * backtrace.c (prepare_thread, exec_dump): Likewise. + +2015-05-04 Anthony G. Basile + + * Makefile.am (line2addr_LDADD, addrscopes_LDADD, funcscopes_LDADD) + (funcretval_LDADD, allregs_LDADD, find_prologues_LDADD) + (dwflmodtest_LDADD, dwfl_addr_sect_LDADD, addrcfi_LDADD) + (low_high_pc_LDADD, dwflsyms_LDADD, dwfllines_LDADD, varlocs_LDADD) + (backtrace_LDADD, aggregate_size_LDADD): Append $(argp_LDADD). + +2015-05-01 Mark Wielaard + + * run-stack-d-test.sh: Use --raw and mangled output. + * run-stack-i-test.sh: Likewise. + * run-stack-demangled-test.sh: New test. + * Makefile.am (EXTRA_DIST): Add run-stack-demangled-test.sh. + (TESTS): Likewise. + +2015-04-01 H.J. Lu + + * Makefile.am (TESTS): Add run-strip-test10.sh. + (EXTRA_DIST): Likewise. Add testfile-x32-d.bz2. + Add testfile-x32-debug.bz2. + * run-strip-test10.sh: New file. + * testfile-x32-d.bz2: Likewise. + * testfile-x32-debug.bz2: Likewise. + +2015-04-01 H.J. Lu + + * Makefile.am (TESTS): Add run-strip-test9.sh. + (EXTRA_DIST): Likewise. Add testfile-x32-s.bz2. + * run-strip-test9.sh: New file. + * testfile-x32-s.bz2: Likewise. + +2015-04-01 H.J. Lu + + * Makefile.am (TESTS): Add run-backtrace-core-x32.sh. + (EXTRA_DIST): Likewise. Add backtrace.x32.core.bz2. + Add backtrace.x32.exec.bz2. + * backtrace.x32.core.bz2 : New file. + * backtrace.x32.exec.bz2: Likewise. + * run-backtrace-core-x32.sh: Likewise. + +2015-04-01 H.J. Lu + + * run-addrcfi.sh: Add a test for testfile-x32. + * testfile-x32.bz2: New file. + * Makefile.am (EXTRA_DIST): Add testfile-x32.bz2. + +2015-04-01 H.J. Lu + + * run-allregs.sh: Add a test for testfile-x32-core. + +2015-04-01 H.J. Lu + + * run-readelf-mixed-corenote.sh: Add a test for testfile-x32-core. + * testfile-x32-core.bz2: New file. + * Makefile.am (EXTRA_DIST): Add testfile-x32-core.bz2. + +2015-03-18 Petr Machata + + * addrcfi.c (op_name): Adjust uses of know-dwarf.h macros to match + the API changes. + * allregs.c (dwarf_encoding_string): Likewise. + * show-die-info.c (dwarf_tag_string, dwarf_attr_string): Likewise. + * varlocs.c (dwarf_encoding_string, dwarf_opcode_string): Likewise. + +2015-03-18 Petr Machata + + * Makefile.am (EXTRA_DIST): Add run-dwarf-ranges.sh, + debug-ranges-no-lowpc.o.bz2. + +2015-03-13 Mark Wielaard + + * backtrace-dwarf.c: Add explicit includes. + (cleanup_13_abort): Remove unused static declaration. + (thread_callback): Add explicit return. + +2015-03-13 H.J. Lu + + * backtrace.c (prepare_thread): Use PTRACE_GETREGS/PTRACE_SETREGS + instead of PTRACE_POKEUSER. + (exec_dump): Check EM_X86_64 instead of ELFCLASS64 for + is_x86_64_native. + +2015-02-18 Mark Wielaard + + * newdata.c (check_section_data): Use PRId64 for printing loff_t. + +2015-02-11 Josh Stone + + * backtrace.c (exec_dump): Initialize jmp. + +2015-02-11 Petr Machata + + * run-dwarf-ranges.sh: New test. + * dwarf-ranges.c: New file. + * debug-ranges-no-lowpc.s, debug-ranges-no-lowpc.o.bz2: New test case. + +2015-01-21 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add elfstrtab. + (TESTS): Likewise. + (elfstrtab_LDADD): New variable. + * elfstrtab.c: New test. + +2015-01-20 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add newdata. + (TESTS): Likewise. + (newdata_LDADD): new variable. + * newdata.c: New test. + +2015-01-20 Mark Wielaard + + * strptr.c: New file. + * run-strptr.sh: New test. + * Makefile.am (check_PROGRAMS): Add strptr. + (TESTS): Add run-strptr.sh. + (EXTRA_DIST): Likewise. + (strptr_LDADD): New variable. + +2015-01-15 Mark Wielaard + + * deleted.c (main): Call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY). + * vdsosyms.c (main): Use getpid () instead of getppid (). + +2014-12-27 Mark Wielaard + + * addrscopes.c (handle_address): Last address in scope is highpc - 1. + * funcscopes.c (handle_function): Likewise. + * run-addrscopes.sh: Adjust last address in scope. + * run-funcscopes.sh: Likewise. + +2015-01-07 Mark Wielaard + + * run-addrcfi.sh: Add test for ppc32 eh_frame_hdr address search. + +2015-01-14 Mark Wielaard + + * testfile-debug-types.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add testfile-debug-types.bz2. + * typeiter2.c (main): Print both name and offset of found form DIE. + * run-typeiter.s: Adjust output and add testfile-debug-types. + +2014-12-26 Mark Wielaard + + * run-test-archive64.sh: Add nm test. + +2014-12-19 Mark Wielaard + + * run-deleted.sh: Don't check libfunc on ppc64. + +2014-12-19 Mark Wielaard + + * vdsosyms.c (vdso_seen): Removed. + (vdso_syms): New global. + (module_callback): Set and check vdso_syms. + (main): Return value depends on vdso_syms. + +2014-12-19 Mark Wielaard + + * backtrace-subr.sh (check_native_unsupported): Relax special ARM + grep a little. + * run-deleted.sh: Call check_native_unsupported. + +2014-12-18 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add testfile-macros-0xff.bz2. + +2014-12-12 Mark Wielaard + + * Makefile.am (deleted_lib_so_CFLAGS): Add + -fasynchronous-unwind-tables. + +2014-12-11 Josh Stone + + * run-addr2line-i-lex-test.sh: New test. + * testfile-lex-inlines.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add run-addr2line-i-lex-test.sh and + testfile-lex-inlines.bz2. + (TESTS): Add run-addr2line-i-lex-test.sh. + +2014-12-10 Josh Stone + + * run-addr2line-i-test.sh: Test 0x5f0 to make sure linkage_name is + preferred over the plain die name. + +2014-12-02 Petr Machata + + * dwarf-getmacros.c (mac): Skip over DW_MACINFO_undef, + DW_MACRO_GNU_undef_indirect opcodes. Add a default branch. + (main): Initialize off to DWARF_GETMACROS_START when an extra + command line argument is passed. + * testfile-macros-0xff.bz2: New test case. + * testfile-macros-0xff.s: New file (source for the above). + * run-dwarf-getmacros.sh: Add two tests. + +2014-11-27 Mark Wielaard + + * vdsosyms.c (main): Call dwfl_linux_proc_attach. + +2014-11-21 Mark Wielaard + + * run-readelf-A.sh: New test. + * testfileppc32attrs.o.bz2: New test file. + * Makefile.am (TESTS): Add run-readelf-A.sh. + (EXTRA_DIST): Add run-readelf-A.sh and testfileppc32attrs.o.bz2. + +2014-11-10 Mark Wielaard + + * vdsosyms.c: New test. + * Makefile.am (check_PROGRAMS): Add vdsosyms. + (TESTS): Likewise. + (vdsosyms_LDADD): New variable. + +2014-09-10 Petr Machata + + * dwarf-getmacros.c: Update to use the new macro iteration + interfaces. + * run-dwarf-getmacros.sh: Adjust, add a test that uses + testfile-macros. + +2014-10-06 Mark Wielaard + + * run-aggregate-size.sh: Add testfile-sizes3.o test case. + * testfile-sizes3.o.bz2: New test file. + * Makefile.am (EXTRA_DIST): Add testfile-sizes3.o.bz2. + +2014-10-02 Mark Wielaard + + * run-deleted.sh: Unset VALGRIND_CMD before running deleted. + +2014-10-02 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add aggregate_size.c. + (TESTS): Add run-aggregate-size.sh. + (EXTRA_DIST): Add run-aggregate-size.sh, testfile-sizes1.o.bz2 + and testfile-sizes2.o.bz2. + (aggregate_size_LDADD): New variable. + * aggregate_size.c: New file. + * run-aggregate-size.sh: New test. + * testfile-sizes1.o.bz2: New test file. + * testfile-sizes2.o.bz2: Likewise. + +2014-09-26 Jan Kratochvil + + Support NT_FILE for locating files. + * Makefile.am (TESTS): Add run-linkmap-cut.sh. + (EXTRA_DIST): Add run-linkmap-cut.sh, linkmap-cut-lib.so.bz2, + linkmap-cut.bz2 and linkmap-cut.core.bz2 . + * linkmap-cut-lib.so.bz2: New file. + * linkmap-cut.bz2: New file. + * linkmap-cut.core.bz2: New file. + * run-linkmap-cut.sh: New file. + * run-unstrip-n.sh: Update its expected output. + +2014-08-28 Jan Kratochvil + + * Makefile.am (check_PROGRAMS): Add deleted and deleted-lib.so. + (TESTS, EXTRA_DIST): Add run-deleted.sh. + (deleted_LDADD, deleted_lib_so_LDFLAGS, deleted_lib_so_CFLAGS): New. + * deleted-lib.c: New file. + * deleted.c: New file. + * run-deleted.sh: New file. + +2014-06-15 Mark Wielaard + + * backtrace.c (frame_callback): Error on seeing more than 16 frames. + +2014-06-13 Mark Wielaard + + * backtrace.c (callback_verify): Accept "__libc_do_syscall" as first + frame symname. + +2014-06-13 Mark Wielaard + + * backtrace-subr.sh (check_native_unsupported): New function. + (check_native): Call it. + (check_native_core): Likewise. + * run-backtrace-dwarf.sh: Likewise. + +2014-06-11 Mark Wielaard + + * backtrace.c (main): Check that Dwfl was attached by calling + dwfl_pid and printing the error when it is not. + +2014-05-18 Mark Wielaard + + * testfile-backtrace-demangle.cc (cxxfunc): Make non-static. + (f): Likewise. + * testfile-backtrace-demangle.bz2: Regenerate. + * testfile-backtrace-demangle.core.bz2: Likewise. + +2014-05-02 Mark Wielaard + + * Makefile.am (TESTS): run-readelf-dwz-multi.sh and + run-allfcts-multi.sh are now added unconditionally. + +2014-05-01 Mark Wielaard + + * run-readelf-dwz-multi.sh: Add tests with alt debug files in .dwz + subdir. + +2014-04-30 Mark Wielaard + + * buildid.c, buildid.sh, testfile42_noshdrs.bz2: New files. + * Makefile.am (check_PROGRAMS): Add buildid. + (TESTS): Add run-buildid.sh. + (EXTRA_DISTS): Add run-buildid.sh and testfile42_noshdrs.bz2. + (buildid_LDADD): New variable. + +2014-04-24 Florian Weimer + + * allfcts.c (setup_alt): New function. + (main): Call it. Implementation additional error checking and + reporting. + +2014-04-24 Florian Weimer + + * debugaltlink.c, run-debugaltlink.sh: New files. + * Makefile.am (check_PROGRAMS): Add debugaltlink. + (TESTS): Add run-debugaltlink.sh. + (debugaltlink_LDADD): New variable. + +2014-04-11 Mark Wielaard + + * Makefile.am (AM_CPPFLAGS): Add -I libdwelf. + (check_PROGRAMS): Add debuglink. + (TESTS): Add run-debuglink.sh + (EXTRA_DIST): Likewise. + (debuglink_LDADD): New. + * debuglink.c: New file. + * run-debuglink.sh: Likewise. + +2014-03-23 Mark Wielaard + + * run-nm-self.sh: Use test = not == for string comparisons. + +2014-04-22 Kurt Roeckx + + * backtrace.c: Make Linux only. + * backtrace-child.c: Make Linux only. + * backtrace-data.c: Make Linux only. + * backtrace-dwarf.c: Make Linux only. + * backtrace-subr.sh: Skip core file unwinding tests when not supported. + +2014-03-14 Mark Wielaard + + * Makefile.am: Remove MUDFLAP conditions. Remove libmudflap from all + LDADD lines. + * configure.ac: Remove MUDFLAP conditional. + +2014-04-09 Mark Wielaard + + * run-readelf-zdebug.sh: New test. + * testfile-debug.bz2: New testfile. + * testfile-zdebug.bz2: New testfile. + * Makefile.am (TESTS): Add run-readelf-zdebug.sh if ZLIB. + (EXTRA_DIST): Add run-readelf-zdebug.sh, testfile-debug.bz2 and + testfile-zdebug.bz2. + +2014-04-10 Mark Wielaard + + * testfile_i686_core.bz2: New test file. + * run-readelf-mixed-corenote.sh: Add testfile_i686_core test. + * Makefile.am (EXTRA_DIST): Add testfile_i686_core.bz2 + +2014-04-09 Mark Wielaard + + * Makefile.am (TESTS): Add run-backtrace-core-aarch64.sh. + (EXTRA_DIST): Add run-backtrace-core-aarch64.sh, + backtrace.aarch64.core.bz2 and backtrace.aarch64.exec.bz2. + * run-backtrace-core-aarch64.sh: New test. + +2014-03-11 Josh Stone + + * testfilebaxmin.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add testfilebaxmin.bz2. + * run-readelf-s.sh: Test testfilebaxmin. + * run-dwflsyms.sh: Likewise. + +2014-01-26 Mark Wielaard + + * backtrace-subr.sh (check_unsupported): Special case arm*. + +2014-01-25 Mark Wielaard + + * run-addrcfi.sh (EM_ARM): Change reg13 (sp) from undefined to + location expression: call_frame_cfa stack_value. + +2014-01-22 Mark Wielaard + + * Makefile.am (line2addr_no_Wformat): Removed. + +2014-01-21 Mark Wielaard + + * Makefile.am (TESTS): Add run-stack-i-test.sh. + (EXTRA_DIST): Likewise. + * run-stack-i-test.sh: New test. + +2014-01-20 Mark Wielaard + + * Makefile.am (TESTS): Add run-stack-d-test.sh. + (EXTRA_DIST): Add run-stack-d-test.sh, testfiledwarfinlines.bz2 + testfiledwarfinlines.core.bz2. + * run-stack-d-test.sh: New test. + * testfiledwarfinlines.bz2: New test file. + * testfiledwarfinlines.core.bz2: Likewise. + +2014-01-16 Mark Wielaard + + * run-nm-self.sh: Don't use testrun_on_self_quiet but just testrun + on one ET_REL, one ET_EXEC and one ET_DYN file. + * test-subr.sh (self_test_files): Add two ET_REL files, only add + two libebl ET_DYN backend files. + +2014-01-16 Mark Wielaard + + * run-backtrace-demangle.sh: Check exitcode and max number of frames. + +2014-01-18 Jan Kratochvil + + Fix false FAILs on testsuite with ulimit -c unlimited. + * backtrace-child.c (sigusr2): Call pthread_exit. + (main): Return, do not call abort. + +2014-01-15 Jan Kratochvil + + Fix corruption of non-C++ symbols by the demangler. + * Makefile.am (TESTS): Add run-backtrace-demangle.sh. + : Add ELFUTILS_DISABLE_DEMANGLE export. + (EXTRA_DIST): Add run-backtrace-demangle.sh, + testfile-backtrace-demangle.bz2, testfile-backtrace-demangle.cc, + testfile-backtrace-demangle.core.bz2. + * backtrace-demangle.cc: New file. + * run-backtrace-demangle.sh: New file. + * testfile-backtrace-demangle.bz2: New file. + * testfile-backtrace-demangle.cc: New file. + * testfile-backtrace-demangle.core.bz2: New file. + +2014-01-07 Matthias Klose + + * backtrace-subr.sh (check_native_core): Check to see if core file + was created without ".PID" extension, if so mv core to core.PID. + Skip test if no core file was created or could be found. + +2014-01-04 Mark Wielaard + + * backtrace-data.c (main): Don't assert if raise returns. + * backtrace-dwarf.c (report_pid): Call dwfl_linux_proc_attach with + assume_ptrace_attached true. + (ptrace_detach_stopped): Removed function. + (main): Don't call ptrace_detach_stopped. + * backtrace.c (ptrace_detach_stopped): Removed function. + (report_pid): Call dwfl_linux_proc_attach with assume_ptrace_attached + true. + (exec_dump): Don't call ptrace_detach_stopped. + +2014-01-04 Mark Wielaard + + * backtrace-subr.sh (check_native_core): Skip, exit 77, the test + if we cannot adjust core ulimit. + +2014-01-04 Mark Wielaard + + * cleanup-13.c (force_unwind_stop): Removed. + (force_unwind): Just call abort. Don't setup _Unwind_Exception and + don't call _Unwind_ForcedUnwind. + +2014-01-03 Mark Wielaard + + * run-addrcfi.sh: Add case for EM_AARCH64. + * testfileaarch64.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add testfilesaarch64.bz2. + +2013-12-30 Mark Wielaard + + * backtrace-dwarf.c (report_pid): Explicitly call + dwfl_linux_proc_attach and check for errors. + * backtrace.c (report_pid): Likewise. + +2013-12-21 Mark Wielaard + + * backtrace.c (callback_verify): Only assert that case 5 is the last + instruction of backtracegen on x86_64 native. + +2013-12-18 Jan Kratochvil + Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add testfile66.bz2, testfile66.core.bz2 + and testfilebaz*ppc64*.bz2 files. + * dwflsyms.c (list_syms): Remove unused from parameter mod_name. Print + error on dwfl_module_getsymtab error. + (list_syms): Use dwfl_module_getsym and dwfl_module_getsym_info. + Compare values for non-ET_REL. Use dwfl_module_addrinfo. + Also print section of actual value if different from sym. + * run-addrname-test.sh (testfile66, testfile66.core): New tests. + Test addr2line -x by showing different sections for address and + found name in testfile66. + * run-dwflsyms.sh (testfile66, testfile66.core, hello_ppc64.ko, + testfilebaz*ppc64): New tests. + * testfile66.bz2, testfile66.core.bz2, testfilebazdbgppc64.bz2, + testfilebazdbgppc64.debug.bz2, testfilebazdbgppc64_pl.bz2, + testfilebazdbgppc64_plr.bz2, testfilebazdynppc64.bz2, + testfilebazmdbppc64.bz2, testfilebazminppc64.bz2, + testfilebazminppc64_pl.bz2, testfilebazminppc64_plr.bz2, + testfilebaztabppc64.bz2: New test files. + +2013-12-18 Jan Kratochvil + + unwinder: s390 and s390x + * Makefile.am (TESTS): Add run-backtrace-core-s390x.sh and + run-backtrace-core-s390.sh. + (EXTRA_DIST): Add backtrace.s390x.core.bz2, backtrace.s390x.exec.bz2, + backtrace.s390.core.bz2, backtrace.s390.exec.bz2, + run-backtrace-core-s390x.sh and run-backtrace-core-s390.sh. + * backtrace.s390.core.bz2: New file. + * backtrace.s390.exec.bz2: New file. + * backtrace.s390x.core.bz2: New file. + * backtrace.s390x.exec.bz2: New file. + * run-backtrace-core-s390.sh: New file. + * run-backtrace-core-s390x.sh: New file. + +2013-12-17 Jan Kratochvil + + * backtrace-dwarf.c (executable, find_elf, dwfl_offline): Remove unused + code. + +2013-12-15 Jan Kratochvil + + unwinder: ppc + * Makefile.am (TESTS): Add run-backtrace-core-ppc.sh. + (EXTRA_DIST): Add backtrace.ppc.core.bz2, + backtrace.ppc.exec.bz2 and run-backtrace-core-ppc.sh. + * backtrace.ppc.core.bz2: New file. + * backtrace.ppc.exec.bz2: New file. + * run-backtrace-core-ppc.sh: New file. + +2013-12-10 Mark Wielaard + + * Makefile.am (backtrace_child_biarch_SOURCES): New backtrace-child.c. + +2013-12-10 Mark Wielaard + + * Makefile.am (valgrind_cmd): Remove --trace-children=yes. + * backtrace-subr.sh (check_native_core): Disable valgrind while + dumping core. + * run-backtrace-data.sh: Disable valgrind. + * run-backtrace-dwarf.sh: Likewise. + +2013-12-09 Mark Wielaard + + * varlocs.c (print_expr): Update comment to explain empty location + associated with DW_OP_GNU_implicit_pointer. + +2013-12-05 Jan Kratochvil + + Fix test FAIL with -O2. + * backtrace-child.c (sigusr2): Add NOINLINE_NOCLONE and final asm stub. + +2013-12-05 Mark Wielaard + + * backtrace-data.c (main): If unsupported also print to stderr. + * run-backtrace-dwarf.sh: Add check_unsupported and check_main. + +2013-12-04 Mark Wielaard + + * Makefile.am (backtrace-child-biarch): Add $(EXEEXT). + +2013-12-02 Jan Kratochvil + + * Makefile.am (check_PROGRAMS): Add backtrace, backtrace-child, + backtrace-data and backtrace-dwarf. + (BUILT_SOURCES, clean-local, backtrace-child-biarch): New. + (TESTS): Add run-backtrace-native.sh, run-backtrace-data.sh, + run-backtrace-dwarf.sh, run-backtrace-native-biarch.sh, + run-backtrace-native-core.sh, run-backtrace-native-core-biarch.sh, + run-backtrace-core-x86_64.sh and run-backtrace-core-i386.sh. + Add export of ELFUTILS_DISABLE_BIARCH. + (EXTRA_DIST): Add run-backtrace-data.sh, run-backtrace-dwarf.sh, + cleanup-13.c, run-backtrace-native.sh, run-backtrace-native-biarch.sh, + run-backtrace-native-core.sh, run-backtrace-native-core-biarch.sh, + run-backtrace-core-x86_64.sh, run-backtrace-core-i386.sh, + backtrace-subr.sh, backtrace.i386.core.bz2, backtrace.i386.exec.bz2, + backtrace.x86_64.core.bz2, backtrace.x86_64.exec.bz2. + (backtrace_LDADD, backtrace_child_CFLAGS, backtrace_child_LDFLAGS) + (backtrace_data_LDADD, backtrace_dwarf_CFLAGS, backtrace_dwarf_LDADD): + New. + * backtrace-child.c: New file. + * backtrace-data.c: New file. + * backtrace-dwarf.c: New file. + * backtrace-subr.sh: New file. + * backtrace.c: New file. + * cleanup-13.c: New file. + * backtrace.i386.core.bz2: New file. + * backtrace.i386.exec.bz2: New file. + * backtrace.x86_64.core.bz2: New file. + * backtrace.x86_64.exec.bz2: New file. + * run-backtrace-core-i386.sh: New file. + * run-backtrace-core-x86_64.sh: New file. + * run-backtrace-native-biarch.sh: New file. + * run-backtrace-native-core-biarch.sh: New file. + * run-backtrace-native-core.sh: New file. + * run-backtrace-native.sh: New file. + * run-backtrace-data.sh: New file. + * run-backtrace-dwarf.sh: New file. + +2013-11-27 Mark Wielaard + + * dwflsyms.c (gelf_bind_order): New function. + (elf_section_name): Likewise. + (addr_in_section): Likewise. + (list_syms): Use dwfl_module_getsym_elf and dwfl_module_addrsym_elf. + Refine assert using gelf_bind_order. Print elf_section_name. Check + bias with addr_in_section. + * run-dwflsyms.sh: Add section names to expected output. + +2013-11-26 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add run-funcretval.sh. + +2013-11-25 Petr Machata + + * testfile_aarch64_core.bz2, hello_aarch64.ko.bz2: New files. + * funcretval_test.c, funcretval_test_aarch64.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add these. + (TESTS): Add run-funcretval.sh. + * run-allregs.sh: Use testfile_aarch64_core.bz2 for a regs_test. + * run-readelf-mixed-corenote.sh: ... and for a readelf -n test. + * run-strip-reloc.sh: Add a test on hello_aarch64.ko.bz2. + * run-funcretval.sh: New file. + +2013-11-18 Josh Stone + + * testfilebazdbg_plr.bz2: New testfile. + * testfilebazmin_plr.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add the above files. + * run-dwflsyms.sh: Add prelink -r tests. + +2013-11-15 Mark Wielaard + + * testfilebazmdb.bz2: Regenerated. + * testfilebazmin.bz2: Likewise. + * testfilebazdbg_pl.bz2: New testfile. + * testfilebazmin_pl.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add testfilebazdbg_pl.bz2 and + testfilebazmin_pl.bz2. + * dwflsyms.c (list_syms): Call dwfl_module_relocate_address and + print relative address of function symbols. + * run-dwflsyms.sh: Add prelink tests and adjust expected output. + +2013-11-01 Michael Forney + + * Makefile.am (TESTS_ENVIRONMENT): Use and export NM. + * run-arsymtest.sh: Use NM. + +2013-11-05 Mark Wielaard + + * allfcts.c (main): Correct dwarf_getfuncs return value check. + +2013-10-10 Mark Wielaard + Josh Stone + + * run-allfcts-multi.sh: New test. + * test-offset-loop.bz2: New testfile. + * test-offset-loop.alt.bz2: New testfile. + * Makefile.am (TESTS): Add run-allcft-multi.sh if ENABLE_DWZ. + (EXTRA_DIST): Add run-allfcts-multi.sh, test-offset-loop.bz2 and + test-offset-loop.alt.bz2. + +2013-10-15 Mark Wielaard + + * run-unstrip-M.sh: New test. + * Makefile.am (TESTS): Add run-unstrip-M.sh. + (EXTRA_DIST): Likewise. + +2013-10-06 Mark Wielaard + + * run-addrcfi.sh: Remove nop from expected ppc and ppc64 + location expression. + +2013-10-03 Josh Stone + + * typeiter2.c: New file, reversing typeiter.c. + * run-typeiter.sh: Also run typeiter2. + * Makefile.am (check_PROGRAMS): Add typeiter2. + (typeiter2_LDADD): New variable. + +2013-09-26 Petr Machata + + * run-readelf-mixed-corenote.sh: Update output of testfile71 + dump--readelf can newly decode the NT_FILE note. + +2013-09-26 Petr Machata + + * Makefile.am (EXTRA_DIST): Add testfile71.bz2. + * run-readelf-mixed-corenote.sh: New test for this file. + * testfile71.bz2: New file. + +2013-09-20 Mark Wielaard + + * allfcts.c (cb): Return DWARF_CB_ABORT. + (main): Iterate over all offsets returned by dwarf_getfuncs. + * run-allfcts.sh: Add nested_funcs and class_func testcases. + * testfile_nested_funcs.bz2: New test file. + * testfile_class_func.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add testfile_class_func.bz2 and + testfile_nested_funcs.bz2. + +2013-08-30 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add varlocs. + (TESTS): Add run-varlocs.sh. + (EXTRA_DIST): Add run-varlocs.sh, testfile_const_type.c, + testfile_const_type.bz2, testfile_implicit_pointer.c, + testfile_implicit_pointer.bz2, testfile_parameter_ref.c, + testfile_entry_value.c, testfile_entry_value.bz2, + testfile_implicit_value.c and testfile_implicit_value.bz2. + (varlocs_LDADD): New. + * run-varlocs: New test. + * testfile_const_type.c: New test source file. + * testfile_entry_value.c: Likewise. + * testfile_implicit_pointer.c: Likewise. + * testfile_implicit_value.c: Likewise. + * testfile_parameter_ref.c: Likewise. + * testfile_const_type.bz2: New test file. + * testfile_entry_value.bz2: Likewise. + * testfile_implicit_pointer.bz2: Likewise. + * testfile_implicit_value.bz2: Likewise. + * testfile_parameter_ref.bz2: Likewise. + * varlocs.c: New test source. + +2013-08-29 Mark Wielaard + + * run-addrcfi.sh: Add case for EM_ARM. + * testfilearm.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add testfilesarm.bz2. + +2013-08-28 Mark Wielaard + + * addrcfi.c (handle_cfi): Handle .debug_frame or .eh_frame + completely missing. + * run-addrcfi.sh: Add case for EM_S390 ELFCLASS32 and ELFCLASS64. + * testfiles390.bz2: New testfile. + * testfiles390x.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add testfiles390.bz2 and + testfiles390x.bz2. + +2013-08-28 Mark Wielaard + + * addrcfi.c (handle_cfi): Use printf not error. + * run-addrcfi.sh: Add case for EM_PPC and EM_PPC64. + * testfileppc32.bz2: New testfile. + * testfileppc64.bz2: Likewise. + * Makefile.am (EXTRA_DIST): Add testfileppc32.bz2 and + testfileppc64.bz2. + +2013-08-27 Mark Wielaard + + * run-addrcfi.sh: New test. + * Makefile.am (TESTS): Add run-addrcfi.sh. + (EXTRA_DIST): Likewise. + * addrcfi.c (op_name): New function. + (print_detail): Call and print op_name. Check ops, not result + to check if this is "same value" or "undefined". + (handle_cfi): Make sure cfa_ops doesn't point to NULL. + +2013-08-13 Mark Wielaard + + * run-addr2line-i-test.sh: New test. + * testfile-inlines.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add run-addr2line-i-test.sh and + testfile-inlines.bz2. + (TESTS): Add run-addr2line-i-test.sh. + +2013-08-12 Mark Wielaard + + * run-addr2line-test.sh: New test. + * Makefile.am (EXTRA_DIST): Add run-addr2line-test.sh. + (TESTS): Likewise. + +2013-07-23 Jan Kratochvil + + * run-unstrip-n.sh (test-core.*): Ignore libc.so.6 entry and order of + the entries. + +2013-07-02 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Fix typo, forgot extension in + testfilenolines.bz2. + +2013-05-30 Jan Kratochvil + + * Makefile.am (EXTRA_DIST): Add test-core-lib.so.bz2, + test-core.core.bz2 and test-core.exec.bz2. + * run-addrname-test.sh: New test for these files. + * run-unstrip-n.sh: Update expected output. New test for these files. + * test-core-lib.so.bz2: New file. + * test-core.core.bz2: New file. + * test-core.exec.bz2: New file. + +2013-05-03 Mark Wielaard + + * testfilenolines.bz2: New test file. + * Makefile.am (EXTRA_DIST): Add testfilenolines.bz2. + * run-get-lines.sh: Run testrun_compare on testfilenolines. + +2013-04-30 Jan Kratochvil + + * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf. + +2013-04-29 Mark Wielaard + + * test-subr.sh: Don't use pushd, just cd into test-dir. + (exit_cleanup): Don't use popd, just cd .. to get out. + +2013-04-27 Mark Wielaard + + * test-subr.sh (exit_cleanup): New function. + (trap): Use exit_cleanup as argument. + * run-native-test.sh (native_exit): New function. + (trap): For EXIT (0) use native_exit as argument. + +2013-04-27 Mark Wielaard + + * update1.c (main): Use unique tempfile name and unlink file. + * update2.c (main): Likewise. + * update3.c (main): Likewise. + * update4.c (main): Use unique tempfile name. + +2013-04-27 Mark Wielaard + + * run-alldts.sh: Add testfile-alldts to tempfiles. + * run-elf_cntl_gelf_getshdr.sh: Add test_shdr.out to tempfiles. + * run-macro-test.sh: Add readelf.macros.out to tempfiles. + * run-strip-reloc.sh: Add readelf.out, readelf.out1, readelf.out2 + and out.stripped1, out.debug1, out.stripped2, out.debug2 to tempfiles. + +2013-04-26 Mark Wielaard + + * Makefile.am (installed_TESTS_ENVIRONMENT): Export environment, + remove wrapper. + (TESTS_ENVIRONMENT): Likewise. + (installed_LOG_COMPILER): New variable defining wrapper. + (LOG_COMPILER): Likewise. + * run-*.sh: Fixup location of input and output files. + * test-subr.sh: Create test_dir, pushd to execute test in. + (trap): Remove test_dir. + (testfiles): Use abs_srcdir. + (installed_testrun): Match on abs_builddir or abs_top_builddir. + (self_test_files): Adjust path. + +2013-04-24 Mark Wielaard + + * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. + +2013-03-25 Mark Wielaard + + * run-readelf-aranges.sh: New test. + * testfilefoobarbaz.bz2: New test file. + * Makefile.am (TESTS): Add run-readelf-aranges.sh. + (EXTRA_DIST): Add run-readelf-aranges.sh and testfilefoobarbaz.bz2. + +2013-03-25 Mark Wielaard + + * run-readelf-dwz-multi.sh: Expect high_pc also as address. + +2013-03-20 Jan Kratochvil + + * Makefile.am (check_PROGRAMS): Add dwfl-report-elf-align. + (TESTS): Add run-dwfl-report-elf-align.sh. + (EXTRA_DIST): Add run-dwfl-report-elf-align.sh and + testfile-dwfl-report-elf-align-shlib.so.bz2 . + (dwfl_report_elf_align_LDADD): New. + * dwfl-report-elf-align.c: New file. + * run-dwfl-report-elf-align.sh: New file. + * testfile-dwfl-report-elf-align-shlib.so.bz2: New file. + +2013-03-12 Mark Wielaard + + * run-dwfllines.sh: New test. + * dwfllines.c: New test program. + * Makefile.am (TESTS): Add run-dwfllines.sh. + (EXTRA_DIST): Likewise. + (dwfllines_LDADD): New variable. + +2013-02-22 Mark Wielaard + + * Makefile.am (TESTS): Remove run-readelf-s.sh and run-dwflsyms.sh. + (LZMA): Add run-readelf-s.sh and run-dwflsyms.sh to TESTS. + +2013-02-15 Mark Wielaard + + * testfile-dwzstr.bz2: New testfile. + * testfile-dwzstr.multi.bz2: Likewise. + * run-readelf-dwz-multi.sh: Add readelf testfile-dwzstr test. + * Makefile.am (EXTRA_DIST): Add testfile-dwzstr.bz2 and + testfile-dwzstr.multi.bz2. + +2013-01-30 Mark Wielaard + + * testfileloc.bz2: New testfile. + * run-readelf-loc.sh: New test. + * Makefile.am (TESTS): Add run-readelf-loc.sh. + (EXTRA_DIST): Add run-readelf-loc.sh and testfileloc.bz2. + +2013-01-29 Jan Kratochvil + + * run-readelf-mixed-corenote.sh: New testcase for readelf -n of s390 + and s390x core notes. + * testfile67.bz2: New file. + * testfile68.bz2: New file. + * Makefile.am (EXTRA_DIST): Add testfile67.bz2 and testfile68.bz2 . + +2013-01-23 Mark Wielaard + + * testfilebasmin.bz2: New testfile. + * Makefile.am (EXTRA_DIST): Add testfilebasmin.bz2. + * run-readelf-s.sh: Test testfilebasmin. + * run-dwflsyms.sh: Likewise. + +2013-01-16 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add dwflsyms. + (TESTS): Add run-readelf-s.sh and run-dwflsyms.sh. + (EXTRA_DIST): Add run-readelf-s.sh, testfilebazdbg.bz2, + testfilebazdyn.bz2, testfilebazmin.bz2, testfilebazdbg.debug.bz2, + testfilebazmdb.bz2, testfilebaztab.bz2 and run-dwflsyms.sh. + (dwflsyms_LDADD): New variable. + +2013-01-07 Roland McGrath + + * run-prelink-addr-test.sh: Use ln -snf. + +2012-12-03 Mark Wielaard + + * Makefile.am (valgrind_cmd): Add --run-libc-freeres=no. + +2012-11-29 Jan Kratochvil + + * run-addrname-test.sh: New test for PIE relocation. + * testfile70.core.bz2: New file. + * testfile70.exec.bz2: New file. + * Makefile.am (EXTRA_DIST): Add testfile70.core.bz2 and + testfile70.exec.bz2 . + +2012-10-27 Jan Kratochvil + + * Makefile.am (EXTRA_DIST): Add testfile64.bz2, testfile65.bz2, + testfile69.core.bz2 and testfile69.so.bz2 . + +2012-10-17 Jan Kratochvil + + * run-addrname-test.sh: New test for DSO with build-id bias. + * testfile69.core.bz2: New file. + * testfile69.so.bz2: New file. + +2012-10-10 Jan Kratochvil + + * run-addrname-test.sh: New test for core vDSO bias. + * testfile65.bz2: New file. + +2012-10-10 Jan Kratochvil + + * run-addrname-test.sh: New test for symbol preferences. + * testfile64.bz2: New file. + +2012-10-01 Mark Wielaard + + * Makefile.am (TESTS_ENVIRONMENT): Define valgrind_cmd if USE_VALGRIND. + * test-wrapper.sh: Export VALGRIND_CMD if available. + * test-subr.sh (built_testrun): Use VALGRIND_CMD to invoke test prog. + (installed_testrun): Likewise. + +2012-09-24 Petr Machata + + * testfile63.bz2: New testfile. + * run-readelf-mixed-corenote.sh: New test. + * Makefile.am (TEST): Add run-readelf-mixed-corenote.sh. + (EXTRA_DIST): Add testfile63.bz2 and run-readelf-mixed-corenote.sh. + +2012-09-24 Petr Machata + + * testfile62.bz2: New testfile. + * run-readelf-vmcoreinfo.sh: New test. + * Makefile.am (TEST): Add run-readelf-vmcoreinfo.sh. + (EXTRA_DIST): Add testfile62.bz2 and run-readelf-vmcoreinfo.sh. + +2012-09-18 Petr Machata + + * testfile61.bz2: New testfile. + * run-allregs.sh: Run reg_test testfile61. + * Makefile.am (EXTRA_DIST): Add testfile61.bz2. + +2012-08-24 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add testfile60.bz2. + +2012-08-22 Jeff Kenton + + * testfile60.bz2: New testfile. + * run-allregs.sh: Run reg_test testfile60. + +2012-08-24 Mark Wielaard + + * Makefile.am (TESTS): Only add run-readelf-dwz-multi.sh if + ENABLE_DWZ. + +2012-08-16 Mark Wielaard + + * allregs.c (dwarf_encoding_string): Rewritten using known-dwarf + macros. + * show-die-info.c (tagnames): Removed. + (attrs): Removed. + (dwarf_tag_string): New function using known-dwarf macros. + (dwarf_attr_string): Likewise. + (handle): Call dwarf_tag_string and dwarf_attr_string instead. + * run-readelf-dwz-multi.sh: Expect language C89, not ISO C89. + +2012-06-27 Mark Wielaard + + * Makefile.am (TESTS): Add run-readelf-dwz-multi.sh. + (EXTRA_DIST): Add run-readelf-dwz-multi.sh, + libtestfile_multi_shared.so.bz2, testfile_multi.dwz.bz2 and + testfile_multi_main.bz2. + * run-readelf-dwz-multi.sh: New test. + * libtestfile_multi_shared.so.bz2: New testfile. + * testfile_multi.dwz.bz2: New testifle. + * testfile_multi_main.bz2: New testifle. + +2012-08-01 Petr Machata + + * run-test-archive64.sh: New test. + * testarchive64.a.bz2: New testfile. + * Makefile.am (TESTS): Add run-test-archive64.sh. + (EXTRA_DIST): Likewise. + +2012-08-01 Mark Wielaard + + * run-nm-self.sh: New test. + * run-readelf-self.sh: Likewise. + * test-subr.sh (testrun_on_self_quiet): New function. + * Makefile.am (TESTS): Add run-nm-self.sh and run-readelf-self.sh. + (EXTRA_DIST): Likewise. + +2012-08-01 Mark Wielaard + + * test-subr.sh (self_test_files): New list of files. + (testrun_on_self): New function. + * run-elflint-self.sh: Use testrun_on_self. + +2012-07-19 Mark Wielaard + + * Makefile.am (check_PROGRAMS): Add test-elf_cntl_gelf_getshdr. + (TESTS): Add run-elf_cntl_gelf_getshdr.sh. + (EXTRA_DIST): Likewise. + (test_elf_cntl_gelf_getshdr_LDADD): New. + test-elf_cntl_gelf_getshdr.c: New test program. + run-elf_cntl_gelf_getshdr.sh: New test script. + +2012-07-19 Mark Wielaard + + * run-elflint-self.sh: runtests on ../backends/*so files. + +2012-07-19 Mark Wielaard + + * run-unstrip-n.sh: test_cleanup. + * Makefile.am (EXTRA_DIST): Add testcore-rtlib-ppc.bz2. + +2012-07-11 Mark Wielaard + + * run-readelf-macro.sh: New test. + * testfilemacro.bz2: New testfile. + * Makefile.am (TESTS): Add run-readelf-macro.sh. + (EXTRA_DIST): Add run-readelf-macro.sh and testfilemacro.bz2. + +2012-06-27 Mark Wielaard + + * run-readelf-gdb-index.sh: New test. + * testfilegdbindex5.bz2: New testfile. + * testfilegdbindex7.bz2: Likewise. + * Makefile.am (TESTS): Add run-readelf-gdb-index.sh. + (EXTRA_DIST): run-readelf-gdb_index.sh, testfilegdbindex5.bz2 and + testfilegdbindex7.bz2. + +2012-07-17 Mark Wielaard + + * testcore-rtlib-ppc.bz2: New testfile. + * run-unstrip-n.sh: Check new ppc core testfile. + +2012-06-26 Mike Frysinger + + * Makefile.am (check_PROGRAMS): Rename from noinst_PROGRAMS. + +2012-06-26 Mark Wielaard + + * run-macro-test.sh: New test. + * testfile-macinfo.bz2: New testfile. + * testfile-macros.bz2: Likewise. + +2012-05-07 Mark Wielaard + + * low_high_pc.c: Use proper inttypes in printf formats. + +2012-05-11 Mark Wielaard + + * Makefile.am (TESTS_ENVIRONMENT): Set LC_ALL and LANG to C. + +2012-05-07 Mark Wielaard + + * low_high_pc.c: Allow highpc == lowpc for CU DIEs for buggy GCC. + +2012-04-27 Mark Wielaard + + * Makefile.am (TESTS): Add run-low_high_pc.sh + (EXTRA_DIST): Add run-low_high_pc.sh and testfile_low_high_pc.bz2 + (noinst_PROGRAMS): Add low_high_pc. + (low_high_pc_LDADD): New variable. + * low_high_pc.c: New test. + +2012-04-26 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Remove run-show-ciefde.sh. + * run-show-ciefde.sh: Removed old libdwarf test. + * show-ciefde.c: Likewise. + +2012-04-02 Mark Wielaard + + * Makefile.am (TESTS): Add run-unstrip-n.sh. + (EXTRA_DIST): Add testcore-rtlib.bz2 and run-unstrip-n.sh. + * run-unstrip-n.sh: New test. + * testcore-rtlib.bz2: New testfile. + +2012-04-02 Mark Wielaard + + * Makefile.am (TESTS): Add run-readelf-d.sh. + (EXTRA_DIST): Add testlib_dynseg.so.bz2 and run-readelf-d.sh. + * run-readelf-d.sh: New test. + * run-elflint-test.sh: Check new testfile. + +2012-03-21 Tom Tromey + + * typeiter.c: New file. + * run-typeiter.sh: New file. + * testfile59.bz2: New file. + * Makefile.am (noinst_PROGRAMS): Add typeiter. + (TESTS): Add run-typeiter.sh. + (EXTRA_DIST): Add run-typeiter.sh, testfile59.bz2. + (typeiter_LDADD): New variable. + +2012-02-21 Kurt Roeckx + + * run-alldts.sh: testrun ./alldts. + +2012-02-21 Roland McGrath + + * test-wrapper.sh: Add ${libdir}/elfutils to LD_LIBRARY_PATH. + * test-subr.sh (installed_testrun): Likewise. + +2012-01-18 Roland McGrath + + * asm-tst4.c (main): Don't set LD_LIBRARY_PATH in system invocation; + it will have been inherited correctly from the test harness. + * asm-tst5.c (main): Likewise. + * asm-tst6.c (main): Likewise. + Reported by Serge Pavlov . + +2011-07-09 Roland McGrath + + * sha1-tst.c: File removed. + * Makefile.am (noinst_PROGRAMS, TESTS): Remove it. + (sha1_tst_LDADD): Variable removed. + + * md5-sha1-test.c: New file. + * Makefile.am [!STANDALONE] (noinst_PROGRAMS, TESTS): Add it. + (md5_sha1_test_LDADD): New variable. + +2011-05-30 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add run-readelf-twofiles.sh and + run-rerequest_tag.sh + +2011-05-24 Mark Wielaard + + * Makefile.am (EXTRA_DIST): Add hello_s390.ko.bz2. + * run-strip-reloc.sh: Add hello_s390.ko testcase. + * hello_s390.ko.bz2: New test file. + +2011-05-23 Mark Wielaard + + * Makefile.am (TESTS): Add run-strip-reloc.sh. + (EXTRA_DIST): Add run-strip-reloc.sh, hello_i386.ko.bz2 + hello_x86_64.ko.bz2 and hello_ppc64.ko.bz2 + * run-strip-reloc.sh: New test. + * hello_i386.ko.bz2: New test file. + * hello_x86_64.ko.bz2: Likewise. + * hello_ppc64.ko.bz2: Likewise. + +2011-05-18 Mark Wielaard + + * run-strip-groups.sh: New test. + * testfile58.bz2: New test file. + * Makefile.am (EXTRA_DIST): Add testfile58.bz2. + (TESTS): Add run-strip-groups.sh. + (EXTRA_DIST): Likewise. + +2011-03-28 Marek Polacek + + * alldts.c: New file. + * run-alldts.sh: Use it. + * Makefile.am (TESTS, EXTRA_DIST, noinst_PROGRAMS): Add them. + (alldts_LDADD): New variable. + +2011-03-02 Marek Polacek + + * dwarf-getstring.c: New test. + * run-dwarf-getstring.sh: And its wrapper. + * Makefile.am (EXTRA_DIST): Add and update all. + +2011-02-27 Jan Kratochvil + + * Makefile.am (TESTS): Add run-readelf-twofiles.sh. + * run-readelf-twofiles.sh: New file. + +2011-02-25 Mark Wielaard + + * Makefile.am (BUILD_RPATH): Be consistent in naming. + +2011-02-02 Josh Stone + + * run-prelink-addr-test.sh: Add testfile55, 32 and 64-bit. + * testfile55-64.bz2, testfile55-64.debug.bz2, + testfile55-64.prelink.bz2, testfile55-32.bz2, + testfile55-32.debug.bz2, testfile55-32.prelink.bz2: New. + * Makefile.am (EXTRA_DIST): Add and update all. + +2011-01-12 Roland McGrath + + * run-prelink-addr-test.sh: Make symlinks to find .debug files + corresponding to .noshdrs files. + +2011-01-11 Josh Stone + + * run-prelink-addr-test.sh: Add testfile54, 32 and 64-bit. + * testfile54-32.so.bz2, testfile54-32.so.debug.bz2, + testfile54-32.prelink.so.bz2, testfile54-32.noshdrs.so.bz2, + testfile54-64.so.bz2, testfile54-64.so.debug.bz2, + testfile54-64.prelink.so.bz2, testfile54-64.noshdrs.so.bz2: New. + * Makefile.am (EXTRA_DIST): Add and update all. + + * run-prelink-addr-test.sh: Run 32 and 64-bit testfile53 tests. + * testfile53.bz2, testfile53.debug.bz2, + testfile53.prelink.bz2: Deleted, so... + * testfile53-64.bz2, testfile53-64.debug.bz2, + testfile53-64.prelink.bz2: Recreated with 64-bit names. + * testfile53-32.bz2, testfile53-32.debug.bz2, + testfile53-32.prelink.bz2: New in 32-bit. + * Makefile.am (EXTRA_DIST): Add and update all. + + * run-prelink-addr-test.sh: Run 32 and 64-bit testfile52 tests. + * testfile52.so.bz2, testfile52.so.debug.bz2, + testfile52.prelink.so.bz2: Deleted, so... + * testfile52-32.so.bz2, testfile52-32.so.debug.bz2, + testfile52-32.prelink.so.bz2: Recreated with 32-bit names. + * testfile52-32.noshdrs.so.bz2: New data file, stripped of headers. + * testfile52-64.so.bz2, testfile52-64.so.debug.bz2, + testfile52-64.prelink.so.bz2, testfile52-64.noshdrs.so.bz2: New files. + * Makefile.am (EXTRA_DIST): Add and update all. + +2011-01-10 Josh Stone + + * run-prelink-addr-test.sh: New test for prelinked addrs. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + * testfile52.so.bz2, testfile52.so.debug.bz2: New data files. + * testfile52.prelink.so.bz2: New data file, shows REL->RELA. + * testfile53.bz2, testfile53.debug.bz2: New data files. + * testfile53.prelink.bz2: New data file, shows ET_EXEC remap. + * Makefile.am (EXTRA_DIST): Add them. + +2010-06-04 Roland McGrath + + * run-unstrip-test.sh: Also test modifying the file in place. + +2010-04-22 Roland McGrath + + * addrcfi.c (handle_cfi): Fix function name in error message. + Use dwarf_errmsg, not dwfl_errmsg, after dwarf_cfi_addrframe. + +2010-04-14 Roland McGrath + + * Makefile.am (EXTRA_DIST): Add run-test-flag-nobits.sh here too. + +2010-04-10 Ulrich Drepper + + * msg_tst.c: Adjust expected error message. + +2010-04-01 Petr Machata + + * test-flag-nobits.c: New test. + * run-test-flag-nobits.sh: And its wrapper. + * Makefile.am (noinst_PROGRAMS, TESTS): Add them. + (test_flag_nobits_LDADD): New variable. + +2010-02-15 Roland McGrath + + * Makefile.am: Use config/eu.am for common stuff. + + * asm-tst9.c (main): Rename local to avoid shadowing another local. + +2009-07-22 Roland McGrath + + * addrcfi.c: Update dwarf_frame_{cfa,register} calling convention. + +2009-07-08 Roland McGrath + + * addrcfi.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (addrcfi_LDADD): New variable. + +2009-05-07 Petr Machata + + * testfile51.bz2: New data file. + * dwarf-getmacros.c: New test core. + * run-dwarf-getmacros.sh: New test wrapper. + * Makefile.am (TESTS, EXTRA_DIST, noinst_PROGRAMS): Add them. + (dwarf_getmacros_LDADD): New variable. + +2009-04-23 Ulrich Drepper + + * Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS). + (rdwrmmap_LDADD): Add $(libmudflap). + +2009-04-21 Roland McGrath + + * testfile50.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-dwfl-addr-sect.sh: Add a case using it. + +2008-12-31 Ulrich Drepper + + * testfile44.S.bz2: Add tests for dppd, dpps, insertps, movntdqa, + mpsadbw, packusdw, pblendvb, pblendw, pcmpeqq, pcmpestri, pcmpestrm, + pcmpistri, pcmpistrm, pcmpgtq, phminposuw, pinsrb, pinsrd, pmaxsb, + pmaxsd, pmaxud, pmaxuw, pminsb, pminsd, pminud, pminuw, pmovsxbw, + pmovsxbd, pmovsxbq, pmovsxwd, pmovsxwq, pmovsxdq, pmovsxbw, pmovsxbd, + pmovsxbq, pmovsxwd, pmovsxwq, pmovsxdq, pmuldq, pmulld, popcnt, ptest, + roundss, roundps, roundpd, and roundsd. + * testfile45.S.bz2: Likewise. + * testfile44.expect.bz2: Adjust accordingly. + * testfile45.expect.bz2: Likewise. + + * testfile44.S.bz2: Add tests for blendvpd and blendvps. + * testfile45.S.bz2: Likewise. + * testfile44.expect.bz2: Adjust accordingly. + * testfile45.expect.bz2: Likewise. + +2008-12-30 Ulrich Drepper + + * testfile44.S.bz2: Add tests for blendpd and blendps. + * testfile45.S.bz2: Likewise. + * testfile44.expect.bz2: Adjust accordingly. + * testfile45.expect.bz2: Likewise. + +2008-12-19 Ulrich Drepper + + * testfile44.S.bz2: Add tests for AMD 3DNOW. + * testfile45.S.bz2: Likewise. + * testfile44.expect.bz2: Adjust accordingly. + * testfile45.expect.bz2: Likewise. + +2008-11-26 Roland McGrath + + * dwfl-bug-getmodules.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (dwfl_bug_getmodules_LDADD): New variable. + +2008-09-10 Roland McGrath + + * test-subr.sh (LC_ALL): Export it set to "C". + * run-dwfl-addr-sect.sh: Don't do it here. + * run-strings-test.sh: Likewise. + +2008-08-21 Denys Vlasenko + + * run-addrname-test.sh: Add a new case. + * testfile49.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + +2008-04-10 Roland McGrath + + * testfile48.bz2, testfile48.bz2.debug: New data files. + * Makefile.am (EXTRA_DIST): Add them. + * run-strip-test8.sh: Use them. + + * testfile16.bz2, testfile16.debug.bz2: Replace data files. + + * run-strip-test.sh: Fail if stripped output has ".debug_*" sections. + * run-strip-test8.sh: New file. + * testfile47.bz2: New data file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2008-03-31 Roland McGrath + + * run-early-offscn.sh: New file. + * early-offscn.c: New file. + * Makefile.am (noinst_PROGRAMS, TESTS, EXTRA_DIST): Add them. + (early_offscn_LDADD): New variable. + +2008-03-19 Roland McGrath + + * run-addrname-test.sh: Add a new case. + +2008-02-22 Roland McGrath + + * run-elflint-test.sh: Typo fix. + +2008-02-21 Roland McGrath + + * run-disasm-x86.sh: Use uname instead of arch, keep tools required + for the build down to minimum. + * run-disasm-x86-64.sh: Likewise. + +2008-02-20 Roland McGrath + + * testfile46.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-elflint-test.sh: Test on it. + +2008-02-01 Ulrich Drepper + + * Makefile.am: Hook up sha1-tst.c. + * sha1-tst.c: New file. + +2008-01-21 Roland McGrath + + * testfile45.S.bz2: Add tests for cltq, cqto. + * testfile45.expect.bz2: Adjust. + +2008-01-14 Ulrich Drepper + + * testfile45.S.bz2: Add more tests. + * testfile45.expect.bz2: Adjust. + +2008-01-11 Ulrich Drepper + + * testfile45.expect.bz2: Adjust for adding of address for %rip based + address mode. + +2008-01-10 Ulrich Drepper + + * testfile45.S.bz2: Add more tests. + * testfile45.expect.bz2: Adjust. + +2008-01-08 Ulrich Drepper + + * Makefile.am (TESTS): Add run-disasm-x86-64.sh. + (EXTRA): Add testfile45.S.bz2, testfile45.expect.bz2, + run-disasm-x86-64.sh. + * run-disasm-x86-64.sh: New file. + * testfile45.S.bz2: New file. + * testfile45.expect.bz2: New file. + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2008-01-04 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2008-01-04 Roland McGrath + + * dwfl-bug-fd-leak.c (main): Add a cast. + +2008-01-03 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2008-01-01 Ulrich Drepper + + * line2addr.c: Use %m modifier instead of %a to appease gcc. + +2008-01-01 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2007-12-31 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2007-12-30 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2007-12-29 Ulrich Drepper + + * testfile44.s.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2007-12-28 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2007-12-27 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust. + +2007-12-26 Ulrich Drepper + + * testfile44.S.bz2: New tests. + * testfile44.expect.bz2: Adjust + +2007-12-21 Ulrich Drepper + + * testfile44.S.bz2: More tests. + * testfile44.expect.bz2: Adjust appropriately. + +2007-12-19 Ulrich Drepper + + * Makefile.am (TESTS): Add run-disasm.sh. + (EXTRA_DIST): Add run-disasm.sh, testfile44.S.bz2, and + testfile44.expect.bz2. + * run-disasm.sh: New file. + * testfile44.S.bz2: New file. + * testfile44.expect.bz2: New file. + +2007-12-15 Roland McGrath + + * run-allregs.sh: Change expected output for powerpc spefscr. + +2007-10-20 Roland McGrath + + * run-dwfl-addr-sect.sh: Change expected output, no errors. + +2007-10-19 Roland McGrath + + * dwfl-addr-sect.c (handle_address): Return int. + Don't exit on error, just return nonzero. + (main): Collect results. + * run-dwfl-addr-sect.sh: New file. + * testfile43.bz2: New data file. + * Makefile.am (EXTRA_DIST, TESTS): Add them. + +2007-10-18 Roland McGrath + + * run-allregs.sh: Update expected ppc output for vrsave/vscr. + +2007-10-16 Roland McGrath + + * test-subr.sh (remove_files): Don't pass -Bb to diff. + +2007-10-09 Roland McGrath + + * dwflmodtest.c (print_module): Don't use %p in output. + * run-dwfl-bug-offline-rel.sh: Updated expected output. + +2007-10-08 Roland McGrath + + * testfile42.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-elflint-test.sh: New test on that file. + +2007-10-04 Roland McGrath + + * run-readelf-test4.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + +2007-10-03 Roland McGrath + + * run-readelf-test3.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + +2007-10-01 Roland McGrath + + * run-readelf-test2.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + +2007-09-11 Roland McGrath + + * run-addrname-test.sh: Add a new case. + * testfile41.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + +2007-08-23 Roland McGrath + + * run-allregs.sh: Update expected x86-64 output for %rflags. + +2007-08-12 Roland McGrath + + * run-strip-test7.sh: New file. + * testfile39.bz2: New data file. + * testfile40.bz2: New data file. + * testfile40.debug.bz2: New data file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2007-08-09 Roland McGrath + + * dwfl-bug-report.c: Fix header inclusion. + +2007-08-08 Roland McGrath + + * run-addrname-test.sh: Add a new case using addr2line -S. + * testfile38.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + +2007-07-16 Roland McGrath + + * dwfl-bug-report.c: New file. + * Makefile.am (noinst_PROGRAMS, TESTS): Add it. + (dwfl_bug_report_LDADD): New variable. + +2007-06-06 Roland McGrath + + * run-unstrip-test.sh: Declare testfile.unstrip for removal. + +2007-06-05 Ulrich Drepper + + * Makefile.am (EXTRA_DIST): Add missing line continuation and + testfile37.bz and testfile37.debug.bz2. + +2007-05-23 Roland McGrath + + * run-allregs.sh: Update expected Alpha results. + +2007-05-18 Roland McGrath + + * run-strip-test4.sh (stripped, debugfile): Use new reference files. + * testfile37.bz2: New data file. + * testfile37.debug.bz2: New data file. + * run-unstrip-test2.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2007-05-10 Roland McGrath + + * run-dwfl-bug-offline-rel.sh: New file. + * testfile36.bz2: New data file. + * testfile36.debug.bz2: New data file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2007-04-28 Roland McGrath + + * run-strip-test6.sh (stripped, debugfile): Use new reference files. + * testfile35.bz2: New data file. + * testfile35.debug.bz2: New data file. + * run-unstrip-test.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + + * run-strip-test.sh: Do all elflint and cmp runs even when some fail. + +2007-04-26 Roland McGrath + + * run-elflint-self.sh: Run all tests even if one fails. + + * run-allregs.sh: Add expected output for alpha. + +2007-04-24 Roland McGrath + + * run-strip-test.sh: When we saved the debug info, test unstrip too. + +2007-04-22 Roland McGrath + + * run-allregs.sh: Update expected register info. + +2007-04-16 Roland McGrath + + * dwfl-addr-sect.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (dwfl_addr_sect_LDADD): New variable. + +2007-04-05 Roland McGrath + + * get-files.c: Test dwarf_getsrcdirs. + * run-get-files.sh: Update expected output. + +2007-04-01 Roland McGrath + + * run-allregs.sh: Updated expected output for x86_64. + +2007-03-04 Roland McGrath + + * dwfl-bug-fd-leak.c: New file. + * Makefile.am (noinst_PROGRAMS, TESTS): Add it. + (dwfl_bug_fd_leak_LDADD): New variable. + + * dwflmodtest.c: Test dwfl_getmodules before and after getdwarf, + show what files have been located. + +2007-02-02 Roland McGrath + + * run-addrname-test.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + * testfile34.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + +2007-01-20 Roland McGrath + + * testfile33.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-elflint-test.sh: Test on it too. + +2007-01-18 Roland McGrath + + * Makefile.am (CFLAGS): Don't molest it. + +2007-01-11 Roland McGrath + + * testfile32.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-elflint-test.sh: Test on it too. + +2007-02-04 Ulrich Drepper + + * arls.c: New file. + * Makefile (noinst_PROGRAMS): Add arls. + + * run-ranlib-test2.sh: Fix type in comment. + +2007-01-10 Ulrich Drepper + + * run-elflint-self.sh (runtest): Show which file has the problem. + +2007-01-10 Roland McGrath + + * dwfl-bug-addr-overflow.c: New file. + * Makefile.am (TESTS): Add it. + (dwfl_bug_addr_overflow_LDADD): New variable. + +2006-12-17 Roland McGrath + + * msg_tst.c (libelf_msgs): Fix ELF_E_INVALID_PHDR msg. + +2006-09-05 Roland McGrath + + * run-strings-test.sh: Export LC_ALL=C for the test. + +2006-08-29 Roland McGrath + + * run-arextract.sh: Use testrun, tempfiles functions from test-subr.sh. + * run-arsymtest.sh: Likewise. + + * run-native-test.sh (native.c compilation): Add some braces. + +2006-08-22 Roland McGrath + + * allregs.c (dwarf_encoding_string): New function, swiped from readelf. + (struct reginfo): New members bits, type. + (one_register, match_register): Update to take new args, + record and display new info. + (main): Display new info. + * run-allregs.sh: Update expected results. + +2006-08-03 Roland McGrath + + * run-allregs.sh: Add sparc cases. + * testfile30.bz2: New data file. + * testfile31.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add them. + +2006-07-21 Roland McGrath + + * allregs.c (struct reginfo): Increase size of name. + (one_register): Assert that it's big enough. + +2006-04-04 Roland McGrath + + * run-bug1-test.sh: Test a second case, to cover both byte orders. + * testfile29.bz2: New file. + * testfile29.rdwr.bz2: New file. + * Makefile.am (EXTRA_DIST): Add them. + +2006-04-04 Ulrich Drepper + + * Makefile.am: Add rules to run run-bug1-test.sh. + * rdwrmmap.c: New file. + * run-bug1-test.sh: New file. + * testfile28.bz2: New file. + * testfile28.rdwr.bz2: New file. + +2006-03-09 Roland McGrath + + * Makefile.am (AM_LDFLAGS): Define to pass -rpath-link. + +2006-03-01 Roland McGrath + + * show-die-info.c (tagnames, attrs): Update name tables for dwarf.h + changes matching 3.0 spec. + +2006-01-13 Roland McGrath + + * run-native-test.sh: Do kill -9 and reap explicitly at end, since + bash 3.1 whines when it's done in the trap 0 handler. + +2006-01-11 Roland McGrath + + * testfile26.bz2: New data file. + * testfile27.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add them. + * run-allregs.sh: Test s390 data. + +2005-12-14 Roland McGrath + + * run-native-test.sh: Redirect output from native test process. + +2005-12-13 Roland McGrath + + * allregs.c (main): Fail if we find no registers. + + * run-native-test.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + +2005-12-10 Ulrich Drepper + + * ecp.c (main): Use elf_end to clean up. + +2005-11-25 Roland McGrath + + * coverage.sh: Given -v argument, print names of unused files. + + * addrscopes.c (main): Use dwfl_end before return. + * allregs.c (main): Likewise. + * find-prologues.c (main): Likewise. + * funcretval.c (main): Likewise. + * funcscopes.c (main): Likewise. + * line2addr.c (main): Likewise. + + * run-allregs.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + + * allregs.c: Use libdwfl wrapper instead of direct libebl calls. + * Makefile.am (allregs_LDADD): Updated. + + * allregs.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (allregs_LDADD): New variable. + +2005-11-18 Roland McGrath + + * test-subr.sh (installed_testrun): Treat /usr/lib64 like /usr/lib. + * test-wrapper.sh: Likewise. + +2005-11-17 Roland McGrath + + * Makefile.am (installed_TESTS_ENVIRONMENT): Set libdir, bindir in + environment for test-wrapper.sh. + * test-wrapper.sh: Set LD_LIBRARY_PATH from ${libdir} if not /usr/lib. + * test-subr.sh (installed_testrun): Likewise. + Use explicit path in ${bindir}. + + * Makefile.am (installcheck-local): Fix typo in last change. + +2005-11-16 Roland McGrath + + * configure.ac: New file, for standalone build/dist of test suite. + * Makefile.am [!STANDALONE] (INCLUDES): Don't define it. + (asm_TESTS): New variable, broken out of ... + (TESTS): ... here. Also remove msg_tst. + [!STANDALONE] (TESTS, noinst_PROGRAMS): Add in $(asm_TESTS), msg_tst. + (installed_TESTS_ENVIRONMENT): New variable. + [STANDALONE] (TESTS_ENVIRONMENT): Use that. + [!STANDALONE] (installcheck-local): Likewise. + [STANDALONE] (libdw, libelf, libasm, libebl): Define using -lfoo. + * addrscopes.c: Include . + Use ELFUTILS_HEADER macro in #include of installed elfutils/ headers. + * allfcts.c: Likewise. + * asm-tst1.c: Likewise. + * asm-tst2.c: Likewise. + * asm-tst3.c: Likewise. + * asm-tst4.c: Likewise. + * asm-tst5.c: Likewise. + * asm-tst6.c: Likewise. + * asm-tst7.c: Likewise. + * asm-tst8.c: Likewise. + * asm-tst9.c: Likewise. + * dwflmodtest.c: Likewise. + * find-prologues.c: Likewise. + * funcscopes.c: Likewise. + * get-aranges.c: Likewise. + * get-files.c: Likewise. + * get-lines.c: Likewise. + * get-pubnames.c: Likewise. + * line2addr.c: Likewise. + * newscn.c: Likewise. + * show-abbrev.c: Likewise. + * show-die-info.c: Likewise. + * update3.c: Likewise. + * update4.c: Likewise. + * funcretval.c: Likewise. + + * dwflmodtest.c (print_instance): Don't use INTUSE. + (options): Don't use N_ macro. + +2005-11-15 Roland McGrath + + * coverage.sh: Look in backends. + * Makefile.am (BUILD_RPATH): Search ../backends, not ../libebl. + (TESTS_ENVIRONMENT): Likewise. + + * funcretval.c (handle_function): Don't take DW_AT_type of FUNCDIE, + pass FUNCDIE direclty to dwfl_module_return_value_location. + + * Makefile.am (BUILD_RPATH): New variable. + [TESTS_RPATH] (AM_LDFLAGS): Pass -rpath option using that value. + (tests_rpath): New variable. + (installcheck-local): Pass it to test-wrapper.sh. + * test-wrapper.sh: In "installed" format, take yes/no value + for elfutils_tests_rpath, which export. When running a test + binary for installcheck, exit 77. + * test-subr.sh (installed_testrun): When running a test binary + for installcheck, exit 77 if $elfutils_tests_rpath = yes. + +2005-11-14 Roland McGrath + + * test-subr.sh: New file. + * test-wrapper.sh: New file. + * Makefile.am (EXTRA_DIST): Add them. + (AM_LDFLAGS): Variable removed. + (TESTS_ENVIRONMENT): New variable. + (installcheck-local): New target. + * run-addrscopes.sh: Use test-subr.sh. + * run-allfcts.sh: Likewise. + * run-ecp-test.sh: Likewise. + * run-ecp-test2.sh: Likewise. + * run-elflint-self.sh: Likewise. + * run-elflint-test.sh: Likewise. + * run-find-prologues.sh: Likewise. + * run-funcscopes.sh: Likewise. + * run-get-aranges.sh: Likewise. + * run-get-files.sh: Likewise. + * run-get-lines.sh: Likewise. + * run-get-pubnames.sh: Likewise. + * run-line2addr.sh: Likewise. + * run-ranlib-test.sh: Likewise. + * run-ranlib-test2.sh: Likewise. + * run-show-abbrev.sh: Likewise. + * run-show-ciefde.sh: Likewise. + * run-show-die-info.sh: Likewise. + * run-strings-test.sh: Likewise. + * run-strip-test.sh: Likewise. + +2005-11-13 Roland McGrath + + * funcretval.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (funcretval_LDADD): New variable. + +2005-11-09 Ulrich Drepper + + * line2addr.c (handle_module): Add missing parameter to printf. + +2005-10-27 Roland McGrath + + * allfcts.c (cb): Update for dwarf_func_* -> dwarf_decl_* changes. + * funcscopes.c (handle_function): Likewise. + * dwflmodtest.c (print_inline, print_func): Likewise. + * find-prologues.c (handle_function): Likewise. + +2005-10-27 Roland McGrath + + * run-find-prologues.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + + * find-prologues.c (handle_function): Skip inlines. + +2005-10-25 Roland McGrath + + * find-prologues.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (find_prologues_LDADD): New variable. + +2005-09-02 Ulrich Drepper + + * run-strings-test.sh: Remove strings.out in the end. + +2005-08-31 Ulrich Drepper + + * run-addrscopes.sh: Use correct exit code if test cannot be performed. + * run-allfcts.sh: Likewise. + * run-ecp-test.sh: Likewise. + * run-ecp-test2.sh: Likewise. + * run-elflint-test.sh: Likewise. + * run-funcscopes.sh: Likewise. + * run-get-aranges.sh: Likewise. + * run-get-files.sh: Likewise. + * run-get-lines.sh: Likewise. + * run-get-pubnames.sh: Likewise. + * run-line2addr.sh: Likewise. + * run-ranlib-test2.sh: Likewise. + * run-show-abbrev.sh: Likewise. + * run-show-ciefde.sh: Likewise. + * run-show-die-info.sh: Likewise. + * run-strings-test.sh: Likewise. + * run-strip-test.sh: Likewise. + +2005-08-30 Ulrich Drepper + + * coverage.sh: Handle case where there is no .gcno file at all. + +2005-08-29 Ulrich Drepper + + * Makefile.am (EXTRA_DIST): Add coverage. + [GCOV]: Generate coverage summary after the tests ran + * coverage.sh: New file. + +2005-08-28 Ulrich Drepper + + * Makefile.an [BUILD_STATIC] (libdw): Add -ldl. + (CLEANFILES): Add *.gcno *.gcda *.gconv. + +2005-08-28 Ulrich Drepper + + * run-strings-test.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + +2005-08-27 Roland McGrath + + * addrscopes.c (handle_address): Apply bias to PC addresses. + + * run-funcscopes.sh: New file. + * testfile25.bz2: New data file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2005-08-26 Roland McGrath + + * addrscopes.c (dwarf_diename_integrate): Removed. + (print_vars, handle_address): Use plain dwarf_diename. + +2005-08-25 Roland McGrath + + * funcscopes.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (funcscopes_LDADD): New variable. + + * run-addrscopes.sh: Add another case. + * testfile24.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + + * addrscopes.c (handle_address): Take new argument IGNORE_INLINES, + pass it to dwarf_getscopes. + (main): Pass it, true when '=' follows an address. + +2005-08-24 Roland McGrath + + * line2addr.c (print_address): Omit () for DSOs. + +2005-08-24 Ulrich Drepper + + * run-line2addr.sh: Remove testfile23 in the end. + + * Makefile.am [BUILD_STATIC] (libdw): Add $(libelf) and $(libebl). + [MUDFLAP] (AM_LDFLAGS): Define to find libebl modules. + +2005-08-22 Roland McGrath + + * run-line2addr.sh: Add a case. + * testfile23.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + +2005-08-18 Roland McGrath + + * run-addrscopes.sh: New file. + * testfile22.bz2: New data file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + + * addrscopes.c: New file. + * Makefile.am (noinst_PROGRAMS): Add it. + (addrscopes_LDADD): New variable. + +2005-08-15 Ulrich Drepper + + * run-elflint-self.sh: Don't run test if the file doesn't exist. + +2005-08-15 Roland McGrath + + * dwflmodtest.c (print_instance, print_inline): New functions. + (print_func): Call print_inline. + (options, parse_opt): Grok -i/--inlines. + +2005-08-07 Roland McGrath + + * dwflmodtest.c: Print function details only if -f flag is given. + +2005-08-06 Ulrich Drepper + + * run-elflint-self.sh: New file. + * Makefile.am (TESTS): Add run-elflint-self.sh. + (EXTRA_DIST): Likewise. + + * Makefile.am: Link with statis libs if BUILD_STATIC. + (dwflmodtest_LDADD): Also link with -ldl. + +2005-08-02 Ulrich Drepper + + * Makefile.am: Add -ldl to asm_tst[1-9]_LDASS. + * asm-tst1.c: Adjust for new asm_begin interface. Open backend + library first. + * asm-tst2.c: Likewise. + * asm-tst3.c: Likewise. + * asm-tst4.c: Likewise. + * asm-tst5.c: Likewise. + * asm-tst6.c: Likewise. + * asm-tst7.c: Likewise. + * asm-tst8.c: Likewise. + * asm-tst9.c: Likewise. + + * msg_tst.c: Add new error message. + +2005-07-28 Ulrich Drepper + + * Makefile.am (dwflmodtest_LDADD): Add $(libebl). + +2005-06-01 Roland McGrath + + * line2addr.c: Rewritten using libdwfl. + * run-line2addr.sh: Update test for changed arguments. + * Makefile.am (INCLUDES): Add libdwfl source directory to path. + (libdwfl): New variable. + (line2addr_LDADD): Use it. + +2005-07-28 Roland McGrath + + * dwflmodtest.c: New file, moved from ../libdwfl/ptest.c to here. + * Makefile.am (noinst_PROGRAMS): Add dwflmodtest. + (dwflmodtest_LDADD): New variable. + (INCLUDES): Add -I$(top_srcdir)/libdwfl here. + +2005-07-21 Ulrich Drepper + + * testfile18.bz2: New file. + * run-elflint-test.sh: New file. + * Makefile.am (TESTS): Add run-elflint-test.sh. + (EXTRA_DIST): Add run-elflint-test.sh and testfile18.bz2. + +2005-05-24 Ulrich Drepper + + * get-files.c (main): Use correct format specifier. + +2005-05-21 Ulrich Drepper + + * Makefile.am: Add -Wextra to CFLAGS. + * get-files.c: Remove warning this produced. + * get-pubnames.c: Likewise. + * newfile.c: Likewise. + * newscn.c: Likewise. + * scnnames.c: Likewise. + * showptable.c: Likewise. + * test-nlist.c: Likewise. + * update1.c: Likewise. + * update2.c: Likewise. + * update3.c: Likewise. + * update4.c: Likewise. + +2005-05-08 Ulrich Drepper + + * run-line2addr.sh: Remove testfile14 at the end. + + * run-strip-test.sh: Remove debuginfo test input file as well. + + * Makefile.am (EXTRA_DIST): Newly added files incorrectly used + .bz, not .bz2. + +2005-05-03 Roland McGrath + + * run-strip-test.sh: Use variables for test file names. + Optionally produce separate debug file and check it. + * run-strip-test2.sh: Use run-strip-test.sh via ., no duplication. + * run-strip-test3.sh: Likewise. + * run-strip-test4.sh: New file. + * run-strip-test5.sh: New file. + * run-strip-test6.sh: New file. + * testfile15.bz: New file. + * testfile15.debug.bz: New file. + * testfile16.bz: New file. + * testfile16.debug.bz: New file. + * testfile17.bz: New file. + * testfile17.debug.bz: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add them. + +2005-04-25 Ulrich Drepper + + * run-line2addr.sh: Also use testfile14. Adjust for correct + return of multiple matches. + * testfile14.bz2: New file. + * Makefile.am (EXTRA_DIST): Add testfile14.bz2. + + * show-abbrev.c (main): Adjust for dwarf_getabbrev interface change. + +2005-04-04 Roland McGrath + + * line2addr.c (main): Initialize LINES and NLINES before calling + dwarf_getsrc_file, and free LINES afterwards. + + * allfcts.c (main): Use size_t for CUHL. + +2005-04-04 Ulrich Drepper + + * line2addr.c: New file. + * run-line2addr.sh: New file. + * Makefile.am: Add rules to build, run, and distribute new code. + +2005-04-02 Ulrich Drepper + + * allfcts.c: New file. + * run-allfcts.sh: New file. + * Makefile.am: Add rules to build, run, and distribute new code. + +2005-02-05 Ulrich Drepper + + * Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fmudflap. Link all test + programs with -lmudflap. + +2004-09-25 Ulrich Drepper + + * asm-tst4.c (main): Add LD_LIBRARY_PATH to elflint invocation. + * asm-tst5.c (main): Likewise. + * asm-tst6.c (main): Likewise. + +2004-01-17 Ulrich Drepper + + * Makefile.am: Support building with mudflap. + +2004-01-12 Ulrich Drepper + + * get-aranges.c: Rewrite to use libdw. + * Makefile.am: Reenable get-aranges test. + +2004-01-11 Ulrich Drepper + + * get-lines.c: New file. + * get-files.c: Adjust for libdw. + * run-get-files.sh: Adjust expected result. + * run-get-lines.sh: Likewise. + * Makefile.am: Run get-lines test. Don't run get-aranges and + get-ciefde test for now. + + * show-abbrev.c: Adjust call to dwarf_getabbrevattr after interface + change. Print attribute offset information. + * run-show-abbrev.sh: Adjust expected output. + +2004-01-09 Ulrich Drepper + + * show-abbrev.c: Adjust call to dwarf_nextcu after interface change. + * show-die-info.c: Likewise. + * run-show-die-info.sh: Adjust expected output. + +2003-08-13 Ulrich Drepper + + * Makefile.in: Depend on libebl.a, not libebl.so. + +2003-08-11 Ulrich Drepper + + * Moved to CVS archive. diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 00000000..dc7517d9 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,703 @@ +## Process this file with automake to create Makefile.in +## +## Copyright (C) 1996-2019 Red Hat, Inc. +## This file is part of elfutils. +## +## 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 3 of the License, or +## (at your option) any later version. +## +## elfutils 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, see . +## +include $(top_srcdir)/config/eu.am +BUILD_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../backends:\$$ORIGIN/../libelf + +AM_CPPFLAGS += -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \ + -I$(top_srcdir)/libdwfl -I$(top_srcdir)/libdwelf \ + -I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \ + -I$(top_srcdir)/lib -I.. +AM_LDFLAGS = -Wl,-rpath-link,../libasm:../libdw:../libelf + +if TESTS_RPATH +AM_LDFLAGS += -Wl,-rpath,$(BUILD_RPATH) +tests_rpath = yes +else +tests_rpath = no +endif + +check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ + showptable update1 update2 update3 update4 test-nlist \ + show-die-info get-files next-files get-lines next-lines \ + get-pubnames \ + get-aranges allfcts line2addr addrscopes funcscopes \ + show-abbrev hash newscn ecp dwflmodtest \ + find-prologues funcretval allregs rdwrmmap \ + dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \ + dwfl-addr-sect dwfl-bug-report early-offscn \ + dwfl-bug-getmodules dwarf-getmacros dwarf-ranges addrcfi \ + dwarfcfi \ + test-flag-nobits dwarf-getstring rerequest_tag \ + alldts typeiter typeiter2 low_high_pc \ + test-elf_cntl_gelf_getshdr dwflsyms dwfllines \ + dwfl-report-elf-align dwfl-report-segment-contiguous \ + varlocs backtrace backtrace-child \ + backtrace-data backtrace-dwarf debuglink debugaltlink \ + buildid deleted deleted-lib.so aggregate_size peel_type \ + vdsosyms \ + getsrc_die strptr newdata elfstrtab dwfl-proc-attach \ + elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr \ + elfgetzdata elfputzdata zstrptr emptyfile vendorelf \ + fillfile dwarf_default_lower_bound dwarf-die-addr-die \ + get-units-invalid get-units-split attr-integrate-skel \ + all-dwarf-ranges unit-info next_cfi \ + elfcopy addsections xlate_notes elfrdwrnop \ + dwelf_elf_e_machine_string \ + getphdrnum leb128 read_unaligned \ + msg_tst system-elf-libelf-test \ + $(asm_TESTS) + +asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ + asm-tst6 asm-tst7 asm-tst8 asm-tst9 + +if BIARCH +check_PROGRAMS += backtrace-child-biarch +endif + +# Substitute $(COMPILE). +backtrace-child-biarch$(EXEEXT): backtrace-child.c + $(AM_V_CC)$(CC_BIARCH) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) $(backtrace_child_CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) $(backtrace_child_LDFLAGS) \ + -o $@ $< + +if GCOV +GCOV_FLAGS=-fprofile-arcs -ftest-coverage +else +GCOV_FLAGS= +endif + +# test_nlist checks its own symbol table, and expects various symbols +# to be in the order as specified in the source file. Explicitly set +# minimal CFLAGS +test-nlist$(EXEEXT): test-nlist.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(test_nlist_CFLAGS) $(GCOV_FLAGS) -o $@ $< $(test_nlist_LDADD) + +TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ + update1 update2 update3 update4 \ + run-show-die-info.sh run-get-files.sh run-get-lines.sh \ + run-next-files.sh run-next-lines.sh \ + run-get-pubnames.sh run-get-aranges.sh run-allfcts.sh \ + run-show-abbrev.sh run-line2addr.sh hash \ + run-large-elf-file.sh \ + newscn run-strip-test.sh run-strip-test2.sh \ + run-strip-test3.sh run-strip-test4.sh run-strip-test5.sh \ + run-strip-test6.sh run-strip-test7.sh run-strip-test8.sh \ + run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \ + run-strip-test12.sh \ + run-strip-nothing.sh run-strip-g.sh run-annobingroup.sh \ + run-strip-groups.sh run-strip-reloc.sh run-strip-strmerge.sh \ + run-strip-nobitsalign.sh run-strip-remove-keep.sh \ + run-unstrip-test.sh run-unstrip-test2.sh run-unstrip-test3.sh \ + run-unstrip-test4.sh run-unstrip-M.sh run-elfstrmerge-test.sh \ + run-ecp-test.sh run-ecp-test2.sh run-alldts.sh \ + run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \ + run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \ + run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ + run-find-prologues.sh run-allregs.sh run-addrcfi.sh \ + run-dwarfcfi.sh run-nm-syms.sh \ + run-nm-self.sh run-readelf-self.sh run-readelf-info-plus.sh \ + run-readelf-compressed.sh \ + run-readelf-const-values.sh \ + run-varlocs-self.sh run-exprlocs-self.sh \ + run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \ + run-readelf-test4.sh run-readelf-twofiles.sh \ + run-readelf-macro.sh run-readelf-loc.sh run-readelf-ranges.sh \ + run-readelf-aranges.sh run-readelf-line.sh run-readelf-z.sh \ + run-readelf-frames.sh \ + run-readelf-n.sh \ + run-retain.sh \ + run-native-test.sh run-bug1-test.sh \ + run-debuglink.sh run-debugaltlink.sh run-buildid.sh \ + dwfl-bug-addr-overflow run-addrname-test.sh \ + dwfl-bug-fd-leak dwfl-bug-report dwfl-report-segment-contiguous \ + run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \ + run-disasm-x86.sh run-disasm-x86-64.sh \ + run-early-offscn.sh run-dwarf-getmacros.sh run-dwarf-ranges.sh \ + run-test-flag-nobits.sh run-prelink-addr-test.sh \ + run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \ + run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \ + run-low_high_pc.sh run-macro-test.sh run-elf_cntl_gelf_getshdr.sh \ + run-test-archive64.sh run-readelf-vmcoreinfo.sh \ + run-readelf-mixed-corenote.sh run-dwfllines.sh \ + run-readelf-variant.sh \ + run-dwfl-report-elf-align.sh run-addr2line-test.sh \ + run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \ + run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ + run-varlocs.sh run-exprlocs.sh run-funcretval.sh \ + run-backtrace-native.sh run-backtrace-data.sh run-backtrace-dwarf.sh \ + run-backtrace-native-biarch.sh run-backtrace-native-core.sh \ + run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \ + run-backtrace-fp-core-x86_64.sh \ + run-backtrace-fp-core-aarch64.sh \ + run-backtrace-fp-core-ppc64le.sh \ + run-backtrace-core-x32.sh \ + run-backtrace-core-i386.sh run-backtrace-fp-core-i386.sh \ + run-backtrace-core-ppc.sh \ + run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \ + run-backtrace-core-aarch64.sh run-backtrace-core-sparc.sh \ + run-backtrace-demangle.sh run-stack-d-test.sh run-stack-i-test.sh \ + run-stack-demangled-test.sh run-readelf-zx.sh run-readelf-zp.sh \ + run-readelf-addr.sh run-readelf-str.sh \ + run-readelf-types.sh \ + run-readelf-dwz-multi.sh run-allfcts-multi.sh run-deleted.sh \ + run-linkmap-cut.sh run-aggregate-size.sh run-peel-type.sh \ + vdsosyms run-readelf-A.sh \ + run-getsrc-die.sh run-strptr.sh newdata elfstrtab dwfl-proc-attach \ + elfshphehdr run-lfs-symbols.sh run-dwelfgnucompressed.sh \ + run-elfgetchdr.sh \ + run-elfgetzdata.sh run-elfputzdata.sh run-zstrptr.sh \ + run-compress-test.sh \ + run-readelf-zdebug.sh run-readelf-zdebug-rel.sh \ + emptyfile vendorelf fillfile dwarf_default_lower_bound \ + run-dwarf-die-addr-die.sh \ + run-get-units-invalid.sh run-get-units-split.sh \ + run-attr-integrate-skel.sh \ + run-all-dwarf-ranges.sh run-unit-info.sh \ + run-reloc-bpf.sh \ + run-next-cfi.sh run-next-cfi-self.sh \ + run-reverse-sections.sh run-reverse-sections-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ + run-strip-version.sh run-xlate-note.sh \ + run-readelf-discr.sh \ + run-dwelf_elf_e_machine_string.sh \ + run-elfclassify.sh run-elfclassify-self.sh \ + run-disasm-riscv64.sh \ + run-pt_gnu_prop-tests.sh \ + run-getphdrnum.sh run-test-includes.sh \ + leb128 read_unaligned \ + msg_tst system-elf-libelf-test \ + $(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \ + run-readelf-dw-form-indirect.sh + +if !BIARCH +export ELFUTILS_DISABLE_BIARCH = 1 +endif + +if !DEMANGLE +export ELFUTILS_DISABLE_DEMANGLE = 1 +endif + +if LZMA +TESTS += run-readelf-s.sh run-dwflsyms.sh +endif + +if HAVE_ZSTD +TESTS += run-readelf-compressed-zstd.sh +endif + +if DEBUGINFOD +check_PROGRAMS += debuginfod_build_id_find +# With the dummy delegation doesn't work +if !DUMMY_LIBDEBUGINFOD +TESTS += run-debuginfod-find.sh +endif +endif + +EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ + run-show-die-info.sh run-get-files.sh run-get-lines.sh \ + run-next-files.sh run-next-lines.sh testfile-only-debug-line.bz2 \ + run-get-pubnames.sh run-get-aranges.sh \ + run-show-abbrev.sh run-strip-test.sh \ + run-strip-test2.sh run-ecp-test.sh run-ecp-test2.sh \ + testfile.bz2 testfile2.bz2 testfile3.bz2 testfile4.bz2 \ + testfile5.bz2 testfile6.bz2 testfile7.bz2 testfile8.bz2 \ + testfile9.bz2 testfile10.bz2 testfile11.bz2 testfile12.bz2 \ + testfile13.bz2 run-strip-test3.sh run-allfcts.sh \ + testfile_class_func.bz2 testfile_nested_funcs.bz2 \ + testfile-lto-gcc10.bz2 \ + testfile-lto-gcc9.bz2 testfile-lto-gcc8.bz2 \ + run-line2addr.sh run-elflint-test.sh testfile14.bz2 \ + run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \ + run-strip-test7.sh run-strip-test8.sh run-strip-groups.sh \ + run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \ + run-strip-test12.sh \ + run-strip-nothing.sh run-strip-remove-keep.sh run-strip-g.sh \ + run-annobingroup.sh testfile-annobingroup.o.bz2 \ + testfile-annobingroup-i386.o.bz2 \ + testfile-annobingroup-x86_64.o.bz2 \ + run-strip-strmerge.sh run-strip-nobitsalign.sh \ + testfile-nobitsalign.bz2 testfile-nobitsalign.strip.bz2 \ + run-strip-reloc.sh hello_i386.ko.bz2 hello_x86_64.ko.bz2 \ + hello_ppc64.ko.bz2 hello_s390.ko.bz2 hello_aarch64.ko.bz2 \ + hello_m68k.ko.bz2 hello_riscv64.ko.bz2 hello_csky.ko.bz2 \ + run-unstrip-test.sh run-unstrip-test2.sh \ + testfile-info-link.bz2 testfile-info-link.debuginfo.bz2 \ + testfile-info-link.stripped.bz2 run-unstrip-test3.sh \ + run-unstrip-test4.sh testfile-strtab.bz2 \ + testfile-strtab.stripped.bz2 testfile-strtab.debuginfo.bz2 \ + run-unstrip-M.sh run-elfstrmerge-test.sh \ + run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \ + run-ranlib-test3.sh run-ranlib-test4.sh \ + run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ + run-nm-syms.sh testfilesyms32.bz2 testfilesyms64.bz2 \ + run-nm-self.sh run-readelf-self.sh run-readelf-info-plus.sh \ + run-readelf-compressed.sh \ + run-readelf-compressed-zstd.sh \ + run-readelf-const-values.sh testfile-const-values.debug.bz2 \ + run-addrcfi.sh run-dwarfcfi.sh \ + testfile11-debugframe.bz2 testfile12-debugframe.bz2 \ + testfileaarch64-debugframe.bz2 testfilearm-debugframe.bz2 \ + testfileppc32-debugframe.bz2 testfileppc64-debugframe.bz2 \ + testfilecsky.bz2 \ + run-varlocs-self.sh run-exprlocs-self.sh \ + run-find-prologues.sh run-allregs.sh run-native-test.sh \ + run-addrname-test.sh run-dwfl-bug-offline-rel.sh \ + run-dwfl-addr-sect.sh run-early-offscn.sh \ + run-dwarf-getmacros.sh \ + run-dwarf-ranges.sh debug-ranges-no-lowpc.o.bz2 \ + testfileranges4.debug.bz2 testfileranges5.debug.bz2 \ + testfilesplitranges5.debug.bz2 \ + testfile-ranges-hello5.dwo.bz2 testfile-ranges-world5.dwo.bz2 \ + run-test-flag-nobits.sh \ + run-dwarf-getstring.sh run-rerequest_tag.sh run-alldts.sh \ + testfile15.bz2 testfile15.debug.bz2 \ + testfile16.bz2 testfile16.debug.bz2 \ + testfile17.bz2 testfile17.debug.bz2 \ + testfile18.bz2 testfile19.bz2 testfile19.index.bz2 \ + testfile20.bz2 testfile20.index.bz2 \ + testfile21.bz2 testfile21.index.bz2 \ + testfile22.bz2 testfile23.bz2 testfile24.bz2 testfile25.bz2 \ + testfile26.bz2 testfile27.bz2 \ + coverage.sh test-subr.sh test-wrapper.sh \ + run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \ + run-readelf-test4.sh run-readelf-twofiles.sh \ + run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \ + run-debuglink.sh run-debugaltlink.sh run-buildid.sh \ + testfile29.bz2 testfile29.rdwr.bz2 \ + testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ + testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 \ + testfile36.bz2 testfile36.debug.bz2 \ + testfile37.bz2 testfile37.debug.bz2 \ + testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2 \ + testfile41.bz2 testfile42.bz2 testfile42_noshdrs.bz2 \ + testfile43.bz2 \ + testfile44.S.bz2 testfile44.expect.bz2 run-disasm-x86.sh \ + testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \ + testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \ + testfile49.bz2 testfile50.bz2 testfile51.bz2 \ + testfile-macros-0xff.bz2 \ + run-readelf-macro.sh testfilemacro.bz2 \ + run-readelf-loc.sh testfileloc.bz2 \ + splitdwarf4-not-split4.dwo.bz2 \ + testfile-splitdwarf4-not-split4.debug.bz2 \ + run-readelf-ranges.sh \ + run-readelf-aranges.sh run-readelf-line.sh testfilefoobarbaz.bz2 \ + testfile-ppc64-min-instr.bz2 \ + testfile-dwarf-45.source \ + testfile-dwarf-4.bz2 testfile-dwarf-5.bz2 \ + run-readelf-z.sh \ + run-readelf-dwz-multi.sh libtestfile_multi_shared.so.bz2 \ + testfile_multi.dwz.bz2 testfile_multi_main.bz2 \ + testfile-dwzstr.bz2 testfile-dwzstr.multi.bz2 \ + run-readelf-addr.sh run-readelf-str.sh \ + run-readelf-types.sh \ + run-readelf-frames.sh \ + run-readelf-n.sh \ + testfile-gnu-property-note.bz2 testfile-gnu-property-note.o.bz2 \ + testfile_gnu_props.32le.o.bz2 \ + testfile_gnu_props.64le.o.bz2 \ + testfile_gnu_props.32be.o.bz2 \ + testfile_gnu_props.64be.o.bz2 \ + testfile-gnu-property-note-aarch64.bz2 \ + run-retain.sh testfile-retain.o.bz2 \ + run-allfcts-multi.sh \ + test-offset-loop.bz2 test-offset-loop.alt.bz2 \ + run-prelink-addr-test.sh \ + testfile52-32.so.bz2 testfile52-32.so.debug.bz2 \ + testfile52-32.prelink.so.bz2 testfile52-32.noshdrs.so.bz2 \ + testfile52-64.so.bz2 testfile52-64.so.debug.bz2 \ + testfile52-64.prelink.so.bz2 testfile52-64.noshdrs.so.bz2 \ + testfile53-32.bz2 testfile53-32.debug.bz2 \ + testfile53-32.prelink.bz2 testfile53-64.bz2 \ + testfile53-64.debug.bz2 testfile53-64.prelink.bz2 \ + testfile54-32.so.bz2 testfile54-32.so.debug.bz2 \ + testfile54-32.prelink.so.bz2 testfile54-32.noshdrs.so.bz2 \ + testfile54-64.so.bz2 testfile54-64.so.debug.bz2 \ + testfile54-64.prelink.so.bz2 testfile54-64.noshdrs.so.bz2 \ + testfile55-32.bz2 testfile55-32.debug.bz2 \ + testfile55-32.prelink.bz2 testfile55-64.bz2 \ + testfile55-64.debug.bz2 testfile55-64.prelink.bz2 \ + testfile56.bz2 testfile57.bz2 testfile58.bz2 \ + run-typeiter.sh testfile59.bz2 \ + run-readelf-d.sh testlib_dynseg.so.bz2 \ + testfile-s390x-hash-both.bz2 \ + run-readelf-gdb_index.sh testfilegdbindex5.bz2 \ + testfilegdbindex7.bz2 \ + run-readelf-s.sh testfilebazdbg.bz2 testfilebazdyn.bz2 \ + testfilebazmin.bz2 testfilebazdbg.debug.bz2 testfilebazmdb.bz2 \ + testfilebaztab.bz2 testfilebasmin.bz2 testfilebaxmin.bz2 \ + testfilebazdbg_pl.bz2 testfilebazmin_pl.bz2 \ + testfilebazdbg_plr.bz2 testfilebazmin_plr.bz2 \ + testfilebazdbgppc64.bz2 testfilebazdbgppc64.debug.bz2 \ + testfilebazdbgppc64_pl.bz2 testfilebazdbgppc64_plr.bz2 \ + testfilebazdynppc64.bz2 testfilebazmdbppc64.bz2 \ + testfilebazminppc64.bz2 testfilebazminppc64_pl.bz2 \ + testfilebazminppc64_plr.bz2 testfilebaztabppc64.bz2 \ + run-readelf-variant.sh testfile-ada-variant.bz2 \ + run-dwflsyms.sh \ + run-unstrip-n.sh testcore-rtlib.bz2 testcore-rtlib-ppc.bz2 \ + run-low_high_pc.sh testfile_low_high_pc.bz2 \ + run-macro-test.sh testfile-macinfo.bz2 testfile-macros.bz2 \ + run-elf_cntl_gelf_getshdr.sh \ + run-test-archive64.sh testarchive64.a.bz2 \ + testfile61.bz2 \ + run-readelf-vmcoreinfo.sh testfile62.bz2 \ + run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \ + testfile65.bz2 testfile67.bz2 testfile68.bz2 \ + testfile69.core.bz2 testfile69.so.bz2 \ + testfile70.core.bz2 testfile70.exec.bz2 testfile71.bz2 \ + run-dwfllines.sh run-dwfl-report-elf-align.sh \ + testfile-dwfl-report-elf-align-shlib.so.bz2 \ + testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \ + test-core.exec.bz2 run-addr2line-test.sh \ + run-addr2line-i-test.sh testfile-inlines.bz2 \ + run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \ + run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ + testfileppc32.bz2 testfileppc64.bz2 \ + testfiles390.bz2 testfiles390x.bz2 \ + testfilearm.bz2 testfileaarch64.bz2 \ + run-varlocs.sh run-exprlocs.sh testfile-stridex.bz2 \ + testfile_const_type.c testfile_const_type.bz2 \ + testfile_implicit_pointer.c testfile_implicit_pointer.bz2 \ + testfile_parameter_ref.c testfile_parameter_ref.bz2 \ + testfile_entry_value.c testfile_entry_value.bz2 \ + testfile_implicit_value.c testfile_implicit_value.bz2 \ + testfile_aarch64_core.bz2 testfile_i686_core.bz2 \ + addrx_constx-4.dwo.bz2 addrx_constx-5.dwo.bz2 \ + testfile-addrx_constx-4.bz2 testfile-addrx_constx-5.bz2 \ + run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \ + run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \ + run-backtrace-native.sh run-backtrace-native-biarch.sh \ + run-backtrace-native-core.sh run-backtrace-native-core-biarch.sh \ + run-backtrace-core-x86_64.sh run-backtrace-core-i386.sh \ + run-backtrace-fp-core-x86_64.sh \ + run-backtrace-core-x32.sh \ + run-backtrace-fp-core-aarch64.sh \ + backtrace.aarch64.fp.core.bz2 backtrace.aarch64.fp.exec.bz2 \ + backtrace-subr.sh backtrace.i386.core.bz2 backtrace.i386.exec.bz2 \ + run-backtrace-fp-core-i386.sh \ + backtrace.i386.fp.core.bz2 backtrace.i386.fp.exec.bz2 \ + run-backtrace-fp-core-ppc64le.sh \ + backtrace.ppc64le.fp.core.bz2 backtrace.ppc64le.fp.exec.bz2 \ + backtrace.x86_64.core.bz2 backtrace.x86_64.exec.bz2 \ + backtrace.x86_64.fp.core.bz2 backtrace.x86_64.fp.exec.bz2 \ + backtrace.ppc.core.bz2 backtrace.ppc.exec.bz2 \ + run-backtrace-core-ppc.sh testfile66.bz2 testfile66.core.bz2 \ + backtrace.s390x.core.bz2 backtrace.s390x.exec.bz2 \ + backtrace.s390.core.bz2 backtrace.s390.exec.bz2 \ + run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \ + run-backtrace-core-aarch64.sh \ + backtrace.aarch64.core.bz2 backtrace.aarch64.exec.bz2 \ + run-backtrace-core-sparc.sh \ + backtrace.sparc.core.bz2 backtrace.sparc.exec.bz2 \ + run-backtrace-demangle.sh testfile-backtrace-demangle.bz2 \ + testfile-backtrace-demangle.cc \ + testfile-backtrace-demangle.core.bz2 \ + run-stack-d-test.sh run-stack-i-test.sh \ + run-stack-demangled-test.sh \ + testfiledwarfinlines.bz2 testfiledwarfinlines.core.bz2 \ + run-readelf-zdebug.sh testfile-debug.bz2 testfile-zdebug.bz2 \ + run-readelf-zdebug-rel.sh testfile-debug-rel.o.bz2 \ + testfile-debug-rel-g.o.bz2 testfile-debug-rel-z.o.bz2 \ + run-readelf-zx.sh run-readelf-zp.sh \ + run-deleted.sh run-linkmap-cut.sh linkmap-cut-lib.so.bz2 \ + linkmap-cut.bz2 linkmap-cut.core.bz2 \ + run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2 \ + testfile-sizes3.o.bz2 testfile-sizes4.o.bz2 testfile-sizes4.s \ + run-peel-type.sh \ + run-readelf-A.sh testfileppc32attrs.o.bz2 \ + testfilesparc64attrs.o.bz2 testfileppc64attrs.o.bz2 \ + testfile-debug-types.bz2 \ + run-getsrc-die.sh run-strptr.sh \ + testfile-x32-core.bz2 testfile-x32.bz2 \ + backtrace.x32.core.bz2 backtrace.x32.exec.bz2 \ + testfile-x32-s.bz2 testfile-x32-d.bz2 testfile-x32-debug.bz2 \ + run-lfs-symbols.sh lfs-symbols testfile-nolfs.bz2 \ + testfile-zgnu32.bz2 testfile-zgnu64.bz2 \ + testfile-zgnu32be.bz2 testfile-zgnu64be.bz2 \ + run-dwelfgnucompressed.sh \ + testfile-zgabi32.bz2 testfile-zgabi64.bz2 \ + testfile-zgabi32be.bz2 testfile-zgabi64be.bz2 \ + run-elfgetchdr.sh run-elfgetzdata.sh run-elfputzdata.sh \ + run-zstrptr.sh run-compress-test.sh \ + run-disasm-bpf.sh \ + testfile-bpf-dis1.expect.bz2 testfile-bpf-dis1.o.bz2 \ + run-reloc-bpf.sh \ + testfile-bpf-reloc.expect.bz2 testfile-bpf-reloc.o.bz2 \ + testfile-m68k-core.bz2 testfile-m68k.bz2 testfile-m68k-s.bz2 \ + run-dwarf-die-addr-die.sh \ + run-get-units-invalid.sh run-get-units-split.sh \ + testfile-hello4.dwo.bz2 testfile-hello5.dwo.bz2 \ + testfile-splitdwarf-4.bz2 testfile-splitdwarf-5.bz2 \ + testfile-world5.dwo.bz2 testfile-world4.dwo.bz2 \ + run-attr-integrate-skel.sh \ + run-all-dwarf-ranges.sh testfilesplitranges4.debug.bz2 \ + testfile-ranges-hello.dwo.bz2 testfile-ranges-world.dwo.bz2 \ + run-unit-info.sh run-next-cfi.sh run-next-cfi-self.sh \ + testfile-riscv64.bz2 testfile-riscv64-s.bz2 \ + testfile-riscv64-core.bz2 \ + run-reverse-sections.sh run-reverse-sections-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-large-elf-file.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ + testfile-debug-rel-ppc64-g.o.bz2 \ + testfile-debug-rel-ppc64-z.o.bz2 \ + testfile-debug-rel-ppc64.o.bz2 \ + run-strip-version.sh testfile-version.bz2 \ + run-xlate-note.sh \ + run-readelf-discr.sh \ + testfile-rng.debug.bz2 testfile-urng.debug.bz2 \ + run-dwelf_elf_e_machine_string.sh \ + run-elfclassify.sh run-elfclassify-self.sh \ + run-disasm-riscv64.sh \ + testfile-riscv64-dis1.o.bz2 testfile-riscv64-dis1.expect.bz2 \ + run-debuginfod-find.sh \ + debuginfod-rpms/fedora30/hello2-1.0-2.src.rpm \ + debuginfod-rpms/fedora30/hello2-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-debugsource-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-two-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-two-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-1.0-2.src.rpm \ + debuginfod-rpms/fedora31/hello3-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-debugsource-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-two-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-two-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/hello2.spec. \ + debuginfod-rpms/rhel6/hello2-1.0-2.i686.rpm \ + debuginfod-rpms/rhel6/hello2-1.0-2.src.rpm \ + debuginfod-rpms/rhel6/hello2-debuginfo-1.0-2.i686.rpm \ + debuginfod-rpms/rhel6/hello2-two-1.0-2.i686.rpm \ + debuginfod-rpms/rhel7/hello2-1.0-2.src.rpm \ + debuginfod-rpms/rhel7/hello2-1.0-2.x86_64.rpm \ + debuginfod-rpms/rhel7/hello2-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/rhel7/hello2-two-1.0-2.x86_64.rpm \ + debuginfod-rpms/rhel7/hello2-two-1.0-2.x86_64.rpm \ + debuginfod-debs/hithere-dbgsym_1.0-1_amd64.ddeb \ + debuginfod-debs/hithere_1.0-1.debian.tar.xz \ + debuginfod-debs/hithere_1.0-1.dsc \ + debuginfod-debs/hithere_1.0-1_amd64.deb \ + debuginfod-debs/hithere_1.0.orig.tar.gz \ + debuginfod-tars/hello-1-1-x86_64.pkg.tar.xz \ + debuginfod-tars/hello-debug-1-1-x86_64.pkg.tar.bz2 \ + debuginfod-tars/pacman-sources/PKGBUILD \ + debuginfod-tars/pacman-sources/README.md \ + debuginfod-tars/pacman-sources/hello.c \ + run-pt_gnu_prop-tests.sh \ + testfile_pt_gnu_prop.bz2 testfile_pt_gnu_prop32.bz2 \ + run-getphdrnum.sh testfile-phdrs.elf.bz2 \ + run-test-includes.sh run-low_high_pc-dw-form-indirect.sh \ + run-readelf-dw-form-indirect.sh testfile-dw-form-indirect.bz2 + + +if USE_VALGRIND +valgrind_cmd=valgrind -q --leak-check=full --error-exitcode=1 +endif + + +installed_TESTS_ENVIRONMENT = libdir='$(DESTDIR)$(libdir)'; \ + bindir='$(DESTDIR)$(bindir)'; \ + LC_ALL=C; LANG=C; \ + VALGRIND_CMD='$(valgrind_cmd)'; \ + abs_srcdir='$(abs_srcdir)'; \ + abs_builddir='$(abs_builddir)'; \ + abs_top_builddir='$(abs_top_builddir)'; \ + export abs_srcdir; export abs_builddir; \ + export abs_top_builddir; \ + export libdir; export bindir; \ + export LC_ALL; export LANG; export VALGRIND_CMD; \ + unset DEBUGINFOD_URLS; \ + NM='$(NM)'; export NM; \ + CC='$(CC)'; export CC; +installed_LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \ + installed $(tests_rpath) \ + '$(program_transform_name)' +TESTS_ENVIRONMENT = LC_ALL=C; LANG=C; VALGRIND_CMD='$(valgrind_cmd)'; \ + abs_srcdir='$(abs_srcdir)'; \ + abs_builddir='$(abs_builddir)'; \ + abs_top_builddir='$(abs_top_builddir)'; \ + export abs_srcdir; export abs_builddir; \ + export abs_top_builddir; \ + export LC_ALL; export LANG; export VALGRIND_CMD; \ + unset DEBUGINFOD_URLS; \ + NM='$(NM)'; export NM; \ + CC='$(CC)'; export CC; +LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \ + $(abs_top_builddir)/libdw:$(abs_top_builddir)/backends:$(abs_top_builddir)/libelf:$(abs_top_builddir)/libasm:$(abs_top_builddir)/debuginfod + +installcheck-local: + $(MAKE) $(AM_MAKEFLAGS) \ + TESTS_ENVIRONMENT="$(installed_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(installed_LOG_COMPILER)" check-TESTS + +if BUILD_STATIC +libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread +libelf = ../libelf/libelf.a -lz +libasm = ../libasm/libasm.a +else +libdw = ../libdw/libdw.so +libelf = ../libelf/libelf.so +libasm = ../libasm/libasm.so +endif +libebl = ../libebl/libebl.a ../backends/libebl_backends.a ../libcpu/libcpu.a +libeu = ../lib/libeu.a + +arextract_LDADD = $(libelf) +arsymtest_LDADD = $(libelf) +newfile_LDADD = $(libelf) +saridx_LDADD = $(libelf) +scnnames_LDADD = $(libelf) +sectiondump_LDADD = $(libelf) +showptable_LDADD = $(libelf) +hash_LDADD = $(libelf) +test_nlist_CFLAGS =-g -O0 +test_nlist_LDADD = $(libelf) +msg_tst_LDADD = $(libelf) +newscn_LDADD = $(libelf) +early_offscn_LDADD = $(libelf) +ecp_LDADD = $(libelf) +update1_LDADD = $(libelf) +update2_LDADD = $(libelf) +update3_LDADD = $(libdw) $(libelf) +update4_LDADD = $(libdw) $(libelf) +show_die_info_LDADD = $(libdw) $(libelf) +get_pubnames_LDADD = $(libdw) $(libelf) +show_abbrev_LDADD = $(libdw) $(libelf) +get_lines_LDADD = $(libdw) $(libelf) +next_lines_LDADD = $(libdw) $(libelf) +get_files_LDADD = $(libdw) $(libelf) +next_files_LDADD = $(libdw) $(libelf) +get_aranges_LDADD = $(libdw) $(libelf) +allfcts_LDADD = $(libdw) $(libelf) +line2addr_LDADD = $(libdw) $(argp_LDADD) +addrscopes_LDADD = $(libdw) $(argp_LDADD) +funcscopes_LDADD = $(libdw) $(argp_LDADD) +funcretval_LDADD = $(libdw) $(argp_LDADD) +allregs_LDADD = $(libdw) $(argp_LDADD) +find_prologues_LDADD = $(libdw) $(argp_LDADD) +#show_ciefde_LDADD = ../libdwarf/libdwarf.so $(libelf) +asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +dwflmodtest_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) +rdwrmmap_LDADD = $(libelf) +dwfl_bug_addr_overflow_LDADD = $(libdw) $(libebl) $(libelf) +arls_LDADD = $(libelf) +dwfl_bug_fd_leak_LDADD = $(libdw) $(libebl) $(libelf) +dwfl_bug_report_LDADD = $(libdw) $(libebl) $(libelf) +dwfl_bug_getmodules_LDADD = $(libdw) $(libebl) $(libelf) +dwfl_addr_sect_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) +dwarf_getmacros_LDADD = $(libdw) +dwarf_ranges_LDADD = $(libdw) +dwarf_getstring_LDADD = $(libdw) +addrcfi_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) +dwarfcfi_LDADD = $(libdw) $(libelf) +test_flag_nobits_LDADD = $(libelf) +rerequest_tag_LDADD = $(libdw) +alldts_LDADD = $(libdw) $(libelf) +typeiter_LDADD = $(libdw) $(libelf) +typeiter2_LDADD = $(libdw) $(libelf) +low_high_pc_LDADD = $(libdw) $(libelf) $(argp_LDADD) +test_elf_cntl_gelf_getshdr_LDADD = $(libelf) +dwflsyms_LDADD = $(libdw) $(libelf) $(argp_LDADD) +dwfllines_LDADD = $(libdw) $(libelf) $(argp_LDADD) +dwfl_report_elf_align_LDADD = $(libdw) +dwfl_report_segment_contiguous_LDADD = $(libdw) $(libebl) $(libelf) +varlocs_LDADD = $(libdw) $(libelf) $(argp_LDADD) +backtrace_LDADD = $(libdw) $(libelf) $(argp_LDADD) +# backtrace-child-biarch also uses those *_CFLAGS and *_LDLAGS variables: +backtrace_child_CFLAGS = $(fpie_CFLAGS) +backtrace_child_LDFLAGS = -pie -pthread +backtrace_child_biarch_SOURCES = backtrace-child.c +backtrace_data_LDADD = $(libdw) $(libelf) +backtrace_dwarf_CFLAGS = -Wno-unused-parameter +backtrace_dwarf_LDADD = $(libdw) $(libelf) +debuglink_LDADD = $(libdw) $(libelf) +debugaltlink_LDADD = $(libdw) $(libelf) +buildid_LDADD = $(libdw) $(libelf) +deleted_LDADD = ./deleted-lib.so +deleted_lib_so_LDFLAGS = -shared +deleted_lib_so_CFLAGS = $(fpic_CFLAGS) -fasynchronous-unwind-tables +aggregate_size_LDADD = $(libdw) $(libelf) $(argp_LDADD) +peel_type_LDADD = $(libdw) $(libelf) $(argp_LDADD) +vdsosyms_LDADD = $(libdw) $(libelf) +getsrc_die_LDADD = $(libdw) $(libelf) +strptr_LDADD = $(libelf) +newdata_LDADD = $(libelf) +elfstrtab_LDADD = $(libelf) +dwfl_proc_attach_LDADD = $(libdw) +dwfl_proc_attach_LDFLAGS = -pthread $(AM_LDFLAGS) +elfshphehdr_LDADD =$(libelf) +elfstrmerge_LDADD = $(libdw) $(libelf) +dwelfgnucompressed_LDADD = $(libelf) $(libdw) +elfgetchdr_LDADD = $(libelf) $(libdw) +elfgetzdata_LDADD = $(libelf) +elfputzdata_LDADD = $(libelf) +zstrptr_LDADD = $(libelf) +emptyfile_LDADD = $(libelf) +vendorelf_LDADD = $(libelf) +fillfile_LDADD = $(libelf) +dwarf_default_lower_bound_LDADD = $(libdw) +dwarf_die_addr_die_LDADD = $(libdw) +get_units_invalid_LDADD = $(libdw) +get_units_split_LDADD = $(libdw) +attr_integrate_skel_LDADD = $(libdw) +all_dwarf_ranges_LDADD = $(libdw) +unit_info_LDADD = $(libdw) +next_cfi_LDADD = $(libelf) $(libdw) +elfcopy_LDADD = $(libelf) +addsections_LDADD = $(libelf) +debuginfod_build_id_find_LDADD = $(libelf) $(libdw) +xlate_notes_LDADD = $(libelf) +elfrdwrnop_LDADD = $(libelf) +dwelf_elf_e_machine_string_LDADD = $(libelf) $(libdw) +getphdrnum_LDADD = $(libelf) $(libdw) +leb128_LDADD = $(libelf) $(libdw) +read_unaligned_LDADD = $(libelf) $(libdw) + +# We want to test the libelf header against the system elf.h header. +# Don't include any -I CPPFLAGS. Except when we install our own elf.h. +if !INSTALL_ELFH +system_elf_libelf_test_CPPFLAGS = +else +system_elf_libelf_test_CPPFLAGS = -I$(top_srcdir)/libelf +endif +system_elf_libelf_test_LDADD = $(libelf) + +# A lock file used to make sure only one test dumps core at a time +CLEANFILES += core-dump-backtrace.lock + +if GCOV +check: check-am coverage +.PHONY: coverage +coverage: + -$(srcdir)/coverage.sh +endif diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 00000000..2bf0c6d1 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,4642 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@SYMBOL_VERSIONING_TRUE@am__append_1 = -DSYMBOL_VERSIONING +@TESTS_RPATH_TRUE@am__append_2 = -Wl,-rpath,$(BUILD_RPATH) +check_PROGRAMS = arextract$(EXEEXT) arsymtest$(EXEEXT) \ + newfile$(EXEEXT) saridx$(EXEEXT) scnnames$(EXEEXT) \ + sectiondump$(EXEEXT) showptable$(EXEEXT) update1$(EXEEXT) \ + update2$(EXEEXT) update3$(EXEEXT) update4$(EXEEXT) \ + test-nlist$(EXEEXT) show-die-info$(EXEEXT) get-files$(EXEEXT) \ + next-files$(EXEEXT) get-lines$(EXEEXT) next-lines$(EXEEXT) \ + get-pubnames$(EXEEXT) get-aranges$(EXEEXT) allfcts$(EXEEXT) \ + line2addr$(EXEEXT) addrscopes$(EXEEXT) funcscopes$(EXEEXT) \ + show-abbrev$(EXEEXT) hash$(EXEEXT) newscn$(EXEEXT) \ + ecp$(EXEEXT) dwflmodtest$(EXEEXT) find-prologues$(EXEEXT) \ + funcretval$(EXEEXT) allregs$(EXEEXT) rdwrmmap$(EXEEXT) \ + dwfl-bug-addr-overflow$(EXEEXT) arls$(EXEEXT) \ + dwfl-bug-fd-leak$(EXEEXT) dwfl-addr-sect$(EXEEXT) \ + dwfl-bug-report$(EXEEXT) early-offscn$(EXEEXT) \ + dwfl-bug-getmodules$(EXEEXT) dwarf-getmacros$(EXEEXT) \ + dwarf-ranges$(EXEEXT) addrcfi$(EXEEXT) dwarfcfi$(EXEEXT) \ + test-flag-nobits$(EXEEXT) dwarf-getstring$(EXEEXT) \ + rerequest_tag$(EXEEXT) alldts$(EXEEXT) typeiter$(EXEEXT) \ + typeiter2$(EXEEXT) low_high_pc$(EXEEXT) \ + test-elf_cntl_gelf_getshdr$(EXEEXT) dwflsyms$(EXEEXT) \ + dwfllines$(EXEEXT) dwfl-report-elf-align$(EXEEXT) \ + dwfl-report-segment-contiguous$(EXEEXT) varlocs$(EXEEXT) \ + backtrace$(EXEEXT) backtrace-child$(EXEEXT) \ + backtrace-data$(EXEEXT) backtrace-dwarf$(EXEEXT) \ + debuglink$(EXEEXT) debugaltlink$(EXEEXT) buildid$(EXEEXT) \ + deleted$(EXEEXT) deleted-lib.so$(EXEEXT) \ + aggregate_size$(EXEEXT) peel_type$(EXEEXT) vdsosyms$(EXEEXT) \ + getsrc_die$(EXEEXT) strptr$(EXEEXT) newdata$(EXEEXT) \ + elfstrtab$(EXEEXT) dwfl-proc-attach$(EXEEXT) \ + elfshphehdr$(EXEEXT) elfstrmerge$(EXEEXT) \ + dwelfgnucompressed$(EXEEXT) elfgetchdr$(EXEEXT) \ + elfgetzdata$(EXEEXT) elfputzdata$(EXEEXT) zstrptr$(EXEEXT) \ + emptyfile$(EXEEXT) vendorelf$(EXEEXT) fillfile$(EXEEXT) \ + dwarf_default_lower_bound$(EXEEXT) dwarf-die-addr-die$(EXEEXT) \ + get-units-invalid$(EXEEXT) get-units-split$(EXEEXT) \ + attr-integrate-skel$(EXEEXT) all-dwarf-ranges$(EXEEXT) \ + unit-info$(EXEEXT) next_cfi$(EXEEXT) elfcopy$(EXEEXT) \ + addsections$(EXEEXT) xlate_notes$(EXEEXT) elfrdwrnop$(EXEEXT) \ + dwelf_elf_e_machine_string$(EXEEXT) getphdrnum$(EXEEXT) \ + leb128$(EXEEXT) read_unaligned$(EXEEXT) msg_tst$(EXEEXT) \ + system-elf-libelf-test$(EXEEXT) $(am__EXEEXT_1) \ + $(am__EXEEXT_2) $(am__EXEEXT_3) +@BIARCH_TRUE@am__append_3 = backtrace-child-biarch +TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile$(EXEEXT) \ + test-nlist$(EXEEXT) update1$(EXEEXT) update2$(EXEEXT) \ + update3$(EXEEXT) update4$(EXEEXT) run-show-die-info.sh \ + run-get-files.sh run-get-lines.sh run-next-files.sh \ + run-next-lines.sh run-get-pubnames.sh run-get-aranges.sh \ + run-allfcts.sh run-show-abbrev.sh run-line2addr.sh \ + hash$(EXEEXT) run-large-elf-file.sh newscn$(EXEEXT) \ + run-strip-test.sh run-strip-test2.sh run-strip-test3.sh \ + run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \ + run-strip-test7.sh run-strip-test8.sh run-strip-test9.sh \ + run-strip-test10.sh run-strip-test11.sh run-strip-test12.sh \ + run-strip-nothing.sh run-strip-g.sh run-annobingroup.sh \ + run-strip-groups.sh run-strip-reloc.sh run-strip-strmerge.sh \ + run-strip-nobitsalign.sh run-strip-remove-keep.sh \ + run-unstrip-test.sh run-unstrip-test2.sh run-unstrip-test3.sh \ + run-unstrip-test4.sh run-unstrip-M.sh run-elfstrmerge-test.sh \ + run-ecp-test.sh run-ecp-test2.sh run-alldts.sh \ + run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \ + run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \ + run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ + run-find-prologues.sh run-allregs.sh run-addrcfi.sh \ + run-dwarfcfi.sh run-nm-syms.sh run-nm-self.sh \ + run-readelf-self.sh run-readelf-info-plus.sh \ + run-readelf-compressed.sh run-readelf-const-values.sh \ + run-varlocs-self.sh run-exprlocs-self.sh run-readelf-test1.sh \ + run-readelf-test2.sh run-readelf-test3.sh run-readelf-test4.sh \ + run-readelf-twofiles.sh run-readelf-macro.sh \ + run-readelf-loc.sh run-readelf-ranges.sh \ + run-readelf-aranges.sh run-readelf-line.sh run-readelf-z.sh \ + run-readelf-frames.sh run-readelf-n.sh run-retain.sh \ + run-native-test.sh run-bug1-test.sh run-debuglink.sh \ + run-debugaltlink.sh run-buildid.sh \ + dwfl-bug-addr-overflow$(EXEEXT) run-addrname-test.sh \ + dwfl-bug-fd-leak$(EXEEXT) dwfl-bug-report$(EXEEXT) \ + dwfl-report-segment-contiguous$(EXEEXT) \ + run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \ + run-disasm-x86.sh run-disasm-x86-64.sh run-early-offscn.sh \ + run-dwarf-getmacros.sh run-dwarf-ranges.sh \ + run-test-flag-nobits.sh run-prelink-addr-test.sh \ + run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \ + run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \ + run-low_high_pc.sh run-macro-test.sh \ + run-elf_cntl_gelf_getshdr.sh run-test-archive64.sh \ + run-readelf-vmcoreinfo.sh run-readelf-mixed-corenote.sh \ + run-dwfllines.sh run-readelf-variant.sh \ + run-dwfl-report-elf-align.sh run-addr2line-test.sh \ + run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \ + run-addr2line-i-demangle-test.sh \ + run-addr2line-alt-debugpath.sh run-varlocs.sh run-exprlocs.sh \ + run-funcretval.sh run-backtrace-native.sh \ + run-backtrace-data.sh run-backtrace-dwarf.sh \ + run-backtrace-native-biarch.sh run-backtrace-native-core.sh \ + run-backtrace-native-core-biarch.sh \ + run-backtrace-core-x86_64.sh run-backtrace-fp-core-x86_64.sh \ + run-backtrace-fp-core-aarch64.sh \ + run-backtrace-fp-core-ppc64le.sh run-backtrace-core-x32.sh \ + run-backtrace-core-i386.sh run-backtrace-fp-core-i386.sh \ + run-backtrace-core-ppc.sh run-backtrace-core-s390x.sh \ + run-backtrace-core-s390.sh run-backtrace-core-aarch64.sh \ + run-backtrace-core-sparc.sh run-backtrace-demangle.sh \ + run-stack-d-test.sh run-stack-i-test.sh \ + run-stack-demangled-test.sh run-readelf-zx.sh \ + run-readelf-zp.sh run-readelf-addr.sh run-readelf-str.sh \ + run-readelf-types.sh run-readelf-dwz-multi.sh \ + run-allfcts-multi.sh run-deleted.sh run-linkmap-cut.sh \ + run-aggregate-size.sh run-peel-type.sh vdsosyms$(EXEEXT) \ + run-readelf-A.sh run-getsrc-die.sh run-strptr.sh \ + newdata$(EXEEXT) elfstrtab$(EXEEXT) dwfl-proc-attach$(EXEEXT) \ + elfshphehdr$(EXEEXT) run-lfs-symbols.sh \ + run-dwelfgnucompressed.sh run-elfgetchdr.sh run-elfgetzdata.sh \ + run-elfputzdata.sh run-zstrptr.sh run-compress-test.sh \ + run-readelf-zdebug.sh run-readelf-zdebug-rel.sh \ + emptyfile$(EXEEXT) vendorelf$(EXEEXT) fillfile$(EXEEXT) \ + dwarf_default_lower_bound$(EXEEXT) run-dwarf-die-addr-die.sh \ + run-get-units-invalid.sh run-get-units-split.sh \ + run-attr-integrate-skel.sh run-all-dwarf-ranges.sh \ + run-unit-info.sh run-reloc-bpf.sh run-next-cfi.sh \ + run-next-cfi-self.sh run-reverse-sections.sh \ + run-reverse-sections-self.sh run-copyadd-sections.sh \ + run-copymany-sections.sh run-typeiter-many.sh \ + run-strip-test-many.sh run-strip-version.sh run-xlate-note.sh \ + run-readelf-discr.sh run-dwelf_elf_e_machine_string.sh \ + run-elfclassify.sh run-elfclassify-self.sh \ + run-disasm-riscv64.sh run-pt_gnu_prop-tests.sh \ + run-getphdrnum.sh run-test-includes.sh leb128$(EXEEXT) \ + read_unaligned$(EXEEXT) msg_tst$(EXEEXT) \ + system-elf-libelf-test$(EXEEXT) $(am__EXEEXT_1) \ + run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \ + run-readelf-dw-form-indirect.sh $(am__append_4) \ + $(am__append_5) $(am__append_7) +@LZMA_TRUE@am__append_4 = run-readelf-s.sh run-dwflsyms.sh +@HAVE_ZSTD_TRUE@am__append_5 = run-readelf-compressed-zstd.sh +@DEBUGINFOD_TRUE@am__append_6 = debuginfod_build_id_find +# With the dummy delegation doesn't work +@DEBUGINFOD_TRUE@@DUMMY_LIBDEBUGINFOD_FALSE@am__append_7 = run-debuginfod-find.sh +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/biarch.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = asm-tst1$(EXEEXT) asm-tst2$(EXEEXT) asm-tst3$(EXEEXT) \ + asm-tst4$(EXEEXT) asm-tst5$(EXEEXT) asm-tst6$(EXEEXT) \ + asm-tst7$(EXEEXT) asm-tst8$(EXEEXT) asm-tst9$(EXEEXT) +@BIARCH_TRUE@am__EXEEXT_2 = backtrace-child-biarch$(EXEEXT) +@DEBUGINFOD_TRUE@am__EXEEXT_3 = debuginfod_build_id_find$(EXEEXT) +addrcfi_SOURCES = addrcfi.c +addrcfi_OBJECTS = addrcfi.$(OBJEXT) +am__DEPENDENCIES_1 = +@BUILD_STATIC_FALSE@am__DEPENDENCIES_2 = ../libelf/libelf.so +@BUILD_STATIC_TRUE@am__DEPENDENCIES_2 = ../libelf/libelf.a +@BUILD_STATIC_FALSE@am__DEPENDENCIES_3 = ../libdw/libdw.so +@BUILD_STATIC_TRUE@am__DEPENDENCIES_3 = ../libdw/libdw.a \ +@BUILD_STATIC_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ +@BUILD_STATIC_TRUE@ $(libebl) +addrcfi_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) +addrscopes_SOURCES = addrscopes.c +addrscopes_OBJECTS = addrscopes.$(OBJEXT) +addrscopes_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) +addsections_SOURCES = addsections.c +addsections_OBJECTS = addsections.$(OBJEXT) +addsections_DEPENDENCIES = $(am__DEPENDENCIES_2) +aggregate_size_SOURCES = aggregate_size.c +aggregate_size_OBJECTS = aggregate_size.$(OBJEXT) +aggregate_size_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) +all_dwarf_ranges_SOURCES = all-dwarf-ranges.c +all_dwarf_ranges_OBJECTS = all-dwarf-ranges.$(OBJEXT) +all_dwarf_ranges_DEPENDENCIES = $(am__DEPENDENCIES_3) +alldts_SOURCES = alldts.c +alldts_OBJECTS = alldts.$(OBJEXT) +alldts_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +allfcts_SOURCES = allfcts.c +allfcts_OBJECTS = allfcts.$(OBJEXT) +allfcts_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +allregs_SOURCES = allregs.c +allregs_OBJECTS = allregs.$(OBJEXT) +allregs_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) +arextract_SOURCES = arextract.c +arextract_OBJECTS = arextract.$(OBJEXT) +arextract_DEPENDENCIES = $(am__DEPENDENCIES_2) +arls_SOURCES = arls.c +arls_OBJECTS = arls.$(OBJEXT) +arls_DEPENDENCIES = $(am__DEPENDENCIES_2) +arsymtest_SOURCES = arsymtest.c +arsymtest_OBJECTS = arsymtest.$(OBJEXT) +arsymtest_DEPENDENCIES = $(am__DEPENDENCIES_2) +asm_tst1_SOURCES = asm-tst1.c +asm_tst1_OBJECTS = asm-tst1.$(OBJEXT) +asm_tst1_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst2_SOURCES = asm-tst2.c +asm_tst2_OBJECTS = asm-tst2.$(OBJEXT) +asm_tst2_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst3_SOURCES = asm-tst3.c +asm_tst3_OBJECTS = asm-tst3.$(OBJEXT) +asm_tst3_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst4_SOURCES = asm-tst4.c +asm_tst4_OBJECTS = asm-tst4.$(OBJEXT) +asm_tst4_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst5_SOURCES = asm-tst5.c +asm_tst5_OBJECTS = asm-tst5.$(OBJEXT) +asm_tst5_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst6_SOURCES = asm-tst6.c +asm_tst6_OBJECTS = asm-tst6.$(OBJEXT) +asm_tst6_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst7_SOURCES = asm-tst7.c +asm_tst7_OBJECTS = asm-tst7.$(OBJEXT) +asm_tst7_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst8_SOURCES = asm-tst8.c +asm_tst8_OBJECTS = asm-tst8.$(OBJEXT) +asm_tst8_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +asm_tst9_SOURCES = asm-tst9.c +asm_tst9_OBJECTS = asm-tst9.$(OBJEXT) +asm_tst9_DEPENDENCIES = $(libasm) $(libebl) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +attr_integrate_skel_SOURCES = attr-integrate-skel.c +attr_integrate_skel_OBJECTS = attr-integrate-skel.$(OBJEXT) +attr_integrate_skel_DEPENDENCIES = $(am__DEPENDENCIES_3) +backtrace_SOURCES = backtrace.c +backtrace_OBJECTS = backtrace.$(OBJEXT) +backtrace_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) +backtrace_child_SOURCES = backtrace-child.c +backtrace_child_OBJECTS = backtrace_child-backtrace-child.$(OBJEXT) +backtrace_child_LDADD = $(LDADD) +backtrace_child_LINK = $(CCLD) $(backtrace_child_CFLAGS) $(CFLAGS) \ + $(backtrace_child_LDFLAGS) $(LDFLAGS) -o $@ +am_backtrace_child_biarch_OBJECTS = backtrace-child.$(OBJEXT) +backtrace_child_biarch_OBJECTS = $(am_backtrace_child_biarch_OBJECTS) +backtrace_child_biarch_LDADD = $(LDADD) +backtrace_data_SOURCES = backtrace-data.c +backtrace_data_OBJECTS = backtrace-data.$(OBJEXT) +backtrace_data_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) +backtrace_dwarf_SOURCES = backtrace-dwarf.c +backtrace_dwarf_OBJECTS = backtrace_dwarf-backtrace-dwarf.$(OBJEXT) +backtrace_dwarf_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) +backtrace_dwarf_LINK = $(CCLD) $(backtrace_dwarf_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +buildid_SOURCES = buildid.c +buildid_OBJECTS = buildid.$(OBJEXT) +buildid_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +debugaltlink_SOURCES = debugaltlink.c +debugaltlink_OBJECTS = debugaltlink.$(OBJEXT) +debugaltlink_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) +debuginfod_build_id_find_SOURCES = debuginfod_build_id_find.c +debuginfod_build_id_find_OBJECTS = debuginfod_build_id_find.$(OBJEXT) +debuginfod_build_id_find_DEPENDENCIES = $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +debuglink_SOURCES = debuglink.c +debuglink_OBJECTS = debuglink.$(OBJEXT) +debuglink_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +deleted_SOURCES = deleted.c +deleted_OBJECTS = deleted.$(OBJEXT) +deleted_DEPENDENCIES = ./deleted-lib.so +deleted_lib_so_SOURCES = deleted-lib.c +deleted_lib_so_OBJECTS = deleted_lib_so-deleted-lib.$(OBJEXT) +deleted_lib_so_LDADD = $(LDADD) +deleted_lib_so_LINK = $(CCLD) $(deleted_lib_so_CFLAGS) $(CFLAGS) \ + $(deleted_lib_so_LDFLAGS) $(LDFLAGS) -o $@ +dwarf_die_addr_die_SOURCES = dwarf-die-addr-die.c +dwarf_die_addr_die_OBJECTS = dwarf-die-addr-die.$(OBJEXT) +dwarf_die_addr_die_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwarf_getmacros_SOURCES = dwarf-getmacros.c +dwarf_getmacros_OBJECTS = dwarf-getmacros.$(OBJEXT) +dwarf_getmacros_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwarf_getstring_SOURCES = dwarf-getstring.c +dwarf_getstring_OBJECTS = dwarf-getstring.$(OBJEXT) +dwarf_getstring_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwarf_ranges_SOURCES = dwarf-ranges.c +dwarf_ranges_OBJECTS = dwarf-ranges.$(OBJEXT) +dwarf_ranges_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwarf_default_lower_bound_SOURCES = dwarf_default_lower_bound.c +dwarf_default_lower_bound_OBJECTS = \ + dwarf_default_lower_bound.$(OBJEXT) +dwarf_default_lower_bound_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwarfcfi_SOURCES = dwarfcfi.c +dwarfcfi_OBJECTS = dwarfcfi.$(OBJEXT) +dwarfcfi_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +dwelf_elf_e_machine_string_SOURCES = dwelf_elf_e_machine_string.c +dwelf_elf_e_machine_string_OBJECTS = \ + dwelf_elf_e_machine_string.$(OBJEXT) +dwelf_elf_e_machine_string_DEPENDENCIES = $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +dwelfgnucompressed_SOURCES = dwelfgnucompressed.c +dwelfgnucompressed_OBJECTS = dwelfgnucompressed.$(OBJEXT) +dwelfgnucompressed_DEPENDENCIES = $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +dwfl_addr_sect_SOURCES = dwfl-addr-sect.c +dwfl_addr_sect_OBJECTS = dwfl-addr-sect.$(OBJEXT) +dwfl_addr_sect_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) +dwfl_bug_addr_overflow_SOURCES = dwfl-bug-addr-overflow.c +dwfl_bug_addr_overflow_OBJECTS = dwfl-bug-addr-overflow.$(OBJEXT) +dwfl_bug_addr_overflow_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) +dwfl_bug_fd_leak_SOURCES = dwfl-bug-fd-leak.c +dwfl_bug_fd_leak_OBJECTS = dwfl-bug-fd-leak.$(OBJEXT) +dwfl_bug_fd_leak_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) +dwfl_bug_getmodules_SOURCES = dwfl-bug-getmodules.c +dwfl_bug_getmodules_OBJECTS = dwfl-bug-getmodules.$(OBJEXT) +dwfl_bug_getmodules_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) +dwfl_bug_report_SOURCES = dwfl-bug-report.c +dwfl_bug_report_OBJECTS = dwfl-bug-report.$(OBJEXT) +dwfl_bug_report_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) +dwfl_proc_attach_SOURCES = dwfl-proc-attach.c +dwfl_proc_attach_OBJECTS = dwfl-proc-attach.$(OBJEXT) +dwfl_proc_attach_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwfl_proc_attach_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(dwfl_proc_attach_LDFLAGS) $(LDFLAGS) -o $@ +dwfl_report_elf_align_SOURCES = dwfl-report-elf-align.c +dwfl_report_elf_align_OBJECTS = dwfl-report-elf-align.$(OBJEXT) +dwfl_report_elf_align_DEPENDENCIES = $(am__DEPENDENCIES_3) +dwfl_report_segment_contiguous_SOURCES = \ + dwfl-report-segment-contiguous.c +dwfl_report_segment_contiguous_OBJECTS = \ + dwfl-report-segment-contiguous.$(OBJEXT) +dwfl_report_segment_contiguous_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(libebl) $(am__DEPENDENCIES_2) +dwfllines_SOURCES = dwfllines.c +dwfllines_OBJECTS = dwfllines.$(OBJEXT) +dwfllines_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) +dwflmodtest_SOURCES = dwflmodtest.c +dwflmodtest_OBJECTS = dwflmodtest.$(OBJEXT) +dwflmodtest_DEPENDENCIES = $(am__DEPENDENCIES_3) $(libebl) \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) +dwflsyms_SOURCES = dwflsyms.c +dwflsyms_OBJECTS = dwflsyms.$(OBJEXT) +dwflsyms_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) +early_offscn_SOURCES = early-offscn.c +early_offscn_OBJECTS = early-offscn.$(OBJEXT) +early_offscn_DEPENDENCIES = $(am__DEPENDENCIES_2) +ecp_SOURCES = ecp.c +ecp_OBJECTS = ecp.$(OBJEXT) +ecp_DEPENDENCIES = $(am__DEPENDENCIES_2) +elfcopy_SOURCES = elfcopy.c +elfcopy_OBJECTS = elfcopy.$(OBJEXT) +elfcopy_DEPENDENCIES = $(am__DEPENDENCIES_2) +elfgetchdr_SOURCES = elfgetchdr.c +elfgetchdr_OBJECTS = elfgetchdr.$(OBJEXT) +elfgetchdr_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) +elfgetzdata_SOURCES = elfgetzdata.c +elfgetzdata_OBJECTS = elfgetzdata.$(OBJEXT) +elfgetzdata_DEPENDENCIES = $(am__DEPENDENCIES_2) +elfputzdata_SOURCES = elfputzdata.c +elfputzdata_OBJECTS = elfputzdata.$(OBJEXT) +elfputzdata_DEPENDENCIES = $(am__DEPENDENCIES_2) +elfrdwrnop_SOURCES = elfrdwrnop.c +elfrdwrnop_OBJECTS = elfrdwrnop.$(OBJEXT) +elfrdwrnop_DEPENDENCIES = $(am__DEPENDENCIES_2) +elfshphehdr_SOURCES = elfshphehdr.c +elfshphehdr_OBJECTS = elfshphehdr.$(OBJEXT) +elfshphehdr_DEPENDENCIES = $(am__DEPENDENCIES_2) +elfstrmerge_SOURCES = elfstrmerge.c +elfstrmerge_OBJECTS = elfstrmerge.$(OBJEXT) +elfstrmerge_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +elfstrtab_SOURCES = elfstrtab.c +elfstrtab_OBJECTS = elfstrtab.$(OBJEXT) +elfstrtab_DEPENDENCIES = $(am__DEPENDENCIES_2) +emptyfile_SOURCES = emptyfile.c +emptyfile_OBJECTS = emptyfile.$(OBJEXT) +emptyfile_DEPENDENCIES = $(am__DEPENDENCIES_2) +fillfile_SOURCES = fillfile.c +fillfile_OBJECTS = fillfile.$(OBJEXT) +fillfile_DEPENDENCIES = $(am__DEPENDENCIES_2) +find_prologues_SOURCES = find-prologues.c +find_prologues_OBJECTS = find-prologues.$(OBJEXT) +find_prologues_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_1) +funcretval_SOURCES = funcretval.c +funcretval_OBJECTS = funcretval.$(OBJEXT) +funcretval_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) +funcscopes_SOURCES = funcscopes.c +funcscopes_OBJECTS = funcscopes.$(OBJEXT) +funcscopes_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) +get_aranges_SOURCES = get-aranges.c +get_aranges_OBJECTS = get-aranges.$(OBJEXT) +get_aranges_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +get_files_SOURCES = get-files.c +get_files_OBJECTS = get-files.$(OBJEXT) +get_files_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +get_lines_SOURCES = get-lines.c +get_lines_OBJECTS = get-lines.$(OBJEXT) +get_lines_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +get_pubnames_SOURCES = get-pubnames.c +get_pubnames_OBJECTS = get-pubnames.$(OBJEXT) +get_pubnames_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) +get_units_invalid_SOURCES = get-units-invalid.c +get_units_invalid_OBJECTS = get-units-invalid.$(OBJEXT) +get_units_invalid_DEPENDENCIES = $(am__DEPENDENCIES_3) +get_units_split_SOURCES = get-units-split.c +get_units_split_OBJECTS = get-units-split.$(OBJEXT) +get_units_split_DEPENDENCIES = $(am__DEPENDENCIES_3) +getphdrnum_SOURCES = getphdrnum.c +getphdrnum_OBJECTS = getphdrnum.$(OBJEXT) +getphdrnum_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) +getsrc_die_SOURCES = getsrc_die.c +getsrc_die_OBJECTS = getsrc_die.$(OBJEXT) +getsrc_die_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +hash_SOURCES = hash.c +hash_OBJECTS = hash.$(OBJEXT) +hash_DEPENDENCIES = $(am__DEPENDENCIES_2) +leb128_SOURCES = leb128.c +leb128_OBJECTS = leb128.$(OBJEXT) +leb128_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) +line2addr_SOURCES = line2addr.c +line2addr_OBJECTS = line2addr.$(OBJEXT) +line2addr_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) +low_high_pc_SOURCES = low_high_pc.c +low_high_pc_OBJECTS = low_high_pc.$(OBJEXT) +low_high_pc_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) +msg_tst_SOURCES = msg_tst.c +msg_tst_OBJECTS = msg_tst.$(OBJEXT) +msg_tst_DEPENDENCIES = $(am__DEPENDENCIES_2) +newdata_SOURCES = newdata.c +newdata_OBJECTS = newdata.$(OBJEXT) +newdata_DEPENDENCIES = $(am__DEPENDENCIES_2) +newfile_SOURCES = newfile.c +newfile_OBJECTS = newfile.$(OBJEXT) +newfile_DEPENDENCIES = $(am__DEPENDENCIES_2) +newscn_SOURCES = newscn.c +newscn_OBJECTS = newscn.$(OBJEXT) +newscn_DEPENDENCIES = $(am__DEPENDENCIES_2) +next_files_SOURCES = next-files.c +next_files_OBJECTS = next-files.$(OBJEXT) +next_files_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +next_lines_SOURCES = next-lines.c +next_lines_OBJECTS = next-lines.$(OBJEXT) +next_lines_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +next_cfi_SOURCES = next_cfi.c +next_cfi_OBJECTS = next_cfi.$(OBJEXT) +next_cfi_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) +peel_type_SOURCES = peel_type.c +peel_type_OBJECTS = peel_type.$(OBJEXT) +peel_type_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) +rdwrmmap_SOURCES = rdwrmmap.c +rdwrmmap_OBJECTS = rdwrmmap.$(OBJEXT) +rdwrmmap_DEPENDENCIES = $(am__DEPENDENCIES_2) +read_unaligned_SOURCES = read_unaligned.c +read_unaligned_OBJECTS = read_unaligned.$(OBJEXT) +read_unaligned_DEPENDENCIES = $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +rerequest_tag_SOURCES = rerequest_tag.c +rerequest_tag_OBJECTS = rerequest_tag.$(OBJEXT) +rerequest_tag_DEPENDENCIES = $(am__DEPENDENCIES_3) +saridx_SOURCES = saridx.c +saridx_OBJECTS = saridx.$(OBJEXT) +saridx_DEPENDENCIES = $(am__DEPENDENCIES_2) +scnnames_SOURCES = scnnames.c +scnnames_OBJECTS = scnnames.$(OBJEXT) +scnnames_DEPENDENCIES = $(am__DEPENDENCIES_2) +sectiondump_SOURCES = sectiondump.c +sectiondump_OBJECTS = sectiondump.$(OBJEXT) +sectiondump_DEPENDENCIES = $(am__DEPENDENCIES_2) +show_abbrev_SOURCES = show-abbrev.c +show_abbrev_OBJECTS = show-abbrev.$(OBJEXT) +show_abbrev_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +show_die_info_SOURCES = show-die-info.c +show_die_info_OBJECTS = show-die-info.$(OBJEXT) +show_die_info_DEPENDENCIES = $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_2) +showptable_SOURCES = showptable.c +showptable_OBJECTS = showptable.$(OBJEXT) +showptable_DEPENDENCIES = $(am__DEPENDENCIES_2) +strptr_SOURCES = strptr.c +strptr_OBJECTS = strptr.$(OBJEXT) +strptr_DEPENDENCIES = $(am__DEPENDENCIES_2) +system_elf_libelf_test_SOURCES = system-elf-libelf-test.c +system_elf_libelf_test_OBJECTS = \ + system_elf_libelf_test-system-elf-libelf-test.$(OBJEXT) +system_elf_libelf_test_DEPENDENCIES = $(am__DEPENDENCIES_2) +test_elf_cntl_gelf_getshdr_SOURCES = test-elf_cntl_gelf_getshdr.c +test_elf_cntl_gelf_getshdr_OBJECTS = \ + test-elf_cntl_gelf_getshdr.$(OBJEXT) +test_elf_cntl_gelf_getshdr_DEPENDENCIES = $(am__DEPENDENCIES_2) +test_flag_nobits_SOURCES = test-flag-nobits.c +test_flag_nobits_OBJECTS = test-flag-nobits.$(OBJEXT) +test_flag_nobits_DEPENDENCIES = $(am__DEPENDENCIES_2) +test_nlist_SOURCES = test-nlist.c +test_nlist_OBJECTS = test_nlist-test-nlist.$(OBJEXT) +test_nlist_DEPENDENCIES = $(am__DEPENDENCIES_2) +test_nlist_LINK = $(CCLD) $(test_nlist_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +typeiter_SOURCES = typeiter.c +typeiter_OBJECTS = typeiter.$(OBJEXT) +typeiter_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +typeiter2_SOURCES = typeiter2.c +typeiter2_OBJECTS = typeiter2.$(OBJEXT) +typeiter2_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +unit_info_SOURCES = unit-info.c +unit_info_OBJECTS = unit-info.$(OBJEXT) +unit_info_DEPENDENCIES = $(am__DEPENDENCIES_3) +update1_SOURCES = update1.c +update1_OBJECTS = update1.$(OBJEXT) +update1_DEPENDENCIES = $(am__DEPENDENCIES_2) +update2_SOURCES = update2.c +update2_OBJECTS = update2.$(OBJEXT) +update2_DEPENDENCIES = $(am__DEPENDENCIES_2) +update3_SOURCES = update3.c +update3_OBJECTS = update3.$(OBJEXT) +update3_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +update4_SOURCES = update4.c +update4_OBJECTS = update4.$(OBJEXT) +update4_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +varlocs_SOURCES = varlocs.c +varlocs_OBJECTS = varlocs.$(OBJEXT) +varlocs_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) +vdsosyms_SOURCES = vdsosyms.c +vdsosyms_OBJECTS = vdsosyms.$(OBJEXT) +vdsosyms_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2) +vendorelf_SOURCES = vendorelf.c +vendorelf_OBJECTS = vendorelf.$(OBJEXT) +vendorelf_DEPENDENCIES = $(am__DEPENDENCIES_2) +xlate_notes_SOURCES = xlate_notes.c +xlate_notes_OBJECTS = xlate_notes.$(OBJEXT) +xlate_notes_DEPENDENCIES = $(am__DEPENDENCIES_2) +zstrptr_SOURCES = zstrptr.c +zstrptr_OBJECTS = zstrptr.$(OBJEXT) +zstrptr_DEPENDENCIES = $(am__DEPENDENCIES_2) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/addrcfi.Po ./$(DEPDIR)/addrscopes.Po \ + ./$(DEPDIR)/addsections.Po ./$(DEPDIR)/aggregate_size.Po \ + ./$(DEPDIR)/all-dwarf-ranges.Po ./$(DEPDIR)/alldts.Po \ + ./$(DEPDIR)/allfcts.Po ./$(DEPDIR)/allregs.Po \ + ./$(DEPDIR)/arextract.Po ./$(DEPDIR)/arls.Po \ + ./$(DEPDIR)/arsymtest.Po ./$(DEPDIR)/asm-tst1.Po \ + ./$(DEPDIR)/asm-tst2.Po ./$(DEPDIR)/asm-tst3.Po \ + ./$(DEPDIR)/asm-tst4.Po ./$(DEPDIR)/asm-tst5.Po \ + ./$(DEPDIR)/asm-tst6.Po ./$(DEPDIR)/asm-tst7.Po \ + ./$(DEPDIR)/asm-tst8.Po ./$(DEPDIR)/asm-tst9.Po \ + ./$(DEPDIR)/attr-integrate-skel.Po \ + ./$(DEPDIR)/backtrace-child.Po ./$(DEPDIR)/backtrace-data.Po \ + ./$(DEPDIR)/backtrace.Po \ + ./$(DEPDIR)/backtrace_child-backtrace-child.Po \ + ./$(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Po \ + ./$(DEPDIR)/buildid.Po ./$(DEPDIR)/debugaltlink.Po \ + ./$(DEPDIR)/debuginfod_build_id_find.Po \ + ./$(DEPDIR)/debuglink.Po ./$(DEPDIR)/deleted.Po \ + ./$(DEPDIR)/deleted_lib_so-deleted-lib.Po \ + ./$(DEPDIR)/dwarf-die-addr-die.Po \ + ./$(DEPDIR)/dwarf-getmacros.Po ./$(DEPDIR)/dwarf-getstring.Po \ + ./$(DEPDIR)/dwarf-ranges.Po \ + ./$(DEPDIR)/dwarf_default_lower_bound.Po \ + ./$(DEPDIR)/dwarfcfi.Po \ + ./$(DEPDIR)/dwelf_elf_e_machine_string.Po \ + ./$(DEPDIR)/dwelfgnucompressed.Po \ + ./$(DEPDIR)/dwfl-addr-sect.Po \ + ./$(DEPDIR)/dwfl-bug-addr-overflow.Po \ + ./$(DEPDIR)/dwfl-bug-fd-leak.Po \ + ./$(DEPDIR)/dwfl-bug-getmodules.Po \ + ./$(DEPDIR)/dwfl-bug-report.Po ./$(DEPDIR)/dwfl-proc-attach.Po \ + ./$(DEPDIR)/dwfl-report-elf-align.Po \ + ./$(DEPDIR)/dwfl-report-segment-contiguous.Po \ + ./$(DEPDIR)/dwfllines.Po ./$(DEPDIR)/dwflmodtest.Po \ + ./$(DEPDIR)/dwflsyms.Po ./$(DEPDIR)/early-offscn.Po \ + ./$(DEPDIR)/ecp.Po ./$(DEPDIR)/elfcopy.Po \ + ./$(DEPDIR)/elfgetchdr.Po ./$(DEPDIR)/elfgetzdata.Po \ + ./$(DEPDIR)/elfputzdata.Po ./$(DEPDIR)/elfrdwrnop.Po \ + ./$(DEPDIR)/elfshphehdr.Po ./$(DEPDIR)/elfstrmerge.Po \ + ./$(DEPDIR)/elfstrtab.Po ./$(DEPDIR)/emptyfile.Po \ + ./$(DEPDIR)/fillfile.Po ./$(DEPDIR)/find-prologues.Po \ + ./$(DEPDIR)/funcretval.Po ./$(DEPDIR)/funcscopes.Po \ + ./$(DEPDIR)/get-aranges.Po ./$(DEPDIR)/get-files.Po \ + ./$(DEPDIR)/get-lines.Po ./$(DEPDIR)/get-pubnames.Po \ + ./$(DEPDIR)/get-units-invalid.Po \ + ./$(DEPDIR)/get-units-split.Po ./$(DEPDIR)/getphdrnum.Po \ + ./$(DEPDIR)/getsrc_die.Po ./$(DEPDIR)/hash.Po \ + ./$(DEPDIR)/leb128.Po ./$(DEPDIR)/line2addr.Po \ + ./$(DEPDIR)/low_high_pc.Po ./$(DEPDIR)/msg_tst.Po \ + ./$(DEPDIR)/newdata.Po ./$(DEPDIR)/newfile.Po \ + ./$(DEPDIR)/newscn.Po ./$(DEPDIR)/next-files.Po \ + ./$(DEPDIR)/next-lines.Po ./$(DEPDIR)/next_cfi.Po \ + ./$(DEPDIR)/peel_type.Po ./$(DEPDIR)/rdwrmmap.Po \ + ./$(DEPDIR)/read_unaligned.Po ./$(DEPDIR)/rerequest_tag.Po \ + ./$(DEPDIR)/saridx.Po ./$(DEPDIR)/scnnames.Po \ + ./$(DEPDIR)/sectiondump.Po ./$(DEPDIR)/show-abbrev.Po \ + ./$(DEPDIR)/show-die-info.Po ./$(DEPDIR)/showptable.Po \ + ./$(DEPDIR)/strptr.Po \ + ./$(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Po \ + ./$(DEPDIR)/test-elf_cntl_gelf_getshdr.Po \ + ./$(DEPDIR)/test-flag-nobits.Po \ + ./$(DEPDIR)/test_nlist-test-nlist.Po ./$(DEPDIR)/typeiter.Po \ + ./$(DEPDIR)/typeiter2.Po ./$(DEPDIR)/unit-info.Po \ + ./$(DEPDIR)/update1.Po ./$(DEPDIR)/update2.Po \ + ./$(DEPDIR)/update3.Po ./$(DEPDIR)/update4.Po \ + ./$(DEPDIR)/varlocs.Po ./$(DEPDIR)/vdsosyms.Po \ + ./$(DEPDIR)/vendorelf.Po ./$(DEPDIR)/xlate_notes.Po \ + ./$(DEPDIR)/zstrptr.Po +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = addrcfi.c addrscopes.c addsections.c aggregate_size.c \ + all-dwarf-ranges.c alldts.c allfcts.c allregs.c arextract.c \ + arls.c arsymtest.c asm-tst1.c asm-tst2.c asm-tst3.c asm-tst4.c \ + asm-tst5.c asm-tst6.c asm-tst7.c asm-tst8.c asm-tst9.c \ + attr-integrate-skel.c backtrace.c backtrace-child.c \ + $(backtrace_child_biarch_SOURCES) backtrace-data.c \ + backtrace-dwarf.c buildid.c debugaltlink.c \ + debuginfod_build_id_find.c debuglink.c deleted.c deleted-lib.c \ + dwarf-die-addr-die.c dwarf-getmacros.c dwarf-getstring.c \ + dwarf-ranges.c dwarf_default_lower_bound.c dwarfcfi.c \ + dwelf_elf_e_machine_string.c dwelfgnucompressed.c \ + dwfl-addr-sect.c dwfl-bug-addr-overflow.c dwfl-bug-fd-leak.c \ + dwfl-bug-getmodules.c dwfl-bug-report.c dwfl-proc-attach.c \ + dwfl-report-elf-align.c dwfl-report-segment-contiguous.c \ + dwfllines.c dwflmodtest.c dwflsyms.c early-offscn.c ecp.c \ + elfcopy.c elfgetchdr.c elfgetzdata.c elfputzdata.c \ + elfrdwrnop.c elfshphehdr.c elfstrmerge.c elfstrtab.c \ + emptyfile.c fillfile.c find-prologues.c funcretval.c \ + funcscopes.c get-aranges.c get-files.c get-lines.c \ + get-pubnames.c get-units-invalid.c get-units-split.c \ + getphdrnum.c getsrc_die.c hash.c leb128.c line2addr.c \ + low_high_pc.c msg_tst.c newdata.c newfile.c newscn.c \ + next-files.c next-lines.c next_cfi.c peel_type.c rdwrmmap.c \ + read_unaligned.c rerequest_tag.c saridx.c scnnames.c \ + sectiondump.c show-abbrev.c show-die-info.c showptable.c \ + strptr.c system-elf-libelf-test.c test-elf_cntl_gelf_getshdr.c \ + test-flag-nobits.c test-nlist.c typeiter.c typeiter2.c \ + unit-info.c update1.c update2.c update3.c update4.c varlocs.c \ + vdsosyms.c vendorelf.c xlate_notes.c zstrptr.c +DIST_SOURCES = addrcfi.c addrscopes.c addsections.c aggregate_size.c \ + all-dwarf-ranges.c alldts.c allfcts.c allregs.c arextract.c \ + arls.c arsymtest.c asm-tst1.c asm-tst2.c asm-tst3.c asm-tst4.c \ + asm-tst5.c asm-tst6.c asm-tst7.c asm-tst8.c asm-tst9.c \ + attr-integrate-skel.c backtrace.c backtrace-child.c \ + $(backtrace_child_biarch_SOURCES) backtrace-data.c \ + backtrace-dwarf.c buildid.c debugaltlink.c \ + debuginfod_build_id_find.c debuglink.c deleted.c deleted-lib.c \ + dwarf-die-addr-die.c dwarf-getmacros.c dwarf-getstring.c \ + dwarf-ranges.c dwarf_default_lower_bound.c dwarfcfi.c \ + dwelf_elf_e_machine_string.c dwelfgnucompressed.c \ + dwfl-addr-sect.c dwfl-bug-addr-overflow.c dwfl-bug-fd-leak.c \ + dwfl-bug-getmodules.c dwfl-bug-report.c dwfl-proc-attach.c \ + dwfl-report-elf-align.c dwfl-report-segment-contiguous.c \ + dwfllines.c dwflmodtest.c dwflsyms.c early-offscn.c ecp.c \ + elfcopy.c elfgetchdr.c elfgetzdata.c elfputzdata.c \ + elfrdwrnop.c elfshphehdr.c elfstrmerge.c elfstrtab.c \ + emptyfile.c fillfile.c find-prologues.c funcretval.c \ + funcscopes.c get-aranges.c get-files.c get-lines.c \ + get-pubnames.c get-units-invalid.c get-units-split.c \ + getphdrnum.c getsrc_die.c hash.c leb128.c line2addr.c \ + low_high_pc.c msg_tst.c newdata.c newfile.c newscn.c \ + next-files.c next-lines.c next_cfi.c peel_type.c rdwrmmap.c \ + read_unaligned.c rerequest_tag.c saridx.c scnnames.c \ + sectiondump.c show-abbrev.c show-die-info.c showptable.c \ + strptr.c system-elf-libelf-test.c test-elf_cntl_gelf_getshdr.c \ + test-flag-nobits.c test-nlist.c typeiter.c typeiter2.c \ + unit-info.c update1.c update2.c update3.c update4.c varlocs.c \ + vdsosyms.c vendorelf.c xlate_notes.c zstrptr.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + $(top_srcdir)/config/eu.am $(top_srcdir)/config/test-driver \ + ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIB = @BZ2_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_BIARCH = @CC_BIARCH@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUGINFOD_URLS = @DEBUGINFOD_URLS@ +DEBUGPRED = @DEBUGPRED@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"' +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_BISON = @HAVE_BISON@ +HAVE_BUNZIP2 = @HAVE_BUNZIP2@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_FLEX = @HAVE_FLEX@ +HAVE_GAWK = @HAVE_GAWK@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_ZSTD = @HAVE_ZSTD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDEBUGINFOD_SONAME = @LIBDEBUGINFOD_SONAME@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLZMA = @LIBLZMA@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBZSTD = @LIBZSTD@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +argp_LDADD = @argp_LDADD@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dso_LDFLAGS = @dso_LDFLAGS@ +dvidir = @dvidir@ +eu_version = @eu_version@ +exec_prefix = @exec_prefix@ +fpic_CFLAGS = @fpic_CFLAGS@ +fpie_CFLAGS = @fpie_CFLAGS@ +fts_LIBS = @fts_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libarchive_CFLAGS = @libarchive_CFLAGS@ +libarchive_LIBS = @libarchive_LIBS@ +libcurl_CFLAGS = @libcurl_CFLAGS@ +libcurl_LIBS = @libcurl_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +obstack_LIBS = @obstack_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zip_LIBS = @zip_LIBS@ +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \ + -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \ + -I$(top_srcdir)/libdwfl -I$(top_srcdir)/libdwelf \ + -I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \ + -I$(top_srcdir)/lib -I.. + +# Drop the 'u' flag that automake adds by default. It is incompatible +# with deterministic archives. +ARFLAGS = cr +@ADD_STACK_USAGE_WARNING_FALSE@STACK_USAGE_WARNING = + +# Warn about stack usage of more than 256K = 262144 bytes. +@ADD_STACK_USAGE_WARNING_TRUE@STACK_USAGE_WARNING = -Wstack-usage=262144 +@SANE_LOGICAL_OP_WARNING_FALSE@LOGICAL_OP_WARNING = +@SANE_LOGICAL_OP_WARNING_TRUE@LOGICAL_OP_WARNING = -Wlogical-op +@HAVE_DUPLICATED_COND_WARNING_FALSE@DUPLICATED_COND_WARNING = +@HAVE_DUPLICATED_COND_WARNING_TRUE@DUPLICATED_COND_WARNING = -Wduplicated-cond +@HAVE_NULL_DEREFERENCE_WARNING_FALSE@NULL_DEREFERENCE_WARNING = +@HAVE_NULL_DEREFERENCE_WARNING_TRUE@NULL_DEREFERENCE_WARNING = -Wnull-dereference +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_FALSE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough + +# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the +# warning +@HAVE_IMPLICIT_FALLTHROUGH_5_WARNING_TRUE@@HAVE_IMPLICIT_FALLTHROUGH_WARNING_TRUE@IMPLICIT_FALLTHROUGH_WARNING = -Wimplicit-fallthrough=5 +@HAVE_IMPLICIT_FALLTHROUGH_WARNING_FALSE@IMPLICIT_FALLTHROUGH_WARNING = +@HAVE_TRAMPOLINES_WARNING_FALSE@TRAMPOLINES_WARNING = +@HAVE_TRAMPOLINES_WARNING_TRUE@TRAMPOLINES_WARNING = -Wtrampolines +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_FALSE@NO_PACKED_NOT_ALIGNED_WARNING = +@HAVE_NO_PACKED_NOT_ALIGNED_WARNING_TRUE@NO_PACKED_NOT_ALIGNED_WARNING = -Wno-packed-not-aligned +AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \ + -Wold-style-definition -Wstrict-prototypes $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CFLAGS) + +AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \ + $(TRAMPOLINES_WARNING) \ + $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \ + $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \ + $(if $($(*F)_no_Werror),,-Werror) \ + $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \ + $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \ + $(if $($(*F)_no_Wpacked_not_aligned),$(NO_PACKED_NOT_ALIGNED_WARNING),) \ + $($(*F)_CXXFLAGS) + +COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE)) +DEFS.os = -DPIC -DSHARED $(am__append_1) + +# A lock file used to make sure only one test dumps core at a time +CLEANFILES = *.gcno *.gcda core-dump-backtrace.lock +textrel_msg = echo "WARNING: TEXTREL found in '$@'" +@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg) +@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1 +textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi +BUILD_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../backends:\$$ORIGIN/../libelf +AM_LDFLAGS = -Wl,-rpath-link,../libasm:../libdw:../libelf \ + $(am__append_2) +@TESTS_RPATH_FALSE@tests_rpath = no +@TESTS_RPATH_TRUE@tests_rpath = yes +asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ + asm-tst6 asm-tst7 asm-tst8 asm-tst9 + +@GCOV_FALSE@GCOV_FLAGS = +@GCOV_TRUE@GCOV_FLAGS = -fprofile-arcs -ftest-coverage +EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ + run-show-die-info.sh run-get-files.sh run-get-lines.sh \ + run-next-files.sh run-next-lines.sh testfile-only-debug-line.bz2 \ + run-get-pubnames.sh run-get-aranges.sh \ + run-show-abbrev.sh run-strip-test.sh \ + run-strip-test2.sh run-ecp-test.sh run-ecp-test2.sh \ + testfile.bz2 testfile2.bz2 testfile3.bz2 testfile4.bz2 \ + testfile5.bz2 testfile6.bz2 testfile7.bz2 testfile8.bz2 \ + testfile9.bz2 testfile10.bz2 testfile11.bz2 testfile12.bz2 \ + testfile13.bz2 run-strip-test3.sh run-allfcts.sh \ + testfile_class_func.bz2 testfile_nested_funcs.bz2 \ + testfile-lto-gcc10.bz2 \ + testfile-lto-gcc9.bz2 testfile-lto-gcc8.bz2 \ + run-line2addr.sh run-elflint-test.sh testfile14.bz2 \ + run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \ + run-strip-test7.sh run-strip-test8.sh run-strip-groups.sh \ + run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \ + run-strip-test12.sh \ + run-strip-nothing.sh run-strip-remove-keep.sh run-strip-g.sh \ + run-annobingroup.sh testfile-annobingroup.o.bz2 \ + testfile-annobingroup-i386.o.bz2 \ + testfile-annobingroup-x86_64.o.bz2 \ + run-strip-strmerge.sh run-strip-nobitsalign.sh \ + testfile-nobitsalign.bz2 testfile-nobitsalign.strip.bz2 \ + run-strip-reloc.sh hello_i386.ko.bz2 hello_x86_64.ko.bz2 \ + hello_ppc64.ko.bz2 hello_s390.ko.bz2 hello_aarch64.ko.bz2 \ + hello_m68k.ko.bz2 hello_riscv64.ko.bz2 hello_csky.ko.bz2 \ + run-unstrip-test.sh run-unstrip-test2.sh \ + testfile-info-link.bz2 testfile-info-link.debuginfo.bz2 \ + testfile-info-link.stripped.bz2 run-unstrip-test3.sh \ + run-unstrip-test4.sh testfile-strtab.bz2 \ + testfile-strtab.stripped.bz2 testfile-strtab.debuginfo.bz2 \ + run-unstrip-M.sh run-elfstrmerge-test.sh \ + run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \ + run-ranlib-test3.sh run-ranlib-test4.sh \ + run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ + run-nm-syms.sh testfilesyms32.bz2 testfilesyms64.bz2 \ + run-nm-self.sh run-readelf-self.sh run-readelf-info-plus.sh \ + run-readelf-compressed.sh \ + run-readelf-compressed-zstd.sh \ + run-readelf-const-values.sh testfile-const-values.debug.bz2 \ + run-addrcfi.sh run-dwarfcfi.sh \ + testfile11-debugframe.bz2 testfile12-debugframe.bz2 \ + testfileaarch64-debugframe.bz2 testfilearm-debugframe.bz2 \ + testfileppc32-debugframe.bz2 testfileppc64-debugframe.bz2 \ + testfilecsky.bz2 \ + run-varlocs-self.sh run-exprlocs-self.sh \ + run-find-prologues.sh run-allregs.sh run-native-test.sh \ + run-addrname-test.sh run-dwfl-bug-offline-rel.sh \ + run-dwfl-addr-sect.sh run-early-offscn.sh \ + run-dwarf-getmacros.sh \ + run-dwarf-ranges.sh debug-ranges-no-lowpc.o.bz2 \ + testfileranges4.debug.bz2 testfileranges5.debug.bz2 \ + testfilesplitranges5.debug.bz2 \ + testfile-ranges-hello5.dwo.bz2 testfile-ranges-world5.dwo.bz2 \ + run-test-flag-nobits.sh \ + run-dwarf-getstring.sh run-rerequest_tag.sh run-alldts.sh \ + testfile15.bz2 testfile15.debug.bz2 \ + testfile16.bz2 testfile16.debug.bz2 \ + testfile17.bz2 testfile17.debug.bz2 \ + testfile18.bz2 testfile19.bz2 testfile19.index.bz2 \ + testfile20.bz2 testfile20.index.bz2 \ + testfile21.bz2 testfile21.index.bz2 \ + testfile22.bz2 testfile23.bz2 testfile24.bz2 testfile25.bz2 \ + testfile26.bz2 testfile27.bz2 \ + coverage.sh test-subr.sh test-wrapper.sh \ + run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \ + run-readelf-test4.sh run-readelf-twofiles.sh \ + run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \ + run-debuglink.sh run-debugaltlink.sh run-buildid.sh \ + testfile29.bz2 testfile29.rdwr.bz2 \ + testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ + testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 \ + testfile36.bz2 testfile36.debug.bz2 \ + testfile37.bz2 testfile37.debug.bz2 \ + testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2 \ + testfile41.bz2 testfile42.bz2 testfile42_noshdrs.bz2 \ + testfile43.bz2 \ + testfile44.S.bz2 testfile44.expect.bz2 run-disasm-x86.sh \ + testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \ + testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \ + testfile49.bz2 testfile50.bz2 testfile51.bz2 \ + testfile-macros-0xff.bz2 \ + run-readelf-macro.sh testfilemacro.bz2 \ + run-readelf-loc.sh testfileloc.bz2 \ + splitdwarf4-not-split4.dwo.bz2 \ + testfile-splitdwarf4-not-split4.debug.bz2 \ + run-readelf-ranges.sh \ + run-readelf-aranges.sh run-readelf-line.sh testfilefoobarbaz.bz2 \ + testfile-ppc64-min-instr.bz2 \ + testfile-dwarf-45.source \ + testfile-dwarf-4.bz2 testfile-dwarf-5.bz2 \ + run-readelf-z.sh \ + run-readelf-dwz-multi.sh libtestfile_multi_shared.so.bz2 \ + testfile_multi.dwz.bz2 testfile_multi_main.bz2 \ + testfile-dwzstr.bz2 testfile-dwzstr.multi.bz2 \ + run-readelf-addr.sh run-readelf-str.sh \ + run-readelf-types.sh \ + run-readelf-frames.sh \ + run-readelf-n.sh \ + testfile-gnu-property-note.bz2 testfile-gnu-property-note.o.bz2 \ + testfile_gnu_props.32le.o.bz2 \ + testfile_gnu_props.64le.o.bz2 \ + testfile_gnu_props.32be.o.bz2 \ + testfile_gnu_props.64be.o.bz2 \ + testfile-gnu-property-note-aarch64.bz2 \ + run-retain.sh testfile-retain.o.bz2 \ + run-allfcts-multi.sh \ + test-offset-loop.bz2 test-offset-loop.alt.bz2 \ + run-prelink-addr-test.sh \ + testfile52-32.so.bz2 testfile52-32.so.debug.bz2 \ + testfile52-32.prelink.so.bz2 testfile52-32.noshdrs.so.bz2 \ + testfile52-64.so.bz2 testfile52-64.so.debug.bz2 \ + testfile52-64.prelink.so.bz2 testfile52-64.noshdrs.so.bz2 \ + testfile53-32.bz2 testfile53-32.debug.bz2 \ + testfile53-32.prelink.bz2 testfile53-64.bz2 \ + testfile53-64.debug.bz2 testfile53-64.prelink.bz2 \ + testfile54-32.so.bz2 testfile54-32.so.debug.bz2 \ + testfile54-32.prelink.so.bz2 testfile54-32.noshdrs.so.bz2 \ + testfile54-64.so.bz2 testfile54-64.so.debug.bz2 \ + testfile54-64.prelink.so.bz2 testfile54-64.noshdrs.so.bz2 \ + testfile55-32.bz2 testfile55-32.debug.bz2 \ + testfile55-32.prelink.bz2 testfile55-64.bz2 \ + testfile55-64.debug.bz2 testfile55-64.prelink.bz2 \ + testfile56.bz2 testfile57.bz2 testfile58.bz2 \ + run-typeiter.sh testfile59.bz2 \ + run-readelf-d.sh testlib_dynseg.so.bz2 \ + testfile-s390x-hash-both.bz2 \ + run-readelf-gdb_index.sh testfilegdbindex5.bz2 \ + testfilegdbindex7.bz2 \ + run-readelf-s.sh testfilebazdbg.bz2 testfilebazdyn.bz2 \ + testfilebazmin.bz2 testfilebazdbg.debug.bz2 testfilebazmdb.bz2 \ + testfilebaztab.bz2 testfilebasmin.bz2 testfilebaxmin.bz2 \ + testfilebazdbg_pl.bz2 testfilebazmin_pl.bz2 \ + testfilebazdbg_plr.bz2 testfilebazmin_plr.bz2 \ + testfilebazdbgppc64.bz2 testfilebazdbgppc64.debug.bz2 \ + testfilebazdbgppc64_pl.bz2 testfilebazdbgppc64_plr.bz2 \ + testfilebazdynppc64.bz2 testfilebazmdbppc64.bz2 \ + testfilebazminppc64.bz2 testfilebazminppc64_pl.bz2 \ + testfilebazminppc64_plr.bz2 testfilebaztabppc64.bz2 \ + run-readelf-variant.sh testfile-ada-variant.bz2 \ + run-dwflsyms.sh \ + run-unstrip-n.sh testcore-rtlib.bz2 testcore-rtlib-ppc.bz2 \ + run-low_high_pc.sh testfile_low_high_pc.bz2 \ + run-macro-test.sh testfile-macinfo.bz2 testfile-macros.bz2 \ + run-elf_cntl_gelf_getshdr.sh \ + run-test-archive64.sh testarchive64.a.bz2 \ + testfile61.bz2 \ + run-readelf-vmcoreinfo.sh testfile62.bz2 \ + run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \ + testfile65.bz2 testfile67.bz2 testfile68.bz2 \ + testfile69.core.bz2 testfile69.so.bz2 \ + testfile70.core.bz2 testfile70.exec.bz2 testfile71.bz2 \ + run-dwfllines.sh run-dwfl-report-elf-align.sh \ + testfile-dwfl-report-elf-align-shlib.so.bz2 \ + testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \ + test-core.exec.bz2 run-addr2line-test.sh \ + run-addr2line-i-test.sh testfile-inlines.bz2 \ + run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \ + run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ + testfileppc32.bz2 testfileppc64.bz2 \ + testfiles390.bz2 testfiles390x.bz2 \ + testfilearm.bz2 testfileaarch64.bz2 \ + run-varlocs.sh run-exprlocs.sh testfile-stridex.bz2 \ + testfile_const_type.c testfile_const_type.bz2 \ + testfile_implicit_pointer.c testfile_implicit_pointer.bz2 \ + testfile_parameter_ref.c testfile_parameter_ref.bz2 \ + testfile_entry_value.c testfile_entry_value.bz2 \ + testfile_implicit_value.c testfile_implicit_value.bz2 \ + testfile_aarch64_core.bz2 testfile_i686_core.bz2 \ + addrx_constx-4.dwo.bz2 addrx_constx-5.dwo.bz2 \ + testfile-addrx_constx-4.bz2 testfile-addrx_constx-5.bz2 \ + run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \ + run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \ + run-backtrace-native.sh run-backtrace-native-biarch.sh \ + run-backtrace-native-core.sh run-backtrace-native-core-biarch.sh \ + run-backtrace-core-x86_64.sh run-backtrace-core-i386.sh \ + run-backtrace-fp-core-x86_64.sh \ + run-backtrace-core-x32.sh \ + run-backtrace-fp-core-aarch64.sh \ + backtrace.aarch64.fp.core.bz2 backtrace.aarch64.fp.exec.bz2 \ + backtrace-subr.sh backtrace.i386.core.bz2 backtrace.i386.exec.bz2 \ + run-backtrace-fp-core-i386.sh \ + backtrace.i386.fp.core.bz2 backtrace.i386.fp.exec.bz2 \ + run-backtrace-fp-core-ppc64le.sh \ + backtrace.ppc64le.fp.core.bz2 backtrace.ppc64le.fp.exec.bz2 \ + backtrace.x86_64.core.bz2 backtrace.x86_64.exec.bz2 \ + backtrace.x86_64.fp.core.bz2 backtrace.x86_64.fp.exec.bz2 \ + backtrace.ppc.core.bz2 backtrace.ppc.exec.bz2 \ + run-backtrace-core-ppc.sh testfile66.bz2 testfile66.core.bz2 \ + backtrace.s390x.core.bz2 backtrace.s390x.exec.bz2 \ + backtrace.s390.core.bz2 backtrace.s390.exec.bz2 \ + run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \ + run-backtrace-core-aarch64.sh \ + backtrace.aarch64.core.bz2 backtrace.aarch64.exec.bz2 \ + run-backtrace-core-sparc.sh \ + backtrace.sparc.core.bz2 backtrace.sparc.exec.bz2 \ + run-backtrace-demangle.sh testfile-backtrace-demangle.bz2 \ + testfile-backtrace-demangle.cc \ + testfile-backtrace-demangle.core.bz2 \ + run-stack-d-test.sh run-stack-i-test.sh \ + run-stack-demangled-test.sh \ + testfiledwarfinlines.bz2 testfiledwarfinlines.core.bz2 \ + run-readelf-zdebug.sh testfile-debug.bz2 testfile-zdebug.bz2 \ + run-readelf-zdebug-rel.sh testfile-debug-rel.o.bz2 \ + testfile-debug-rel-g.o.bz2 testfile-debug-rel-z.o.bz2 \ + run-readelf-zx.sh run-readelf-zp.sh \ + run-deleted.sh run-linkmap-cut.sh linkmap-cut-lib.so.bz2 \ + linkmap-cut.bz2 linkmap-cut.core.bz2 \ + run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2 \ + testfile-sizes3.o.bz2 testfile-sizes4.o.bz2 testfile-sizes4.s \ + run-peel-type.sh \ + run-readelf-A.sh testfileppc32attrs.o.bz2 \ + testfilesparc64attrs.o.bz2 testfileppc64attrs.o.bz2 \ + testfile-debug-types.bz2 \ + run-getsrc-die.sh run-strptr.sh \ + testfile-x32-core.bz2 testfile-x32.bz2 \ + backtrace.x32.core.bz2 backtrace.x32.exec.bz2 \ + testfile-x32-s.bz2 testfile-x32-d.bz2 testfile-x32-debug.bz2 \ + run-lfs-symbols.sh lfs-symbols testfile-nolfs.bz2 \ + testfile-zgnu32.bz2 testfile-zgnu64.bz2 \ + testfile-zgnu32be.bz2 testfile-zgnu64be.bz2 \ + run-dwelfgnucompressed.sh \ + testfile-zgabi32.bz2 testfile-zgabi64.bz2 \ + testfile-zgabi32be.bz2 testfile-zgabi64be.bz2 \ + run-elfgetchdr.sh run-elfgetzdata.sh run-elfputzdata.sh \ + run-zstrptr.sh run-compress-test.sh \ + run-disasm-bpf.sh \ + testfile-bpf-dis1.expect.bz2 testfile-bpf-dis1.o.bz2 \ + run-reloc-bpf.sh \ + testfile-bpf-reloc.expect.bz2 testfile-bpf-reloc.o.bz2 \ + testfile-m68k-core.bz2 testfile-m68k.bz2 testfile-m68k-s.bz2 \ + run-dwarf-die-addr-die.sh \ + run-get-units-invalid.sh run-get-units-split.sh \ + testfile-hello4.dwo.bz2 testfile-hello5.dwo.bz2 \ + testfile-splitdwarf-4.bz2 testfile-splitdwarf-5.bz2 \ + testfile-world5.dwo.bz2 testfile-world4.dwo.bz2 \ + run-attr-integrate-skel.sh \ + run-all-dwarf-ranges.sh testfilesplitranges4.debug.bz2 \ + testfile-ranges-hello.dwo.bz2 testfile-ranges-world.dwo.bz2 \ + run-unit-info.sh run-next-cfi.sh run-next-cfi-self.sh \ + testfile-riscv64.bz2 testfile-riscv64-s.bz2 \ + testfile-riscv64-core.bz2 \ + run-reverse-sections.sh run-reverse-sections-self.sh \ + run-copyadd-sections.sh run-copymany-sections.sh \ + run-large-elf-file.sh \ + run-typeiter-many.sh run-strip-test-many.sh \ + testfile-debug-rel-ppc64-g.o.bz2 \ + testfile-debug-rel-ppc64-z.o.bz2 \ + testfile-debug-rel-ppc64.o.bz2 \ + run-strip-version.sh testfile-version.bz2 \ + run-xlate-note.sh \ + run-readelf-discr.sh \ + testfile-rng.debug.bz2 testfile-urng.debug.bz2 \ + run-dwelf_elf_e_machine_string.sh \ + run-elfclassify.sh run-elfclassify-self.sh \ + run-disasm-riscv64.sh \ + testfile-riscv64-dis1.o.bz2 testfile-riscv64-dis1.expect.bz2 \ + run-debuginfod-find.sh \ + debuginfod-rpms/fedora30/hello2-1.0-2.src.rpm \ + debuginfod-rpms/fedora30/hello2-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-debugsource-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-two-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora30/hello2-two-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-1.0-2.src.rpm \ + debuginfod-rpms/fedora31/hello3-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-debugsource-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-two-1.0-2.x86_64.rpm \ + debuginfod-rpms/fedora31/hello3-two-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/hello2.spec. \ + debuginfod-rpms/rhel6/hello2-1.0-2.i686.rpm \ + debuginfod-rpms/rhel6/hello2-1.0-2.src.rpm \ + debuginfod-rpms/rhel6/hello2-debuginfo-1.0-2.i686.rpm \ + debuginfod-rpms/rhel6/hello2-two-1.0-2.i686.rpm \ + debuginfod-rpms/rhel7/hello2-1.0-2.src.rpm \ + debuginfod-rpms/rhel7/hello2-1.0-2.x86_64.rpm \ + debuginfod-rpms/rhel7/hello2-debuginfo-1.0-2.x86_64.rpm \ + debuginfod-rpms/rhel7/hello2-two-1.0-2.x86_64.rpm \ + debuginfod-rpms/rhel7/hello2-two-1.0-2.x86_64.rpm \ + debuginfod-debs/hithere-dbgsym_1.0-1_amd64.ddeb \ + debuginfod-debs/hithere_1.0-1.debian.tar.xz \ + debuginfod-debs/hithere_1.0-1.dsc \ + debuginfod-debs/hithere_1.0-1_amd64.deb \ + debuginfod-debs/hithere_1.0.orig.tar.gz \ + debuginfod-tars/hello-1-1-x86_64.pkg.tar.xz \ + debuginfod-tars/hello-debug-1-1-x86_64.pkg.tar.bz2 \ + debuginfod-tars/pacman-sources/PKGBUILD \ + debuginfod-tars/pacman-sources/README.md \ + debuginfod-tars/pacman-sources/hello.c \ + run-pt_gnu_prop-tests.sh \ + testfile_pt_gnu_prop.bz2 testfile_pt_gnu_prop32.bz2 \ + run-getphdrnum.sh testfile-phdrs.elf.bz2 \ + run-test-includes.sh run-low_high_pc-dw-form-indirect.sh \ + run-readelf-dw-form-indirect.sh testfile-dw-form-indirect.bz2 + +@USE_VALGRIND_TRUE@valgrind_cmd = valgrind -q --leak-check=full --error-exitcode=1 +installed_TESTS_ENVIRONMENT = libdir='$(DESTDIR)$(libdir)'; \ + bindir='$(DESTDIR)$(bindir)'; \ + LC_ALL=C; LANG=C; \ + VALGRIND_CMD='$(valgrind_cmd)'; \ + abs_srcdir='$(abs_srcdir)'; \ + abs_builddir='$(abs_builddir)'; \ + abs_top_builddir='$(abs_top_builddir)'; \ + export abs_srcdir; export abs_builddir; \ + export abs_top_builddir; \ + export libdir; export bindir; \ + export LC_ALL; export LANG; export VALGRIND_CMD; \ + unset DEBUGINFOD_URLS; \ + NM='$(NM)'; export NM; \ + CC='$(CC)'; export CC; + +installed_LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \ + installed $(tests_rpath) \ + '$(program_transform_name)' + +TESTS_ENVIRONMENT = LC_ALL=C; LANG=C; VALGRIND_CMD='$(valgrind_cmd)'; \ + abs_srcdir='$(abs_srcdir)'; \ + abs_builddir='$(abs_builddir)'; \ + abs_top_builddir='$(abs_top_builddir)'; \ + export abs_srcdir; export abs_builddir; \ + export abs_top_builddir; \ + export LC_ALL; export LANG; export VALGRIND_CMD; \ + unset DEBUGINFOD_URLS; \ + NM='$(NM)'; export NM; \ + CC='$(CC)'; export CC; + +LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \ + $(abs_top_builddir)/libdw:$(abs_top_builddir)/backends:$(abs_top_builddir)/libelf:$(abs_top_builddir)/libasm:$(abs_top_builddir)/debuginfod + +@BUILD_STATIC_FALSE@libdw = ../libdw/libdw.so +@BUILD_STATIC_TRUE@libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread +@BUILD_STATIC_FALSE@libelf = ../libelf/libelf.so +@BUILD_STATIC_TRUE@libelf = ../libelf/libelf.a -lz +@BUILD_STATIC_FALSE@libasm = ../libasm/libasm.so +@BUILD_STATIC_TRUE@libasm = ../libasm/libasm.a +libebl = ../libebl/libebl.a ../backends/libebl_backends.a ../libcpu/libcpu.a +libeu = ../lib/libeu.a +arextract_LDADD = $(libelf) +arsymtest_LDADD = $(libelf) +newfile_LDADD = $(libelf) +saridx_LDADD = $(libelf) +scnnames_LDADD = $(libelf) +sectiondump_LDADD = $(libelf) +showptable_LDADD = $(libelf) +hash_LDADD = $(libelf) +test_nlist_CFLAGS = -g -O0 +test_nlist_LDADD = $(libelf) +msg_tst_LDADD = $(libelf) +newscn_LDADD = $(libelf) +early_offscn_LDADD = $(libelf) +ecp_LDADD = $(libelf) +update1_LDADD = $(libelf) +update2_LDADD = $(libelf) +update3_LDADD = $(libdw) $(libelf) +update4_LDADD = $(libdw) $(libelf) +show_die_info_LDADD = $(libdw) $(libelf) +get_pubnames_LDADD = $(libdw) $(libelf) +show_abbrev_LDADD = $(libdw) $(libelf) +get_lines_LDADD = $(libdw) $(libelf) +next_lines_LDADD = $(libdw) $(libelf) +get_files_LDADD = $(libdw) $(libelf) +next_files_LDADD = $(libdw) $(libelf) +get_aranges_LDADD = $(libdw) $(libelf) +allfcts_LDADD = $(libdw) $(libelf) +line2addr_LDADD = $(libdw) $(argp_LDADD) +addrscopes_LDADD = $(libdw) $(argp_LDADD) +funcscopes_LDADD = $(libdw) $(argp_LDADD) +funcretval_LDADD = $(libdw) $(argp_LDADD) +allregs_LDADD = $(libdw) $(argp_LDADD) +find_prologues_LDADD = $(libdw) $(argp_LDADD) +#show_ciefde_LDADD = ../libdwarf/libdwarf.so $(libelf) +asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) +dwflmodtest_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) +rdwrmmap_LDADD = $(libelf) +dwfl_bug_addr_overflow_LDADD = $(libdw) $(libebl) $(libelf) +arls_LDADD = $(libelf) +dwfl_bug_fd_leak_LDADD = $(libdw) $(libebl) $(libelf) +dwfl_bug_report_LDADD = $(libdw) $(libebl) $(libelf) +dwfl_bug_getmodules_LDADD = $(libdw) $(libebl) $(libelf) +dwfl_addr_sect_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) +dwarf_getmacros_LDADD = $(libdw) +dwarf_ranges_LDADD = $(libdw) +dwarf_getstring_LDADD = $(libdw) +addrcfi_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) +dwarfcfi_LDADD = $(libdw) $(libelf) +test_flag_nobits_LDADD = $(libelf) +rerequest_tag_LDADD = $(libdw) +alldts_LDADD = $(libdw) $(libelf) +typeiter_LDADD = $(libdw) $(libelf) +typeiter2_LDADD = $(libdw) $(libelf) +low_high_pc_LDADD = $(libdw) $(libelf) $(argp_LDADD) +test_elf_cntl_gelf_getshdr_LDADD = $(libelf) +dwflsyms_LDADD = $(libdw) $(libelf) $(argp_LDADD) +dwfllines_LDADD = $(libdw) $(libelf) $(argp_LDADD) +dwfl_report_elf_align_LDADD = $(libdw) +dwfl_report_segment_contiguous_LDADD = $(libdw) $(libebl) $(libelf) +varlocs_LDADD = $(libdw) $(libelf) $(argp_LDADD) +backtrace_LDADD = $(libdw) $(libelf) $(argp_LDADD) +# backtrace-child-biarch also uses those *_CFLAGS and *_LDLAGS variables: +backtrace_child_CFLAGS = $(fpie_CFLAGS) +backtrace_child_LDFLAGS = -pie -pthread +backtrace_child_biarch_SOURCES = backtrace-child.c +backtrace_data_LDADD = $(libdw) $(libelf) +backtrace_dwarf_CFLAGS = -Wno-unused-parameter +backtrace_dwarf_LDADD = $(libdw) $(libelf) +debuglink_LDADD = $(libdw) $(libelf) +debugaltlink_LDADD = $(libdw) $(libelf) +buildid_LDADD = $(libdw) $(libelf) +deleted_LDADD = ./deleted-lib.so +deleted_lib_so_LDFLAGS = -shared +deleted_lib_so_CFLAGS = $(fpic_CFLAGS) -fasynchronous-unwind-tables +aggregate_size_LDADD = $(libdw) $(libelf) $(argp_LDADD) +peel_type_LDADD = $(libdw) $(libelf) $(argp_LDADD) +vdsosyms_LDADD = $(libdw) $(libelf) +getsrc_die_LDADD = $(libdw) $(libelf) +strptr_LDADD = $(libelf) +newdata_LDADD = $(libelf) +elfstrtab_LDADD = $(libelf) +dwfl_proc_attach_LDADD = $(libdw) +dwfl_proc_attach_LDFLAGS = -pthread $(AM_LDFLAGS) +elfshphehdr_LDADD = $(libelf) +elfstrmerge_LDADD = $(libdw) $(libelf) +dwelfgnucompressed_LDADD = $(libelf) $(libdw) +elfgetchdr_LDADD = $(libelf) $(libdw) +elfgetzdata_LDADD = $(libelf) +elfputzdata_LDADD = $(libelf) +zstrptr_LDADD = $(libelf) +emptyfile_LDADD = $(libelf) +vendorelf_LDADD = $(libelf) +fillfile_LDADD = $(libelf) +dwarf_default_lower_bound_LDADD = $(libdw) +dwarf_die_addr_die_LDADD = $(libdw) +get_units_invalid_LDADD = $(libdw) +get_units_split_LDADD = $(libdw) +attr_integrate_skel_LDADD = $(libdw) +all_dwarf_ranges_LDADD = $(libdw) +unit_info_LDADD = $(libdw) +next_cfi_LDADD = $(libelf) $(libdw) +elfcopy_LDADD = $(libelf) +addsections_LDADD = $(libelf) +debuginfod_build_id_find_LDADD = $(libelf) $(libdw) +xlate_notes_LDADD = $(libelf) +elfrdwrnop_LDADD = $(libelf) +dwelf_elf_e_machine_string_LDADD = $(libelf) $(libdw) +getphdrnum_LDADD = $(libelf) $(libdw) +leb128_LDADD = $(libelf) $(libdw) +read_unaligned_LDADD = $(libelf) $(libdw) + +# We want to test the libelf header against the system elf.h header. +# Don't include any -I CPPFLAGS. Except when we install our own elf.h. +@INSTALL_ELFH_FALSE@system_elf_libelf_test_CPPFLAGS = +@INSTALL_ELFH_TRUE@system_elf_libelf_test_CPPFLAGS = -I$(top_srcdir)/libelf +system_elf_libelf_test_LDADD = $(libelf) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/config/eu.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) + +addrcfi$(EXEEXT): $(addrcfi_OBJECTS) $(addrcfi_DEPENDENCIES) $(EXTRA_addrcfi_DEPENDENCIES) + @rm -f addrcfi$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(addrcfi_OBJECTS) $(addrcfi_LDADD) $(LIBS) + +addrscopes$(EXEEXT): $(addrscopes_OBJECTS) $(addrscopes_DEPENDENCIES) $(EXTRA_addrscopes_DEPENDENCIES) + @rm -f addrscopes$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(addrscopes_OBJECTS) $(addrscopes_LDADD) $(LIBS) + +addsections$(EXEEXT): $(addsections_OBJECTS) $(addsections_DEPENDENCIES) $(EXTRA_addsections_DEPENDENCIES) + @rm -f addsections$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(addsections_OBJECTS) $(addsections_LDADD) $(LIBS) + +aggregate_size$(EXEEXT): $(aggregate_size_OBJECTS) $(aggregate_size_DEPENDENCIES) $(EXTRA_aggregate_size_DEPENDENCIES) + @rm -f aggregate_size$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(aggregate_size_OBJECTS) $(aggregate_size_LDADD) $(LIBS) + +all-dwarf-ranges$(EXEEXT): $(all_dwarf_ranges_OBJECTS) $(all_dwarf_ranges_DEPENDENCIES) $(EXTRA_all_dwarf_ranges_DEPENDENCIES) + @rm -f all-dwarf-ranges$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(all_dwarf_ranges_OBJECTS) $(all_dwarf_ranges_LDADD) $(LIBS) + +alldts$(EXEEXT): $(alldts_OBJECTS) $(alldts_DEPENDENCIES) $(EXTRA_alldts_DEPENDENCIES) + @rm -f alldts$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(alldts_OBJECTS) $(alldts_LDADD) $(LIBS) + +allfcts$(EXEEXT): $(allfcts_OBJECTS) $(allfcts_DEPENDENCIES) $(EXTRA_allfcts_DEPENDENCIES) + @rm -f allfcts$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(allfcts_OBJECTS) $(allfcts_LDADD) $(LIBS) + +allregs$(EXEEXT): $(allregs_OBJECTS) $(allregs_DEPENDENCIES) $(EXTRA_allregs_DEPENDENCIES) + @rm -f allregs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(allregs_OBJECTS) $(allregs_LDADD) $(LIBS) + +arextract$(EXEEXT): $(arextract_OBJECTS) $(arextract_DEPENDENCIES) $(EXTRA_arextract_DEPENDENCIES) + @rm -f arextract$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(arextract_OBJECTS) $(arextract_LDADD) $(LIBS) + +arls$(EXEEXT): $(arls_OBJECTS) $(arls_DEPENDENCIES) $(EXTRA_arls_DEPENDENCIES) + @rm -f arls$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(arls_OBJECTS) $(arls_LDADD) $(LIBS) + +arsymtest$(EXEEXT): $(arsymtest_OBJECTS) $(arsymtest_DEPENDENCIES) $(EXTRA_arsymtest_DEPENDENCIES) + @rm -f arsymtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(arsymtest_OBJECTS) $(arsymtest_LDADD) $(LIBS) + +asm-tst1$(EXEEXT): $(asm_tst1_OBJECTS) $(asm_tst1_DEPENDENCIES) $(EXTRA_asm_tst1_DEPENDENCIES) + @rm -f asm-tst1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst1_OBJECTS) $(asm_tst1_LDADD) $(LIBS) + +asm-tst2$(EXEEXT): $(asm_tst2_OBJECTS) $(asm_tst2_DEPENDENCIES) $(EXTRA_asm_tst2_DEPENDENCIES) + @rm -f asm-tst2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst2_OBJECTS) $(asm_tst2_LDADD) $(LIBS) + +asm-tst3$(EXEEXT): $(asm_tst3_OBJECTS) $(asm_tst3_DEPENDENCIES) $(EXTRA_asm_tst3_DEPENDENCIES) + @rm -f asm-tst3$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst3_OBJECTS) $(asm_tst3_LDADD) $(LIBS) + +asm-tst4$(EXEEXT): $(asm_tst4_OBJECTS) $(asm_tst4_DEPENDENCIES) $(EXTRA_asm_tst4_DEPENDENCIES) + @rm -f asm-tst4$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst4_OBJECTS) $(asm_tst4_LDADD) $(LIBS) + +asm-tst5$(EXEEXT): $(asm_tst5_OBJECTS) $(asm_tst5_DEPENDENCIES) $(EXTRA_asm_tst5_DEPENDENCIES) + @rm -f asm-tst5$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst5_OBJECTS) $(asm_tst5_LDADD) $(LIBS) + +asm-tst6$(EXEEXT): $(asm_tst6_OBJECTS) $(asm_tst6_DEPENDENCIES) $(EXTRA_asm_tst6_DEPENDENCIES) + @rm -f asm-tst6$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst6_OBJECTS) $(asm_tst6_LDADD) $(LIBS) + +asm-tst7$(EXEEXT): $(asm_tst7_OBJECTS) $(asm_tst7_DEPENDENCIES) $(EXTRA_asm_tst7_DEPENDENCIES) + @rm -f asm-tst7$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst7_OBJECTS) $(asm_tst7_LDADD) $(LIBS) + +asm-tst8$(EXEEXT): $(asm_tst8_OBJECTS) $(asm_tst8_DEPENDENCIES) $(EXTRA_asm_tst8_DEPENDENCIES) + @rm -f asm-tst8$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst8_OBJECTS) $(asm_tst8_LDADD) $(LIBS) + +asm-tst9$(EXEEXT): $(asm_tst9_OBJECTS) $(asm_tst9_DEPENDENCIES) $(EXTRA_asm_tst9_DEPENDENCIES) + @rm -f asm-tst9$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(asm_tst9_OBJECTS) $(asm_tst9_LDADD) $(LIBS) + +attr-integrate-skel$(EXEEXT): $(attr_integrate_skel_OBJECTS) $(attr_integrate_skel_DEPENDENCIES) $(EXTRA_attr_integrate_skel_DEPENDENCIES) + @rm -f attr-integrate-skel$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(attr_integrate_skel_OBJECTS) $(attr_integrate_skel_LDADD) $(LIBS) + +backtrace$(EXEEXT): $(backtrace_OBJECTS) $(backtrace_DEPENDENCIES) $(EXTRA_backtrace_DEPENDENCIES) + @rm -f backtrace$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(backtrace_OBJECTS) $(backtrace_LDADD) $(LIBS) + +backtrace-child$(EXEEXT): $(backtrace_child_OBJECTS) $(backtrace_child_DEPENDENCIES) $(EXTRA_backtrace_child_DEPENDENCIES) + @rm -f backtrace-child$(EXEEXT) + $(AM_V_CCLD)$(backtrace_child_LINK) $(backtrace_child_OBJECTS) $(backtrace_child_LDADD) $(LIBS) + +backtrace-data$(EXEEXT): $(backtrace_data_OBJECTS) $(backtrace_data_DEPENDENCIES) $(EXTRA_backtrace_data_DEPENDENCIES) + @rm -f backtrace-data$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(backtrace_data_OBJECTS) $(backtrace_data_LDADD) $(LIBS) + +backtrace-dwarf$(EXEEXT): $(backtrace_dwarf_OBJECTS) $(backtrace_dwarf_DEPENDENCIES) $(EXTRA_backtrace_dwarf_DEPENDENCIES) + @rm -f backtrace-dwarf$(EXEEXT) + $(AM_V_CCLD)$(backtrace_dwarf_LINK) $(backtrace_dwarf_OBJECTS) $(backtrace_dwarf_LDADD) $(LIBS) + +buildid$(EXEEXT): $(buildid_OBJECTS) $(buildid_DEPENDENCIES) $(EXTRA_buildid_DEPENDENCIES) + @rm -f buildid$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(buildid_OBJECTS) $(buildid_LDADD) $(LIBS) + +debugaltlink$(EXEEXT): $(debugaltlink_OBJECTS) $(debugaltlink_DEPENDENCIES) $(EXTRA_debugaltlink_DEPENDENCIES) + @rm -f debugaltlink$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(debugaltlink_OBJECTS) $(debugaltlink_LDADD) $(LIBS) + +debuginfod_build_id_find$(EXEEXT): $(debuginfod_build_id_find_OBJECTS) $(debuginfod_build_id_find_DEPENDENCIES) $(EXTRA_debuginfod_build_id_find_DEPENDENCIES) + @rm -f debuginfod_build_id_find$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(debuginfod_build_id_find_OBJECTS) $(debuginfod_build_id_find_LDADD) $(LIBS) + +debuglink$(EXEEXT): $(debuglink_OBJECTS) $(debuglink_DEPENDENCIES) $(EXTRA_debuglink_DEPENDENCIES) + @rm -f debuglink$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(debuglink_OBJECTS) $(debuglink_LDADD) $(LIBS) + +deleted$(EXEEXT): $(deleted_OBJECTS) $(deleted_DEPENDENCIES) $(EXTRA_deleted_DEPENDENCIES) + @rm -f deleted$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(deleted_OBJECTS) $(deleted_LDADD) $(LIBS) + +deleted-lib.so$(EXEEXT): $(deleted_lib_so_OBJECTS) $(deleted_lib_so_DEPENDENCIES) $(EXTRA_deleted_lib_so_DEPENDENCIES) + @rm -f deleted-lib.so$(EXEEXT) + $(AM_V_CCLD)$(deleted_lib_so_LINK) $(deleted_lib_so_OBJECTS) $(deleted_lib_so_LDADD) $(LIBS) + +dwarf-die-addr-die$(EXEEXT): $(dwarf_die_addr_die_OBJECTS) $(dwarf_die_addr_die_DEPENDENCIES) $(EXTRA_dwarf_die_addr_die_DEPENDENCIES) + @rm -f dwarf-die-addr-die$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwarf_die_addr_die_OBJECTS) $(dwarf_die_addr_die_LDADD) $(LIBS) + +dwarf-getmacros$(EXEEXT): $(dwarf_getmacros_OBJECTS) $(dwarf_getmacros_DEPENDENCIES) $(EXTRA_dwarf_getmacros_DEPENDENCIES) + @rm -f dwarf-getmacros$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwarf_getmacros_OBJECTS) $(dwarf_getmacros_LDADD) $(LIBS) + +dwarf-getstring$(EXEEXT): $(dwarf_getstring_OBJECTS) $(dwarf_getstring_DEPENDENCIES) $(EXTRA_dwarf_getstring_DEPENDENCIES) + @rm -f dwarf-getstring$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwarf_getstring_OBJECTS) $(dwarf_getstring_LDADD) $(LIBS) + +dwarf-ranges$(EXEEXT): $(dwarf_ranges_OBJECTS) $(dwarf_ranges_DEPENDENCIES) $(EXTRA_dwarf_ranges_DEPENDENCIES) + @rm -f dwarf-ranges$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwarf_ranges_OBJECTS) $(dwarf_ranges_LDADD) $(LIBS) + +dwarf_default_lower_bound$(EXEEXT): $(dwarf_default_lower_bound_OBJECTS) $(dwarf_default_lower_bound_DEPENDENCIES) $(EXTRA_dwarf_default_lower_bound_DEPENDENCIES) + @rm -f dwarf_default_lower_bound$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwarf_default_lower_bound_OBJECTS) $(dwarf_default_lower_bound_LDADD) $(LIBS) + +dwarfcfi$(EXEEXT): $(dwarfcfi_OBJECTS) $(dwarfcfi_DEPENDENCIES) $(EXTRA_dwarfcfi_DEPENDENCIES) + @rm -f dwarfcfi$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwarfcfi_OBJECTS) $(dwarfcfi_LDADD) $(LIBS) + +dwelf_elf_e_machine_string$(EXEEXT): $(dwelf_elf_e_machine_string_OBJECTS) $(dwelf_elf_e_machine_string_DEPENDENCIES) $(EXTRA_dwelf_elf_e_machine_string_DEPENDENCIES) + @rm -f dwelf_elf_e_machine_string$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwelf_elf_e_machine_string_OBJECTS) $(dwelf_elf_e_machine_string_LDADD) $(LIBS) + +dwelfgnucompressed$(EXEEXT): $(dwelfgnucompressed_OBJECTS) $(dwelfgnucompressed_DEPENDENCIES) $(EXTRA_dwelfgnucompressed_DEPENDENCIES) + @rm -f dwelfgnucompressed$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwelfgnucompressed_OBJECTS) $(dwelfgnucompressed_LDADD) $(LIBS) + +dwfl-addr-sect$(EXEEXT): $(dwfl_addr_sect_OBJECTS) $(dwfl_addr_sect_DEPENDENCIES) $(EXTRA_dwfl_addr_sect_DEPENDENCIES) + @rm -f dwfl-addr-sect$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_addr_sect_OBJECTS) $(dwfl_addr_sect_LDADD) $(LIBS) + +dwfl-bug-addr-overflow$(EXEEXT): $(dwfl_bug_addr_overflow_OBJECTS) $(dwfl_bug_addr_overflow_DEPENDENCIES) $(EXTRA_dwfl_bug_addr_overflow_DEPENDENCIES) + @rm -f dwfl-bug-addr-overflow$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_bug_addr_overflow_OBJECTS) $(dwfl_bug_addr_overflow_LDADD) $(LIBS) + +dwfl-bug-fd-leak$(EXEEXT): $(dwfl_bug_fd_leak_OBJECTS) $(dwfl_bug_fd_leak_DEPENDENCIES) $(EXTRA_dwfl_bug_fd_leak_DEPENDENCIES) + @rm -f dwfl-bug-fd-leak$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_bug_fd_leak_OBJECTS) $(dwfl_bug_fd_leak_LDADD) $(LIBS) + +dwfl-bug-getmodules$(EXEEXT): $(dwfl_bug_getmodules_OBJECTS) $(dwfl_bug_getmodules_DEPENDENCIES) $(EXTRA_dwfl_bug_getmodules_DEPENDENCIES) + @rm -f dwfl-bug-getmodules$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_bug_getmodules_OBJECTS) $(dwfl_bug_getmodules_LDADD) $(LIBS) + +dwfl-bug-report$(EXEEXT): $(dwfl_bug_report_OBJECTS) $(dwfl_bug_report_DEPENDENCIES) $(EXTRA_dwfl_bug_report_DEPENDENCIES) + @rm -f dwfl-bug-report$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_bug_report_OBJECTS) $(dwfl_bug_report_LDADD) $(LIBS) + +dwfl-proc-attach$(EXEEXT): $(dwfl_proc_attach_OBJECTS) $(dwfl_proc_attach_DEPENDENCIES) $(EXTRA_dwfl_proc_attach_DEPENDENCIES) + @rm -f dwfl-proc-attach$(EXEEXT) + $(AM_V_CCLD)$(dwfl_proc_attach_LINK) $(dwfl_proc_attach_OBJECTS) $(dwfl_proc_attach_LDADD) $(LIBS) + +dwfl-report-elf-align$(EXEEXT): $(dwfl_report_elf_align_OBJECTS) $(dwfl_report_elf_align_DEPENDENCIES) $(EXTRA_dwfl_report_elf_align_DEPENDENCIES) + @rm -f dwfl-report-elf-align$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_report_elf_align_OBJECTS) $(dwfl_report_elf_align_LDADD) $(LIBS) + +dwfl-report-segment-contiguous$(EXEEXT): $(dwfl_report_segment_contiguous_OBJECTS) $(dwfl_report_segment_contiguous_DEPENDENCIES) $(EXTRA_dwfl_report_segment_contiguous_DEPENDENCIES) + @rm -f dwfl-report-segment-contiguous$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfl_report_segment_contiguous_OBJECTS) $(dwfl_report_segment_contiguous_LDADD) $(LIBS) + +dwfllines$(EXEEXT): $(dwfllines_OBJECTS) $(dwfllines_DEPENDENCIES) $(EXTRA_dwfllines_DEPENDENCIES) + @rm -f dwfllines$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwfllines_OBJECTS) $(dwfllines_LDADD) $(LIBS) + +dwflmodtest$(EXEEXT): $(dwflmodtest_OBJECTS) $(dwflmodtest_DEPENDENCIES) $(EXTRA_dwflmodtest_DEPENDENCIES) + @rm -f dwflmodtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwflmodtest_OBJECTS) $(dwflmodtest_LDADD) $(LIBS) + +dwflsyms$(EXEEXT): $(dwflsyms_OBJECTS) $(dwflsyms_DEPENDENCIES) $(EXTRA_dwflsyms_DEPENDENCIES) + @rm -f dwflsyms$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dwflsyms_OBJECTS) $(dwflsyms_LDADD) $(LIBS) + +early-offscn$(EXEEXT): $(early_offscn_OBJECTS) $(early_offscn_DEPENDENCIES) $(EXTRA_early_offscn_DEPENDENCIES) + @rm -f early-offscn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(early_offscn_OBJECTS) $(early_offscn_LDADD) $(LIBS) + +ecp$(EXEEXT): $(ecp_OBJECTS) $(ecp_DEPENDENCIES) $(EXTRA_ecp_DEPENDENCIES) + @rm -f ecp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecp_OBJECTS) $(ecp_LDADD) $(LIBS) + +elfcopy$(EXEEXT): $(elfcopy_OBJECTS) $(elfcopy_DEPENDENCIES) $(EXTRA_elfcopy_DEPENDENCIES) + @rm -f elfcopy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfcopy_OBJECTS) $(elfcopy_LDADD) $(LIBS) + +elfgetchdr$(EXEEXT): $(elfgetchdr_OBJECTS) $(elfgetchdr_DEPENDENCIES) $(EXTRA_elfgetchdr_DEPENDENCIES) + @rm -f elfgetchdr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfgetchdr_OBJECTS) $(elfgetchdr_LDADD) $(LIBS) + +elfgetzdata$(EXEEXT): $(elfgetzdata_OBJECTS) $(elfgetzdata_DEPENDENCIES) $(EXTRA_elfgetzdata_DEPENDENCIES) + @rm -f elfgetzdata$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfgetzdata_OBJECTS) $(elfgetzdata_LDADD) $(LIBS) + +elfputzdata$(EXEEXT): $(elfputzdata_OBJECTS) $(elfputzdata_DEPENDENCIES) $(EXTRA_elfputzdata_DEPENDENCIES) + @rm -f elfputzdata$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfputzdata_OBJECTS) $(elfputzdata_LDADD) $(LIBS) + +elfrdwrnop$(EXEEXT): $(elfrdwrnop_OBJECTS) $(elfrdwrnop_DEPENDENCIES) $(EXTRA_elfrdwrnop_DEPENDENCIES) + @rm -f elfrdwrnop$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfrdwrnop_OBJECTS) $(elfrdwrnop_LDADD) $(LIBS) + +elfshphehdr$(EXEEXT): $(elfshphehdr_OBJECTS) $(elfshphehdr_DEPENDENCIES) $(EXTRA_elfshphehdr_DEPENDENCIES) + @rm -f elfshphehdr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfshphehdr_OBJECTS) $(elfshphehdr_LDADD) $(LIBS) + +elfstrmerge$(EXEEXT): $(elfstrmerge_OBJECTS) $(elfstrmerge_DEPENDENCIES) $(EXTRA_elfstrmerge_DEPENDENCIES) + @rm -f elfstrmerge$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfstrmerge_OBJECTS) $(elfstrmerge_LDADD) $(LIBS) + +elfstrtab$(EXEEXT): $(elfstrtab_OBJECTS) $(elfstrtab_DEPENDENCIES) $(EXTRA_elfstrtab_DEPENDENCIES) + @rm -f elfstrtab$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(elfstrtab_OBJECTS) $(elfstrtab_LDADD) $(LIBS) + +emptyfile$(EXEEXT): $(emptyfile_OBJECTS) $(emptyfile_DEPENDENCIES) $(EXTRA_emptyfile_DEPENDENCIES) + @rm -f emptyfile$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(emptyfile_OBJECTS) $(emptyfile_LDADD) $(LIBS) + +fillfile$(EXEEXT): $(fillfile_OBJECTS) $(fillfile_DEPENDENCIES) $(EXTRA_fillfile_DEPENDENCIES) + @rm -f fillfile$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fillfile_OBJECTS) $(fillfile_LDADD) $(LIBS) + +find-prologues$(EXEEXT): $(find_prologues_OBJECTS) $(find_prologues_DEPENDENCIES) $(EXTRA_find_prologues_DEPENDENCIES) + @rm -f find-prologues$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(find_prologues_OBJECTS) $(find_prologues_LDADD) $(LIBS) + +funcretval$(EXEEXT): $(funcretval_OBJECTS) $(funcretval_DEPENDENCIES) $(EXTRA_funcretval_DEPENDENCIES) + @rm -f funcretval$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(funcretval_OBJECTS) $(funcretval_LDADD) $(LIBS) + +funcscopes$(EXEEXT): $(funcscopes_OBJECTS) $(funcscopes_DEPENDENCIES) $(EXTRA_funcscopes_DEPENDENCIES) + @rm -f funcscopes$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(funcscopes_OBJECTS) $(funcscopes_LDADD) $(LIBS) + +get-aranges$(EXEEXT): $(get_aranges_OBJECTS) $(get_aranges_DEPENDENCIES) $(EXTRA_get_aranges_DEPENDENCIES) + @rm -f get-aranges$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(get_aranges_OBJECTS) $(get_aranges_LDADD) $(LIBS) + +get-files$(EXEEXT): $(get_files_OBJECTS) $(get_files_DEPENDENCIES) $(EXTRA_get_files_DEPENDENCIES) + @rm -f get-files$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(get_files_OBJECTS) $(get_files_LDADD) $(LIBS) + +get-lines$(EXEEXT): $(get_lines_OBJECTS) $(get_lines_DEPENDENCIES) $(EXTRA_get_lines_DEPENDENCIES) + @rm -f get-lines$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(get_lines_OBJECTS) $(get_lines_LDADD) $(LIBS) + +get-pubnames$(EXEEXT): $(get_pubnames_OBJECTS) $(get_pubnames_DEPENDENCIES) $(EXTRA_get_pubnames_DEPENDENCIES) + @rm -f get-pubnames$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(get_pubnames_OBJECTS) $(get_pubnames_LDADD) $(LIBS) + +get-units-invalid$(EXEEXT): $(get_units_invalid_OBJECTS) $(get_units_invalid_DEPENDENCIES) $(EXTRA_get_units_invalid_DEPENDENCIES) + @rm -f get-units-invalid$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(get_units_invalid_OBJECTS) $(get_units_invalid_LDADD) $(LIBS) + +get-units-split$(EXEEXT): $(get_units_split_OBJECTS) $(get_units_split_DEPENDENCIES) $(EXTRA_get_units_split_DEPENDENCIES) + @rm -f get-units-split$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(get_units_split_OBJECTS) $(get_units_split_LDADD) $(LIBS) + +getphdrnum$(EXEEXT): $(getphdrnum_OBJECTS) $(getphdrnum_DEPENDENCIES) $(EXTRA_getphdrnum_DEPENDENCIES) + @rm -f getphdrnum$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(getphdrnum_OBJECTS) $(getphdrnum_LDADD) $(LIBS) + +getsrc_die$(EXEEXT): $(getsrc_die_OBJECTS) $(getsrc_die_DEPENDENCIES) $(EXTRA_getsrc_die_DEPENDENCIES) + @rm -f getsrc_die$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(getsrc_die_OBJECTS) $(getsrc_die_LDADD) $(LIBS) + +hash$(EXEEXT): $(hash_OBJECTS) $(hash_DEPENDENCIES) $(EXTRA_hash_DEPENDENCIES) + @rm -f hash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(hash_OBJECTS) $(hash_LDADD) $(LIBS) + +leb128$(EXEEXT): $(leb128_OBJECTS) $(leb128_DEPENDENCIES) $(EXTRA_leb128_DEPENDENCIES) + @rm -f leb128$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(leb128_OBJECTS) $(leb128_LDADD) $(LIBS) + +line2addr$(EXEEXT): $(line2addr_OBJECTS) $(line2addr_DEPENDENCIES) $(EXTRA_line2addr_DEPENDENCIES) + @rm -f line2addr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(line2addr_OBJECTS) $(line2addr_LDADD) $(LIBS) + +low_high_pc$(EXEEXT): $(low_high_pc_OBJECTS) $(low_high_pc_DEPENDENCIES) $(EXTRA_low_high_pc_DEPENDENCIES) + @rm -f low_high_pc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(low_high_pc_OBJECTS) $(low_high_pc_LDADD) $(LIBS) + +msg_tst$(EXEEXT): $(msg_tst_OBJECTS) $(msg_tst_DEPENDENCIES) $(EXTRA_msg_tst_DEPENDENCIES) + @rm -f msg_tst$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(msg_tst_OBJECTS) $(msg_tst_LDADD) $(LIBS) + +newdata$(EXEEXT): $(newdata_OBJECTS) $(newdata_DEPENDENCIES) $(EXTRA_newdata_DEPENDENCIES) + @rm -f newdata$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(newdata_OBJECTS) $(newdata_LDADD) $(LIBS) + +newfile$(EXEEXT): $(newfile_OBJECTS) $(newfile_DEPENDENCIES) $(EXTRA_newfile_DEPENDENCIES) + @rm -f newfile$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(newfile_OBJECTS) $(newfile_LDADD) $(LIBS) + +newscn$(EXEEXT): $(newscn_OBJECTS) $(newscn_DEPENDENCIES) $(EXTRA_newscn_DEPENDENCIES) + @rm -f newscn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(newscn_OBJECTS) $(newscn_LDADD) $(LIBS) + +next-files$(EXEEXT): $(next_files_OBJECTS) $(next_files_DEPENDENCIES) $(EXTRA_next_files_DEPENDENCIES) + @rm -f next-files$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(next_files_OBJECTS) $(next_files_LDADD) $(LIBS) + +next-lines$(EXEEXT): $(next_lines_OBJECTS) $(next_lines_DEPENDENCIES) $(EXTRA_next_lines_DEPENDENCIES) + @rm -f next-lines$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(next_lines_OBJECTS) $(next_lines_LDADD) $(LIBS) + +next_cfi$(EXEEXT): $(next_cfi_OBJECTS) $(next_cfi_DEPENDENCIES) $(EXTRA_next_cfi_DEPENDENCIES) + @rm -f next_cfi$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(next_cfi_OBJECTS) $(next_cfi_LDADD) $(LIBS) + +peel_type$(EXEEXT): $(peel_type_OBJECTS) $(peel_type_DEPENDENCIES) $(EXTRA_peel_type_DEPENDENCIES) + @rm -f peel_type$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(peel_type_OBJECTS) $(peel_type_LDADD) $(LIBS) + +rdwrmmap$(EXEEXT): $(rdwrmmap_OBJECTS) $(rdwrmmap_DEPENDENCIES) $(EXTRA_rdwrmmap_DEPENDENCIES) + @rm -f rdwrmmap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rdwrmmap_OBJECTS) $(rdwrmmap_LDADD) $(LIBS) + +read_unaligned$(EXEEXT): $(read_unaligned_OBJECTS) $(read_unaligned_DEPENDENCIES) $(EXTRA_read_unaligned_DEPENDENCIES) + @rm -f read_unaligned$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(read_unaligned_OBJECTS) $(read_unaligned_LDADD) $(LIBS) + +rerequest_tag$(EXEEXT): $(rerequest_tag_OBJECTS) $(rerequest_tag_DEPENDENCIES) $(EXTRA_rerequest_tag_DEPENDENCIES) + @rm -f rerequest_tag$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rerequest_tag_OBJECTS) $(rerequest_tag_LDADD) $(LIBS) + +saridx$(EXEEXT): $(saridx_OBJECTS) $(saridx_DEPENDENCIES) $(EXTRA_saridx_DEPENDENCIES) + @rm -f saridx$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(saridx_OBJECTS) $(saridx_LDADD) $(LIBS) + +scnnames$(EXEEXT): $(scnnames_OBJECTS) $(scnnames_DEPENDENCIES) $(EXTRA_scnnames_DEPENDENCIES) + @rm -f scnnames$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(scnnames_OBJECTS) $(scnnames_LDADD) $(LIBS) + +sectiondump$(EXEEXT): $(sectiondump_OBJECTS) $(sectiondump_DEPENDENCIES) $(EXTRA_sectiondump_DEPENDENCIES) + @rm -f sectiondump$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sectiondump_OBJECTS) $(sectiondump_LDADD) $(LIBS) + +show-abbrev$(EXEEXT): $(show_abbrev_OBJECTS) $(show_abbrev_DEPENDENCIES) $(EXTRA_show_abbrev_DEPENDENCIES) + @rm -f show-abbrev$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(show_abbrev_OBJECTS) $(show_abbrev_LDADD) $(LIBS) + +show-die-info$(EXEEXT): $(show_die_info_OBJECTS) $(show_die_info_DEPENDENCIES) $(EXTRA_show_die_info_DEPENDENCIES) + @rm -f show-die-info$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(show_die_info_OBJECTS) $(show_die_info_LDADD) $(LIBS) + +showptable$(EXEEXT): $(showptable_OBJECTS) $(showptable_DEPENDENCIES) $(EXTRA_showptable_DEPENDENCIES) + @rm -f showptable$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(showptable_OBJECTS) $(showptable_LDADD) $(LIBS) + +strptr$(EXEEXT): $(strptr_OBJECTS) $(strptr_DEPENDENCIES) $(EXTRA_strptr_DEPENDENCIES) + @rm -f strptr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(strptr_OBJECTS) $(strptr_LDADD) $(LIBS) + +system-elf-libelf-test$(EXEEXT): $(system_elf_libelf_test_OBJECTS) $(system_elf_libelf_test_DEPENDENCIES) $(EXTRA_system_elf_libelf_test_DEPENDENCIES) + @rm -f system-elf-libelf-test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(system_elf_libelf_test_OBJECTS) $(system_elf_libelf_test_LDADD) $(LIBS) + +test-elf_cntl_gelf_getshdr$(EXEEXT): $(test_elf_cntl_gelf_getshdr_OBJECTS) $(test_elf_cntl_gelf_getshdr_DEPENDENCIES) $(EXTRA_test_elf_cntl_gelf_getshdr_DEPENDENCIES) + @rm -f test-elf_cntl_gelf_getshdr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_elf_cntl_gelf_getshdr_OBJECTS) $(test_elf_cntl_gelf_getshdr_LDADD) $(LIBS) + +test-flag-nobits$(EXEEXT): $(test_flag_nobits_OBJECTS) $(test_flag_nobits_DEPENDENCIES) $(EXTRA_test_flag_nobits_DEPENDENCIES) + @rm -f test-flag-nobits$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_flag_nobits_OBJECTS) $(test_flag_nobits_LDADD) $(LIBS) + +typeiter$(EXEEXT): $(typeiter_OBJECTS) $(typeiter_DEPENDENCIES) $(EXTRA_typeiter_DEPENDENCIES) + @rm -f typeiter$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(typeiter_OBJECTS) $(typeiter_LDADD) $(LIBS) + +typeiter2$(EXEEXT): $(typeiter2_OBJECTS) $(typeiter2_DEPENDENCIES) $(EXTRA_typeiter2_DEPENDENCIES) + @rm -f typeiter2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(typeiter2_OBJECTS) $(typeiter2_LDADD) $(LIBS) + +unit-info$(EXEEXT): $(unit_info_OBJECTS) $(unit_info_DEPENDENCIES) $(EXTRA_unit_info_DEPENDENCIES) + @rm -f unit-info$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(unit_info_OBJECTS) $(unit_info_LDADD) $(LIBS) + +update1$(EXEEXT): $(update1_OBJECTS) $(update1_DEPENDENCIES) $(EXTRA_update1_DEPENDENCIES) + @rm -f update1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(update1_OBJECTS) $(update1_LDADD) $(LIBS) + +update2$(EXEEXT): $(update2_OBJECTS) $(update2_DEPENDENCIES) $(EXTRA_update2_DEPENDENCIES) + @rm -f update2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(update2_OBJECTS) $(update2_LDADD) $(LIBS) + +update3$(EXEEXT): $(update3_OBJECTS) $(update3_DEPENDENCIES) $(EXTRA_update3_DEPENDENCIES) + @rm -f update3$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(update3_OBJECTS) $(update3_LDADD) $(LIBS) + +update4$(EXEEXT): $(update4_OBJECTS) $(update4_DEPENDENCIES) $(EXTRA_update4_DEPENDENCIES) + @rm -f update4$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(update4_OBJECTS) $(update4_LDADD) $(LIBS) + +varlocs$(EXEEXT): $(varlocs_OBJECTS) $(varlocs_DEPENDENCIES) $(EXTRA_varlocs_DEPENDENCIES) + @rm -f varlocs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(varlocs_OBJECTS) $(varlocs_LDADD) $(LIBS) + +vdsosyms$(EXEEXT): $(vdsosyms_OBJECTS) $(vdsosyms_DEPENDENCIES) $(EXTRA_vdsosyms_DEPENDENCIES) + @rm -f vdsosyms$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(vdsosyms_OBJECTS) $(vdsosyms_LDADD) $(LIBS) + +vendorelf$(EXEEXT): $(vendorelf_OBJECTS) $(vendorelf_DEPENDENCIES) $(EXTRA_vendorelf_DEPENDENCIES) + @rm -f vendorelf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(vendorelf_OBJECTS) $(vendorelf_LDADD) $(LIBS) + +xlate_notes$(EXEEXT): $(xlate_notes_OBJECTS) $(xlate_notes_DEPENDENCIES) $(EXTRA_xlate_notes_DEPENDENCIES) + @rm -f xlate_notes$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(xlate_notes_OBJECTS) $(xlate_notes_LDADD) $(LIBS) + +zstrptr$(EXEEXT): $(zstrptr_OBJECTS) $(zstrptr_DEPENDENCIES) $(EXTRA_zstrptr_DEPENDENCIES) + @rm -f zstrptr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(zstrptr_OBJECTS) $(zstrptr_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addrcfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addrscopes.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addsections.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aggregate_size.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/all-dwarf-ranges.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alldts.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allfcts.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allregs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arextract.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arsymtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst4.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst5.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst6.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst7.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst8.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asm-tst9.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr-integrate-skel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace-child.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace-data.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace_child-backtrace-child.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buildid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debugaltlink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debuginfod_build_id_find.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debuglink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deleted.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deleted_lib_so-deleted-lib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf-die-addr-die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf-getmacros.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf-getstring.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf-ranges.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_default_lower_bound.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfcfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelf_elf_e_machine_string.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwelfgnucompressed.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-addr-sect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-bug-addr-overflow.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-bug-fd-leak.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-bug-getmodules.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-bug-report.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-proc-attach.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-report-elf-align.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl-report-segment-contiguous.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfllines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwflmodtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwflsyms.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/early-offscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfcopy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfgetchdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfgetzdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfputzdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfrdwrnop.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfshphehdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfstrmerge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfstrtab.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emptyfile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillfile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find-prologues.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funcretval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funcscopes.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-aranges.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-files.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-lines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-pubnames.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-units-invalid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-units-split.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getphdrnum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getsrc_die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leb128.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/line2addr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_high_pc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg_tst.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newfile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newscn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/next-files.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/next-lines.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/next_cfi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peel_type.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdwrmmap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read_unaligned.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rerequest_tag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saridx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scnnames.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sectiondump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/show-abbrev.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/show-die-info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/showptable.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strptr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-elf_cntl_gelf_getshdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-flag-nobits.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_nlist-test-nlist.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typeiter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typeiter2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit-info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update4.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varlocs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vdsosyms.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vendorelf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlate_notes.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zstrptr.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +backtrace_child-backtrace-child.o: backtrace-child.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_child_CFLAGS) $(CFLAGS) -MT backtrace_child-backtrace-child.o -MD -MP -MF $(DEPDIR)/backtrace_child-backtrace-child.Tpo -c -o backtrace_child-backtrace-child.o `test -f 'backtrace-child.c' || echo '$(srcdir)/'`backtrace-child.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backtrace_child-backtrace-child.Tpo $(DEPDIR)/backtrace_child-backtrace-child.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backtrace-child.c' object='backtrace_child-backtrace-child.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_child_CFLAGS) $(CFLAGS) -c -o backtrace_child-backtrace-child.o `test -f 'backtrace-child.c' || echo '$(srcdir)/'`backtrace-child.c + +backtrace_child-backtrace-child.obj: backtrace-child.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_child_CFLAGS) $(CFLAGS) -MT backtrace_child-backtrace-child.obj -MD -MP -MF $(DEPDIR)/backtrace_child-backtrace-child.Tpo -c -o backtrace_child-backtrace-child.obj `if test -f 'backtrace-child.c'; then $(CYGPATH_W) 'backtrace-child.c'; else $(CYGPATH_W) '$(srcdir)/backtrace-child.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backtrace_child-backtrace-child.Tpo $(DEPDIR)/backtrace_child-backtrace-child.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backtrace-child.c' object='backtrace_child-backtrace-child.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_child_CFLAGS) $(CFLAGS) -c -o backtrace_child-backtrace-child.obj `if test -f 'backtrace-child.c'; then $(CYGPATH_W) 'backtrace-child.c'; else $(CYGPATH_W) '$(srcdir)/backtrace-child.c'; fi` + +backtrace_dwarf-backtrace-dwarf.o: backtrace-dwarf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_dwarf_CFLAGS) $(CFLAGS) -MT backtrace_dwarf-backtrace-dwarf.o -MD -MP -MF $(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Tpo -c -o backtrace_dwarf-backtrace-dwarf.o `test -f 'backtrace-dwarf.c' || echo '$(srcdir)/'`backtrace-dwarf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Tpo $(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backtrace-dwarf.c' object='backtrace_dwarf-backtrace-dwarf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_dwarf_CFLAGS) $(CFLAGS) -c -o backtrace_dwarf-backtrace-dwarf.o `test -f 'backtrace-dwarf.c' || echo '$(srcdir)/'`backtrace-dwarf.c + +backtrace_dwarf-backtrace-dwarf.obj: backtrace-dwarf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_dwarf_CFLAGS) $(CFLAGS) -MT backtrace_dwarf-backtrace-dwarf.obj -MD -MP -MF $(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Tpo -c -o backtrace_dwarf-backtrace-dwarf.obj `if test -f 'backtrace-dwarf.c'; then $(CYGPATH_W) 'backtrace-dwarf.c'; else $(CYGPATH_W) '$(srcdir)/backtrace-dwarf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Tpo $(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backtrace-dwarf.c' object='backtrace_dwarf-backtrace-dwarf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(backtrace_dwarf_CFLAGS) $(CFLAGS) -c -o backtrace_dwarf-backtrace-dwarf.obj `if test -f 'backtrace-dwarf.c'; then $(CYGPATH_W) 'backtrace-dwarf.c'; else $(CYGPATH_W) '$(srcdir)/backtrace-dwarf.c'; fi` + +deleted_lib_so-deleted-lib.o: deleted-lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(deleted_lib_so_CFLAGS) $(CFLAGS) -MT deleted_lib_so-deleted-lib.o -MD -MP -MF $(DEPDIR)/deleted_lib_so-deleted-lib.Tpo -c -o deleted_lib_so-deleted-lib.o `test -f 'deleted-lib.c' || echo '$(srcdir)/'`deleted-lib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/deleted_lib_so-deleted-lib.Tpo $(DEPDIR)/deleted_lib_so-deleted-lib.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='deleted-lib.c' object='deleted_lib_so-deleted-lib.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(deleted_lib_so_CFLAGS) $(CFLAGS) -c -o deleted_lib_so-deleted-lib.o `test -f 'deleted-lib.c' || echo '$(srcdir)/'`deleted-lib.c + +deleted_lib_so-deleted-lib.obj: deleted-lib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(deleted_lib_so_CFLAGS) $(CFLAGS) -MT deleted_lib_so-deleted-lib.obj -MD -MP -MF $(DEPDIR)/deleted_lib_so-deleted-lib.Tpo -c -o deleted_lib_so-deleted-lib.obj `if test -f 'deleted-lib.c'; then $(CYGPATH_W) 'deleted-lib.c'; else $(CYGPATH_W) '$(srcdir)/deleted-lib.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/deleted_lib_so-deleted-lib.Tpo $(DEPDIR)/deleted_lib_so-deleted-lib.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='deleted-lib.c' object='deleted_lib_so-deleted-lib.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(deleted_lib_so_CFLAGS) $(CFLAGS) -c -o deleted_lib_so-deleted-lib.obj `if test -f 'deleted-lib.c'; then $(CYGPATH_W) 'deleted-lib.c'; else $(CYGPATH_W) '$(srcdir)/deleted-lib.c'; fi` + +system_elf_libelf_test-system-elf-libelf-test.o: system-elf-libelf-test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(system_elf_libelf_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system_elf_libelf_test-system-elf-libelf-test.o -MD -MP -MF $(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Tpo -c -o system_elf_libelf_test-system-elf-libelf-test.o `test -f 'system-elf-libelf-test.c' || echo '$(srcdir)/'`system-elf-libelf-test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Tpo $(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='system-elf-libelf-test.c' object='system_elf_libelf_test-system-elf-libelf-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(system_elf_libelf_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system_elf_libelf_test-system-elf-libelf-test.o `test -f 'system-elf-libelf-test.c' || echo '$(srcdir)/'`system-elf-libelf-test.c + +system_elf_libelf_test-system-elf-libelf-test.obj: system-elf-libelf-test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(system_elf_libelf_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system_elf_libelf_test-system-elf-libelf-test.obj -MD -MP -MF $(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Tpo -c -o system_elf_libelf_test-system-elf-libelf-test.obj `if test -f 'system-elf-libelf-test.c'; then $(CYGPATH_W) 'system-elf-libelf-test.c'; else $(CYGPATH_W) '$(srcdir)/system-elf-libelf-test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Tpo $(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='system-elf-libelf-test.c' object='system_elf_libelf_test-system-elf-libelf-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(system_elf_libelf_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system_elf_libelf_test-system-elf-libelf-test.obj `if test -f 'system-elf-libelf-test.c'; then $(CYGPATH_W) 'system-elf-libelf-test.c'; else $(CYGPATH_W) '$(srcdir)/system-elf-libelf-test.c'; fi` + +test_nlist-test-nlist.o: test-nlist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_nlist_CFLAGS) $(CFLAGS) -MT test_nlist-test-nlist.o -MD -MP -MF $(DEPDIR)/test_nlist-test-nlist.Tpo -c -o test_nlist-test-nlist.o `test -f 'test-nlist.c' || echo '$(srcdir)/'`test-nlist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_nlist-test-nlist.Tpo $(DEPDIR)/test_nlist-test-nlist.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-nlist.c' object='test_nlist-test-nlist.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_nlist_CFLAGS) $(CFLAGS) -c -o test_nlist-test-nlist.o `test -f 'test-nlist.c' || echo '$(srcdir)/'`test-nlist.c + +test_nlist-test-nlist.obj: test-nlist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_nlist_CFLAGS) $(CFLAGS) -MT test_nlist-test-nlist.obj -MD -MP -MF $(DEPDIR)/test_nlist-test-nlist.Tpo -c -o test_nlist-test-nlist.obj `if test -f 'test-nlist.c'; then $(CYGPATH_W) 'test-nlist.c'; else $(CYGPATH_W) '$(srcdir)/test-nlist.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_nlist-test-nlist.Tpo $(DEPDIR)/test_nlist-test-nlist.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-nlist.c' object='test_nlist-test-nlist.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_nlist_CFLAGS) $(CFLAGS) -c -o test_nlist-test-nlist.obj `if test -f 'test-nlist.c'; then $(CYGPATH_W) 'test-nlist.c'; else $(CYGPATH_W) '$(srcdir)/test-nlist.c'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +run-arextract.sh.log: run-arextract.sh + @p='run-arextract.sh'; \ + b='run-arextract.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-arsymtest.sh.log: run-arsymtest.sh + @p='run-arsymtest.sh'; \ + b='run-arsymtest.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ar.sh.log: run-ar.sh + @p='run-ar.sh'; \ + b='run-ar.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +newfile.log: newfile$(EXEEXT) + @p='newfile$(EXEEXT)'; \ + b='newfile'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +test-nlist.log: test-nlist$(EXEEXT) + @p='test-nlist$(EXEEXT)'; \ + b='test-nlist'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +update1.log: update1$(EXEEXT) + @p='update1$(EXEEXT)'; \ + b='update1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +update2.log: update2$(EXEEXT) + @p='update2$(EXEEXT)'; \ + b='update2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +update3.log: update3$(EXEEXT) + @p='update3$(EXEEXT)'; \ + b='update3'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +update4.log: update4$(EXEEXT) + @p='update4$(EXEEXT)'; \ + b='update4'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-show-die-info.sh.log: run-show-die-info.sh + @p='run-show-die-info.sh'; \ + b='run-show-die-info.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-get-files.sh.log: run-get-files.sh + @p='run-get-files.sh'; \ + b='run-get-files.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-get-lines.sh.log: run-get-lines.sh + @p='run-get-lines.sh'; \ + b='run-get-lines.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-next-files.sh.log: run-next-files.sh + @p='run-next-files.sh'; \ + b='run-next-files.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-next-lines.sh.log: run-next-lines.sh + @p='run-next-lines.sh'; \ + b='run-next-lines.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-get-pubnames.sh.log: run-get-pubnames.sh + @p='run-get-pubnames.sh'; \ + b='run-get-pubnames.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-get-aranges.sh.log: run-get-aranges.sh + @p='run-get-aranges.sh'; \ + b='run-get-aranges.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-allfcts.sh.log: run-allfcts.sh + @p='run-allfcts.sh'; \ + b='run-allfcts.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-show-abbrev.sh.log: run-show-abbrev.sh + @p='run-show-abbrev.sh'; \ + b='run-show-abbrev.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-line2addr.sh.log: run-line2addr.sh + @p='run-line2addr.sh'; \ + b='run-line2addr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +hash.log: hash$(EXEEXT) + @p='hash$(EXEEXT)'; \ + b='hash'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-large-elf-file.sh.log: run-large-elf-file.sh + @p='run-large-elf-file.sh'; \ + b='run-large-elf-file.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +newscn.log: newscn$(EXEEXT) + @p='newscn$(EXEEXT)'; \ + b='newscn'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test.sh.log: run-strip-test.sh + @p='run-strip-test.sh'; \ + b='run-strip-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test2.sh.log: run-strip-test2.sh + @p='run-strip-test2.sh'; \ + b='run-strip-test2.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test3.sh.log: run-strip-test3.sh + @p='run-strip-test3.sh'; \ + b='run-strip-test3.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test4.sh.log: run-strip-test4.sh + @p='run-strip-test4.sh'; \ + b='run-strip-test4.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test5.sh.log: run-strip-test5.sh + @p='run-strip-test5.sh'; \ + b='run-strip-test5.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test6.sh.log: run-strip-test6.sh + @p='run-strip-test6.sh'; \ + b='run-strip-test6.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test7.sh.log: run-strip-test7.sh + @p='run-strip-test7.sh'; \ + b='run-strip-test7.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test8.sh.log: run-strip-test8.sh + @p='run-strip-test8.sh'; \ + b='run-strip-test8.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test9.sh.log: run-strip-test9.sh + @p='run-strip-test9.sh'; \ + b='run-strip-test9.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test10.sh.log: run-strip-test10.sh + @p='run-strip-test10.sh'; \ + b='run-strip-test10.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test11.sh.log: run-strip-test11.sh + @p='run-strip-test11.sh'; \ + b='run-strip-test11.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test12.sh.log: run-strip-test12.sh + @p='run-strip-test12.sh'; \ + b='run-strip-test12.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-nothing.sh.log: run-strip-nothing.sh + @p='run-strip-nothing.sh'; \ + b='run-strip-nothing.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-g.sh.log: run-strip-g.sh + @p='run-strip-g.sh'; \ + b='run-strip-g.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-annobingroup.sh.log: run-annobingroup.sh + @p='run-annobingroup.sh'; \ + b='run-annobingroup.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-groups.sh.log: run-strip-groups.sh + @p='run-strip-groups.sh'; \ + b='run-strip-groups.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-reloc.sh.log: run-strip-reloc.sh + @p='run-strip-reloc.sh'; \ + b='run-strip-reloc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-strmerge.sh.log: run-strip-strmerge.sh + @p='run-strip-strmerge.sh'; \ + b='run-strip-strmerge.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-nobitsalign.sh.log: run-strip-nobitsalign.sh + @p='run-strip-nobitsalign.sh'; \ + b='run-strip-nobitsalign.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-remove-keep.sh.log: run-strip-remove-keep.sh + @p='run-strip-remove-keep.sh'; \ + b='run-strip-remove-keep.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unstrip-test.sh.log: run-unstrip-test.sh + @p='run-unstrip-test.sh'; \ + b='run-unstrip-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unstrip-test2.sh.log: run-unstrip-test2.sh + @p='run-unstrip-test2.sh'; \ + b='run-unstrip-test2.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unstrip-test3.sh.log: run-unstrip-test3.sh + @p='run-unstrip-test3.sh'; \ + b='run-unstrip-test3.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unstrip-test4.sh.log: run-unstrip-test4.sh + @p='run-unstrip-test4.sh'; \ + b='run-unstrip-test4.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unstrip-M.sh.log: run-unstrip-M.sh + @p='run-unstrip-M.sh'; \ + b='run-unstrip-M.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elfstrmerge-test.sh.log: run-elfstrmerge-test.sh + @p='run-elfstrmerge-test.sh'; \ + b='run-elfstrmerge-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ecp-test.sh.log: run-ecp-test.sh + @p='run-ecp-test.sh'; \ + b='run-ecp-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ecp-test2.sh.log: run-ecp-test2.sh + @p='run-ecp-test2.sh'; \ + b='run-ecp-test2.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-alldts.sh.log: run-alldts.sh + @p='run-alldts.sh'; \ + b='run-alldts.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elflint-test.sh.log: run-elflint-test.sh + @p='run-elflint-test.sh'; \ + b='run-elflint-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elflint-self.sh.log: run-elflint-self.sh + @p='run-elflint-self.sh'; \ + b='run-elflint-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ranlib-test.sh.log: run-ranlib-test.sh + @p='run-ranlib-test.sh'; \ + b='run-ranlib-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ranlib-test2.sh.log: run-ranlib-test2.sh + @p='run-ranlib-test2.sh'; \ + b='run-ranlib-test2.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ranlib-test3.sh.log: run-ranlib-test3.sh + @p='run-ranlib-test3.sh'; \ + b='run-ranlib-test3.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-ranlib-test4.sh.log: run-ranlib-test4.sh + @p='run-ranlib-test4.sh'; \ + b='run-ranlib-test4.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addrscopes.sh.log: run-addrscopes.sh + @p='run-addrscopes.sh'; \ + b='run-addrscopes.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strings-test.sh.log: run-strings-test.sh + @p='run-strings-test.sh'; \ + b='run-strings-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-funcscopes.sh.log: run-funcscopes.sh + @p='run-funcscopes.sh'; \ + b='run-funcscopes.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-find-prologues.sh.log: run-find-prologues.sh + @p='run-find-prologues.sh'; \ + b='run-find-prologues.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-allregs.sh.log: run-allregs.sh + @p='run-allregs.sh'; \ + b='run-allregs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addrcfi.sh.log: run-addrcfi.sh + @p='run-addrcfi.sh'; \ + b='run-addrcfi.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwarfcfi.sh.log: run-dwarfcfi.sh + @p='run-dwarfcfi.sh'; \ + b='run-dwarfcfi.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-nm-syms.sh.log: run-nm-syms.sh + @p='run-nm-syms.sh'; \ + b='run-nm-syms.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-nm-self.sh.log: run-nm-self.sh + @p='run-nm-self.sh'; \ + b='run-nm-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-self.sh.log: run-readelf-self.sh + @p='run-readelf-self.sh'; \ + b='run-readelf-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-info-plus.sh.log: run-readelf-info-plus.sh + @p='run-readelf-info-plus.sh'; \ + b='run-readelf-info-plus.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-compressed.sh.log: run-readelf-compressed.sh + @p='run-readelf-compressed.sh'; \ + b='run-readelf-compressed.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-const-values.sh.log: run-readelf-const-values.sh + @p='run-readelf-const-values.sh'; \ + b='run-readelf-const-values.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-varlocs-self.sh.log: run-varlocs-self.sh + @p='run-varlocs-self.sh'; \ + b='run-varlocs-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-exprlocs-self.sh.log: run-exprlocs-self.sh + @p='run-exprlocs-self.sh'; \ + b='run-exprlocs-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-test1.sh.log: run-readelf-test1.sh + @p='run-readelf-test1.sh'; \ + b='run-readelf-test1.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-test2.sh.log: run-readelf-test2.sh + @p='run-readelf-test2.sh'; \ + b='run-readelf-test2.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-test3.sh.log: run-readelf-test3.sh + @p='run-readelf-test3.sh'; \ + b='run-readelf-test3.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-test4.sh.log: run-readelf-test4.sh + @p='run-readelf-test4.sh'; \ + b='run-readelf-test4.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-twofiles.sh.log: run-readelf-twofiles.sh + @p='run-readelf-twofiles.sh'; \ + b='run-readelf-twofiles.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-macro.sh.log: run-readelf-macro.sh + @p='run-readelf-macro.sh'; \ + b='run-readelf-macro.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-loc.sh.log: run-readelf-loc.sh + @p='run-readelf-loc.sh'; \ + b='run-readelf-loc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-ranges.sh.log: run-readelf-ranges.sh + @p='run-readelf-ranges.sh'; \ + b='run-readelf-ranges.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-aranges.sh.log: run-readelf-aranges.sh + @p='run-readelf-aranges.sh'; \ + b='run-readelf-aranges.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-line.sh.log: run-readelf-line.sh + @p='run-readelf-line.sh'; \ + b='run-readelf-line.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-z.sh.log: run-readelf-z.sh + @p='run-readelf-z.sh'; \ + b='run-readelf-z.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-frames.sh.log: run-readelf-frames.sh + @p='run-readelf-frames.sh'; \ + b='run-readelf-frames.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-n.sh.log: run-readelf-n.sh + @p='run-readelf-n.sh'; \ + b='run-readelf-n.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-retain.sh.log: run-retain.sh + @p='run-retain.sh'; \ + b='run-retain.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-native-test.sh.log: run-native-test.sh + @p='run-native-test.sh'; \ + b='run-native-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-bug1-test.sh.log: run-bug1-test.sh + @p='run-bug1-test.sh'; \ + b='run-bug1-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-debuglink.sh.log: run-debuglink.sh + @p='run-debuglink.sh'; \ + b='run-debuglink.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-debugaltlink.sh.log: run-debugaltlink.sh + @p='run-debugaltlink.sh'; \ + b='run-debugaltlink.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-buildid.sh.log: run-buildid.sh + @p='run-buildid.sh'; \ + b='run-buildid.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dwfl-bug-addr-overflow.log: dwfl-bug-addr-overflow$(EXEEXT) + @p='dwfl-bug-addr-overflow$(EXEEXT)'; \ + b='dwfl-bug-addr-overflow'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addrname-test.sh.log: run-addrname-test.sh + @p='run-addrname-test.sh'; \ + b='run-addrname-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dwfl-bug-fd-leak.log: dwfl-bug-fd-leak$(EXEEXT) + @p='dwfl-bug-fd-leak$(EXEEXT)'; \ + b='dwfl-bug-fd-leak'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dwfl-bug-report.log: dwfl-bug-report$(EXEEXT) + @p='dwfl-bug-report$(EXEEXT)'; \ + b='dwfl-bug-report'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dwfl-report-segment-contiguous.log: dwfl-report-segment-contiguous$(EXEEXT) + @p='dwfl-report-segment-contiguous$(EXEEXT)'; \ + b='dwfl-report-segment-contiguous'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwfl-bug-offline-rel.sh.log: run-dwfl-bug-offline-rel.sh + @p='run-dwfl-bug-offline-rel.sh'; \ + b='run-dwfl-bug-offline-rel.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwfl-addr-sect.sh.log: run-dwfl-addr-sect.sh + @p='run-dwfl-addr-sect.sh'; \ + b='run-dwfl-addr-sect.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-disasm-x86.sh.log: run-disasm-x86.sh + @p='run-disasm-x86.sh'; \ + b='run-disasm-x86.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-disasm-x86-64.sh.log: run-disasm-x86-64.sh + @p='run-disasm-x86-64.sh'; \ + b='run-disasm-x86-64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-early-offscn.sh.log: run-early-offscn.sh + @p='run-early-offscn.sh'; \ + b='run-early-offscn.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwarf-getmacros.sh.log: run-dwarf-getmacros.sh + @p='run-dwarf-getmacros.sh'; \ + b='run-dwarf-getmacros.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwarf-ranges.sh.log: run-dwarf-ranges.sh + @p='run-dwarf-ranges.sh'; \ + b='run-dwarf-ranges.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-test-flag-nobits.sh.log: run-test-flag-nobits.sh + @p='run-test-flag-nobits.sh'; \ + b='run-test-flag-nobits.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-prelink-addr-test.sh.log: run-prelink-addr-test.sh + @p='run-prelink-addr-test.sh'; \ + b='run-prelink-addr-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwarf-getstring.sh.log: run-dwarf-getstring.sh + @p='run-dwarf-getstring.sh'; \ + b='run-dwarf-getstring.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-rerequest_tag.sh.log: run-rerequest_tag.sh + @p='run-rerequest_tag.sh'; \ + b='run-rerequest_tag.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-typeiter.sh.log: run-typeiter.sh + @p='run-typeiter.sh'; \ + b='run-typeiter.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-d.sh.log: run-readelf-d.sh + @p='run-readelf-d.sh'; \ + b='run-readelf-d.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-gdb_index.sh.log: run-readelf-gdb_index.sh + @p='run-readelf-gdb_index.sh'; \ + b='run-readelf-gdb_index.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unstrip-n.sh.log: run-unstrip-n.sh + @p='run-unstrip-n.sh'; \ + b='run-unstrip-n.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-low_high_pc.sh.log: run-low_high_pc.sh + @p='run-low_high_pc.sh'; \ + b='run-low_high_pc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-macro-test.sh.log: run-macro-test.sh + @p='run-macro-test.sh'; \ + b='run-macro-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elf_cntl_gelf_getshdr.sh.log: run-elf_cntl_gelf_getshdr.sh + @p='run-elf_cntl_gelf_getshdr.sh'; \ + b='run-elf_cntl_gelf_getshdr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-test-archive64.sh.log: run-test-archive64.sh + @p='run-test-archive64.sh'; \ + b='run-test-archive64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-vmcoreinfo.sh.log: run-readelf-vmcoreinfo.sh + @p='run-readelf-vmcoreinfo.sh'; \ + b='run-readelf-vmcoreinfo.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-mixed-corenote.sh.log: run-readelf-mixed-corenote.sh + @p='run-readelf-mixed-corenote.sh'; \ + b='run-readelf-mixed-corenote.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwfllines.sh.log: run-dwfllines.sh + @p='run-dwfllines.sh'; \ + b='run-dwfllines.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-variant.sh.log: run-readelf-variant.sh + @p='run-readelf-variant.sh'; \ + b='run-readelf-variant.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwfl-report-elf-align.sh.log: run-dwfl-report-elf-align.sh + @p='run-dwfl-report-elf-align.sh'; \ + b='run-dwfl-report-elf-align.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addr2line-test.sh.log: run-addr2line-test.sh + @p='run-addr2line-test.sh'; \ + b='run-addr2line-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addr2line-i-test.sh.log: run-addr2line-i-test.sh + @p='run-addr2line-i-test.sh'; \ + b='run-addr2line-i-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addr2line-i-lex-test.sh.log: run-addr2line-i-lex-test.sh + @p='run-addr2line-i-lex-test.sh'; \ + b='run-addr2line-i-lex-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addr2line-i-demangle-test.sh.log: run-addr2line-i-demangle-test.sh + @p='run-addr2line-i-demangle-test.sh'; \ + b='run-addr2line-i-demangle-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-addr2line-alt-debugpath.sh.log: run-addr2line-alt-debugpath.sh + @p='run-addr2line-alt-debugpath.sh'; \ + b='run-addr2line-alt-debugpath.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-varlocs.sh.log: run-varlocs.sh + @p='run-varlocs.sh'; \ + b='run-varlocs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-exprlocs.sh.log: run-exprlocs.sh + @p='run-exprlocs.sh'; \ + b='run-exprlocs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-funcretval.sh.log: run-funcretval.sh + @p='run-funcretval.sh'; \ + b='run-funcretval.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-native.sh.log: run-backtrace-native.sh + @p='run-backtrace-native.sh'; \ + b='run-backtrace-native.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-data.sh.log: run-backtrace-data.sh + @p='run-backtrace-data.sh'; \ + b='run-backtrace-data.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-dwarf.sh.log: run-backtrace-dwarf.sh + @p='run-backtrace-dwarf.sh'; \ + b='run-backtrace-dwarf.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-native-biarch.sh.log: run-backtrace-native-biarch.sh + @p='run-backtrace-native-biarch.sh'; \ + b='run-backtrace-native-biarch.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-native-core.sh.log: run-backtrace-native-core.sh + @p='run-backtrace-native-core.sh'; \ + b='run-backtrace-native-core.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-native-core-biarch.sh.log: run-backtrace-native-core-biarch.sh + @p='run-backtrace-native-core-biarch.sh'; \ + b='run-backtrace-native-core-biarch.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-x86_64.sh.log: run-backtrace-core-x86_64.sh + @p='run-backtrace-core-x86_64.sh'; \ + b='run-backtrace-core-x86_64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-fp-core-x86_64.sh.log: run-backtrace-fp-core-x86_64.sh + @p='run-backtrace-fp-core-x86_64.sh'; \ + b='run-backtrace-fp-core-x86_64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-fp-core-aarch64.sh.log: run-backtrace-fp-core-aarch64.sh + @p='run-backtrace-fp-core-aarch64.sh'; \ + b='run-backtrace-fp-core-aarch64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-fp-core-ppc64le.sh.log: run-backtrace-fp-core-ppc64le.sh + @p='run-backtrace-fp-core-ppc64le.sh'; \ + b='run-backtrace-fp-core-ppc64le.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-x32.sh.log: run-backtrace-core-x32.sh + @p='run-backtrace-core-x32.sh'; \ + b='run-backtrace-core-x32.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-i386.sh.log: run-backtrace-core-i386.sh + @p='run-backtrace-core-i386.sh'; \ + b='run-backtrace-core-i386.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-fp-core-i386.sh.log: run-backtrace-fp-core-i386.sh + @p='run-backtrace-fp-core-i386.sh'; \ + b='run-backtrace-fp-core-i386.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-ppc.sh.log: run-backtrace-core-ppc.sh + @p='run-backtrace-core-ppc.sh'; \ + b='run-backtrace-core-ppc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-s390x.sh.log: run-backtrace-core-s390x.sh + @p='run-backtrace-core-s390x.sh'; \ + b='run-backtrace-core-s390x.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-s390.sh.log: run-backtrace-core-s390.sh + @p='run-backtrace-core-s390.sh'; \ + b='run-backtrace-core-s390.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-aarch64.sh.log: run-backtrace-core-aarch64.sh + @p='run-backtrace-core-aarch64.sh'; \ + b='run-backtrace-core-aarch64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-core-sparc.sh.log: run-backtrace-core-sparc.sh + @p='run-backtrace-core-sparc.sh'; \ + b='run-backtrace-core-sparc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-backtrace-demangle.sh.log: run-backtrace-demangle.sh + @p='run-backtrace-demangle.sh'; \ + b='run-backtrace-demangle.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-stack-d-test.sh.log: run-stack-d-test.sh + @p='run-stack-d-test.sh'; \ + b='run-stack-d-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-stack-i-test.sh.log: run-stack-i-test.sh + @p='run-stack-i-test.sh'; \ + b='run-stack-i-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-stack-demangled-test.sh.log: run-stack-demangled-test.sh + @p='run-stack-demangled-test.sh'; \ + b='run-stack-demangled-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-zx.sh.log: run-readelf-zx.sh + @p='run-readelf-zx.sh'; \ + b='run-readelf-zx.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-zp.sh.log: run-readelf-zp.sh + @p='run-readelf-zp.sh'; \ + b='run-readelf-zp.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-addr.sh.log: run-readelf-addr.sh + @p='run-readelf-addr.sh'; \ + b='run-readelf-addr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-str.sh.log: run-readelf-str.sh + @p='run-readelf-str.sh'; \ + b='run-readelf-str.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-types.sh.log: run-readelf-types.sh + @p='run-readelf-types.sh'; \ + b='run-readelf-types.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-dwz-multi.sh.log: run-readelf-dwz-multi.sh + @p='run-readelf-dwz-multi.sh'; \ + b='run-readelf-dwz-multi.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-allfcts-multi.sh.log: run-allfcts-multi.sh + @p='run-allfcts-multi.sh'; \ + b='run-allfcts-multi.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-deleted.sh.log: run-deleted.sh + @p='run-deleted.sh'; \ + b='run-deleted.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-linkmap-cut.sh.log: run-linkmap-cut.sh + @p='run-linkmap-cut.sh'; \ + b='run-linkmap-cut.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-aggregate-size.sh.log: run-aggregate-size.sh + @p='run-aggregate-size.sh'; \ + b='run-aggregate-size.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-peel-type.sh.log: run-peel-type.sh + @p='run-peel-type.sh'; \ + b='run-peel-type.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +vdsosyms.log: vdsosyms$(EXEEXT) + @p='vdsosyms$(EXEEXT)'; \ + b='vdsosyms'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-A.sh.log: run-readelf-A.sh + @p='run-readelf-A.sh'; \ + b='run-readelf-A.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-getsrc-die.sh.log: run-getsrc-die.sh + @p='run-getsrc-die.sh'; \ + b='run-getsrc-die.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strptr.sh.log: run-strptr.sh + @p='run-strptr.sh'; \ + b='run-strptr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +newdata.log: newdata$(EXEEXT) + @p='newdata$(EXEEXT)'; \ + b='newdata'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +elfstrtab.log: elfstrtab$(EXEEXT) + @p='elfstrtab$(EXEEXT)'; \ + b='elfstrtab'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dwfl-proc-attach.log: dwfl-proc-attach$(EXEEXT) + @p='dwfl-proc-attach$(EXEEXT)'; \ + b='dwfl-proc-attach'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +elfshphehdr.log: elfshphehdr$(EXEEXT) + @p='elfshphehdr$(EXEEXT)'; \ + b='elfshphehdr'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-lfs-symbols.sh.log: run-lfs-symbols.sh + @p='run-lfs-symbols.sh'; \ + b='run-lfs-symbols.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwelfgnucompressed.sh.log: run-dwelfgnucompressed.sh + @p='run-dwelfgnucompressed.sh'; \ + b='run-dwelfgnucompressed.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elfgetchdr.sh.log: run-elfgetchdr.sh + @p='run-elfgetchdr.sh'; \ + b='run-elfgetchdr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elfgetzdata.sh.log: run-elfgetzdata.sh + @p='run-elfgetzdata.sh'; \ + b='run-elfgetzdata.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elfputzdata.sh.log: run-elfputzdata.sh + @p='run-elfputzdata.sh'; \ + b='run-elfputzdata.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-zstrptr.sh.log: run-zstrptr.sh + @p='run-zstrptr.sh'; \ + b='run-zstrptr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-compress-test.sh.log: run-compress-test.sh + @p='run-compress-test.sh'; \ + b='run-compress-test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-zdebug.sh.log: run-readelf-zdebug.sh + @p='run-readelf-zdebug.sh'; \ + b='run-readelf-zdebug.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-zdebug-rel.sh.log: run-readelf-zdebug-rel.sh + @p='run-readelf-zdebug-rel.sh'; \ + b='run-readelf-zdebug-rel.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +emptyfile.log: emptyfile$(EXEEXT) + @p='emptyfile$(EXEEXT)'; \ + b='emptyfile'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +vendorelf.log: vendorelf$(EXEEXT) + @p='vendorelf$(EXEEXT)'; \ + b='vendorelf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +fillfile.log: fillfile$(EXEEXT) + @p='fillfile$(EXEEXT)'; \ + b='fillfile'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dwarf_default_lower_bound.log: dwarf_default_lower_bound$(EXEEXT) + @p='dwarf_default_lower_bound$(EXEEXT)'; \ + b='dwarf_default_lower_bound'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwarf-die-addr-die.sh.log: run-dwarf-die-addr-die.sh + @p='run-dwarf-die-addr-die.sh'; \ + b='run-dwarf-die-addr-die.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-get-units-invalid.sh.log: run-get-units-invalid.sh + @p='run-get-units-invalid.sh'; \ + b='run-get-units-invalid.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-get-units-split.sh.log: run-get-units-split.sh + @p='run-get-units-split.sh'; \ + b='run-get-units-split.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-attr-integrate-skel.sh.log: run-attr-integrate-skel.sh + @p='run-attr-integrate-skel.sh'; \ + b='run-attr-integrate-skel.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-all-dwarf-ranges.sh.log: run-all-dwarf-ranges.sh + @p='run-all-dwarf-ranges.sh'; \ + b='run-all-dwarf-ranges.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-unit-info.sh.log: run-unit-info.sh + @p='run-unit-info.sh'; \ + b='run-unit-info.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-reloc-bpf.sh.log: run-reloc-bpf.sh + @p='run-reloc-bpf.sh'; \ + b='run-reloc-bpf.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-next-cfi.sh.log: run-next-cfi.sh + @p='run-next-cfi.sh'; \ + b='run-next-cfi.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-next-cfi-self.sh.log: run-next-cfi-self.sh + @p='run-next-cfi-self.sh'; \ + b='run-next-cfi-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-reverse-sections.sh.log: run-reverse-sections.sh + @p='run-reverse-sections.sh'; \ + b='run-reverse-sections.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-reverse-sections-self.sh.log: run-reverse-sections-self.sh + @p='run-reverse-sections-self.sh'; \ + b='run-reverse-sections-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-copyadd-sections.sh.log: run-copyadd-sections.sh + @p='run-copyadd-sections.sh'; \ + b='run-copyadd-sections.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-copymany-sections.sh.log: run-copymany-sections.sh + @p='run-copymany-sections.sh'; \ + b='run-copymany-sections.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-typeiter-many.sh.log: run-typeiter-many.sh + @p='run-typeiter-many.sh'; \ + b='run-typeiter-many.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-test-many.sh.log: run-strip-test-many.sh + @p='run-strip-test-many.sh'; \ + b='run-strip-test-many.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-strip-version.sh.log: run-strip-version.sh + @p='run-strip-version.sh'; \ + b='run-strip-version.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-xlate-note.sh.log: run-xlate-note.sh + @p='run-xlate-note.sh'; \ + b='run-xlate-note.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-discr.sh.log: run-readelf-discr.sh + @p='run-readelf-discr.sh'; \ + b='run-readelf-discr.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwelf_elf_e_machine_string.sh.log: run-dwelf_elf_e_machine_string.sh + @p='run-dwelf_elf_e_machine_string.sh'; \ + b='run-dwelf_elf_e_machine_string.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elfclassify.sh.log: run-elfclassify.sh + @p='run-elfclassify.sh'; \ + b='run-elfclassify.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-elfclassify-self.sh.log: run-elfclassify-self.sh + @p='run-elfclassify-self.sh'; \ + b='run-elfclassify-self.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-disasm-riscv64.sh.log: run-disasm-riscv64.sh + @p='run-disasm-riscv64.sh'; \ + b='run-disasm-riscv64.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-pt_gnu_prop-tests.sh.log: run-pt_gnu_prop-tests.sh + @p='run-pt_gnu_prop-tests.sh'; \ + b='run-pt_gnu_prop-tests.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-getphdrnum.sh.log: run-getphdrnum.sh + @p='run-getphdrnum.sh'; \ + b='run-getphdrnum.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-test-includes.sh.log: run-test-includes.sh + @p='run-test-includes.sh'; \ + b='run-test-includes.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +leb128.log: leb128$(EXEEXT) + @p='leb128$(EXEEXT)'; \ + b='leb128'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +read_unaligned.log: read_unaligned$(EXEEXT) + @p='read_unaligned$(EXEEXT)'; \ + b='read_unaligned'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +msg_tst.log: msg_tst$(EXEEXT) + @p='msg_tst$(EXEEXT)'; \ + b='msg_tst'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +system-elf-libelf-test.log: system-elf-libelf-test$(EXEEXT) + @p='system-elf-libelf-test$(EXEEXT)'; \ + b='system-elf-libelf-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst1.log: asm-tst1$(EXEEXT) + @p='asm-tst1$(EXEEXT)'; \ + b='asm-tst1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst2.log: asm-tst2$(EXEEXT) + @p='asm-tst2$(EXEEXT)'; \ + b='asm-tst2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst3.log: asm-tst3$(EXEEXT) + @p='asm-tst3$(EXEEXT)'; \ + b='asm-tst3'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst4.log: asm-tst4$(EXEEXT) + @p='asm-tst4$(EXEEXT)'; \ + b='asm-tst4'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst5.log: asm-tst5$(EXEEXT) + @p='asm-tst5$(EXEEXT)'; \ + b='asm-tst5'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst6.log: asm-tst6$(EXEEXT) + @p='asm-tst6$(EXEEXT)'; \ + b='asm-tst6'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst7.log: asm-tst7$(EXEEXT) + @p='asm-tst7$(EXEEXT)'; \ + b='asm-tst7'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst8.log: asm-tst8$(EXEEXT) + @p='asm-tst8$(EXEEXT)'; \ + b='asm-tst8'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +asm-tst9.log: asm-tst9$(EXEEXT) + @p='asm-tst9$(EXEEXT)'; \ + b='asm-tst9'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-disasm-bpf.sh.log: run-disasm-bpf.sh + @p='run-disasm-bpf.sh'; \ + b='run-disasm-bpf.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-low_high_pc-dw-form-indirect.sh.log: run-low_high_pc-dw-form-indirect.sh + @p='run-low_high_pc-dw-form-indirect.sh'; \ + b='run-low_high_pc-dw-form-indirect.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-dw-form-indirect.sh.log: run-readelf-dw-form-indirect.sh + @p='run-readelf-dw-form-indirect.sh'; \ + b='run-readelf-dw-form-indirect.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-s.sh.log: run-readelf-s.sh + @p='run-readelf-s.sh'; \ + b='run-readelf-s.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-dwflsyms.sh.log: run-dwflsyms.sh + @p='run-dwflsyms.sh'; \ + b='run-dwflsyms.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-readelf-compressed-zstd.sh.log: run-readelf-compressed-zstd.sh + @p='run-readelf-compressed-zstd.sh'; \ + b='run-readelf-compressed-zstd.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +run-debuginfod-find.sh.log: run-debuginfod-find.sh + @p='run-debuginfod-find.sh'; \ + b='run-debuginfod-find.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/addrcfi.Po + -rm -f ./$(DEPDIR)/addrscopes.Po + -rm -f ./$(DEPDIR)/addsections.Po + -rm -f ./$(DEPDIR)/aggregate_size.Po + -rm -f ./$(DEPDIR)/all-dwarf-ranges.Po + -rm -f ./$(DEPDIR)/alldts.Po + -rm -f ./$(DEPDIR)/allfcts.Po + -rm -f ./$(DEPDIR)/allregs.Po + -rm -f ./$(DEPDIR)/arextract.Po + -rm -f ./$(DEPDIR)/arls.Po + -rm -f ./$(DEPDIR)/arsymtest.Po + -rm -f ./$(DEPDIR)/asm-tst1.Po + -rm -f ./$(DEPDIR)/asm-tst2.Po + -rm -f ./$(DEPDIR)/asm-tst3.Po + -rm -f ./$(DEPDIR)/asm-tst4.Po + -rm -f ./$(DEPDIR)/asm-tst5.Po + -rm -f ./$(DEPDIR)/asm-tst6.Po + -rm -f ./$(DEPDIR)/asm-tst7.Po + -rm -f ./$(DEPDIR)/asm-tst8.Po + -rm -f ./$(DEPDIR)/asm-tst9.Po + -rm -f ./$(DEPDIR)/attr-integrate-skel.Po + -rm -f ./$(DEPDIR)/backtrace-child.Po + -rm -f ./$(DEPDIR)/backtrace-data.Po + -rm -f ./$(DEPDIR)/backtrace.Po + -rm -f ./$(DEPDIR)/backtrace_child-backtrace-child.Po + -rm -f ./$(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Po + -rm -f ./$(DEPDIR)/buildid.Po + -rm -f ./$(DEPDIR)/debugaltlink.Po + -rm -f ./$(DEPDIR)/debuginfod_build_id_find.Po + -rm -f ./$(DEPDIR)/debuglink.Po + -rm -f ./$(DEPDIR)/deleted.Po + -rm -f ./$(DEPDIR)/deleted_lib_so-deleted-lib.Po + -rm -f ./$(DEPDIR)/dwarf-die-addr-die.Po + -rm -f ./$(DEPDIR)/dwarf-getmacros.Po + -rm -f ./$(DEPDIR)/dwarf-getstring.Po + -rm -f ./$(DEPDIR)/dwarf-ranges.Po + -rm -f ./$(DEPDIR)/dwarf_default_lower_bound.Po + -rm -f ./$(DEPDIR)/dwarfcfi.Po + -rm -f ./$(DEPDIR)/dwelf_elf_e_machine_string.Po + -rm -f ./$(DEPDIR)/dwelfgnucompressed.Po + -rm -f ./$(DEPDIR)/dwfl-addr-sect.Po + -rm -f ./$(DEPDIR)/dwfl-bug-addr-overflow.Po + -rm -f ./$(DEPDIR)/dwfl-bug-fd-leak.Po + -rm -f ./$(DEPDIR)/dwfl-bug-getmodules.Po + -rm -f ./$(DEPDIR)/dwfl-bug-report.Po + -rm -f ./$(DEPDIR)/dwfl-proc-attach.Po + -rm -f ./$(DEPDIR)/dwfl-report-elf-align.Po + -rm -f ./$(DEPDIR)/dwfl-report-segment-contiguous.Po + -rm -f ./$(DEPDIR)/dwfllines.Po + -rm -f ./$(DEPDIR)/dwflmodtest.Po + -rm -f ./$(DEPDIR)/dwflsyms.Po + -rm -f ./$(DEPDIR)/early-offscn.Po + -rm -f ./$(DEPDIR)/ecp.Po + -rm -f ./$(DEPDIR)/elfcopy.Po + -rm -f ./$(DEPDIR)/elfgetchdr.Po + -rm -f ./$(DEPDIR)/elfgetzdata.Po + -rm -f ./$(DEPDIR)/elfputzdata.Po + -rm -f ./$(DEPDIR)/elfrdwrnop.Po + -rm -f ./$(DEPDIR)/elfshphehdr.Po + -rm -f ./$(DEPDIR)/elfstrmerge.Po + -rm -f ./$(DEPDIR)/elfstrtab.Po + -rm -f ./$(DEPDIR)/emptyfile.Po + -rm -f ./$(DEPDIR)/fillfile.Po + -rm -f ./$(DEPDIR)/find-prologues.Po + -rm -f ./$(DEPDIR)/funcretval.Po + -rm -f ./$(DEPDIR)/funcscopes.Po + -rm -f ./$(DEPDIR)/get-aranges.Po + -rm -f ./$(DEPDIR)/get-files.Po + -rm -f ./$(DEPDIR)/get-lines.Po + -rm -f ./$(DEPDIR)/get-pubnames.Po + -rm -f ./$(DEPDIR)/get-units-invalid.Po + -rm -f ./$(DEPDIR)/get-units-split.Po + -rm -f ./$(DEPDIR)/getphdrnum.Po + -rm -f ./$(DEPDIR)/getsrc_die.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/leb128.Po + -rm -f ./$(DEPDIR)/line2addr.Po + -rm -f ./$(DEPDIR)/low_high_pc.Po + -rm -f ./$(DEPDIR)/msg_tst.Po + -rm -f ./$(DEPDIR)/newdata.Po + -rm -f ./$(DEPDIR)/newfile.Po + -rm -f ./$(DEPDIR)/newscn.Po + -rm -f ./$(DEPDIR)/next-files.Po + -rm -f ./$(DEPDIR)/next-lines.Po + -rm -f ./$(DEPDIR)/next_cfi.Po + -rm -f ./$(DEPDIR)/peel_type.Po + -rm -f ./$(DEPDIR)/rdwrmmap.Po + -rm -f ./$(DEPDIR)/read_unaligned.Po + -rm -f ./$(DEPDIR)/rerequest_tag.Po + -rm -f ./$(DEPDIR)/saridx.Po + -rm -f ./$(DEPDIR)/scnnames.Po + -rm -f ./$(DEPDIR)/sectiondump.Po + -rm -f ./$(DEPDIR)/show-abbrev.Po + -rm -f ./$(DEPDIR)/show-die-info.Po + -rm -f ./$(DEPDIR)/showptable.Po + -rm -f ./$(DEPDIR)/strptr.Po + -rm -f ./$(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Po + -rm -f ./$(DEPDIR)/test-elf_cntl_gelf_getshdr.Po + -rm -f ./$(DEPDIR)/test-flag-nobits.Po + -rm -f ./$(DEPDIR)/test_nlist-test-nlist.Po + -rm -f ./$(DEPDIR)/typeiter.Po + -rm -f ./$(DEPDIR)/typeiter2.Po + -rm -f ./$(DEPDIR)/unit-info.Po + -rm -f ./$(DEPDIR)/update1.Po + -rm -f ./$(DEPDIR)/update2.Po + -rm -f ./$(DEPDIR)/update3.Po + -rm -f ./$(DEPDIR)/update4.Po + -rm -f ./$(DEPDIR)/varlocs.Po + -rm -f ./$(DEPDIR)/vdsosyms.Po + -rm -f ./$(DEPDIR)/vendorelf.Po + -rm -f ./$(DEPDIR)/xlate_notes.Po + -rm -f ./$(DEPDIR)/zstrptr.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: installcheck-local + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/addrcfi.Po + -rm -f ./$(DEPDIR)/addrscopes.Po + -rm -f ./$(DEPDIR)/addsections.Po + -rm -f ./$(DEPDIR)/aggregate_size.Po + -rm -f ./$(DEPDIR)/all-dwarf-ranges.Po + -rm -f ./$(DEPDIR)/alldts.Po + -rm -f ./$(DEPDIR)/allfcts.Po + -rm -f ./$(DEPDIR)/allregs.Po + -rm -f ./$(DEPDIR)/arextract.Po + -rm -f ./$(DEPDIR)/arls.Po + -rm -f ./$(DEPDIR)/arsymtest.Po + -rm -f ./$(DEPDIR)/asm-tst1.Po + -rm -f ./$(DEPDIR)/asm-tst2.Po + -rm -f ./$(DEPDIR)/asm-tst3.Po + -rm -f ./$(DEPDIR)/asm-tst4.Po + -rm -f ./$(DEPDIR)/asm-tst5.Po + -rm -f ./$(DEPDIR)/asm-tst6.Po + -rm -f ./$(DEPDIR)/asm-tst7.Po + -rm -f ./$(DEPDIR)/asm-tst8.Po + -rm -f ./$(DEPDIR)/asm-tst9.Po + -rm -f ./$(DEPDIR)/attr-integrate-skel.Po + -rm -f ./$(DEPDIR)/backtrace-child.Po + -rm -f ./$(DEPDIR)/backtrace-data.Po + -rm -f ./$(DEPDIR)/backtrace.Po + -rm -f ./$(DEPDIR)/backtrace_child-backtrace-child.Po + -rm -f ./$(DEPDIR)/backtrace_dwarf-backtrace-dwarf.Po + -rm -f ./$(DEPDIR)/buildid.Po + -rm -f ./$(DEPDIR)/debugaltlink.Po + -rm -f ./$(DEPDIR)/debuginfod_build_id_find.Po + -rm -f ./$(DEPDIR)/debuglink.Po + -rm -f ./$(DEPDIR)/deleted.Po + -rm -f ./$(DEPDIR)/deleted_lib_so-deleted-lib.Po + -rm -f ./$(DEPDIR)/dwarf-die-addr-die.Po + -rm -f ./$(DEPDIR)/dwarf-getmacros.Po + -rm -f ./$(DEPDIR)/dwarf-getstring.Po + -rm -f ./$(DEPDIR)/dwarf-ranges.Po + -rm -f ./$(DEPDIR)/dwarf_default_lower_bound.Po + -rm -f ./$(DEPDIR)/dwarfcfi.Po + -rm -f ./$(DEPDIR)/dwelf_elf_e_machine_string.Po + -rm -f ./$(DEPDIR)/dwelfgnucompressed.Po + -rm -f ./$(DEPDIR)/dwfl-addr-sect.Po + -rm -f ./$(DEPDIR)/dwfl-bug-addr-overflow.Po + -rm -f ./$(DEPDIR)/dwfl-bug-fd-leak.Po + -rm -f ./$(DEPDIR)/dwfl-bug-getmodules.Po + -rm -f ./$(DEPDIR)/dwfl-bug-report.Po + -rm -f ./$(DEPDIR)/dwfl-proc-attach.Po + -rm -f ./$(DEPDIR)/dwfl-report-elf-align.Po + -rm -f ./$(DEPDIR)/dwfl-report-segment-contiguous.Po + -rm -f ./$(DEPDIR)/dwfllines.Po + -rm -f ./$(DEPDIR)/dwflmodtest.Po + -rm -f ./$(DEPDIR)/dwflsyms.Po + -rm -f ./$(DEPDIR)/early-offscn.Po + -rm -f ./$(DEPDIR)/ecp.Po + -rm -f ./$(DEPDIR)/elfcopy.Po + -rm -f ./$(DEPDIR)/elfgetchdr.Po + -rm -f ./$(DEPDIR)/elfgetzdata.Po + -rm -f ./$(DEPDIR)/elfputzdata.Po + -rm -f ./$(DEPDIR)/elfrdwrnop.Po + -rm -f ./$(DEPDIR)/elfshphehdr.Po + -rm -f ./$(DEPDIR)/elfstrmerge.Po + -rm -f ./$(DEPDIR)/elfstrtab.Po + -rm -f ./$(DEPDIR)/emptyfile.Po + -rm -f ./$(DEPDIR)/fillfile.Po + -rm -f ./$(DEPDIR)/find-prologues.Po + -rm -f ./$(DEPDIR)/funcretval.Po + -rm -f ./$(DEPDIR)/funcscopes.Po + -rm -f ./$(DEPDIR)/get-aranges.Po + -rm -f ./$(DEPDIR)/get-files.Po + -rm -f ./$(DEPDIR)/get-lines.Po + -rm -f ./$(DEPDIR)/get-pubnames.Po + -rm -f ./$(DEPDIR)/get-units-invalid.Po + -rm -f ./$(DEPDIR)/get-units-split.Po + -rm -f ./$(DEPDIR)/getphdrnum.Po + -rm -f ./$(DEPDIR)/getsrc_die.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/leb128.Po + -rm -f ./$(DEPDIR)/line2addr.Po + -rm -f ./$(DEPDIR)/low_high_pc.Po + -rm -f ./$(DEPDIR)/msg_tst.Po + -rm -f ./$(DEPDIR)/newdata.Po + -rm -f ./$(DEPDIR)/newfile.Po + -rm -f ./$(DEPDIR)/newscn.Po + -rm -f ./$(DEPDIR)/next-files.Po + -rm -f ./$(DEPDIR)/next-lines.Po + -rm -f ./$(DEPDIR)/next_cfi.Po + -rm -f ./$(DEPDIR)/peel_type.Po + -rm -f ./$(DEPDIR)/rdwrmmap.Po + -rm -f ./$(DEPDIR)/read_unaligned.Po + -rm -f ./$(DEPDIR)/rerequest_tag.Po + -rm -f ./$(DEPDIR)/saridx.Po + -rm -f ./$(DEPDIR)/scnnames.Po + -rm -f ./$(DEPDIR)/sectiondump.Po + -rm -f ./$(DEPDIR)/show-abbrev.Po + -rm -f ./$(DEPDIR)/show-die-info.Po + -rm -f ./$(DEPDIR)/showptable.Po + -rm -f ./$(DEPDIR)/strptr.Po + -rm -f ./$(DEPDIR)/system_elf_libelf_test-system-elf-libelf-test.Po + -rm -f ./$(DEPDIR)/test-elf_cntl_gelf_getshdr.Po + -rm -f ./$(DEPDIR)/test-flag-nobits.Po + -rm -f ./$(DEPDIR)/test_nlist-test-nlist.Po + -rm -f ./$(DEPDIR)/typeiter.Po + -rm -f ./$(DEPDIR)/typeiter2.Po + -rm -f ./$(DEPDIR)/unit-info.Po + -rm -f ./$(DEPDIR)/update1.Po + -rm -f ./$(DEPDIR)/update2.Po + -rm -f ./$(DEPDIR)/update3.Po + -rm -f ./$(DEPDIR)/update4.Po + -rm -f ./$(DEPDIR)/varlocs.Po + -rm -f ./$(DEPDIR)/vdsosyms.Po + -rm -f ./$(DEPDIR)/vendorelf.Po + -rm -f ./$(DEPDIR)/xlate_notes.Po + -rm -f ./$(DEPDIR)/zstrptr.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installcheck-local \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +%.os: %.c %.o +@AMDEP_TRUE@ $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \ +@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@AMDEP_TRUE@ fi +@AMDEP_FALSE@ $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $< + +print-%: + @echo $*=$($*) + +# Substitute $(COMPILE). +backtrace-child-biarch$(EXEEXT): backtrace-child.c + $(AM_V_CC)$(CC_BIARCH) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) $(backtrace_child_CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) $(backtrace_child_LDFLAGS) \ + -o $@ $< + +# test_nlist checks its own symbol table, and expects various symbols +# to be in the order as specified in the source file. Explicitly set +# minimal CFLAGS +test-nlist$(EXEEXT): test-nlist.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(test_nlist_CFLAGS) $(GCOV_FLAGS) -o $@ $< $(test_nlist_LDADD) + +@BIARCH_FALSE@export ELFUTILS_DISABLE_BIARCH = 1 + +@DEMANGLE_FALSE@export ELFUTILS_DISABLE_DEMANGLE = 1 + +installcheck-local: + $(MAKE) $(AM_MAKEFLAGS) \ + TESTS_ENVIRONMENT="$(installed_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(installed_LOG_COMPILER)" check-TESTS + +@GCOV_TRUE@check: check-am coverage +@GCOV_TRUE@.PHONY: coverage +@GCOV_TRUE@coverage: +@GCOV_TRUE@ -$(srcdir)/coverage.sh + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tests/addrcfi.c b/tests/addrcfi.c new file mode 100644 index 00000000..2b7d7bd0 --- /dev/null +++ b/tests/addrcfi.c @@ -0,0 +1,233 @@ +/* Test program for CFI handling. + Copyright (C) 2009-2010, 2013, 2015 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) +#include +#include +#include +#include +#include +#include +#include + +#include "../libdw/known-dwarf.h" + +static const char * +op_name (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_OP +#undef DWARF_ONE_KNOWN_DW_OP + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + +static void +print_detail (int result, const Dwarf_Op *ops, size_t nops, Dwarf_Addr bias) +{ + if (result < 0) + printf ("indeterminate (%s)\n", dwarf_errmsg (-1)); + else if (nops == 0) + printf ("%s\n", ops == NULL ? "same_value" : "undefined"); + else + { + printf ("%s expression:", result == 0 ? "location" : "value"); + for (size_t i = 0; i < nops; ++i) + { + printf (" %s", op_name(ops[i].atom)); + if (ops[i].number2 == 0) + { + if (ops[i].atom == DW_OP_addr) + printf ("(%#" PRIx64 ")", ops[i].number + bias); + else if (ops[i].number != 0) + printf ("(%" PRId64 ")", ops[i].number); + } + else + printf ("(%" PRId64 ",%" PRId64 ")", + ops[i].number, ops[i].number2); + } + puts (""); + } +} + +struct stuff +{ + Dwarf_Frame *frame; + Dwarf_Addr bias; +}; + +static int +print_register (void *arg, + int regno, + const char *setname, + const char *prefix, + const char *regname, + int bits __attribute__ ((unused)), + int type __attribute__ ((unused))) +{ + struct stuff *stuff = arg; + + printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname); + + Dwarf_Op ops_mem[3]; + Dwarf_Op *ops; + size_t nops; + int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops); + print_detail (result, ops, nops, stuff->bias); + + return DWARF_CB_OK; +} + +static int +handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi, + GElf_Addr pc, struct stuff *stuff) +{ + if (cfi == NULL) + { + printf ("handle_cfi no CFI (%s): %s\n", which, dwarf_errmsg (-1)); + return -1; + } + + int result = dwarf_cfi_addrframe (cfi, pc - stuff->bias, &stuff->frame); + if (result != 0) + { + printf ("dwarf_cfi_addrframe (%s): %s\n", which, dwarf_errmsg (-1)); + return 1; + } + + Dwarf_Addr start = pc; + Dwarf_Addr end = pc; + bool signalp; + int ra_regno = dwarf_frame_info (stuff->frame, &start, &end, &signalp); + if (ra_regno >= 0) + { + start += stuff->bias; + end += stuff->bias; + } + + printf ("%s has %#" PRIx64 " => [%#" PRIx64 ", %#" PRIx64 "):\n", + which, pc, start, end); + + if (ra_regno < 0) + printf ("\treturn address register unavailable (%s)\n", + dwarf_errmsg (0)); + else + printf ("\treturn address in reg%u%s\n", + ra_regno, signalp ? " (signal frame)" : ""); + + // Point cfa_ops to dummy to match print_detail expectations. + // (nops == 0 && cfa_ops != NULL => "undefined") + Dwarf_Op dummy; + Dwarf_Op *cfa_ops = &dummy; + size_t cfa_nops; + result = dwarf_frame_cfa (stuff->frame, &cfa_ops, &cfa_nops); + + printf ("\tCFA "); + print_detail (result, cfa_ops, cfa_nops, stuff->bias); + + (void) dwfl_module_register_names (dwfl_addrmodule (dwfl, pc), + &print_register, stuff); + + return 0; +} + +static int +handle_address (GElf_Addr pc, Dwfl *dwfl) +{ + Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc); + + struct stuff stuff; + stuff.frame = NULL; + stuff.bias = 0; + int res = handle_cfi (dwfl, ".eh_frame", + dwfl_module_eh_cfi (mod, &stuff.bias), pc, &stuff); + free (stuff.frame); + + stuff.frame = NULL; + stuff.bias = 0; + res &= handle_cfi (dwfl, ".debug_frame", + dwfl_module_dwarf_cfi (mod, &stuff.bias), pc, &stuff); + free (stuff.frame); + + return res; +} + +int +main (int argc, char *argv[]) +{ + int remaining; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + Dwfl *dwfl = NULL; + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl); + assert (dwfl != NULL); + + int result = 0; + + /* Now handle the addresses. In case none are given on the command + line, read from stdin. */ + if (remaining == argc) + { + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + + char *buf = NULL; + size_t len = 0; + while (!feof_unlocked (stdin)) + { + if (getline (&buf, &len, stdin) < 0) + break; + + char *endp; + uintmax_t addr = strtoumax (buf, &endp, 0); + if (endp != buf) + result |= handle_address (addr, dwfl); + else + result = 1; + } + + free (buf); + } + else + { + do + { + char *endp; + uintmax_t addr = strtoumax (argv[remaining], &endp, 0); + if (endp != argv[remaining]) + result |= handle_address (addr, dwfl); + else + result = 1; + } + while (++remaining < argc); + } + + dwfl_end (dwfl); + + return result; +} diff --git a/tests/addrscopes.c b/tests/addrscopes.c new file mode 100644 index 00000000..b231b6a9 --- /dev/null +++ b/tests/addrscopes.c @@ -0,0 +1,196 @@ +/* Test program for dwarf_getscopes. + Copyright (C) 2005, 2014 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) +#include +#include +#include +#include +#include +#include +#include +#include "system.h" + + +static void +paddr (const char *prefix, Dwarf_Addr addr, Dwfl_Line *line) +{ + const char *src; + int lineno, linecol; + if (line != NULL + && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol, + NULL, NULL)) != NULL) + { + if (linecol != 0) + printf ("%s%#" PRIx64 " (%s:%d:%d)", + prefix, addr, src, lineno, linecol); + else + printf ("%s%#" PRIx64 " (%s:%d)", + prefix, addr, src, lineno); + } + else + printf ("%s%#" PRIx64, prefix, addr); +} + +static void +print_vars (unsigned int indent, Dwarf_Die *die) +{ + Dwarf_Die child; + if (dwarf_child (die, &child) == 0) + do + switch (dwarf_tag (&child)) + { + case DW_TAG_variable: + case DW_TAG_formal_parameter: + printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "", + dwarf_diename (&child), + (uint64_t) dwarf_dieoffset (&child)); + break; + default: + break; + } + while (dwarf_siblingof (&child, &child) == 0); + + Dwarf_Attribute attr_mem; + Dwarf_Die origin; + if (dwarf_hasattr (die, DW_AT_abstract_origin) + && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem), + &origin) != NULL + && dwarf_child (&origin, &child) == 0) + do + switch (dwarf_tag (&child)) + { + case DW_TAG_variable: + case DW_TAG_formal_parameter: + printf ("%*s%s (abstract)\n", indent, "", + dwarf_diename (&child)); + break; + default: + break; + } + while (dwarf_siblingof (&child, &child) == 0); +} + + +#define INDENT 4 + +static void +handle_address (GElf_Addr pc, Dwfl *dwfl) +{ + Dwarf_Addr cubias; + Dwarf_Die *cudie = dwfl_addrdie (dwfl, pc, &cubias); + if (cudie == NULL) + error (EXIT_FAILURE, 0, "dwfl_addrdie: %s", dwfl_errmsg (-1)); + + Dwarf_Die *scopes; + int n = dwarf_getscopes (cudie, pc - cubias, &scopes); + if (n < 0) + error (EXIT_FAILURE, 0, "dwarf_getscopes: %s", dwarf_errmsg (-1)); + else if (n == 0) + printf ("%#" PRIx64 ": not in any scope\n", pc); + else + { + printf ("%#" PRIx64 ":\n", pc); + unsigned int indent = 0; + while (n-- > 0) + { + Dwarf_Die *const die = &scopes[n]; + + indent += INDENT; + printf ("%*s%s (%#x)", indent, "", + dwarf_diename (die) ?: "", + dwarf_tag (die)); + + Dwarf_Addr lowpc, highpc; + if (dwarf_lowpc (die, &lowpc) == 0 + && dwarf_highpc (die, &highpc) == 0) + { + lowpc += cubias; + highpc += cubias; + Dwfl_Line *loline = dwfl_getsrc (dwfl, lowpc); + Dwfl_Line *hiline = dwfl_getsrc (dwfl, highpc - 1); + paddr (": ", lowpc, loline); + if (highpc != lowpc) + paddr (" .. ", highpc - 1, hiline == loline ? NULL : hiline); + } + puts (""); + + print_vars (indent + INDENT, die); + } + free (scopes); + } +} + +int +main (int argc, char *argv[]) +{ + int remaining; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + Dwfl *dwfl = NULL; + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl); + assert (dwfl != NULL); + + int result = 0; + + /* Now handle the addresses. In case none are given on the command + line, read from stdin. */ + if (remaining == argc) + { + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); + + char *buf = NULL; + size_t len = 0; + while (!feof_unlocked (stdin)) + { + if (getline (&buf, &len, stdin) < 0) + break; + + char *endp; + uintmax_t addr = strtoumax (buf, &endp, 0); + if (endp != buf) + handle_address (addr, dwfl); + else + result = 1; + } + + free (buf); + } + else + { + do + { + char *endp; + uintmax_t addr = strtoumax (argv[remaining], &endp, 0); + if (endp != argv[remaining]) + handle_address (addr, dwfl); + else + result = 1; + } + while (++remaining < argc); + } + + dwfl_end (dwfl); + + return result; +} diff --git a/tests/addrx_constx-4.dwo.bz2 b/tests/addrx_constx-4.dwo.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..f0bae1cd56a3448993c40664f22ab1d7ebfb9a9a GIT binary patch literal 809 zcmV+^1J?XPT4*^jL0KkKS+X85FaQCsfB*mQ`0m$l|NHx|?-&37|K|T>aNLsnHd6Fr zVUC1Gd*eU?91Bg(;Zss#8a)xFgGPf*4^RU^pfn8tXlNP+o}r)vMuv?VG6PING}KbgG~U@pglt%4F;Mt0MG!_Kn#XKlR(e`6+DTk zY2`LZ%?%?XAZRiT4F-S!0B8nAfB*o{00000000=06pz%z^-m;dHmB;3C;-u+pfu0` zdV|tv&<0OJ02&%J000dSNB{uP2v|9SKqd6NtdaeGp$kZ1#6KAjjy$IB35@xHsKPAAzfv7|n5fQAS0Fc^x#|(ljh$#&aM6wA3 z5(aVrW{?0{*0w8liWWFWg1V&Wkb3qP0oAH!=hqV8mOVW3V6Z=U%`5NIzstOKi$NO` zs6z6C8z~?#mWaim*d`=HS7&9=edG{CB}D)-F)?wXTBeC(GXpx}DNUz+gROuK{Hm+H z;~^g+0YQsSha?H|n6MOs?Y75XVhhEH^R@|?&q5QgjF=sYM(zzJ?vOzi%pd}$EDzA` zfw2Q_$swdeh9cdo!sE{v?qC*`V`b(>Xrb}cyX0g_CL}E+VNZn@=)xX<1zl)HHUKL{ z(Wx?N!qEr~-ByUE7R0(Z+tJLD?)ALG=A1wxgUuQl<@I(lMhTs@C+V@XD<+wjM0L!;+#>t2nAmS zOT6B5ePZQxX+Nd8u!g#0>Uh#pU8?PPNq+ANepBuBL$b%iv!8HB;_|r6KH4Dc0-;5F nQzMLr2}B4`TAY(dQd~9NOp7f;+vfF=-{S5_rwS4lL&gRG7{6Ga literal 0 HcmV?d00001 diff --git a/tests/addrx_constx-5.dwo.bz2 b/tests/addrx_constx-5.dwo.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..a5f4b1a6766b726587ea13584ece648527c0fea9 GIT binary patch literal 824 zcmV-81IPSAT4*^jL0KkKS=}ah;s628fB*mfz5VxV|NHyD?)Sg{|Nh%MVpa1{> z001-whJXM70fb^=0LB0@`LIOPl$Kz@LWSZC(wNg&8+e>TQh5}B$V3*dd6du5v#8Z7 zbTNIJ<_M^|!B{3{ZZ(x2ECW*}D-#Tm*ksdC0aTeF9h$6u4Fi_d134E00mw*ca~w2C z3sk^Ns!WOUU@v=@5!2BH&avU?km^XWEYA{#2ou>ezZZA@ z>WBb$th&X+7&e!Z#U%>Fve?UzHw|fk*z|fmPRg~|noWCPrp-Ey4Uq-_-u}Yj2C+aW z_@<&wh`cZZ90?+gG6?uUVR*#K;RV;4fodK~EG`vH(qkdZMP}Iii`zKI56pB05|rVo zNI@G)C{H>D#PJz?e6@*;_%e!4nA9}U!r>knh6gL<G7uqvG^i^YfcAp{&UcGAd0J^&Ocla@Lstv;xa9zcoDia|i^mJPmVn3qQJ`Dxd#-9IXpUGL-q zBL^q1sEv=}NE!C}$g^. */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include ELFUTILS_HEADER(elf) +#include + + +/* shstrndx is special, might overflow into section zero header sh_link. */ +static int +setshstrndx (Elf *elf, size_t ndx) +{ + printf ("setshstrndx: %zd\n", ndx); + + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + return -1; + + if (ndx < SHN_LORESERVE) + ehdr->e_shstrndx = ndx; + else + { + ehdr->e_shstrndx = SHN_XINDEX; + Elf_Scn *zscn = elf_getscn (elf, 0); + GElf_Shdr zshdr_mem; + GElf_Shdr *zshdr = gelf_getshdr (zscn, &zshdr_mem); + if (zshdr == NULL) + return -1; + zshdr->sh_link = ndx; + if (gelf_update_shdr (zscn, zshdr) == 0) + return -1; + } + + if (gelf_update_ehdr (elf, ehdr) == 0) + return -1; + + return 0; +} + +/* Will add nr new '.extra' sections and a new '.new_shstrtab' section + at the end. */ +static void +add_sections (const char *name, size_t nr, int use_mmap, size_t sec_size) +{ + printf ("add_sections '%s': %zd (sec_size: %zd)\n", name, nr, sec_size); + + int fd = open (name, O_RDWR); + if (fd < 0) + { + fprintf (stderr, "Couldn't open file '%s': %s\n", + name, strerror (errno)); + exit (1); + } + + Elf *elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL); + if (elf == NULL) + { + fprintf (stderr, "Couldn't open ELF file '%s': %s\n", + name, elf_errmsg (-1)); + exit (1); + } + + /* We will add a new shstrtab section with two new names at the end. + Just get the current shstrtab table and add two entries '.extra' + and '.old_shstrtab' at the end of the table, so all existing indexes + are still valid. */ + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) < 0) + { + printf ("cannot get shstrndx: %s\n", elf_errmsg (-1)); + exit (1); + } + + Elf_Scn *shstrtab_scn = elf_getscn (elf, shstrndx); + if (shstrtab_scn == NULL) + { + printf ("couldn't get shstrtab scn: %s\n", elf_errmsg (-1)); + exit (1); + } + Elf_Data *shstrtab_data = elf_getdata (shstrtab_scn, NULL); + if (shstrtab_data == NULL) + { + printf ("couldn't get shstrtab data: %s\n", elf_errmsg (-1)); + exit (1); + } + size_t new_shstrtab_size = (shstrtab_data->d_size + + strlen (".extra") + 1 + + strlen (".old_shstrtab") + 1); + void *new_shstrtab_buf = malloc (new_shstrtab_size); + if (new_shstrtab_buf == NULL) + { + printf ("couldn't allocate new shstrtab data d_buf\n"); + exit (1); + } + memcpy (new_shstrtab_buf, shstrtab_data->d_buf, shstrtab_data->d_size); + size_t extra_idx = shstrtab_data->d_size; + size_t old_shstrtab_idx = extra_idx + strlen (".extra") + 1; + strcpy (new_shstrtab_buf + extra_idx, ".extra"); + strcpy (new_shstrtab_buf + old_shstrtab_idx, ".old_shstrtab"); + + /* Change the name of the old shstrtab section, because elflint + has a strict check on the name/type for .shstrtab. */ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (shstrtab_scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get header for old shstrtab section: %s\n", + elf_errmsg (-1)); + exit (1); + } + + size_t shstrtab_idx = shdr->sh_name; + shdr->sh_name = old_shstrtab_idx; + + if (gelf_update_shdr (shstrtab_scn, shdr) == 0) + { + printf ("cannot update old shstrtab section header: %s\n", + elf_errmsg (-1)); + exit (1); + } + + void *buf; + size_t bufsz; + if (sec_size == 0) + { + buf = strdup ("extra"); + bufsz = strlen ("extra") + 1; + } + else + { + buf = malloc (sec_size); + if (buf == NULL) + { + printf ("cannot allocate buffer data of %zd bytes\n", sec_size); + exit (1); + } + memset (buf, 0xAA, sec_size); + bufsz = sec_size; + } + + // Add lots of .extra sections... + size_t cnt = 0; + while (cnt++ < nr) + { + Elf_Scn *scn = elf_newscn (elf); + if (scn == NULL) + { + printf ("cannot create .extra section (%zd): %s\n", cnt, + elf_errmsg (-1)); + exit (1); + } + + Elf_Data *data = elf_newdata (scn); + if (data == NULL) + { + printf ("couldn't create new section data (%zd): %s\n", cnt, + elf_errmsg (-1)); + exit (1); + } + + data->d_size = bufsz; + data->d_buf = buf; + data->d_type = ELF_T_BYTE; + data->d_align = 1; + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get header for new section (%zd): %s\n", cnt, + elf_errmsg (-1)); + exit (1); + } + + shdr->sh_type = SHT_PROGBITS; + shdr->sh_flags = 0; + shdr->sh_addr = 0; + shdr->sh_link = SHN_UNDEF; + shdr->sh_info = SHN_UNDEF; + shdr->sh_addralign = 1; + shdr->sh_entsize = 0; + shdr->sh_size = data->d_size; + shdr->sh_name = extra_idx; + + if (gelf_update_shdr (scn, shdr) == 0) + { + printf ("cannot update new section header (%zd): %s\n", cnt, + elf_errmsg (-1)); + exit (1); + } + } + + // Create new shstrtab section. + Elf_Scn *new_shstrtab_scn = elf_newscn (elf); + if (new_shstrtab_scn == NULL) + { + printf ("cannot create new shstrtab section: %s\n", elf_errmsg (-1)); + exit (1); + } + + Elf_Data *new_shstrtab_data = elf_newdata (new_shstrtab_scn); + if (new_shstrtab_data == NULL) + { + printf ("couldn't create new shstrtab section data: %s\n", + elf_errmsg (-1)); + exit (1); + } + + new_shstrtab_data->d_size = new_shstrtab_size; + new_shstrtab_data->d_buf = new_shstrtab_buf; + new_shstrtab_data->d_type = ELF_T_BYTE; + new_shstrtab_data->d_align = 1; + + shdr = gelf_getshdr (new_shstrtab_scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get header for new shstrtab section: %s\n", + elf_errmsg (-1)); + exit (1); + } + + shdr->sh_type = SHT_STRTAB; + shdr->sh_flags = 0; + shdr->sh_addr = 0; + shdr->sh_link = SHN_UNDEF; + shdr->sh_info = SHN_UNDEF; + shdr->sh_addralign = 1; + shdr->sh_entsize = 0; + shdr->sh_size = new_shstrtab_size; + shdr->sh_name = shstrtab_idx; + + // Finished new shstrtab section, update the header. + if (gelf_update_shdr (new_shstrtab_scn, shdr) == 0) + { + printf ("cannot update new shstrtab section header: %s\n", + elf_errmsg (-1)); + exit (1); + } + + // Set it as the new shstrtab section to get the names correct. + size_t new_shstrndx = elf_ndxscn (new_shstrtab_scn); + if (setshstrndx (elf, new_shstrndx) < 0) + { + printf ("cannot set shstrndx: %s\n", elf_errmsg (-1)); + exit (1); + } + + // Write everything to disk. + if (elf_update (elf, ELF_C_WRITE) < 0) + { + printf ("failure in elf_update: %s\n", elf_errmsg (-1)); + exit (1); + } + + if (elf_end (elf) != 0) + { + printf ("couldn't cleanup elf '%s': %s\n", name, elf_errmsg (-1)); + exit (1); + } + + if (close (fd) != 0) + { + printf ("couldn't close '%s': %s\n", name, strerror (errno)); + exit (1); + } + + free (buf); + free (new_shstrtab_buf); +} + +int +main (int argc, char *argv[]) +{ + elf_version (EV_CURRENT); + + /* Takes the given file, and adds the given number of sections. + Optionally using mmap and optionally using a given section size. */ + if (argc < 3 || argc > 5) + { + fprintf (stderr, "addsections [--mmap] nr elf.file [sec_size]\n"); + exit (1); + } + + int argn = 1; + bool use_mmap = false; + if (strcmp (argv[argn], "--mmap") == 0) + { + use_mmap = true; + argn++; + } + + size_t nr = atoi (argv[argn++]); + const char *file = argv[argn++]; + + size_t sec_size = 0; + if (argn < argc) + sec_size = atol (argv[argn++]); + + add_sections (file, nr, use_mmap, sec_size); + + return 0; +} diff --git a/tests/aggregate_size.c b/tests/aggregate_size.c new file mode 100644 index 00000000..930eafa7 --- /dev/null +++ b/tests/aggregate_size.c @@ -0,0 +1,83 @@ +/* Test program for dwarf_aggregate_size. Prints size of top-level vars. + Copyright (C) 2014 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include ELFUTILS_HEADER(dw) +#include ELFUTILS_HEADER(dwfl) +#include +#include +#include + +void +print_var_type_size (Dwarf_Die *var) +{ + Dwarf_Attribute attr_mem; + Dwarf_Die type_mem; + Dwarf_Die *type; + const char *name = dwarf_diename (var); + + type = dwarf_formref_die (dwarf_attr (var, DW_AT_type, &attr_mem), + &type_mem); + if (type != NULL) + { + Dwarf_Word size; + if (dwarf_aggregate_size (type, &size) < 0) + printf ("%s no size: %s\n", name, dwarf_errmsg (-1)); + else + printf ("%s size %" PRIu64 "\n", name, size); + } + else + printf ("%s has no type.\n", name); +} + +int +main (int argc, char *argv[]) +{ + + int remaining; + Dwfl *dwfl; + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, + &dwfl); + assert (dwfl != NULL); + + Dwarf_Die *cu = NULL; + Dwarf_Addr dwbias; + while ((cu = dwfl_nextcu (dwfl, cu, &dwbias)) != NULL) + { + Dwarf_Die die_mem; + Dwarf_Die *die = &die_mem; + dwarf_child (cu, &die_mem); + + while (1) + { + if (dwarf_tag (die) == DW_TAG_variable) + print_var_type_size (die); + + if (dwarf_siblingof (die, &die_mem) != 0) + break; + } + } + + dwfl_end (dwfl); +} diff --git a/tests/all-dwarf-ranges.c b/tests/all-dwarf-ranges.c new file mode 100644 index 00000000..4331a05b --- /dev/null +++ b/tests/all-dwarf-ranges.c @@ -0,0 +1,90 @@ +/* Test program for dwarf_ranges + Copyright (C) 2015, 2018 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +ranges_die (Dwarf_Die *die) +{ + Dwarf_Addr base, start, end; + int ranges = dwarf_ranges (die, 0, &base, &start, &end); + if (ranges < 0) + puts (dwarf_errmsg (-1)); + else if (ranges > 0) + { + printf ("die: %s (%x)\n", dwarf_diename (die) ?: "", + dwarf_tag (die)); + for (ptrdiff_t off = 0; + (off = dwarf_ranges (die, off, &base, &start, &end)); ) + if (off == -1) + { + puts (dwarf_errmsg (-1)); + break; + } + else + printf (" %"PRIx64"..%"PRIx64"\n", start, end); + printf ("\n"); + } +} + +static void +walk_tree (Dwarf_Die *dwarf_die) +{ + Dwarf_Die die = *dwarf_die; + do + { + Dwarf_Die child; + ranges_die (&die); + if (dwarf_child (&die, &child) == 0) + walk_tree (&child); + } + while (dwarf_siblingof (&die, &die) == 0); +} + +int +main (int argc, char *argv[]) +{ + assert (argc >= 2); + const char *name = argv[1]; + + int fd = open (name, O_RDONLY); + Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ); + + Dwarf_CU *cu = NULL; + Dwarf_Die cudie, subdie; + uint8_t unit_type; + while (dwarf_get_units (dbg, cu, &cu, NULL, + &unit_type, &cudie, &subdie) == 0) + { + Dwarf_Die die = (unit_type == DW_UT_skeleton + ? subdie : cudie); + walk_tree (&die); + } + dwarf_end (dbg); + + return 0; +} diff --git a/tests/alldts.c b/tests/alldts.c new file mode 100644 index 00000000..3e9f9fe6 --- /dev/null +++ b/tests/alldts.c @@ -0,0 +1,271 @@ +/* Create an ELF file with all the DT_* flags set. + Copyright (C) 2011, 2016 Red Hat, Inc. + This file is part of elfutils. + Written by Marek Polacek , 2011. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include ELFUTILS_HEADER(dwelf) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "system.h" + + +int +main (void) +{ + static const char fname[] = "testfile-alldts"; + Dwelf_Strtab *shst; + Dwelf_Strent *dynscn; + Dwelf_Strent *shstrtabse; + const Elf32_Sword dtflags[] = + { + DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, + DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA, + DT_RELASZ, DT_RELAENT, DT_STRSZ, DT_SYMENT, + DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, + DT_SYMBOLIC, DT_REL, DT_RELSZ, DT_RELENT, + DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL, + DT_BIND_NOW, DT_INIT_ARRAY, DT_FINI_ARRAY, + DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, + DT_FLAGS, DT_ENCODING, DT_PREINIT_ARRAY, + DT_PREINIT_ARRAYSZ, DT_VERSYM, DT_GNU_PRELINKED, + DT_GNU_CONFLICTSZ, DT_GNU_LIBLISTSZ, DT_CHECKSUM, + DT_PLTPADSZ, DT_MOVEENT, DT_MOVESZ, DT_FEATURE_1, + DT_POSFLAG_1, DT_SYMINSZ, DT_SYMINENT, DT_GNU_HASH, + DT_TLSDESC_PLT, DT_TLSDESC_GOT, DT_GNU_CONFLICT, + DT_GNU_LIBLIST, DT_CONFIG, DT_DEPAUDIT, DT_AUDIT, + DT_PLTPAD, DT_MOVETAB, DT_SYMINFO, DT_RELACOUNT, + DT_RELCOUNT, DT_FLAGS_1, DT_VERDEF, DT_VERDEFNUM, + DT_VERNEED, DT_VERNEEDNUM, DT_AUXILIARY, DT_FILTER + }; + const int ndtflags = sizeof (dtflags) / sizeof (dtflags[0]); + + /* We use no threads here which can interfere with handling a stream. */ + (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); + + /* Open the file. */ + int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE); + if (fd == -1) + { + printf ("cannot open `%s': %m\n", fname); + return 1; + } + + /* Tell the library which version are we expecting. */ + elf_version (EV_CURRENT); + + /* Create an ELF descriptor. */ + Elf *elf = elf_begin (fd, ELF_C_WRITE, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + return 1; + } + + /* Create an ELF header. */ + Elf32_Ehdr *ehdr = elf32_newehdr (elf); + if (ehdr == NULL) + { + printf ("cannot create ELF header: %s\n", elf_errmsg (-1)); + return 1; + } + + ehdr->e_ident[0] = 42; + ehdr->e_ident[5] = 1; + ehdr->e_ident[6] = 2; + ehdr->e_type = ET_EXEC; + ehdr->e_machine = EM_386; + ehdr->e_version = 1; + ehdr->e_ehsize = 1; + ehdr->e_shnum = 3; + + elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY); + + /* Create the program headers. */ + Elf32_Phdr *phdr = elf32_newphdr (elf, 2); + if (phdr == NULL) + { + printf ("cannot create program headers: %s\n", elf_errmsg (-1)); + return 1; + } + + phdr[0].p_type = PT_PHDR; + phdr[1].p_type = PT_DYNAMIC; + + elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY); + shst = dwelf_strtab_init (true); + + /* Create the .dynamic section. */ + Elf_Scn *scn = elf_newscn (elf); + if (scn == NULL) + { + printf ("cannot create DYNAMIC section: %s\n", elf_errmsg (-1)); + return 1; + } + + Elf32_Shdr *shdr = elf32_getshdr (scn); + if (shdr == NULL) + { + printf ("cannot get header for DYNAMIC section: %s\n", elf_errmsg (-1)); + return 1; + } + + dynscn = dwelf_strtab_add (shst, ".dynamic"); + + /* We'll need to know the section offset. But this will be set up + by elf_update later, so for now just store the address. */ + const Elf32_Off *const dynscn_offset = &shdr->sh_offset; + shdr->sh_type = SHT_DYNAMIC; + shdr->sh_flags = SHF_ALLOC | SHF_WRITE; + shdr->sh_link = SHN_UNDEF; + shdr->sh_info = SHN_UNDEF; + /* This section will start here. */ + shdr->sh_addr = 0x1a0; + + /* Create new section data. */ + Elf_Data *data = elf_newdata (scn); + if (data == NULL) + { + printf ("cannot create data for DYNAMIC section: %s\n", elf_errmsg (-1)); + return 1; + } + + /* Allocate memory for all the .dynamic entries. */ + Elf32_Dyn *dyn = malloc (ndtflags * sizeof (Elf32_Dyn)); + if (dyn == NULL) + { + printf ("malloc failed: %m\n"); + return 1; + } + + /* Now write all the DT_* flags. */ + for (int i = 0; i < ndtflags; ++i) + { + dyn[i].d_tag = dtflags[i]; + dyn[i].d_un.d_val = 0xdeadbeef; + } + + /* Set the pointer to allocated memory. */ + data->d_buf = dyn; + data->d_type = ELF_T_DYN; + data->d_version = EV_CURRENT; + data->d_size = ndtflags * sizeof (Elf32_Dyn); + data->d_align = 0x8; + + /* Create .shstrtab section. */ + scn = elf_newscn (elf); + if (scn == NULL) + { + printf ("cannot create SHSTRTAB section: %s\n", elf_errmsg (-1)); + return 1; + } + + shdr = elf32_getshdr (scn); + if (shdr == NULL) + { + printf ("cannot get header for SHSTRTAB section: %s\n", elf_errmsg (-1)); + return 1; + } + + shstrtabse = dwelf_strtab_add (shst, ".shstrtab"); + + shdr->sh_type = SHT_STRTAB; + shdr->sh_flags = 0; + shdr->sh_addr = 0; + shdr->sh_link = SHN_UNDEF; + shdr->sh_info = SHN_UNDEF; + shdr->sh_entsize = 1; + + /* We have to store the section index in the ELF header. */ + ehdr->e_shstrndx = elf_ndxscn (scn); + + data = elf_newdata (scn); + if (data == NULL) + { + printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1)); + return 1; + } + + /* No more sections, finalize the section header string table. */ + dwelf_strtab_finalize (shst, data); + + elf32_getshdr (elf_getscn (elf, 1))->sh_name = dwelf_strent_off (dynscn); + shdr->sh_name = dwelf_strent_off (shstrtabse); + + /* Let the library compute the internal structure information. */ + if (elf_update (elf, ELF_C_NULL) < 0) + { + printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1)); + return 1; + } + + ehdr = elf32_getehdr (elf); + + phdr[0].p_offset = ehdr->e_phoff; + phdr[0].p_vaddr = ehdr->e_phoff; + phdr[0].p_paddr = ehdr->e_phoff; + phdr[0].p_flags = PF_R | PF_X; + phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT); + phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT); + phdr[0].p_align = sizeof (Elf32_Word); + + phdr[1].p_flags = PF_W | PF_R; + phdr[1].p_offset = *dynscn_offset; + /* Set up the start of this segment to equal start address of the + .dynamic section. */ + phdr[1].p_vaddr = 0x1a0; + phdr[1].p_paddr = 0x1a0; + phdr[1].p_align = 2 * sizeof (Elf32_Word); + phdr[1].p_filesz = ndtflags * sizeof (Elf32_Dyn); + phdr[1].p_memsz = ndtflags * sizeof (Elf32_Dyn); + + /* Write out the file. */ + if (elf_update (elf, ELF_C_WRITE) < 0) + { + printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1)); + return 1; + } + + /* We don't need the string table anymore. */ + dwelf_strtab_free (shst); + + /* And the data allocated in the .shstrtab section. */ + free (data->d_buf); + + /* And the dynamic entries. */ + free (dyn); + + /* All done. */ + if (elf_end (elf) != 0) + { + printf ("failure in elf_end: %s\n", elf_errmsg (-1)); + return 1; + } + + return 0; +} diff --git a/tests/allfcts.c b/tests/allfcts.c new file mode 100644 index 00000000..f6373117 --- /dev/null +++ b/tests/allfcts.c @@ -0,0 +1,112 @@ +/* Copyright (C) 2005, 2013 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include ELFUTILS_HEADER(dw) +#include ELFUTILS_HEADER(dwelf) +#include +#include + + +static int +cb (Dwarf_Die *func, void *arg __attribute__ ((unused))) +{ + const char *file = dwarf_decl_file (func); + int line = -1; + dwarf_decl_line (func, &line); + const char *fct = dwarf_diename (func); + + printf ("%s:%d:%s\n", file, line, fct); + + return DWARF_CB_ABORT; +} + +static Dwarf * +setup_alt (Dwarf *main) +{ + const char *alt_name; + const void *build_id; + ssize_t ret = dwelf_dwarf_gnu_debugaltlink (main, &alt_name, &build_id); + if (ret == 0) + return NULL; + if (ret == -1) + errx (1, "dwelf_dwarf_gnu_debugaltlink: %s", dwarf_errmsg (-1)); + int fd = open (alt_name, O_RDONLY); + if (fd < 0) + { + printf ("Warning: no alt file found.\n"); + return NULL; + } + Dwarf *dbg_alt = dwarf_begin (fd, DWARF_C_READ); + if (dbg_alt == NULL) + errx (1, "dwarf_begin (%s): %s", alt_name, dwarf_errmsg (-1)); + if (elf_cntl (dwarf_getelf (dbg_alt), ELF_C_FDREAD) != 0) + errx (1, "elf_cntl (%s, ELF_C_FDREAD): %s", alt_name, elf_errmsg (-1)); + close (fd); + dwarf_setalt (main, dbg_alt); + return dbg_alt; +} + +int +main (int argc, char *argv[]) +{ + for (int i = 1; i < argc; ++i) + { + int fd = open (argv[i], O_RDONLY); + if (fd < 0) + err (1, "open (%s)", argv[i]); + + Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ); + if (dbg != NULL) + { + Dwarf_Off off = 0; + size_t cuhl; + Dwarf_Off noff; + Dwarf *dbg_alt = setup_alt (dbg); + + while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0) + { + Dwarf_Die die_mem; + Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem); + + /* Explicitly stop in the callback and then resume each time. */ + ptrdiff_t doff = 0; + do + { + doff = dwarf_getfuncs (die, cb, NULL, doff); + if (dwarf_errno () != 0) + errx (1, "dwarf_getfuncs (%s): %s", + argv[i], dwarf_errmsg (-1)); + } + while (doff != 0); + + off = noff; + } + + dwarf_end (dbg_alt); + dwarf_end (dbg); + } + else + errx (1, "dwarf_begin (%s): %s", argv[i], dwarf_errmsg (-1)); + + close (fd); + } +} diff --git a/tests/allregs.c b/tests/allregs.c new file mode 100644 index 00000000..f18f0b28 --- /dev/null +++ b/tests/allregs.c @@ -0,0 +1,204 @@ +/* Copyright (C) 2005, 2006, 2015 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) +#include + +#include "system.h" +#include "../libdw/known-dwarf.h" + +static const char * +dwarf_encoding_string (unsigned int code) +{ + static const char *const known[] = + { +#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, + DWARF_ALL_KNOWN_DW_ATE +#undef DWARF_ONE_KNOWN_DW_ATE + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +static int +first_module (Dwfl_Module *mod, + void **userdatap __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr low_addr __attribute__ ((unused)), + void *arg) +{ + Dwarf_Addr bias; + if (dwfl_module_getelf (mod, &bias) == NULL) /* Not really a module. */ + return DWARF_CB_OK; + + *(Dwfl_Module **) arg = mod; + return DWARF_CB_ABORT; +} + + +struct state +{ + struct reginfo *info; + int nregs; +}; + +struct reginfo +{ + const char *set, *pfx; + int regno; + int bits; + int type; + char name[32]; +}; + +static int +compare (const void *r1, const void *r2) +{ + const struct reginfo *a = r1, *b = r2; + if (a->set == b->set) + return a->regno - b->regno; + if (a->set == NULL) + return 1; + if (b->set == NULL) + return -1; + if (!strcmp (a->set, "integer")) + return -1; + if (!strcmp (b->set, "integer")) + return 1; + return strcmp (a->set, b->set); +} + +static int +one_register (void *arg, + int regno, + const char *setname, + const char *prefix, + const char *regname, + int bits, int type) +{ + struct state *state = arg; + + if (regno >= state->nregs) + { + state->info = realloc (state->info, (regno + 1) * sizeof state->info[0]); + memset (&state->info[state->nregs], 0, + ((void *) &state->info[regno + 1] + - (void *) &state->info[state->nregs])); + state->nregs = regno + 1; + } + + state->info[regno].regno = regno; + state->info[regno].set = setname; + state->info[regno].pfx = prefix; + state->info[regno].bits = bits; + state->info[regno].type = type; + assert (strlen (regname) < sizeof state->info[regno].name); + strcpy (state->info[regno].name, regname); + + return DWARF_CB_OK; +} + + +static int +match_register (void *arg, + int regno, + const char *setname, + const char *prefix, + const char *regname, + int bits, int type) +{ + if (regno == *(int *) arg) + printf ("%5d => %s register %s%s %s %d bits\n", + regno, setname, prefix, regname, + dwarf_encoding_string (type), bits); + + return DWARF_CB_ABORT; +} + + +int +main (int argc, char **argv) +{ + int remaining; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + Dwfl *dwfl = NULL; + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl); + assert (dwfl != NULL); + + Dwfl_Module *mod = NULL; + if (dwfl_getmodules (dwfl, &first_module, &mod, 0) < 0) + error (EXIT_FAILURE, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1)); + + if (remaining == argc) + { + struct state state = { NULL, 0 }; + int result = dwfl_module_register_names (mod, &one_register, &state); + if (result != 0 || state.nregs == 0) + error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s", + result ? dwfl_errmsg (-1) : "no backend registers known"); + + qsort (state.info, state.nregs, sizeof state.info[0], &compare); + + const char *set = NULL; + for (int i = 0; i < state.nregs; ++i) + if (state.info[i].set != NULL) + { + if (set != state.info[i].set) + printf ("%s registers:\n", state.info[i].set); + set = state.info[i].set; + + printf ("\t%3d: %s%s (%s), %s %d bits\n", + state.info[i].regno, + state.info[i].pfx ?: "", state.info[i].name, + state.info[i].name, + dwarf_encoding_string (state.info[i].type), + state.info[i].bits); + } + free (state.info); + } + else + do + { + const char *arg = argv[remaining++]; + int regno = atoi (arg); + int result = dwfl_module_register_names (mod, &match_register, ®no); + if (result != DWARF_CB_ABORT) + error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s", + result ? dwfl_errmsg (-1) : "no backend registers known"); + } + while (remaining < argc); + + dwfl_end (dwfl); + + return 0; +} diff --git a/tests/arextract.c b/tests/arextract.c new file mode 100644 index 00000000..936d7f55 --- /dev/null +++ b/tests/arextract.c @@ -0,0 +1,159 @@ +/* Copyright (C) 1999, 2000, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + +int +main (int argc, char *argv[]) +{ + int fd; + Elf *elf; + Elf *subelf; + Elf_Cmd cmd; + off_t offset; + size_t todo; + + if (argc < 4) + exit (1); + + /* Open the archive. */ + fd = open (argv[1], O_RDONLY); + if (fd == -1) + { + printf ("Cannot open input file: %m"); + exit (1); + } + + /* Set the ELF version. */ + elf_version (EV_CURRENT); + + /* Create an ELF descriptor. */ + cmd = ELF_C_READ; + elf = elf_begin (fd, cmd, NULL); + if (elf == NULL) + { + printf ("Cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + exit (1); + } + + /* If it is no archive punt. */ + if (elf_kind (elf) != ELF_K_AR) + { + printf ("`%s' is no archive\n", argv[1]); + exit (1); + } + + /* Get the elements of the archive one after the other. */ + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + + if (arhdr == NULL) + { + printf ("cannot get arhdr: %s\n", elf_errmsg (-1)); + exit (1); + } + + if (strcmp (arhdr->ar_name, argv[2]) == 0) + { + int outfd; + + /* Get the offset of the file in the archive. */ + offset = elf_getbase (subelf); + if (offset == -1) + { + printf ("\ +Failed to get base address for the archive element: %s\n", + elf_errmsg (-1)); + exit (1); + } + + /* Open the output file. */ + outfd = open (argv[3], O_CREAT | O_TRUNC | O_RDWR, DEFFILEMODE); + if (outfd == -1) + { + printf ("cannot open output file: %m"); + exit (1); + } + + /* Now write out the data. */ + todo = arhdr->ar_size; + while (todo > 0) + { + char buf[1024]; + ssize_t n = pread (fd, buf, MIN (sizeof buf, todo), offset); + if (n == 0) + break; + + if (write (outfd, buf, n) != n) + { + puts ("Writing output failed"); + exit (1); + } + + offset += n; + todo -= n; + } + + /* Check whether all the date was read and written out. */ + if (todo != 0) + { + puts ("Reading archive member failed."); + exit (1); + } + + /* Close the descriptors. */ + if (elf_end (subelf) != 0 || elf_end (elf) != 0) + { + printf ("Freeing ELF descriptors failed: %s", elf_errmsg (-1)); + exit (1); + } + + close (outfd); + close (fd); + + /* All went well. */ + exit (0); + } + + /* Get next archive element. */ + cmd = elf_next (subelf); + if (elf_end (subelf) != 0) + { + printf ("error while freeing sub-ELF descriptor: %s\n", + elf_errmsg (-1)); + exit (1); + } + } + + /* When we reach this point we haven't found the given file in the + archive. */ + printf ("File `%s' not found in archive\n", argv[2]); + exit (1); +} diff --git a/tests/arls.c b/tests/arls.c new file mode 100644 index 00000000..ca0d3e6e --- /dev/null +++ b/tests/arls.c @@ -0,0 +1,111 @@ +/* Copyright (C) 2007 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + + +static int handle (const char *fname); + + +int +main (int argc, char *argv[]) +{ + elf_version (EV_CURRENT); + + int result = 0; + if (argc == 1) + result = handle ("a.out"); + else + for (int i = 1; i < argc; ++i) + result |= handle (argv[1]); + + return result; +} + + +static int +handle (const char *fname) +{ + int fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open '%s': %m\n", fname); + return 1; + } + + Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); + if (elf == NULL) + { + printf ("cannot get ELF handling for '%s': %s\n", + fname, elf_errmsg (-1)); + close (fd); + return 1; + } + + if (elf_kind (elf) != ELF_K_AR) + { + printf ("'%s' is no archive\n", fname); + elf_end (elf); + close (fd); + return 1; + } + + printf ("%s:\n", fname); + Elf *subelf = NULL; + Elf_Cmd cmd = ELF_C_READ_MMAP; + while ((subelf = elf_begin (fd, cmd, elf)) != NULL) + { + Elf_Arhdr *arhdr = elf_getarhdr (subelf); + if (arhdr == NULL) + { + printf ("cannot get archive header in '%s': %s\n", + fname, elf_errmsg (-1)); + elf_end (subelf); + elf_end (elf); + close (fd); + return 1; + } + + off_t off = elf_getaroff (subelf); + + printf ("\nOffset %llu\n" + " Name %s\n" + " Date %ld\n" + " UID %d\n" + " GID %d\n" + " Mode %o\n" + " Size %lld\n", + (unsigned long long int) off, + arhdr->ar_name, (long int) arhdr->ar_date, (int) arhdr->ar_uid, + (int) arhdr->ar_gid, + (int) arhdr->ar_mode, (long long int) arhdr->ar_size); + + cmd = elf_next (subelf); + elf_end (subelf); + } + + close (fd); + + return 0; +} diff --git a/tests/arsymtest.c b/tests/arsymtest.c new file mode 100644 index 00000000..c724863f --- /dev/null +++ b/tests/arsymtest.c @@ -0,0 +1,136 @@ +/* Copyright (C) 1999, 2000, 2002 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 1999. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include + +#include +#include +#include +#include +#include + + +int +main (int argc, char *argv[]) +{ + int fd; + FILE *fp; + Elf *elf; + Elf_Arsym *arsym; + size_t narsym; + + if (argc < 3) + exit (1); + + /* Open the archive. */ + fd = open (argv[1], O_RDONLY); + if (fd == -1) + { + printf ("Cannot open input file: %m"); + exit (1); + } + + /* Open the output file. */ + fp = fopen (argv[2], "w"); + if (fp == NULL) + { + printf ("Cannot open output file: %m"); + exit (1); + } + + /* Set the ELF version. */ + elf_version (EV_CURRENT); + + /* Create an ELF descriptor. */ + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("Cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + exit (1); + } + + /* If it is no archive punt. */ + if (elf_kind (elf) != ELF_K_AR) + { + printf ("`%s' is no archive\n", argv[1]); + exit (1); + } + + /* Now get the index of the archive. */ + arsym = elf_getarsym (elf, &narsym); + if (arsym == NULL) + { + printf ("Cannot get archive index: %s\n", elf_errmsg (-1)); + exit (1); + } + + /* If there is no element in the index do nothing. There always is + an empty entry at the end which is included in the count and + which we want to skip. */ + if (narsym-- > 1) + while (narsym-- > 0) + { + Elf *subelf; + Elf_Arhdr *arhdr; + + if (elf_rand (elf, arsym[narsym].as_off) != arsym[narsym].as_off) + { + printf ("random access for symbol `%s' fails: %s\n", + arsym[narsym].as_name, elf_errmsg (-1)); + exit (1); + } + + subelf = elf_begin (fd, ELF_C_READ, elf); + if (subelf == NULL) + { + printf ("Cannot create ELF descriptor for archive member: %s\n", + elf_errmsg (-1)); + exit (1); + } + + arhdr = elf_getarhdr (subelf); + if (arhdr == NULL) + { + printf ("Cannot get archive header for element `%s': %s\n", + arsym[narsym].as_name, elf_errmsg (-1)); + exit (1); + } + + /* Now print what we actually want. */ + fprintf (fp, "%s in %s\n", arsym[narsym].as_name, arhdr->ar_name); + + /* Free the ELF descriptor. */ + if (elf_end (subelf) != 0) + { + printf ("Error while freeing subELF descriptor: %s\n", + elf_errmsg (-1)); + exit (1); + } + } + + /* Free the ELF descriptor. */ + if (elf_end (elf) != 0) + { + printf ("Error while freeing ELF descriptor: %s\n", elf_errmsg (-1)); + exit (1); + } + + close (fd); + fclose (fp); + + return 0; +} diff --git a/tests/asm-tst1.c b/tests/asm-tst1.c new file mode 100644 index 00000000..d03a4361 --- /dev/null +++ b/tests/asm-tst1.c @@ -0,0 +1,257 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include + + +static const char fname[] = "asm-tst1-out.o"; + + +static const GElf_Ehdr expected_ehdr = + { + .e_ident = { [EI_MAG0] = ELFMAG0, + [EI_MAG1] = ELFMAG1, + [EI_MAG2] = ELFMAG2, + [EI_MAG3] = ELFMAG3, + [EI_CLASS] = ELFCLASS32, + [EI_DATA] = ELFDATA2LSB, + [EI_VERSION] = EV_CURRENT }, + .e_type = ET_REL, + .e_machine = EM_386, + .e_version = EV_CURRENT, + .e_shoff = 88, + .e_ehsize = sizeof (Elf32_Ehdr), + .e_shentsize = sizeof (Elf32_Shdr), + .e_shnum = 4, + .e_shstrndx = 3 + }; + + +static const char *scnnames[4] = + { + [0] = "", + [1] = ".text", + [2] = ".data", + [3] = ".shstrtab" + }; + + +int +main (void) +{ + AsmCtx_t *ctx; + AsmScn_t *scn1; + AsmScn_t *scn2; + int fd; + Elf *elf; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + int result = 0; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + /* Create two sections. */ + scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); + scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + if (scn1 == NULL || scn2 == NULL) + { + printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Special alignment for the .text section. */ + if (asm_align (scn1, 32) != 0) + { + printf ("cannot align .text section: %s\n", asm_errmsg (-1)); + result = 1; + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Check the file. */ + fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open generated file: %m\n"); + result = 1; + goto out; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close; + } + if (elf_kind (elf) != ELF_K_ELF) + { + puts ("not a valid ELF file"); + result = 1; + goto out_close2; + } + + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close2; + } + + if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) + { + puts ("ELF header does not match"); + result = 1; + goto out_close2; + } + + for (cnt = 1; cnt < 4; ++cnt) + { + Elf_Scn *scn; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + scn = elf_getscn (elf, cnt); + if (scn == NULL) + { + printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get section header for section %zd: %s\n", + cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]) != 0) + { + printf ("section %zd's name differs: %s vs %s\n", cnt, + elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]); + result = 1; + } + + if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS)) + { + printf ("section %zd's type differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR)) + || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) + || (cnt == 3 && shdr->sh_flags != 0)) + { + printf ("section %zd's flags differs\n", cnt); + result = 1; + } + + if (shdr->sh_addr != 0) + { + printf ("section %zd's address differs\n", cnt); + result = 1; + } + + if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31)) + { + printf ("section %zd's offset differs\n", cnt); + result = 1; + } + + if ((cnt != 3 && shdr->sh_size != 0) + || (cnt == 3 && shdr->sh_size != 23)) + { + printf ("section %zd's size differs\n", cnt); + result = 1; + } + + if (shdr->sh_link != 0) + { + printf ("section %zd's link differs\n", cnt); + result = 1; + } + + if (shdr->sh_info != 0) + { + printf ("section %zd's info differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_addralign != 32) + || (cnt != 1 && shdr->sh_addralign != 1)) + { + printf ("section %zd's addralign differs\n", cnt); + result = 1; + } + + if (shdr->sh_entsize != 0) + { + printf ("section %zd's entsize differs\n", cnt); + result = 1; + } + } + + out_close2: + elf_end (elf); + out_close: + close (fd); + out: + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst2.c b/tests/asm-tst2.c new file mode 100644 index 00000000..e65a9d2f --- /dev/null +++ b/tests/asm-tst2.c @@ -0,0 +1,279 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include + + +static const char fname[] = "asm-tst2-out.o"; + + +static const GElf_Ehdr expected_ehdr = + { + .e_ident = { [EI_MAG0] = ELFMAG0, + [EI_MAG1] = ELFMAG1, + [EI_MAG2] = ELFMAG2, + [EI_MAG3] = ELFMAG3, + [EI_CLASS] = ELFCLASS32, + [EI_DATA] = ELFDATA2LSB, + [EI_VERSION] = EV_CURRENT }, + .e_type = ET_REL, + .e_machine = EM_386, + .e_version = EV_CURRENT, + .e_shoff = 96, + .e_ehsize = sizeof (Elf32_Ehdr), + .e_shentsize = sizeof (Elf32_Shdr), + .e_shnum = 3, + .e_shstrndx = 2 + }; + + +static const char *scnnames[3] = + { + [0] = "", + [1] = ".data", + [2] = ".shstrtab" + }; + + +int +main (void) +{ + AsmCtx_t *ctx; + AsmScn_t *scn1; + AsmScn_t *scn2; + int result = 0; + int fd; + Elf *elf; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + /* Create two sections. */ + scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + scn2 = asm_newsubscn (scn1, 1); + if (scn1 == NULL || scn2 == NULL) + { + printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Special alignment for the .text section. */ + if (asm_align (scn1, 16) != 0) + { + printf ("cannot align .text section: %s\n", asm_errmsg (-1)); + result = 1; + } + + /* Add a few strings. */ + if (asm_addstrz (scn1, "one", 4) != 0) + { + printf ("cannot insert first string: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_addstrz (scn2, "three", 0) != 0) + { + printf ("cannot insert second string: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_addstrz (scn1, "two", 4) != 0) + { + printf ("cannot insert third string: %s\n", asm_errmsg (-1)); + result = 1; + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Check the file. */ + fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open generated file: %m\n"); + result = 1; + goto out; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close; + } + if (elf_kind (elf) != ELF_K_ELF) + { + puts ("not a valid ELF file"); + result = 1; + goto out_close2; + } + + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close2; + } + + if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) + { + puts ("ELF header does not match"); + result = 1; + goto out_close2; + } + + for (cnt = 1; cnt < 3; ++cnt) + { + Elf_Scn *scn; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + scn = elf_getscn (elf, cnt); + if (scn == NULL) + { + printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get section header for section %zd: %s\n", + cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]) != 0) + { + printf ("section %zd's name differs: %s vs %s\n", cnt, + elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]); + result = 1; + } + + if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS)) + { + printf ("section %zd's type differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) + || (cnt == 2 && shdr->sh_flags != 0)) + { + printf ("section %zd's flags differs\n", cnt); + result = 1; + } + + if (shdr->sh_addr != 0) + { + printf ("section %zd's address differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15)) + || (cnt == 2 + && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15) + + strlen ("one") + 1 + + strlen ("two") + 1 + + strlen ("three") + 1))) + { + printf ("section %zd's offset differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_size != (strlen ("one") + 1 + + strlen ("two") + 1 + + strlen ("three") + 1)) + || (cnt == 2 && shdr->sh_size != 17)) + { + printf ("section %zd's size differs\n", cnt); + result = 1; + } + + if (shdr->sh_link != 0) + { + printf ("section %zd's link differs\n", cnt); + result = 1; + } + + if (shdr->sh_info != 0) + { + printf ("section %zd's info differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_addralign != 16) + || (cnt != 1 && shdr->sh_addralign != 1)) + { + printf ("section %zd's addralign differs\n", cnt); + result = 1; + } + + if (shdr->sh_entsize != 0) + { + printf ("section %zd's entsize differs\n", cnt); + result = 1; + } + } + + out_close2: + elf_end (elf); + out_close: + close (fd); + out: + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst3.c b/tests/asm-tst3.c new file mode 100644 index 00000000..e45fa16a --- /dev/null +++ b/tests/asm-tst3.c @@ -0,0 +1,340 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include + + +static const char fname[] = "asm-tst3-out.o"; + + +static const char *scnnames[5] = + { + [0] = "", + [1] = ".data", + [2] = ".strtab", + [3] = ".symtab", + [4] = ".shstrtab" + }; + + +static unsigned int scntypes[5] = + { + [0] = SHT_NULL, + [1] = SHT_PROGBITS, + [2] = SHT_STRTAB, + [3] = SHT_SYMTAB, + [4] = SHT_STRTAB + }; + + +int +main (void) +{ + AsmCtx_t *ctx; + AsmScn_t *scn1; + AsmScn_t *scn2; + int result = 0; + int fd; + Elf *elf; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + /* Create two sections. */ + scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + scn2 = asm_newsubscn (scn1, 1); + if (scn1 == NULL || scn2 == NULL) + { + printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Special alignment for the .text section. */ + if (asm_align (scn1, 16) != 0) + { + printf ("cannot align .text section: %s\n", asm_errmsg (-1)); + result = 1; + } + + /* Add a few strings with names. */ + if (asm_newsym (scn1, "one", 4, STT_OBJECT, STB_GLOBAL) == NULL) + { + printf ("cannot create first name: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_addstrz (scn1, "one", 4) != 0) + { + printf ("cannot insert first string: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_newsym (scn2, "three", 6, STT_OBJECT, STB_WEAK) == NULL) + { + printf ("cannot create second name: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_addstrz (scn2, "three", 0) != 0) + { + printf ("cannot insert second string: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_newsym (scn1, "two", 4, STT_OBJECT, STB_LOCAL) == NULL) + { + printf ("cannot create third name: %s\n", asm_errmsg (-1)); + result = 1; + } + if (asm_addstrz (scn1, "two", 4) != 0) + { + printf ("cannot insert third string: %s\n", asm_errmsg (-1)); + result = 1; + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Check the file. */ + fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open generated file: %m\n"); + result = 1; + goto out; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close; + } + if (elf_kind (elf) != ELF_K_ELF) + { + puts ("not a valid ELF file"); + result = 1; + goto out_close2; + } + + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close2; + } + + for (cnt = 1; cnt < 5; ++cnt) + { + Elf_Scn *scn; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + scn = elf_getscn (elf, cnt); + if (scn == NULL) + { + printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get section header for section %zd: %s\n", + cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]) != 0) + { + printf ("section %zd's name differs: %s vs %s\n", cnt, + elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]); + result = 1; + } + + if (shdr->sh_type != scntypes[cnt]) + { + printf ("section %zd's type differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) + || (cnt != 1 && shdr->sh_flags != 0)) + { + printf ("section %zd's flags differs\n", cnt); + result = 1; + } + + if (shdr->sh_addr != 0) + { + printf ("section %zd's address differs\n", cnt); + result = 1; + } + + if (cnt == 3) + { + Elf_Data *data; + + if (shdr->sh_link != 2) + { + puts ("symbol table has incorrect link"); + result = 1; + } + + data = elf_getdata (scn, NULL); + if (data == NULL) + { + puts ("cannot get data of symbol table"); + result = 1; + } + else + { + size_t inner; + + for (inner = 1; + inner < (shdr->sh_size + / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT)); + ++inner) + { + GElf_Sym sym_mem; + GElf_Sym *sym; + + sym = gelf_getsym (data, inner, &sym_mem); + if (sym == NULL) + { + printf ("cannot get symbol %zu: %s\n", + inner, elf_errmsg (-1)); + result = 1; + } + else + { + /* The order of the third and fourth entry depends + on how the hash table is organized. */ + static const char *names[4] = + { + [0] = "", + [1] = "two", + [2] = "one", + [3] = "three" + }; + static const int info[4] = + { + [0] = GELF_ST_INFO (STB_LOCAL, STT_NOTYPE), + [1] = GELF_ST_INFO (STB_LOCAL, STT_OBJECT), + [2] = GELF_ST_INFO (STB_GLOBAL, STT_OBJECT), + [3] = GELF_ST_INFO (STB_WEAK, STT_OBJECT) + }; + static const unsigned value[4] = + { + [0] = 0, + [1] = 4, + [2] = 0, + [3] = 8 + }; + + if (strcmp (names[inner], + elf_strptr (elf, shdr->sh_link, + sym->st_name)) != 0) + { + printf ("symbol %zu has different name\n", inner); + result = 1; + } + + if (sym->st_value != value[inner]) + { + printf ("symbol %zu has wrong value\n", inner); + result = 1; + } + + if (sym->st_other != 0) + { + printf ("symbol %zu has wrong other info\n", inner); + result = 1; + } + + if (sym->st_shndx != 1) + { + printf ("symbol %zu has wrong section reference\n", + inner); + result = 1; + } + + if (sym->st_info != info[inner]) + { + printf ("symbol %zu has wrong type or binding\n", + inner); + result = 1; + } + + if ((inner != 3 && sym->st_size != 4) + || (inner == 3 && sym->st_size != 6)) + { + printf ("symbol %zu has wrong size\n", inner); + result = 1; + } + } + } + } + } + } + + out_close2: + elf_end (elf); + out_close: + close (fd); + out: + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst4.c b/tests/asm-tst4.c new file mode 100644 index 00000000..1a05bfcc --- /dev/null +++ b/tests/asm-tst4.c @@ -0,0 +1,105 @@ +/* Copyright (C) 2002-2012 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include +#include +#include + + +static const char fname[] = "asm-tst4-out.o"; + + +int +main (void) +{ + AsmCtx_t *ctx; + int result = 0; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + /* Create 66000 sections. */ + for (cnt = 0; cnt < 66000; ++cnt) + { + char buf[20]; + AsmScn_t *scn; + + /* Create a unique name. */ + snprintf (buf, sizeof (buf), ".data.%zu", cnt); + + /* Create the section. */ + scn = asm_newscn (ctx, buf, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + if (scn == NULL) + { + printf ("cannot create section \"%s\" in output file: %s\n", + buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Add some content. */ + if (asm_adduint32 (scn, cnt) != 0) + { + printf ("cannot create content of section \"%s\": %s\n", + buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + if (result == 0) + result = WEXITSTATUS (system ("../src/elflint -q asm-tst4-out.o")); + + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst5.c b/tests/asm-tst5.c new file mode 100644 index 00000000..256873f0 --- /dev/null +++ b/tests/asm-tst5.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2002-2012 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include +#include +#include + +#include "system.h" + + +static const char fname[] = "asm-tst5-out.o"; + + +int +main (void) +{ + AsmCtx_t *ctx; + int result = 0; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + /* Create 66000 sections. */ + for (cnt = 0; cnt < 66000; ++cnt) + { + char buf[20]; + AsmScn_t *scn; + + /* Create a unique name. */ + snprintf (buf, sizeof (buf), ".data.%zu", cnt); + + /* Create the section. */ + scn = asm_newscn (ctx, buf, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + if (scn == NULL) + { + printf ("cannot create section \"%s\" in output file: %s\n", + buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Add a name. */ + snprintf (buf, sizeof (buf), "%zu", cnt); + if (asm_newsym (scn, buf, sizeof (uint32_t), STT_OBJECT, + STB_GLOBAL) == NULL) + { + printf ("cannot create symbol \"%s\": %s\n", buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Add some content. */ + if (asm_adduint32 (scn, cnt) != 0) + { + printf ("cannot create content of section \"%s\": %s\n", + buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + if (result == 0) + result = WEXITSTATUS (system ("../src/elflint -q asm-tst5-out.o")); + + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst6.c b/tests/asm-tst6.c new file mode 100644 index 00000000..4a665ed0 --- /dev/null +++ b/tests/asm-tst6.c @@ -0,0 +1,151 @@ +/* Copyright (C) 2002-2012 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include +#include + +#include + + +static const char fname[] = "asm-tst6-out.o"; + + +int +main (void) +{ + AsmCtx_t *ctx; + int result = 0; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + for (cnt = 0; cnt < 22000; ++cnt) + { + char buf[512]; + AsmScnGrp_t *grp; + AsmScn_t *scn; + AsmSym_t *sym; + + snprintf (buf, sizeof (buf), ".grp%zu", cnt); + grp = asm_newscngrp (ctx, buf, NULL, 0); + if (grp == NULL) + { + printf ("cannot section group %zu: %s\n", cnt, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + scn = asm_newscn_ingrp (ctx, ".data", SHT_PROGBITS, + SHF_ALLOC | SHF_WRITE, grp); + if (scn == NULL) + { + printf ("cannot data section for group %zu: %s\n", + cnt, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Add a name. */ + snprintf (buf, sizeof (buf), "%zu", cnt); + sym = asm_newsym (scn, buf, sizeof (uint32_t), STT_OBJECT, + STB_GLOBAL); + if (sym == NULL) + { + printf ("cannot create symbol \"%s\": %s\n", buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Add some content. */ + if (asm_adduint32 (scn, cnt) != 0) + { + printf ("cannot create content of section \"%s\": %s\n", + buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Now we have a symbol, use it as the signature. */ + if (asm_scngrp_newsignature (grp, sym) != 0) + { + printf ("cannot set signature for section group %zu: %s\n", + cnt, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Create a phony debug info section. */ + scn = asm_newscn_ingrp (ctx, ".stab", SHT_PROGBITS, 0, grp); + if (scn == NULL) + { + printf ("cannot stab section for group %zu: %s\n", + cnt, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Add some content. */ + if (asm_adduint32 (scn, cnt) != 0) + { + printf ("cannot create content of section \"%s\": %s\n", + buf, asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + if (result == 0) + result = WEXITSTATUS (system ("../src/elflint -q asm-tst6-out.o")); + + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst7.c b/tests/asm-tst7.c new file mode 100644 index 00000000..87c21485 --- /dev/null +++ b/tests/asm-tst7.c @@ -0,0 +1,182 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include + + +static const char fname[] = "asm-tst7-out.o"; + + +int +main (void) +{ + int result = 0; + size_t cnt; + AsmCtx_t *ctx; + Elf *elf; + int fd; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + if (asm_newcomsym (ctx, "commsym", 4, 16) == NULL) + { + printf ("cannot create common symbol: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Check the file. */ + fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open generated file: %m\n"); + result = 1; + goto out; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close; + } + if (elf_kind (elf) != ELF_K_ELF) + { + puts ("not a valid ELF file"); + result = 1; + goto out_close2; + } + + for (cnt = 1; 1; ++cnt) + { + Elf_Scn *scn; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + scn = elf_getscn (elf, cnt); + if (scn == NULL) + { + printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get section header for section %zd: %s\n", + cnt, elf_errmsg (-1)); + result = 1; + continue; + } + /* We are looking for the symbol table. */ + if (shdr->sh_type != SHT_SYMTAB) + continue; + + for (cnt = 1; cnt< (shdr->sh_size + / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT)); + ++cnt) + { + GElf_Sym sym_mem; + GElf_Sym *sym; + + if (cnt > 1) + { + puts ("too many symbol"); + result = 1; + break; + } + + sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem); + if (sym == NULL) + { + printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1)); + result = 1; + } + else + { + if (sym->st_shndx != SHN_COMMON) + { + printf ("expected common symbol, got section %u\n", + (unsigned int) sym->st_shndx); + result = 1; + } + + if (sym->st_value != 16) + { + printf ("requested alignment 16, is %" PRIuMAX "\n", + (uintmax_t) sym->st_value); + result = 1; + } + + if (sym->st_size != 4) + { + printf ("requested size 4, is %" PRIuMAX "\n", + (uintmax_t) sym->st_value); + result = 1; + } + } + } + + break; + } + + out_close2: + elf_end (elf); + out_close: + close (fd); + out: + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst8.c b/tests/asm-tst8.c new file mode 100644 index 00000000..7dbac10f --- /dev/null +++ b/tests/asm-tst8.c @@ -0,0 +1,190 @@ +/* Copyright (C) 2002, 2005 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include + + +static const char fname[] = "asm-tst8-out.o"; + + +int +main (void) +{ + int result = 0; + size_t cnt; + AsmCtx_t *ctx; + Elf *elf; + int fd; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + if (asm_newabssym (ctx, "tst8-out.s", 4, 0xfeedbeef, STT_FILE, STB_LOCAL) + == NULL) + { + printf ("cannot create absolute symbol: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Check the file. */ + fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open generated file: %m\n"); + result = 1; + goto out; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close; + } + if (elf_kind (elf) != ELF_K_ELF) + { + puts ("not a valid ELF file"); + result = 1; + goto out_close2; + } + + for (cnt = 1; 1; ++cnt) + { + Elf_Scn *scn; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + scn = elf_getscn (elf, cnt); + if (scn == NULL) + { + printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get section header for section %zd: %s\n", + cnt, elf_errmsg (-1)); + result = 1; + continue; + } + /* We are looking for the symbol table. */ + if (shdr->sh_type != SHT_SYMTAB) + continue; + + for (cnt = 1; cnt< (shdr->sh_size + / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT)); + ++cnt) + { + GElf_Sym sym_mem; + GElf_Sym *sym; + + if (cnt > 1) + { + puts ("too many symbol"); + result = 1; + break; + } + + sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem); + if (sym == NULL) + { + printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1)); + result = 1; + } + else + { + if (sym->st_shndx != SHN_ABS) + { + printf ("expected common symbol, got section %u\n", + (unsigned int) sym->st_shndx); + result = 1; + } + + if (sym->st_value != 0xfeedbeef) + { + printf ("requested value 0xfeedbeef, is %#" PRIxMAX "\n", + (uintmax_t) sym->st_value); + result = 1; + } + + if (sym->st_size != 4) + { + printf ("requested size 4, is %" PRIuMAX "\n", + (uintmax_t) sym->st_value); + result = 1; + } + + if (GELF_ST_TYPE (sym->st_info) != STT_FILE) + { + printf ("requested type FILE, is %u\n", + (unsigned int) GELF_ST_TYPE (sym->st_info)); + result = 1; + } + } + } + + break; + } + + out_close2: + elf_end (elf); + out_close: + close (fd); + out: + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/asm-tst9.c b/tests/asm-tst9.c new file mode 100644 index 00000000..6bec3f6e --- /dev/null +++ b/tests/asm-tst9.c @@ -0,0 +1,336 @@ +/* Copyright (C) 2002-2010 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2002. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include ELFUTILS_HEADER(asm) +#include ELFUTILS_HEADER(ebl) +#include +#include +#include +#include + + +static const char fname[] = "asm-tst9-out.o"; + + +static int32_t input[] = + { + 0, 1, 129, 510, 2000, 33000, 0x7ffffff, 0x7fffffff + }; +#define ninput (sizeof (input) / sizeof (input[0])) + + +static const GElf_Ehdr expected_ehdr = + { + .e_ident = { [EI_MAG0] = ELFMAG0, + [EI_MAG1] = ELFMAG1, + [EI_MAG2] = ELFMAG2, + [EI_MAG3] = ELFMAG3, + [EI_CLASS] = ELFCLASS32, + [EI_DATA] = ELFDATA2LSB, + [EI_VERSION] = EV_CURRENT }, + .e_type = ET_REL, + .e_machine = EM_386, + .e_version = EV_CURRENT, + .e_shoff = 180, + .e_ehsize = sizeof (Elf32_Ehdr), + .e_shentsize = sizeof (Elf32_Shdr), + .e_shnum = 3, + .e_shstrndx = 2 + }; + + +static const char *scnnames[3] = + { + [0] = "", + [1] = ".data", + [2] = ".shstrtab" + }; + + +static const char expecteddata[] = + { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7f, + 0x81, 0x01, 0x81, 0x01, 0xff, 0xfe, 0xff, 0xff, 0x0f, 0xff, 0x7e, 0xfe, + 0x03, 0xfe, 0x03, 0x82, 0xfc, 0xff, 0xff, 0x0f, 0x82, 0x7c, 0xd0, 0x0f, + 0xd0, 0x0f, 0xb0, 0xf0, 0xff, 0xff, 0x0f, 0xb0, 0x70, 0xe8, 0x81, 0x02, + 0xe8, 0x81, 0x02, 0x98, 0xfe, 0xfd, 0xff, 0x0f, 0x98, 0xfe, 0x7d, 0xff, + 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x81, 0x80, 0x80, 0xc0, 0x0f, + 0x81, 0x80, 0x80, 0x40, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, + 0xff, 0x07, 0x81, 0x80, 0x80, 0x80, 0x08, 0x81, 0x80, 0x80, 0x80, 0x78 + }; + + +int +main (void) +{ + AsmCtx_t *ctx; + AsmScn_t *scn; + int result = 0; + int fd; + Elf *elf; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr; + size_t cnt; + + elf_version (EV_CURRENT); + + Ebl *ebl = ebl_openbackend_machine (EM_386); + if (ebl == NULL) + { + puts ("cannot open backend library"); + return 1; + } + + ctx = asm_begin (fname, ebl, false); + if (ctx == NULL) + { + printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); + return 1; + } + + /* Create two sections. */ + scn = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + if (scn == NULL) + { + printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Special alignment for the .text section. */ + if (asm_align (scn, 16) != 0) + { + printf ("cannot align .text section: %s\n", asm_errmsg (-1)); + result = 1; + } + + /* Add a few ULEB128 and SLEB128 numbers. */ + for (cnt = 0; cnt < ninput; ++cnt) + { + if (asm_adduleb128 (scn, input[cnt]) != 0) + { + printf ("cannot insert uleb %" PRIu32 ": %s\n", + (uint32_t) input[cnt], asm_errmsg (-1)); + result = 1; + } + + if (asm_addsleb128 (scn, input[cnt]) != 0) + { + printf ("cannot insert sleb %" PRId32 ": %s\n", + input[cnt], asm_errmsg (-1)); + result = 1; + } + + if (asm_adduleb128 (scn, -input[cnt]) != 0) + { + printf ("cannot insert uleb %" PRIu32 ": %s\n", + (uint32_t) -input[cnt], asm_errmsg (-1)); + result = 1; + } + + if (asm_addsleb128 (scn, -input[cnt]) != 0) + { + printf ("cannot insert sleb %" PRId32 ": %s\n", + -input[cnt], asm_errmsg (-1)); + result = 1; + } + } + + /* Create the output file. */ + if (asm_end (ctx) != 0) + { + printf ("cannot create output file: %s\n", asm_errmsg (-1)); + asm_abort (ctx); + return 1; + } + + /* Check the file. */ + fd = open (fname, O_RDONLY); + if (fd == -1) + { + printf ("cannot open generated file: %m\n"); + result = 1; + goto out; + } + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + { + printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close; + } + if (elf_kind (elf) != ELF_K_ELF) + { + puts ("not a valid ELF file"); + result = 1; + goto out_close2; + } + + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); + result = 1; + goto out_close2; + } + + if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) + { + puts ("ELF header does not match"); + result = 1; + goto out_close2; + } + + for (cnt = 1; cnt < 3; ++cnt) + { + Elf_Scn *escn; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + escn = elf_getscn (elf, cnt); + if (escn == NULL) + { + printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + shdr = gelf_getshdr (escn, &shdr_mem); + if (shdr == NULL) + { + printf ("cannot get section header for section %zd: %s\n", + cnt, elf_errmsg (-1)); + result = 1; + continue; + } + + if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]) != 0) + { + printf ("section %zd's name differs: %s vs %s\n", cnt, + elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), + scnnames[cnt]); + result = 1; + } + + if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS)) + { + printf ("section %zd's type differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) + || (cnt == 2 && shdr->sh_flags != 0)) + { + printf ("section %zd's flags differs\n", cnt); + result = 1; + } + + if (shdr->sh_addr != 0) + { + printf ("section %zd's address differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15)) + || (cnt == 2 + && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15) + + sizeof (expecteddata)))) + { + printf ("section %zd's offset differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_size != sizeof (expecteddata)) + || (cnt == 2 && shdr->sh_size != 17)) + { + printf ("section %zd's size differs\n", cnt); + result = 1; + } + + if (shdr->sh_link != 0) + { + printf ("section %zd's link differs\n", cnt); + result = 1; + } + + if (shdr->sh_info != 0) + { + printf ("section %zd's info differs\n", cnt); + result = 1; + } + + if ((cnt == 1 && shdr->sh_addralign != 16) + || (cnt != 1 && shdr->sh_addralign != 1)) + { + printf ("section %zd's addralign differs\n", cnt); + result = 1; + } + + if (shdr->sh_entsize != 0) + { + printf ("section %zd's entsize differs\n", cnt); + result = 1; + } + + if (cnt == 1) + { + Elf_Data *data = elf_getdata (escn, NULL); + + if (data == NULL) + { + printf ("cannot get data of section %zd\n", cnt); + result = 1; + } + else + { + if (data->d_size != sizeof (expecteddata)) + { + printf ("data block size of section %zd wrong: got %zd, " + "expected 96\n", cnt, data->d_size); + result = 1; + } + + if (memcmp (data->d_buf, expecteddata, sizeof (expecteddata)) + != 0) + { + printf ("data block content of section %zd wrong\n", cnt); + result = 1; + } + } + } + } + + out_close2: + elf_end (elf); + out_close: + close (fd); + out: + /* We don't need the file anymore. */ + unlink (fname); + + ebl_closebackend (ebl); + + return result; +} diff --git a/tests/attr-integrate-skel.c b/tests/attr-integrate-skel.c new file mode 100644 index 00000000..644cd272 --- /dev/null +++ b/tests/attr-integrate-skel.c @@ -0,0 +1,109 @@ +/* Test dwarf_get_units finds split DWO CUs. + Copyright (C) 2018 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include +#include +#include +#include + + +int +main (int argc, char *argv[]) +{ + for (int i = 1; i < argc; i++) + { + printf ("file: %s\n", argv[i]); + int fd = open (argv[i], O_RDONLY); + Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ); + if (dbg == NULL) + { + printf ("%s not usable: %s\n", argv[i], dwarf_errmsg (-1)); + return -1; + } + + Dwarf_CU *cu = NULL; + Dwarf_Die cudie, subdie; + uint8_t unit_type; + Dwarf_Half version; + int count = 0; + while (dwarf_get_units (dbg, cu, &cu, &version, + &unit_type, &cudie, &subdie) == 0) + { + count++; + if (unit_type == DW_UT_skeleton) + { + Dwarf_Attribute attr; + Dwarf_Word word; + Dwarf_Addr addr; + + printf ("Split DIE: %s\n", dwarf_diename (&subdie)); + + if (dwarf_attr_integrate (&subdie, + DW_AT_GNU_addr_base, &attr) == NULL + && dwarf_attr_integrate (&subdie, + DW_AT_addr_base, &attr) == NULL) + printf ("No addr_base"); + else if (dwarf_formudata (&attr, &word) != 0) + printf ("Bad addr_base: %s\n", dwarf_errmsg (-1)); + else + printf ("addr_base secoff: 0x%" PRIx64 "\n", word); + + if (dwarf_attr (&subdie, DW_AT_low_pc, &attr) != NULL) + printf ("Unexpected low_pc on split DIE.\n"); + + if (dwarf_attr_integrate (&subdie, + DW_AT_low_pc, &attr) == NULL) + printf ("No low_pc"); + else if (dwarf_formaddr (&attr, &addr) != 0) + printf ("Bad low_pc: %s\n", dwarf_errmsg (-1)); + else + printf ("low_pc addr: 0x%" PRIx64 "\n", addr); + + if (dwarf_hasattr (&subdie, DW_AT_high_pc)) + printf ("Unexpected highpc on split DIE\n"); + if (dwarf_hasattr (&subdie, DW_AT_ranges)) + printf ("Unexpected ranges on split DIE\n"); + + if (dwarf_hasattr_integrate (&subdie, DW_AT_high_pc)) + printf ("Skel has high_pc.\n"); + if (dwarf_hasattr_integrate (&subdie, DW_AT_ranges)) + printf ("Skel has ranges.\n"); + + printf ("\n"); + } + } + + if (count == 0) + { + printf ("No units found\n"); + return -1; + } + + dwarf_end (dbg); + close (fd); + } + + return 0; +} diff --git a/tests/backtrace-child.c b/tests/backtrace-child.c new file mode 100644 index 00000000..8bfed478 --- /dev/null +++ b/tests/backtrace-child.c @@ -0,0 +1,248 @@ +/* Test child for parent backtrace test. + Copyright (C) 2013, 2016 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +/* Command line syntax: ./backtrace-child [--ptraceme|--gencore] + --ptraceme will call ptrace (PTRACE_TRACEME) in the two threads. + --gencore will call abort () at its end. + Main thread will signal SIGUSR2. Other thread will signal SIGUSR1. + There used to be a difference between x86_64 and other architectures. + To test getting a signal at the very first instruction of a function: + PC will get changed to function 'jmp' by backtrace.c function + prepare_thread. Then SIGUSR2 will be signalled to backtrace-child + which will invoke function sigusr2. + This is all done so that signal interrupts execution of the very first + instruction of a function. Properly handled unwind should not slip into + the previous unrelated function. + The tested functionality is arch-independent but the code reproducing it + has to be arch-specific. + On non-x86_64: + sigusr2 gets called by normal function call from function stdarg. + On any arch then sigusr2 calls raise (SIGUSR1) for --ptraceme. + abort () is called otherwise, expected for --gencore core dump. + + Expected x86_64 output: + TID 10276: + # 0 0x7f7ab61e9e6b raise + # 1 0x7f7ab661af47 - 1 main + # 2 0x7f7ab5e3bb45 - 1 __libc_start_main + # 3 0x7f7ab661aa09 - 1 _start + TID 10278: + # 0 0x7f7ab61e9e6b raise + # 1 0x7f7ab661ab3c - 1 sigusr2 + # 2 0x7f7ab5e4fa60 __restore_rt + # 3 0x7f7ab661ab47 jmp + # 4 0x7f7ab661ac92 - 1 stdarg + # 5 0x7f7ab661acba - 1 backtracegen + # 6 0x7f7ab661acd1 - 1 start + # 7 0x7f7ab61e2c53 - 1 start_thread + # 8 0x7f7ab5f0fdbd - 1 __clone + + Expected non-x86_64 (i386) output; __kernel_vsyscall are skipped if found: + TID 10408: + # 0 0xf779f430 __kernel_vsyscall + # 1 0xf7771466 - 1 raise + # 2 0xf77c1d07 - 1 main + # 3 0xf75bd963 - 1 __libc_start_main + # 4 0xf77c1761 - 1 _start + TID 10412: + # 0 0xf779f430 __kernel_vsyscall + # 1 0xf7771466 - 1 raise + # 2 0xf77c18f4 - 1 sigusr2 + # 3 0xf77c1a10 - 1 stdarg + # 4 0xf77c1a2c - 1 backtracegen + # 5 0xf77c1a48 - 1 start + # 6 0xf77699da - 1 start_thread + # 7 0xf769bbfe - 1 __clone + + But the raise jmp patching was unreliable. It depends on the CFI for the raise() + function in glibc to be the same as for the jmp() function. This is not always + the case. Some newer glibc versions rewrote raise() and now the CFA is calculated + differently. So we disable raise jmp patching everywhere. + */ + +#ifdef __x86_64__ +/* #define RAISE_JMP_PATCHING 1 */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __linux__ + +int +main (int argc __attribute__ ((unused)), char **argv) +{ + fprintf (stderr, "%s: Unwinding not supported for this architecture\n", + argv[0]); + return 77; +} + +#else /* __linux__ */ +#include +#include + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define NOINLINE_NOCLONE __attribute__ ((noinline, noclone)) +#else +#define NOINLINE_NOCLONE __attribute__ ((noinline)) +#endif + +#define NORETURN __attribute__ ((noreturn)) +#define UNUSED __attribute__ ((unused)) +#define USED __attribute__ ((used)) + +static int ptraceme, gencore; + +/* Execution will arrive here from jmp by an artificial ptrace-spawn signal. */ + +static NOINLINE_NOCLONE void +sigusr2 (int signo) +{ + assert (signo == SIGUSR2); + if (! gencore) + { + raise (SIGUSR1); + /* Do not return as stack may be invalid due to ptrace-patched PC to the + jmp function. */ + pthread_exit (NULL); + /* Not reached. */ + abort (); + } + /* Here we dump the core for --gencore. */ + raise (SIGABRT); + /* Avoid tail call optimization for the raise call. */ + asm volatile (""); +} + +static NOINLINE_NOCLONE void +dummy1 (void) +{ + asm volatile (""); +} + +#ifdef RAISE_JMP_PATCHING +static NOINLINE_NOCLONE USED void +jmp (void) +{ + /* Not reached, signal will get ptrace-spawn to jump into sigusr2. */ + abort (); +} +#endif + +static NOINLINE_NOCLONE void +dummy2 (void) +{ + asm volatile (""); +} + +static NOINLINE_NOCLONE NORETURN void +stdarg (int f UNUSED, ...) +{ + sighandler_t sigusr2_orig = signal (SIGUSR2, sigusr2); + assert (sigusr2_orig == SIG_DFL); + errno = 0; + if (ptraceme) + { + long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); + assert (l == 0); + } +#ifdef RAISE_JMP_PATCHING + if (! gencore) + { + /* Execution will get PC patched into function jmp. */ + raise (SIGUSR1); + } +#endif + sigusr2 (SIGUSR2); + /* Not reached. */ + abort (); +} + +static NOINLINE_NOCLONE void +dummy3 (void) +{ + asm volatile (""); +} + +static NOINLINE_NOCLONE void +backtracegen (void) +{ + stdarg (1); + /* Here should be no instruction after the stdarg call as it is noreturn + function. It must be stdarg so that it is a call and not jump (jump as + a tail-call). */ +} + +static NOINLINE_NOCLONE void +dummy4 (void) +{ + asm volatile (""); +} + +static void * +start (void *arg UNUSED) +{ + backtracegen (); + /* Not reached. */ + abort (); +} + +int +main (int argc UNUSED, char **argv) +{ + setbuf (stdout, NULL); + assert (*argv++); + ptraceme = (*argv && strcmp (*argv, "--ptraceme") == 0); + argv += ptraceme; + gencore = (*argv && strcmp (*argv, "--gencore") == 0); + argv += gencore; + assert (!*argv); + /* These dummy* functions are there so that each of their surrounding + functions has some unrelated code around. The purpose of some of the + tests is verify unwinding the very first / after the very last instruction + does not inappropriately slip into the unrelated code around. */ + dummy1 (); + dummy2 (); + dummy3 (); + dummy4 (); + if (gencore) + printf ("%ld\n", (long) getpid ()); + pthread_t thread; + int i = pthread_create (&thread, NULL, start, NULL); + // pthread_* functions do not set errno. + assert (i == 0); + if (ptraceme) + { + errno = 0; + long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); + assert (l == 0); + } + if (gencore) + pthread_join (thread, NULL); + else + raise (SIGUSR2); + return 0; +} + +#endif /* ! __linux__ */ + diff --git a/tests/backtrace-data.c b/tests/backtrace-data.c new file mode 100644 index 00000000..c81880d9 --- /dev/null +++ b/tests/backtrace-data.c @@ -0,0 +1,332 @@ +/* Test custom provided Dwfl_Thread_Callbacks vector. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +/* Test custom provided Dwfl_Thread_Callbacks vector. Test mimics what + a ptrace based vector would do. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(__x86_64__) && defined(__linux__) +#include +#include +#include +#include +#include +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) +#endif +#include "system.h" + +#if !defined(__x86_64__) || !defined(__linux__) + +int +main (int argc __attribute__ ((unused)), char **argv) +{ + fprintf (stderr, "%s: x86_64 linux only test\n", + argv[0]); + return 77; +} + +#else /* __x86_64__ && __linux__ */ + +/* The only arch specific code is set_initial_registers. */ + +static int +find_elf (Dwfl_Module *mod __attribute__ ((unused)), + void **userdata __attribute__ ((unused)), + const char *modname __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + char **file_name __attribute__ ((unused)), + Elf **elfp __attribute__ ((unused))) +{ + /* Not used as modules are reported explicitly. */ + assert (0); +} + +static bool +memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, + void *dwfl_arg __attribute__ ((unused))) +{ + pid_t child = dwfl_pid (dwfl); + + errno = 0; + long l = ptrace (PTRACE_PEEKDATA, child, (void *) (uintptr_t) addr, NULL); + + // The unwinder can ask for an invalid address. + // Don't assert on that but just politely refuse. + if (errno != 0) { + errno = 0; + return false; + } + *result = l; + + return true; +} + +/* Return filename and VMA address *BASEP where its mapping starts which + contains ADDR. */ + +static char * +maps_lookup (pid_t pid, Dwarf_Addr addr, GElf_Addr *basep) +{ + char *fname; + int i = asprintf (&fname, "/proc/%ld/maps", (long) pid); + assert (i > 0); + FILE *f = fopen (fname, "r"); + assert (f); + free (fname); + for (;;) + { + // 37e3c22000-37e3c23000 rw-p 00022000 00:11 49532 /lib64/ld-2.14.90.so */ + unsigned long start, end, offset; + i = fscanf (f, "%lx-%lx %*s %lx %*x:%*x %*u", &start, &end, &offset); + if (i != 3) + break; + char *filename = strdup (""); + assert (filename); + size_t filename_len = 0; + for (;;) + { + int c = fgetc (f); + assert (c != EOF); + if (c == '\n') + break; + if (c == ' ' && *filename == '\0') + continue; + filename = realloc (filename, filename_len + 2); + assert (filename); + filename[filename_len++] = c; + filename[filename_len] = '\0'; + } + if (start <= addr && addr < end) + { + i = fclose (f); + assert (i == 0); + + *basep = start - offset; + return filename; + } + free (filename); + } + *basep = 0; + return NULL; +} + +/* Add module containing ADDR to the DWFL address space. + + dwfl_report_elf call here violates Dwfl manipulation as one should call + dwfl_report only between dwfl_report_begin_add and dwfl_report_end. + Current elfutils implementation does not mind as dwfl_report_begin_add is + empty. */ + +static Dwfl_Module * +report_module (Dwfl *dwfl, pid_t child, Dwarf_Addr addr) +{ + GElf_Addr base; + char *long_name = maps_lookup (child, addr, &base); + if (!long_name) + return NULL; // not found + Dwfl_Module *mod = dwfl_report_elf (dwfl, long_name, long_name, -1, + base, false /* add_p_vaddr */); + assert (mod); + free (long_name); + assert (dwfl_addrmodule (dwfl, addr) == mod); + return mod; +} + +static pid_t +next_thread (Dwfl *dwfl, void *dwfl_arg __attribute__ ((unused)), + void **thread_argp) +{ + if (*thread_argp != NULL) + return 0; + /* Put arbitrary non-NULL value into *THREAD_ARGP as a marker so that this + function returns non-zero PID only once. */ + *thread_argp = thread_argp; + return dwfl_pid (dwfl); +} + +static bool +set_initial_registers (Dwfl_Thread *thread, + void *thread_arg __attribute__ ((unused))) +{ + pid_t child = dwfl_pid (dwfl_thread_dwfl (thread)); + + struct user_regs_struct user_regs; + long l = ptrace (PTRACE_GETREGS, child, NULL, &user_regs); + assert (l == 0); + + Dwarf_Word dwarf_regs[17]; + dwarf_regs[0] = user_regs.rax; + dwarf_regs[1] = user_regs.rdx; + dwarf_regs[2] = user_regs.rcx; + dwarf_regs[3] = user_regs.rbx; + dwarf_regs[4] = user_regs.rsi; + dwarf_regs[5] = user_regs.rdi; + dwarf_regs[6] = user_regs.rbp; + dwarf_regs[7] = user_regs.rsp; + dwarf_regs[8] = user_regs.r8; + dwarf_regs[9] = user_regs.r9; + dwarf_regs[10] = user_regs.r10; + dwarf_regs[11] = user_regs.r11; + dwarf_regs[12] = user_regs.r12; + dwarf_regs[13] = user_regs.r13; + dwarf_regs[14] = user_regs.r14; + dwarf_regs[15] = user_regs.r15; + dwarf_regs[16] = user_regs.rip; + bool ok = dwfl_thread_state_registers (thread, 0, 17, dwarf_regs); + assert (ok); + + /* x86_64 has PC contained in its CFI subset of DWARF register set so + elfutils will figure out the real PC value from REGS. + So no need to explicitly call dwfl_thread_state_register_pc. */ + + return true; +} + +static const Dwfl_Thread_Callbacks callbacks = +{ + next_thread, + NULL, /* get_thread */ + memory_read, + set_initial_registers, + NULL, /* detach */ + NULL, /* thread_detach */ +}; + +static int +frame_callback (Dwfl_Frame *state, void *arg) +{ + unsigned *framenop = arg; + Dwarf_Addr pc; + bool isactivation; + if (! dwfl_frame_pc (state, &pc, &isactivation)) + { + error (1, 0, "%s", dwfl_errmsg (-1)); + return 1; + } + Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); + + /* Get PC->SYMNAME. */ + Dwfl *dwfl = dwfl_thread_dwfl (dwfl_frame_thread (state)); + Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); + if (mod == NULL) + mod = report_module (dwfl, dwfl_pid (dwfl), pc_adjusted); + const char *symname = NULL; + symname = dwfl_module_addrname (mod, pc_adjusted); + + printf ("#%2u %#" PRIx64 "%4s\t%s\n", (*framenop)++, (uint64_t) pc, + ! isactivation ? "- 1" : "", symname); + return DWARF_CB_OK; +} + +static int +thread_callback (Dwfl_Thread *thread, void *thread_arg __attribute__ ((unused))) +{ + unsigned frameno = 0; + switch (dwfl_thread_getframes (thread, frame_callback, &frameno)) + { + case 0: + break; + case -1: + error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1)); + break; + default: + abort (); + } + return DWARF_CB_OK; +} + +int +main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))) +{ + /* We use no threads here which can interfere with handling a stream. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + elf_version (EV_CURRENT); + + pid_t child = fork (); + switch (child) + { + case -1: + assert (0); + break; + case 0:; + long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); + assert (l == 0); + raise (SIGUSR1); + return 0; + default: + break; + } + + int status; + pid_t pid = waitpid (child, &status, 0); + assert (pid == child); + assert (WIFSTOPPED (status)); + assert (WSTOPSIG (status) == SIGUSR1); + + static char *debuginfo_path; + static const Dwfl_Callbacks offline_callbacks = + { + .find_debuginfo = dwfl_standard_find_debuginfo, + .debuginfo_path = &debuginfo_path, + .section_address = dwfl_offline_section_address, + .find_elf = find_elf, + }; + Dwfl *dwfl = dwfl_begin (&offline_callbacks); + assert (dwfl); + + struct user_regs_struct user_regs; + long l = ptrace (PTRACE_GETREGS, child, NULL, &user_regs); + assert (l == 0); + report_module (dwfl, child, user_regs.rip); + + bool ok = dwfl_attach_state (dwfl, EM_NONE, child, &callbacks, NULL); + assert (ok); + + /* Multiple threads are not handled here. */ + int err = dwfl_getthreads (dwfl, thread_callback, NULL); + assert (! err); + + dwfl_end (dwfl); + kill (child, SIGKILL); + pid = waitpid (child, &status, 0); + assert (pid == child); + assert (WIFSIGNALED (status)); + assert (WTERMSIG (status) == SIGKILL); + + return EXIT_SUCCESS; +} + +#endif /* x86_64 */ diff --git a/tests/backtrace-dwarf.c b/tests/backtrace-dwarf.c new file mode 100644 index 00000000..f446bc3b --- /dev/null +++ b/tests/backtrace-dwarf.c @@ -0,0 +1,181 @@ +/* Test program for unwinding of complicated DWARF expressions. + Copyright (C) 2013, 2015, 2018 Red Hat, Inc. + This file is part of elfutils. + + 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 3 of the License, or + (at your option) any later version. + + elfutils 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, see . */ + +#include +#include +#include +#include +#include +#include +#include +#include ELFUTILS_HEADER(dwfl) +#include "system.h" + +#ifndef __linux__ + +int +main (int argc __attribute__ ((unused)), char **argv) +{ + fprintf (stderr, "%s: Unwinding not supported for this architecture\n", + argv[0]); + return 77; +} + +#else /* __linux__ */ +#include +#include +#include + +#define main cleanup_13_main +#include "cleanup-13.c" +#undef main + +static void +report_pid (Dwfl *dwfl, pid_t pid) +{ + int result = dwfl_linux_proc_report (dwfl, pid); + if (result < 0) + error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1)); + else if (result > 0) + error (2, result, "dwfl_linux_proc_report"); + + if (dwfl_report_end (dwfl, NULL, NULL) != 0) + error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1)); + + result = dwfl_linux_proc_attach (dwfl, pid, true); + if (result < 0) + error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1)); + else if (result > 0) + error (2, result, "dwfl_linux_proc_attach"); +} + +static Dwfl * +pid_to_dwfl (pid_t pid) +{ + static char *debuginfo_path; + static const Dwfl_Callbacks proc_callbacks = + { + .find_debuginfo = dwfl_standard_find_debuginfo, + .debuginfo_path = &debuginfo_path, + + .find_elf = dwfl_linux_proc_find_elf, + }; + Dwfl *dwfl = dwfl_begin (&proc_callbacks); + if (dwfl == NULL) + error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); + report_pid (dwfl, pid); + return dwfl; +} + +static int +frame_callback (Dwfl_Frame *state, void *frame_arg) +{ + Dwarf_Addr pc; + bool isactivation; + if (! dwfl_frame_pc (state, &pc, &isactivation)) + { + error (0, 0, "%s", dwfl_errmsg (-1)); + return DWARF_CB_ABORT; + } + Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); + + /* Get PC->SYMNAME. */ + Dwfl_Thread *thread = dwfl_frame_thread (state); + Dwfl *dwfl = dwfl_thread_dwfl (thread); + Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); + const char *symname = NULL; + if (mod) + symname = dwfl_module_addrname (mod, pc_adjusted); + + printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname ?: ""); + + if (symname && (strcmp (symname, "main") == 0 + || strcmp (symname, ".main") == 0)) + { + kill (dwfl_pid (dwfl), SIGKILL); + exit (0); + } + + return DWARF_CB_OK; +} + +static int +thread_callback (Dwfl_Thread *thread, void *thread_arg) +{ + if (dwfl_thread_getframes (thread, frame_callback, NULL) == -1) + error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1)); + + /* frame_callback shall exit (0) on success. */ + printf ("dwfl_thread_getframes returned, main not found\n"); + return DWARF_CB_ABORT; +} + +int +__attribute__((section(".main"))) /* Defeat -freorder-blocks-and-partition */ +main (int argc __attribute__ ((unused)), char **argv) +{ + /* We use no threads here which can interfere with handling a stream. */ + __fsetlocking (stdin, FSETLOCKING_BYCALLER); + __fsetlocking (stdout, FSETLOCKING_BYCALLER); + __fsetlocking (stderr, FSETLOCKING_BYCALLER); + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + elf_version (EV_CURRENT); + + pid_t pid = fork (); + switch (pid) + { + case -1: + perror ("fork failed"); + exit (-1); + case 0:; + long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); + if (l != 0) + { + perror ("PTRACE_TRACEME failed"); + exit (-1); + } + cleanup_13_main (); + printf ("cleanup_13_main returned, impossible...\n"); + exit (-1); + default: + break; + } + + errno = 0; + int status; + pid_t got = waitpid (pid, &status, 0); + if (got != pid) + error (1, errno, "waitpid returned %d", got); + if (!WIFSTOPPED (status)) + error (1, 0, "unexpected wait status %u", status); + if (WSTOPSIG (status) != SIGABRT) + error (1, 0, "unexpected signal %u", WSTOPSIG (status)); + + Dwfl *dwfl = pid_to_dwfl (pid); + if (dwfl_getthreads (dwfl, thread_callback, NULL) == -1) + error (1, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1)); + + /* There is an exit (0) call if we find the "main" frame, */ + printf ("dwfl_getthreads returned, main not found\n"); + exit (-1); +} + +#endif /* ! __linux__ */ + diff --git a/tests/backtrace-subr.sh b/tests/backtrace-subr.sh new file mode 100644 index 00000000..53c719df --- /dev/null +++ b/tests/backtrace-subr.sh @@ -0,0 +1,203 @@ +# Copyright (C) 2013, 2015 Red Hat, Inc. +# This file is part of elfutils. +# +# 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 3 of the License, or +# (at your option) any later version. +# +# elfutils 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, see . + +. $srcdir/test-subr.sh + +# Verify one of the backtraced threads contains function 'main'. +check_main() +{ + if grep -w main $1; then + return + fi + echo >&2 $2: no main + false +} + +# Without proper ELF symbols resolution we could get inappropriate weak +# symbol "gsignal" with the same address as the correct symbol "raise". +# It was fixed by GIT commit 78dec228b3cfb2f9300cd0b682ebf416c9674c91 . +# [patch] Improve ELF symbols preference (global > weak) +# https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/002624.html +check_gsignal() +{ + if ! grep -w gsignal $1; then + return + fi + echo >&2 $2: found gsignal + false +} + + +# Makes sure we saw the function that initiated the backtrace +# when the core was generated through the tests backtrace --gencore. +# This might disappear when frame pointer chasing gone bad. +check_backtracegen() +{ + if grep -w backtracegen $1; then + return + fi + echo >&2 $2: no backtracegen + false +} + +# Verify the STDERR output does not contain unexpected errors. +# In some cases we cannot reliably find out we got behind _start as some +# operating system do not properly terminate CFI by undefined PC. +# Ignore it here as it is a bug of OS, not a bug of elfutils. +check_err() +{ + if [ $(egrep -v <$1 'dwfl_thread_getframes: (No DWARF information found|no matching address range|address out of range|Invalid register|\(null\))$' \ + | wc -c) \ + -eq 0 ] + then + return + fi + echo >&2 $2: neither empty nor just out of DWARF + false +} + +check_all() +{ + bt=$1 + err=$2 + testname=$3 + check_main $bt $testname + check_gsignal $bt $testname + check_err $err $testname +} + +check_unsupported() +{ + err=$1 + testname=$2 + if grep -q ': Unwinding not supported for this architecture$' $err; then + echo >&2 $testname: arch not supported + test_cleanup + exit 77 + fi +} + +check_native_unsupported() +{ + err=$1 + testname=$2 + check_unsupported $err $testname + + # ARM is special. It is supported, but it doesn't use .eh_frame by default + # making the native tests fail unless debuginfo (for glibc) is installed + # and we can fall back on .debug_frame for the CFI. + case "`uname -m`" in + arm* ) + if egrep 'dwfl_thread_getframes(.*)No DWARF information found' $err; then + echo >&2 $testname: arm needs debuginfo installed for all libraries + exit 77 + fi + ;; + esac +} + +check_core() +{ + arch=$1 + testfiles backtrace.$arch.{exec,core} + tempfiles backtrace.$arch.{bt,err} + echo ./backtrace ./backtrace.$arch.{exec,core} + testrun ${abs_builddir}/backtrace -e ./backtrace.$arch.exec --core=./backtrace.$arch.core 1>backtrace.$arch.bt 2>backtrace.$arch.err || true + cat backtrace.$arch.{bt,err} + check_unsupported backtrace.$arch.err backtrace.$arch.core + check_all backtrace.$arch.{bt,err} backtrace.$arch.core + check_backtracegen backtrace.$arch.bt backtrace.$arch.core +} + +# Backtrace live process. +# Do not abort on non-zero exit code due to some warnings of ./backtrace +# - see function check_err. +check_native() +{ + child=$1 + tempfiles $child.{bt,err} + (set +ex; testrun ${abs_builddir}/backtrace --backtrace-exec=${abs_builddir}/$child 1>$child.bt 2>$child.err; true) + cat $child.{bt,err} + check_native_unsupported $child.err $child + check_all $child.{bt,err} $child +} + +# Backtrace core file. +check_native_core() +{ +# systemd-coredump/coredumpctl doesn't seem to like concurrent core dumps +# use a lock file (fd 200) tests/core-dump-backtrace.lock +( + child=$1 + + # Disable valgrind while dumping core. + SAVED_VALGRIND_CMD="$VALGRIND_CMD" + unset VALGRIND_CMD + + # Wait for lock for 10 seconds or skip. + flock -x -w 10 200 || exit 77; + + # Skip the test if we cannot adjust core ulimit. + pid="`ulimit -c unlimited || exit 77; set +ex; testrun ${abs_builddir}/$child --gencore; true`" + core="core.$pid" + # see if /proc/sys/kernel/core_uses_pid is set to 0 + if [ -f core ]; then + mv core "$core" + fi + type -P coredumpctl && have_coredumpctl=1 || have_coredumpctl=0 + if [ ! -f "$core" -a $have_coredumpctl -eq 1 ]; then + # Maybe systemd-coredump took it. But give it some time to dump first... + sleep 1 + coredumpctl --output="$core" dump $pid || rm -f $core + + # Try a couple of times after waiting some more if something went wrong... + if [ ! -f "$core" ]; then + sleep 2 + coredumpctl --output="$core" dump $pid || rm -f $core + fi + + if [ ! -f "$core" ]; then + sleep 3 + coredumpctl --output="$core" dump $pid || rm -f $core + fi + fi + if [ ! -f "$core" ]; then + # In some containers our view of pids is confused. Since tests are + # run in a new fresh directory any core here is most like is ours. + if ls core.[0-9]* 1> /dev/null 2>&1; then + mv core.[0-9]* "$core" + fi + fi + if [ ! -f "$core" ]; then + echo "No $core file generated"; + exit 77; + fi + + if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then + VALGRIND_CMD="$SAVED_VALGRIND_CMD" + export VALGRIND_CMD + fi + + # Do not abort on non-zero exit code due to some warnings of ./backtrace + # - see function check_err. + tempfiles $core{,.{bt,err}} + (set +ex; testrun ${abs_builddir}/backtrace -e ${abs_builddir}/$child --core=$core 1>$core.bt 2>$core.err; true) + cat $core.{bt,err} + check_native_unsupported $core.err $child-$core + check_all $core.{bt,err} $child-$core + rm $core{,.{bt,err}} +) 200>${abs_builddir}/core-dump-backtrace.lock +} diff --git a/tests/backtrace.aarch64.core.bz2 b/tests/backtrace.aarch64.core.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..3082a5ac0ebd059c41bd5f18c2b0967bc63845c1 GIT binary patch literal 7865 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 literal 0 HcmV?d00001 diff --git a/tests/backtrace.aarch64.exec.bz2 b/tests/backtrace.aarch64.exec.bz2 new file mode 100755 index 0000000000000000000000000000000000000000..66216b525f753ac6fce2b8f5b5f957c1a060ffdc GIT binary patch literal 370058 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‡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�B@1>yFeH$N*(l^5o>^l{ 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

b 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

ECgFeYnB@Dvz{aI_jGcmC?P-=K*f)a+ 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

QcP4UAfochoFN4tVk$@C_3f@G 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

BIPmkmw+CqSV8W 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